VirtualBox

Changeset 78468 in vbox for trunk/src/VBox/Additions/WINNT


Ignore:
Timestamp:
May 11, 2019 1:05:49 AM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
130497
Message:

winnt/vboxsf: USe new remove function that also closes the handle to combine two typical host calls and speed up file+dir removal. bugref:9172

Location:
trunk/src/VBox/Additions/WINNT/SharedFolders/driver
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/SharedFolders/driver/path.cpp

    r78465 r78468  
    873873    PMRX_VBOX_FOBX              pVBoxFobx         = VBoxMRxGetFileObjectExtension(capFobx);
    874874    PUNICODE_STRING             pRemainingName    = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
    875     uint16_t                    cwcRemainingName  = pRemainingName->Length / sizeof(WCHAR);
     875    uint16_t const              cwcRemainingName  = pRemainingName->Length / sizeof(WCHAR);
    876876
    877877    Log(("VBOXSF: vbsfNtRemove: Delete %.*ls. open count = %d\n",
     
    880880
    881881    /*
    882      * We allocate a single request buffer for the closing and deletion to save time.
     882     * We've got function that does both deletion and handle closing starting with 6.0.8,
     883     * this saves us a host call when just deleting the file/dir.
    883884     */
    884     AssertCompile(sizeof(VBOXSFCLOSEREQ) <= sizeof(VBOXSFREMOVEREQ));
    885     AssertReturn((cwcRemainingName + 1) * sizeof(RTUTF16) < _64K, STATUS_NAME_TOO_LONG);
    886     size_t cbReq = RT_UOFFSETOF(VBOXSFREMOVEREQ, StrPath.String) + (cwcRemainingName + 1) * sizeof(RTUTF16);
    887     union MyCloseAndRemoveReq
    888     {
    889         VBOXSFCLOSEREQ  Close;
    890         VBOXSFREMOVEREQ Remove;
    891     } *pReq = (union MyCloseAndRemoveReq *)VbglR0PhysHeapAlloc((uint32_t)cbReq);
    892     if (pReq)
    893         RT_ZERO(*pReq);
    894     else
    895         return STATUS_INSUFFICIENT_RESOURCES;
    896 /** @todo Create a function that combines closing and removing since that is
    897  * usually what NT guests will be doing.  Should in theory speed up deletion by 33%. */
    898 
    899     /*
    900      * Close file first if not already done.  We dont use vbsfNtCloseFileHandle here
    901      * as we got our own request buffer and have no need to update any file info.
    902      */
    903     if (pVBoxFobx->hFile != SHFL_HANDLE_NIL)
    904     {
    905         int vrcClose = VbglR0SfHostReqClose(pNetRootExtension->map.root, &pReq->Close, pVBoxFobx->hFile);
    906         pVBoxFobx->hFile = SHFL_HANDLE_NIL;
    907         if (RT_FAILURE(vrcClose))
    908             Log(("VBOXSF: vbsfNtRemove: Closing the handle failed! vrcClose %Rrc, hFile %#RX64 (probably)\n",
    909                  vrcClose, pReq->Close.Parms.u64Handle.u.value64));
    910     }
    911 
    912     /*
    913      * Try remove the file.  The path to the file/whatever string is
    914      * embedded in the request buffer, so we have to assemble it ourselves here.
    915      */
    916     uint16_t cwcToCopy = pRemainingName->Length / sizeof(WCHAR);
    917     AssertMsg(cwcToCopy == cwcRemainingName, ("%#x, was %#x; FCB exclusivity: %d\n", cwcToCopy, cwcRemainingName, RxIsFcbAcquiredExclusive(capFcb)));
    918     if (cwcToCopy <= cwcRemainingName)
    919     { /* Extremely likely... */ }
    920     else
    921     {
    922         VbglR0PhysHeapFree(pReq);
    923         AssertLogRelMsgFailed(("File scheduled for removal was renamed?!?: %#x from %#x; FCB exclusivity: %d\n",
    924                                cwcToCopy, cwcRemainingName, RxIsFcbAcquiredExclusive(capFcb)));
    925         cwcRemainingName = cwcToCopy;
    926         AssertReturn((cwcRemainingName + 1) * sizeof(RTUTF16) < _64K, STATUS_NAME_TOO_LONG);
    927         cbReq = RT_UOFFSETOF(VBOXSFREMOVEREQ, StrPath.String) + (cwcRemainingName + 1) * sizeof(RTUTF16);
    928         pReq = (union MyCloseAndRemoveReq *)VbglR0PhysHeapAlloc((uint32_t)cbReq);
     885    uint32_t const  fRemove = pVBoxFobx->Info.Attr.fMode & RTFS_DOS_DIRECTORY ? SHFL_REMOVE_DIR : SHFL_REMOVE_FILE;
     886    NTSTATUS        Status;
     887    int             vrc;
     888    if (g_uSfLastFunction >= SHFL_FN_CLOSE_AND_REMOVE)
     889    {
     890        size_t const cbReq = RT_UOFFSETOF(VBOXSFCLOSEANDREMOVEREQ, StrPath.String) + (cwcRemainingName + 1) * sizeof(RTUTF16);
     891        VBOXSFCLOSEANDREMOVEREQ *pReq = (VBOXSFCLOSEANDREMOVEREQ *)VbglR0PhysHeapAlloc((uint32_t)cbReq);
    929892        if (pReq)
    930893            RT_ZERO(*pReq);
    931894        else
    932895            return STATUS_INSUFFICIENT_RESOURCES;
    933         AssertMsgReturnStmt(cwcToCopy == pRemainingName->Length / sizeof(WCHAR),
    934                             ("%#x, now %#x;\n", cwcToCopy == pRemainingName->Length / sizeof(WCHAR)),
     896
     897        memcpy(&pReq->StrPath.String, pRemainingName->Buffer, cwcRemainingName * sizeof(RTUTF16));
     898        pReq->StrPath.String.utf16[cwcRemainingName] = '\0';
     899        pReq->StrPath.u16Length = cwcRemainingName * 2;
     900        pReq->StrPath.u16Size   = cwcRemainingName * 2 + (uint16_t)sizeof(RTUTF16);
     901        vrc = VbglR0SfHostReqCloseAndRemove(pNetRootExtension->map.root, pReq, fRemove, pVBoxFobx->hFile);
     902        pVBoxFobx->hFile = SHFL_HANDLE_NIL;
     903
     904        VbglR0PhysHeapFree(pReq);
     905    }
     906    else
     907    {
     908        /*
     909         * We allocate a single request buffer for the closing and deletion to save time.
     910         */
     911        AssertCompile(sizeof(VBOXSFCLOSEREQ) <= sizeof(VBOXSFREMOVEREQ));
     912        AssertReturn((cwcRemainingName + 1) * sizeof(RTUTF16) < _64K, STATUS_NAME_TOO_LONG);
     913        size_t cbReq = RT_UOFFSETOF(VBOXSFREMOVEREQ, StrPath.String) + (cwcRemainingName + 1) * sizeof(RTUTF16);
     914        union MyCloseAndRemoveReq
     915        {
     916            VBOXSFCLOSEREQ  Close;
     917            VBOXSFREMOVEREQ Remove;
     918        } *pReq = (union MyCloseAndRemoveReq *)VbglR0PhysHeapAlloc((uint32_t)cbReq);
     919        if (pReq)
     920            RT_ZERO(*pReq);
     921        else
     922            return STATUS_INSUFFICIENT_RESOURCES;
     923
     924        /*
     925         * Close file first if not already done.  We dont use vbsfNtCloseFileHandle here
     926         * as we got our own request buffer and have no need to update any file info.
     927         */
     928        if (pVBoxFobx->hFile != SHFL_HANDLE_NIL)
     929        {
     930            int vrcClose = VbglR0SfHostReqClose(pNetRootExtension->map.root, &pReq->Close, pVBoxFobx->hFile);
     931            pVBoxFobx->hFile = SHFL_HANDLE_NIL;
     932            if (RT_FAILURE(vrcClose))
     933                Log(("VBOXSF: vbsfNtRemove: Closing the handle failed! vrcClose %Rrc, hFile %#RX64 (probably)\n",
     934                     vrcClose, pReq->Close.Parms.u64Handle.u.value64));
     935        }
     936
     937        /*
     938         * Try remove the file.
     939         */
     940        uint16_t const cwcToCopy = pRemainingName->Length / sizeof(WCHAR);
     941        AssertMsgReturnStmt(cwcToCopy == cwcRemainingName,
     942                            ("%#x, was %#x; FCB exclusivity: %d\n", cwcToCopy, cwcRemainingName, RxIsFcbAcquiredExclusive(capFcb)),
    935943                            VbglR0PhysHeapFree(pReq), STATUS_INTERNAL_ERROR);
    936     }
    937 
    938     memcpy(&pReq->Remove.StrPath.String, pRemainingName->Buffer, cwcToCopy * sizeof(RTUTF16));
    939     pReq->Remove.StrPath.String.utf16[cwcToCopy] = '\0';
    940     pReq->Remove.StrPath.u16Length = cwcToCopy * 2;
    941     pReq->Remove.StrPath.u16Size   = cwcToCopy * 2 + (uint16_t)sizeof(RTUTF16);
    942     int vrc = VbglR0SfHostReqRemove(pNetRootExtension->map.root, &pReq->Remove,
    943                                     pVBoxFobx->Info.Attr.fMode & RTFS_DOS_DIRECTORY ? SHFL_REMOVE_DIR : SHFL_REMOVE_FILE);
    944     NTSTATUS Status;
     944        memcpy(&pReq->Remove.StrPath.String, pRemainingName->Buffer, cwcToCopy * sizeof(RTUTF16));
     945        pReq->Remove.StrPath.String.utf16[cwcToCopy] = '\0';
     946        pReq->Remove.StrPath.u16Length = cwcToCopy * 2;
     947        pReq->Remove.StrPath.u16Size   = cwcToCopy * 2 + (uint16_t)sizeof(RTUTF16);
     948        vrc = VbglR0SfHostReqRemove(pNetRootExtension->map.root, &pReq->Remove, fRemove);
     949
     950        VbglR0PhysHeapFree(pReq);
     951    }
     952
    945953    if (RT_SUCCESS(vrc))
    946954    {
     
    954962        Status = vbsfNtVBoxStatusToNt(vrc);
    955963    }
    956     VbglR0PhysHeapFree(pReq);
    957964
    958965    Log(("VBOXSF: vbsfNtRemove: Returned %#010X (%Rrc)\n", Status, vrc));
  • trunk/src/VBox/Additions/WINNT/SharedFolders/driver/vbsf.h

    r78368 r78468  
    5656 */
    5757extern PRDBSS_DEVICE_OBJECT VBoxMRxDeviceObject;
     58extern uint32_t             g_uSfLastFunction;
    5859
    5960/**
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette