VirtualBox

Ignore:
Timestamp:
Apr 30, 2019 3:48:46 AM (6 years ago)
Author:
vboxsync
Message:

winnt/vboxsf: Reworked the set-timestamp handling. Need testcase and some host service tinkering. Also optimized handle closing. bugref:9172

File:
1 edited

Legend:

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

    r78339 r78355  
    592592    pVBoxFobx->pSrvCall = RxContext->Create.pSrvCall;
    593593    pVBoxFobx->Info = Info;
    594     vbsfNtCopyInfoToLegacy(pVBoxFobx, &Info);
     594    vbsfNtBasicInfoFromVBoxObjInfo(&pVBoxFobx->FileBasicInfo, &Info);
    595595    Log(("VBOXSF: MRxCreate: FileBasicInformation: CreationTime   %RX64\n", pVBoxFobx->FileBasicInfo.CreationTime.QuadPart));
    596596    Log(("VBOXSF: MRxCreate: FileBasicInformation: LastAccessTime %RX64\n", pVBoxFobx->FileBasicInfo.LastAccessTime.QuadPart));
     
    663663}
    664664
    665 static NTSTATUS vbsfSetFileInfoOnClose(PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension,
    666                                        PMRX_VBOX_FOBX pVBoxFobx,
    667                                        PFILE_BASIC_INFORMATION pInfo,
    668                                        BYTE SetAttrFlags)
    669 {
    670     NTSTATUS Status = STATUS_SUCCESS;
    671 
    672     int vrc;
    673     PSHFLFSOBJINFO pSHFLFileInfo;
    674 
    675     uint8_t *pHGCMBuffer = NULL;
    676     uint32_t cbBuffer = 0;
    677 
    678     Log(("VBOXSF: vbsfSetFileInfoOnClose: SetAttrFlags 0x%02X\n", SetAttrFlags));
    679     Log(("VBOXSF: vbsfSetFileInfoOnClose: FileBasicInformation: CreationTime   %RX64\n", pInfo->CreationTime.QuadPart));
    680     Log(("VBOXSF: vbsfSetFileInfoOnClose: FileBasicInformation: LastAccessTime %RX64\n", pInfo->LastAccessTime.QuadPart));
    681     Log(("VBOXSF: vbsfSetFileInfoOnClose: FileBasicInformation: LastWriteTime  %RX64\n", pInfo->LastWriteTime.QuadPart));
    682     Log(("VBOXSF: vbsfSetFileInfoOnClose: FileBasicInformation: ChangeTime     %RX64\n", pInfo->ChangeTime.QuadPart));
    683     Log(("VBOXSF: vbsfSetFileInfoOnClose: FileBasicInformation: FileAttributes %RX32\n", pInfo->FileAttributes));
    684 
    685     if (SetAttrFlags == 0)
    686     {
    687         Log(("VBOXSF: vbsfSetFileInfo: nothing to set\n"));
    688         return STATUS_SUCCESS;
    689     }
    690 
    691     cbBuffer = sizeof(SHFLFSOBJINFO);
    692     pHGCMBuffer = (uint8_t *)vbsfNtAllocNonPagedMem(cbBuffer);
    693     if (!pHGCMBuffer)
    694     {
    695         AssertFailed();
    696         return STATUS_INSUFFICIENT_RESOURCES;
    697     }
    698     RtlZeroMemory(pHGCMBuffer, cbBuffer);
    699     pSHFLFileInfo = (PSHFLFSOBJINFO)pHGCMBuffer;
    700 
    701     /* The properties, that need to be changed, are set to something other than zero */
    702     if (pInfo->CreationTime.QuadPart && (SetAttrFlags & VBOX_FOBX_F_INFO_CREATION_TIME) != 0)
    703         RTTimeSpecSetNtTime(&pSHFLFileInfo->BirthTime, pInfo->CreationTime.QuadPart);
    704     if (pInfo->LastAccessTime.QuadPart && (SetAttrFlags & VBOX_FOBX_F_INFO_LASTACCESS_TIME) != 0)
    705         RTTimeSpecSetNtTime(&pSHFLFileInfo->AccessTime, pInfo->LastAccessTime.QuadPart);
    706     if (pInfo->LastWriteTime.QuadPart && (SetAttrFlags & VBOX_FOBX_F_INFO_LASTWRITE_TIME) != 0)
    707         RTTimeSpecSetNtTime(&pSHFLFileInfo->ModificationTime, pInfo->LastWriteTime.QuadPart);
    708     if (pInfo->ChangeTime.QuadPart && (SetAttrFlags & VBOX_FOBX_F_INFO_CHANGE_TIME) != 0)
    709         RTTimeSpecSetNtTime(&pSHFLFileInfo->ChangeTime, pInfo->ChangeTime.QuadPart);
    710     if (pInfo->FileAttributes && (SetAttrFlags & VBOX_FOBX_F_INFO_ATTRIBUTES) != 0) /// @todo r=bird: never ever set.
    711         pSHFLFileInfo->Attr.fMode = NTToVBoxFileAttributes(pInfo->FileAttributes);
    712 
    713     vrc = VbglR0SfFsInfo(&g_SfClient, &pNetRootExtension->map, pVBoxFobx->hFile,
    714                          SHFL_INFO_SET | SHFL_INFO_FILE, &cbBuffer, (PSHFLDIRINFO)pSHFLFileInfo);
    715 
    716     if (vrc != VINF_SUCCESS)
    717         Status = vbsfNtVBoxStatusToNt(vrc);
    718 
    719     if (pHGCMBuffer)
    720         vbsfNtFreeNonPagedMem(pHGCMBuffer);
    721 
    722     Log(("VBOXSF: vbsfSetFileInfo: Returned 0x%08X\n", Status));
    723     return Status;
    724 }
    725 
    726665/**
    727666 * Closes an opened file handle of a MRX_VBOX_FOBX.
     
    732671 */
    733672NTSTATUS vbsfNtCloseFileHandle(PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension,
    734                                PMRX_VBOX_FOBX pVBoxFobx)
    735 {
    736     NTSTATUS Status = STATUS_SUCCESS;
    737 
    738     int vrc;
    739 
     673                               PMRX_VBOX_FOBX pVBoxFobx,
     674                               PVBSFNTFCBEXT pVBoxFcbx)
     675{
    740676    if (pVBoxFobx->hFile == SHFL_HANDLE_NIL)
    741677    {
     
    744680    }
    745681
    746     Log(("VBOXSF: vbsfCloseFileHandle: 0x%RX64, on close info 0x%02X\n",
    747          pVBoxFobx->hFile, pVBoxFobx->SetFileInfoOnCloseFlags));
    748 
    749     if (pVBoxFobx->SetFileInfoOnCloseFlags)
    750     {
    751         /* If the file timestamps were set by the user, then update them before closing the handle,
    752          * to cancel any effect of the file read/write operations on the host.
    753          */
    754         Status = vbsfSetFileInfoOnClose(pNetRootExtension,
    755                                         pVBoxFobx,
    756                                         &pVBoxFobx->FileBasicInfo,
    757                                         pVBoxFobx->SetFileInfoOnCloseFlags);
    758     }
    759 
    760     vrc = VbglR0SfClose(&g_SfClient,
    761                         &pNetRootExtension->map,
    762                         pVBoxFobx->hFile);
     682    Log(("VBOXSF: vbsfCloseFileHandle: 0x%RX64, fTimestampsUpdatingSuppressed = %#x, fTimestampsImplicitlyUpdated = %#x\n",
     683         pVBoxFobx->hFile, pVBoxFobx->fTimestampsUpdatingSuppressed, pVBoxFobx->fTimestampsImplicitlyUpdated));
     684
     685    /*
     686     * We allocate a single request buffer for the timestamp updating and the closing
     687     * to save time (at the risk of running out of heap, but whatever).
     688     */
     689    union MyCloseAndInfoReq
     690    {
     691        VBOXSFCLOSEREQ   Close;
     692        VBOXSFOBJINFOREQ Info;
     693    } *pReq = (union MyCloseAndInfoReq *)VbglR0PhysHeapAlloc(sizeof(*pReq));
     694    if (pReq)
     695        RT_ZERO(*pReq);
     696    else
     697        return STATUS_INSUFF_SERVER_RESOURCES;
     698
     699    /*
     700     * Restore timestamp that we may implicitly been updated via this handle
     701     * after the user explicitly set them or turn off implict updating (the -1 value).
     702     *
     703     * Note! We ignore the status of this operation.
     704     */
     705    Assert(pVBoxFcbx);
     706    uint8_t fUpdateTs = pVBoxFobx->fTimestampsUpdatingSuppressed & pVBoxFobx->fTimestampsImplicitlyUpdated;
     707    if (fUpdateTs)
     708    {
     709        /** @todo skip this if the host is windows and fTimestampsUpdatingSuppressed == fTimestampsSetByUser */
     710        /** @todo pass -1 timestamps thru so we can always skip this on windows hosts! */
     711        if (   (fUpdateTs & VBOX_FOBX_F_INFO_LASTACCESS_TIME)
     712            && pVBoxFcbx->pFobxLastAccessTime == pVBoxFobx)
     713            pReq->Info.ObjInfo.AccessTime        = pVBoxFobx->Info.AccessTime;
     714        else
     715            fUpdateTs &= ~VBOX_FOBX_F_INFO_LASTACCESS_TIME;
     716
     717        if (   (fUpdateTs & VBOX_FOBX_F_INFO_LASTWRITE_TIME)
     718            && pVBoxFcbx->pFobxLastWriteTime  == pVBoxFobx)
     719            pReq->Info.ObjInfo.ModificationTime  = pVBoxFobx->Info.ModificationTime;
     720        else
     721            fUpdateTs &= ~VBOX_FOBX_F_INFO_LASTWRITE_TIME;
     722
     723        if (   (fUpdateTs & VBOX_FOBX_F_INFO_CHANGE_TIME)
     724            && pVBoxFcbx->pFobxChangeTime     == pVBoxFobx)
     725            pReq->Info.ObjInfo.ChangeTime        = pVBoxFobx->Info.ChangeTime;
     726        else
     727            fUpdateTs &= ~VBOX_FOBX_F_INFO_CHANGE_TIME;
     728        if (fUpdateTs)
     729        {
     730            Log(("VBOXSF: vbsfCloseFileHandle: Updating timestamp: %#x\n", fUpdateTs));
     731            int vrc = VbglR0SfHostReqSetObjInfo(pNetRootExtension->map.root, &pReq->Info, pVBoxFobx->hFile);
     732            if (RT_FAILURE(vrc))
     733                Log(("VBOXSF: vbsfCloseFileHandle: VbglR0SfHostReqSetObjInfo failed for fUpdateTs=%#x: %Rrc\n", fUpdateTs, vrc));
     734            RT_NOREF(vrc);
     735        }
     736        else
     737            Log(("VBOXSF: vbsfCloseFileHandle: no timestamp needing updating\n"));
     738    }
     739
     740    /* This isn't strictly necessary, but best to keep things clean. */
     741    pVBoxFobx->fTimestampsSetByUser          = 0;
     742    pVBoxFobx->fTimestampsUpdatingSuppressed = 0;
     743    pVBoxFobx->fTimestampsImplicitlyUpdated  = 0;
     744    if (pVBoxFcbx->pFobxLastAccessTime == pVBoxFobx)
     745        pVBoxFcbx->pFobxLastAccessTime = NULL;
     746    if (pVBoxFcbx->pFobxLastWriteTime  == pVBoxFobx)
     747        pVBoxFcbx->pFobxLastWriteTime  = NULL;
     748    if (pVBoxFcbx->pFobxChangeTime     == pVBoxFobx)
     749        pVBoxFcbx->pFobxChangeTime     = NULL;
     750
     751    /*
     752     * Now close the handle.
     753     */
     754    int vrc = VbglR0SfHostReqClose(pNetRootExtension->map.root, &pReq->Close, pVBoxFobx->hFile);
    763755
    764756    pVBoxFobx->hFile = SHFL_HANDLE_NIL;
    765757
    766     if (vrc != VINF_SUCCESS)
    767         Status = vbsfNtVBoxStatusToNt(vrc);
    768 
    769     Log(("VBOXSF: vbsfCloseFileHandle: Returned 0x%08X\n", Status));
     758    VbglR0PhysHeapFree(pReq);
     759
     760    NTSTATUS const Status = RT_SUCCESS(vrc) ? STATUS_SUCCESS : vbsfNtVBoxStatusToNt(vrc);
     761    Log(("VBOXSF: vbsfCloseFileHandle: Returned 0x%08X (vrc=%Rrc)\n", Status, vrc));
    770762    return Status;
    771763}
     
    806798    /* Close file */
    807799    if (pVBoxFobx->hFile != SHFL_HANDLE_NIL)
    808         vbsfNtCloseFileHandle(pNetRootExtension, pVBoxFobx);
     800        vbsfNtCloseFileHandle(pNetRootExtension, pVBoxFobx, VBoxMRxGetFcbExtension(capFcb));
    809801
    810802    if (capFcb->FcbState & FCB_STATE_DELETE_ON_CLOSE)
     
    844836    /* Close file first if not already done. */
    845837    if (pVBoxFobx->hFile != SHFL_HANDLE_NIL)
    846         vbsfNtCloseFileHandle(pNetRootExtension, pVBoxFobx);
     838        vbsfNtCloseFileHandle(pNetRootExtension, pVBoxFobx, VBoxMRxGetFcbExtension(capFcb));
    847839
    848840    Log(("VBOXSF: vbsfNtRemove: RemainingName->Length %d\n", RemainingName->Length));
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