VirtualBox

Changeset 78487 in vbox for trunk/src/VBox/Additions


Ignore:
Timestamp:
May 13, 2019 11:25:38 PM (6 years ago)
Author:
vboxsync
Message:

winnt/vboxsf: FileFsSizeInformation and FileFsFullSizeInformation. bugref:9172

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

Legend:

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

    r78473 r78487  
    2222#include "vbsf.h"
    2323#include <iprt/err.h>
     24#include <iprt/asm.h>
    2425
    2526extern "C" NTSTATUS NTAPI RxSetEndOfFileInfo(PRX_CONTEXT, PIRP, PFCB, PFOBX);
     
    535536        if (RT_SUCCESS(vrc))
    536537        {
    537             pVBoxFcbX->VolInfo           = pReq->VolInfo;
     538            /* Make the units compatible with NT before assigning. */
     539            if (pReq->VolInfo.ulBytesPerSector != 0)
     540            {
     541                if (pReq->VolInfo.ulBytesPerAllocationUnit > pReq->VolInfo.ulBytesPerSector)
     542                {
     543                    uint32_t cSectorsPerUnit = pReq->VolInfo.ulBytesPerAllocationUnit / pReq->VolInfo.ulBytesPerSector;
     544                    pReq->VolInfo.ulBytesPerAllocationUnit = pReq->VolInfo.ulBytesPerSector * cSectorsPerUnit;
     545                }
     546                else if (pReq->VolInfo.ulBytesPerAllocationUnit < pReq->VolInfo.ulBytesPerSector)
     547                    pReq->VolInfo.ulBytesPerAllocationUnit = pReq->VolInfo.ulBytesPerSector;
     548            }
     549            else if (pReq->VolInfo.ulBytesPerAllocationUnit == 0)
     550                pReq->VolInfo.ulBytesPerSector = pReq->VolInfo.ulBytesPerAllocationUnit = 512;
     551            else
     552                pReq->VolInfo.ulBytesPerSector = pReq->VolInfo.ulBytesPerAllocationUnit;
     553
     554            /* Copy the info assigning: */
     555            ASMCompilerBarrier();
     556            pVBoxFcbX->VolInfo.ullTotalAllocationBytes       = pReq->VolInfo.ullTotalAllocationBytes;
     557            pVBoxFcbX->VolInfo.ullAvailableAllocationBytes   = pReq->VolInfo.ullAvailableAllocationBytes;
     558            pVBoxFcbX->VolInfo.ulBytesPerAllocationUnit      = pReq->VolInfo.ulBytesPerAllocationUnit;
     559            pVBoxFcbX->VolInfo.ulBytesPerSector              = pReq->VolInfo.ulBytesPerSector;
     560            pVBoxFcbX->VolInfo.ulSerial                      = pReq->VolInfo.ulSerial;
     561            pVBoxFcbX->VolInfo.fsProperties.cbMaxComponent   = pReq->VolInfo.fsProperties.cbMaxComponent;
     562            pVBoxFcbX->VolInfo.fsProperties.fRemote          = pReq->VolInfo.fsProperties.fRemote;
     563            pVBoxFcbX->VolInfo.fsProperties.fCaseSensitive   = pReq->VolInfo.fsProperties.fCaseSensitive;
     564            pVBoxFcbX->VolInfo.fsProperties.fReadOnly        = pReq->VolInfo.fsProperties.fReadOnly;
     565            pVBoxFcbX->VolInfo.fsProperties.fSupportsUnicode = pReq->VolInfo.fsProperties.fSupportsUnicode;
     566            pVBoxFcbX->VolInfo.fsProperties.fCompressed      = pReq->VolInfo.fsProperties.fCompressed;
     567            pVBoxFcbX->VolInfo.fsProperties.fFileCompression = pReq->VolInfo.fsProperties.fFileCompression;
     568            ASMWriteFence();
    538569            pVBoxFcbX->nsVolInfoUpToDate = RTTimeSystemNanoTS();
     570            ASMWriteFence();
     571
    539572            rcNt = STATUS_SUCCESS;
    540573        }
     
    552585 * Handles NtQueryVolumeInformationFile / FileFsVolumeInformation
    553586 */
    554 static NTSTATUS vbsfNtQueryVolumeInfo(IN OUT PRX_CONTEXT pRxContext,
    555                                       PFILE_FS_VOLUME_INFORMATION pInfo,
    556                                       ULONG cbInfo,
    557                                       PMRX_NET_ROOT pNetRoot,
    558                                       PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension,
    559                                       PMRX_VBOX_FOBX pVBoxFobx,
    560                                       PVBSFNTFCBEXT pVBoxFcbX)
     587static NTSTATUS vbsfNtQueryFsVolumeInfo(IN OUT PRX_CONTEXT pRxContext,
     588                                        PFILE_FS_VOLUME_INFORMATION pInfo,
     589                                        ULONG cbInfo,
     590                                        PMRX_NET_ROOT pNetRoot,
     591                                        PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension,
     592                                        PMRX_VBOX_FOBX pVBoxFobx,
     593                                        PVBSFNTFCBEXT pVBoxFcbX)
    561594{
    562595    /*
     
    666699}
    667700
     701/**
     702 * Handles NtQueryVolumeInformationFile / FileFsSizeInformation
     703 *
     704 * @note Almost identical to vbsfNtQueryFsFullSizeInfo.
     705 */
     706static NTSTATUS vbsfNtQueryFsSizeInfo(IN OUT PRX_CONTEXT pRxContext,
     707                                      PFILE_FS_SIZE_INFORMATION pInfo,
     708                                      ULONG cbInfo,
     709                                      PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension,
     710                                      PMRX_VBOX_FOBX pVBoxFobx,
     711                                      PVBSFNTFCBEXT pVBoxFcbX)
     712{
     713    /*
     714     * NtQueryVolumeInformationFile should've checked the minimum buffer size
     715     * but just in case.
     716     */
     717    AssertReturnStmt(cbInfo >= sizeof(FILE_FS_SIZE_INFORMATION),
     718                     pRxContext->InformationToReturn = sizeof(FILE_FS_SIZE_INFORMATION),
     719                     STATUS_BUFFER_TOO_SMALL);
     720
     721    /*
     722     * Get up-to-date information.
     723     * For the time being we always re-query this information from the host.
     724     */
     725    /** @todo don't requery this if it happens with XXXX ns of a _different_ info
     726     *        request to the same handle. */
     727    {
     728        /* Must fetch the info. */
     729        NTSTATUS Status = vbsfNtUpdateFcbVolInfo(pVBoxFcbX, pNetRootExtension, pVBoxFobx);
     730        if (NT_SUCCESS(Status))
     731        { /* likely */ }
     732        else
     733            return Status;
     734    }
     735
     736    /* Make a copy of the info for paranoid reasons: */
     737    SHFLVOLINFO VolInfoCopy;
     738    memcpy(&VolInfoCopy, (void *)&pVBoxFcbX->VolInfo, sizeof(VolInfoCopy));
     739    ASMCompilerBarrier();
     740
     741    /*
     742     * Produce the requested data.
     743     */
     744    pInfo->BytesPerSector                    = RT_MIN(VolInfoCopy.ulBytesPerSector, 1);
     745    pInfo->SectorsPerAllocationUnit          = VolInfoCopy.ulBytesPerAllocationUnit / pInfo->BytesPerSector;
     746    AssertReturn(pInfo->SectorsPerAllocationUnit > 0, STATUS_INTERNAL_ERROR);
     747    pInfo->TotalAllocationUnits.QuadPart     = pVBoxFcbX->VolInfo.ullTotalAllocationBytes
     748                                             / VolInfoCopy.ulBytesPerAllocationUnit;
     749    pInfo->AvailableAllocationUnits.QuadPart = pVBoxFcbX->VolInfo.ullAvailableAllocationBytes
     750                                             / VolInfoCopy.ulBytesPerAllocationUnit;
     751
     752    Log(("VBOXSF: VBoxMRxQueryVolumeInfo: FileFsSizeInformation: BytesPerSector           = %#010RX32\n",
     753         pInfo->BytesPerSector));
     754    Log(("VBOXSF: VBoxMRxQueryVolumeInfo: FileFsSizeInformation: SectorsPerAllocationUnit = %#010RX32\n",
     755         pInfo->SectorsPerAllocationUnit));
     756    Log(("VBOXSF: VBoxMRxQueryVolumeInfo: FileFsSizeInformation: TotalAllocationUnits     = %#018RX32\n",
     757         pInfo->TotalAllocationUnits.QuadPart));
     758    Log(("VBOXSF: VBoxMRxQueryVolumeInfo: FileFsSizeInformation: AvailableAllocationUnits = %#018RX32\n",
     759         pInfo->AvailableAllocationUnits.QuadPart));
     760
     761    /*
     762     * Update the return length in the context.
     763     */
     764    pRxContext->Info.LengthRemaining = cbInfo - sizeof(*pInfo);
     765    pRxContext->InformationToReturn  = sizeof(*pInfo); /* whatever */
     766    return STATUS_SUCCESS;
     767}
     768
     769/**
     770 * Handles NtQueryVolumeInformationFile / FileFsFullSizeInformation
     771 *
     772 * @note Almost identical to vbsfNtQueryFsSizeInfo.
     773 */
     774static NTSTATUS vbsfNtQueryFsFullSizeInfo(IN OUT PRX_CONTEXT pRxContext,
     775                                          PFILE_FS_FULL_SIZE_INFORMATION pInfo,
     776                                          ULONG cbInfo,
     777                                          PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension,
     778                                          PMRX_VBOX_FOBX pVBoxFobx,
     779                                          PVBSFNTFCBEXT pVBoxFcbX)
     780{
     781    /*
     782     * NtQueryVolumeInformationFile should've checked the minimum buffer size
     783     * but just in case.
     784     */
     785    AssertReturnStmt(cbInfo >= sizeof(FILE_FS_SIZE_INFORMATION),
     786                     pRxContext->InformationToReturn = sizeof(FILE_FS_SIZE_INFORMATION),
     787                     STATUS_BUFFER_TOO_SMALL);
     788
     789    /*
     790     * Get up-to-date information.
     791     * For the time being we always re-query this information from the host.
     792     */
     793    /** @todo don't requery this if it happens with XXXX ns of a _different_ info
     794     *        request to the same handle. */
     795    {
     796        /* Must fetch the info. */
     797        NTSTATUS Status = vbsfNtUpdateFcbVolInfo(pVBoxFcbX, pNetRootExtension, pVBoxFobx);
     798        if (NT_SUCCESS(Status))
     799        { /* likely */ }
     800        else
     801            return Status;
     802    }
     803
     804    /* Make a copy of the info for paranoid reasons: */
     805    SHFLVOLINFO VolInfoCopy;
     806    memcpy(&VolInfoCopy, (void *)&pVBoxFcbX->VolInfo, sizeof(VolInfoCopy));
     807    ASMCompilerBarrier();
     808
     809    /*
     810     * Produce the requested data.
     811     */
     812    pInfo->BytesPerSector                          = RT_MIN(VolInfoCopy.ulBytesPerSector, 1);
     813    pInfo->SectorsPerAllocationUnit                = VolInfoCopy.ulBytesPerAllocationUnit / pInfo->BytesPerSector;
     814    AssertReturn(pInfo->SectorsPerAllocationUnit > 0, STATUS_INTERNAL_ERROR);
     815    pInfo->TotalAllocationUnits.QuadPart           = pVBoxFcbX->VolInfo.ullTotalAllocationBytes
     816                                                   / VolInfoCopy.ulBytesPerAllocationUnit;
     817    pInfo->ActualAvailableAllocationUnits.QuadPart = pVBoxFcbX->VolInfo.ullAvailableAllocationBytes
     818                                                   / VolInfoCopy.ulBytesPerAllocationUnit;
     819    pInfo->CallerAvailableAllocationUnits.QuadPart = pInfo->ActualAvailableAllocationUnits.QuadPart;
     820
     821    Log(("VBOXSF: VBoxMRxQueryVolumeInfo: FileFsFullSizeInformation: BytesPerSector                 = %#010RX32\n",
     822         pInfo->BytesPerSector));
     823    Log(("VBOXSF: VBoxMRxQueryVolumeInfo: FileFsFullSizeInformation: SectorsPerAllocationUnit       = %#010RX32\n",
     824         pInfo->SectorsPerAllocationUnit));
     825    Log(("VBOXSF: VBoxMRxQueryVolumeInfo: FileFsFullSizeInformation: TotalAllocationUnits           = %#018RX32\n",
     826         pInfo->TotalAllocationUnits.QuadPart));
     827    Log(("VBOXSF: VBoxMRxQueryVolumeInfo: FileFsFullSizeInformation: ActualAvailableAllocationUnits = %#018RX32\n",
     828         pInfo->ActualAvailableAllocationUnits.QuadPart));
     829    Log(("VBOXSF: VBoxMRxQueryVolumeInfo: FileFsFullSizeInformation: CallerAvailableAllocationUnits = %#018RX32\n",
     830         pInfo->CallerAvailableAllocationUnits.QuadPart));
     831
     832    /*
     833     * Update the return length in the context.
     834     */
     835    pRxContext->Info.LengthRemaining = cbInfo - sizeof(*pInfo);
     836    pRxContext->InformationToReturn  = sizeof(*pInfo); /* whatever */
     837    return STATUS_SUCCESS;
     838}
     839
     840
     841/**
     842 * Handles NtQueryVolumeInformationFile and similar.
     843 */
    668844NTSTATUS VBoxMRxQueryVolumeInfo(IN OUT PRX_CONTEXT RxContext)
    669845{
     
    692868    {
    693869        case FileFsVolumeInformation:
    694         {
     870            Log(("VBOXSF: VBoxMRxQueryVolumeInfo: FileFsVolumeInformation\n"));
    695871            AssertReturn(pVBoxFobx, STATUS_INVALID_PARAMETER);
    696             Log(("VBOXSF: VBoxMRxQueryVolumeInfo: FileFsVolumeInformation\n"));
    697 
    698             Status = vbsfNtQueryVolumeInfo(RxContext, (PFILE_FS_VOLUME_INFORMATION)RxContext->Info.Buffer,
    699                                            RxContext->Info.Length, capFcb->pNetRoot, pNetRootExtension, pVBoxFobx,
    700                                            VBoxMRxGetFcbExtension(capFcb));
     872            Status = vbsfNtQueryFsVolumeInfo(RxContext, (PFILE_FS_VOLUME_INFORMATION)RxContext->Info.Buffer,
     873                                             RxContext->Info.Length, capFcb->pNetRoot, pNetRootExtension, pVBoxFobx,
     874                                             VBoxMRxGetFcbExtension(capFcb));
    701875            return Status;
    702         }
    703876
    704877        case FileFsLabelInformation:
     
    707880            break;
    708881
     882        case FileFsSizeInformation:
     883            Log(("VBOXSF: VBoxMRxQueryVolumeInfo: FileFsSizeInformation\n"));
     884            AssertReturn(pVBoxFobx, STATUS_INVALID_PARAMETER);
     885            Status = vbsfNtQueryFsSizeInfo(RxContext, (PFILE_FS_SIZE_INFORMATION)RxContext->Info.Buffer,
     886                                           RxContext->Info.Length, pNetRootExtension, pVBoxFobx,
     887                                           VBoxMRxGetFcbExtension(capFcb));
     888            return Status;
     889
    709890        case FileFsFullSizeInformation:
    710         case FileFsSizeInformation:
    711         {
    712             PFILE_FS_FULL_SIZE_INFORMATION pFullSizeInfo = (PFILE_FS_FULL_SIZE_INFORMATION)pInfoBuffer;
    713             PFILE_FS_SIZE_INFORMATION pSizeInfo = (PFILE_FS_SIZE_INFORMATION)pInfoBuffer;
    714 
    715             uint32_t cbHGCMBuffer;
    716             uint8_t *pHGCMBuffer;
    717             int vrc;
    718             PSHFLVOLINFO pShflVolInfo;
    719 
    720             LARGE_INTEGER TotalAllocationUnits;
    721             LARGE_INTEGER AvailableAllocationUnits;
    722             ULONG         SectorsPerAllocationUnit;
    723             ULONG         BytesPerSector;
    724 
    725             if (FsInformationClass == FileFsFullSizeInformation)
    726             {
    727                 Log(("VBOXSF: MrxQueryVolumeInfo: FileFsFullSizeInformation\n"));
    728                 cbToCopy = sizeof(FILE_FS_FULL_SIZE_INFORMATION);
    729             }
    730             else
    731             {
    732                 Log(("VBOXSF: MrxQueryVolumeInfo: FileFsSizeInformation\n"));
    733                 cbToCopy = sizeof(FILE_FS_SIZE_INFORMATION);
    734             }
    735 
    736             if (!pVBoxFobx)
    737             {
    738                 Log(("VBOXSF: MrxQueryVolumeInfo: pVBoxFobx is NULL!\n"));
    739                 Status = STATUS_INVALID_PARAMETER;
    740                 break;
    741             }
    742 
    743             if (cbInfoBuffer < cbToCopy)
    744             {
    745                 Status = STATUS_BUFFER_TOO_SMALL;
    746                 break;
    747             }
    748 
    749             RtlZeroMemory(pInfoBuffer, cbToCopy);
    750 
    751             cbHGCMBuffer = sizeof(SHFLVOLINFO);
    752             pHGCMBuffer = (uint8_t *)vbsfNtAllocNonPagedMem(cbHGCMBuffer);
    753             if (!pHGCMBuffer)
    754             {
    755                 Status = STATUS_INSUFFICIENT_RESOURCES;
    756                 break;
    757             }
    758 
    759             vrc = VbglR0SfFsInfo(&g_SfClient, &pNetRootExtension->map, pVBoxFobx->hFile,
    760                                  SHFL_INFO_GET | SHFL_INFO_VOLUME, &cbHGCMBuffer, (PSHFLDIRINFO)pHGCMBuffer);
    761 
    762             if (vrc != VINF_SUCCESS)
    763             {
    764                 Status = vbsfNtVBoxStatusToNt(vrc);
    765                 vbsfNtFreeNonPagedMem(pHGCMBuffer);
    766                 break;
    767             }
    768 
    769             pShflVolInfo = (PSHFLVOLINFO)pHGCMBuffer;
    770 
    771             TotalAllocationUnits.QuadPart     = pShflVolInfo->ullTotalAllocationBytes / pShflVolInfo->ulBytesPerAllocationUnit;
    772             AvailableAllocationUnits.QuadPart = pShflVolInfo->ullAvailableAllocationBytes / pShflVolInfo->ulBytesPerAllocationUnit;
    773             SectorsPerAllocationUnit          = pShflVolInfo->ulBytesPerAllocationUnit / pShflVolInfo->ulBytesPerSector;
    774             BytesPerSector                    = pShflVolInfo->ulBytesPerSector;
    775 
    776             Log(("VBOXSF: MrxQueryVolumeInfo: TotalAllocationUnits     0x%RX64\n", TotalAllocationUnits.QuadPart));
    777             Log(("VBOXSF: MrxQueryVolumeInfo: AvailableAllocationUnits 0x%RX64\n", AvailableAllocationUnits.QuadPart));
    778             Log(("VBOXSF: MrxQueryVolumeInfo: SectorsPerAllocationUnit 0x%X\n", SectorsPerAllocationUnit));
    779             Log(("VBOXSF: MrxQueryVolumeInfo: BytesPerSector           0x%X\n", BytesPerSector));
    780 
    781             if (FsInformationClass == FileFsFullSizeInformation)
    782             {
    783                 pFullSizeInfo->TotalAllocationUnits           = TotalAllocationUnits;
    784                 pFullSizeInfo->CallerAvailableAllocationUnits = AvailableAllocationUnits;
    785                 pFullSizeInfo->ActualAvailableAllocationUnits = AvailableAllocationUnits;
    786                 pFullSizeInfo->SectorsPerAllocationUnit       = SectorsPerAllocationUnit;
    787                 pFullSizeInfo->BytesPerSector                 = BytesPerSector;
    788             }
    789             else
    790             {
    791                 pSizeInfo->TotalAllocationUnits     = TotalAllocationUnits;
    792                 pSizeInfo->AvailableAllocationUnits = AvailableAllocationUnits;
    793                 pSizeInfo->SectorsPerAllocationUnit = SectorsPerAllocationUnit;
    794                 pSizeInfo->BytesPerSector           = BytesPerSector;
    795             }
    796 
    797             vbsfNtFreeNonPagedMem(pHGCMBuffer);
    798 
    799             Status = STATUS_SUCCESS;
    800             break;
    801         }
     891            Log(("VBOXSF: VBoxMRxQueryVolumeInfo: FileFsFullSizeInformation\n"));
     892            AssertReturn(pVBoxFobx, STATUS_INVALID_PARAMETER);
     893            Status = vbsfNtQueryFsFullSizeInfo(RxContext, (PFILE_FS_FULL_SIZE_INFORMATION)RxContext->Info.Buffer,
     894                                               RxContext->Info.Length, pNetRootExtension, pVBoxFobx,
     895                                               VBoxMRxGetFcbExtension(capFcb));
     896            return Status;
    802897
    803898        case FileFsDeviceInformation:
  • trunk/src/VBox/Additions/WINNT/SharedFolders/driver/vbsf.h

    r78471 r78487  
    122122     *
    123123     * @{ */
    124     PMRX_VBOX_FOBX            pFobxLastAccessTime;
    125     PMRX_VBOX_FOBX            pFobxLastWriteTime;
    126     PMRX_VBOX_FOBX            pFobxChangeTime;
     124    PMRX_VBOX_FOBX              pFobxLastAccessTime;
     125    PMRX_VBOX_FOBX              pFobxLastWriteTime;
     126    PMRX_VBOX_FOBX              pFobxChangeTime;
    127127    /** @} */
    128128
     
    130130     * @{ */
    131131    /** The RTTimeSystemNanoTS value when VolInfo was retrieved, 0 to force update. */
    132     uint64_t                  nsVolInfoUpToDate;
     132    uint64_t volatile           nsVolInfoUpToDate;
    133133    /** Volume information. */
    134     SHFLVOLINFO               VolInfo;
     134    SHFLVOLINFO volatile        VolInfo;
    135135    /** @} */
    136136} VBSFNTFCBEXT;
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