Changeset 78487 in vbox for trunk/src/VBox/Additions
- Timestamp:
- May 13, 2019 11:25:38 PM (6 years ago)
- 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 22 22 #include "vbsf.h" 23 23 #include <iprt/err.h> 24 #include <iprt/asm.h> 24 25 25 26 extern "C" NTSTATUS NTAPI RxSetEndOfFileInfo(PRX_CONTEXT, PIRP, PFCB, PFOBX); … … 535 536 if (RT_SUCCESS(vrc)) 536 537 { 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(); 538 569 pVBoxFcbX->nsVolInfoUpToDate = RTTimeSystemNanoTS(); 570 ASMWriteFence(); 571 539 572 rcNt = STATUS_SUCCESS; 540 573 } … … 552 585 * Handles NtQueryVolumeInformationFile / FileFsVolumeInformation 553 586 */ 554 static NTSTATUS vbsfNtQuery VolumeInfo(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)587 static 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) 561 594 { 562 595 /* … … 666 699 } 667 700 701 /** 702 * Handles NtQueryVolumeInformationFile / FileFsSizeInformation 703 * 704 * @note Almost identical to vbsfNtQueryFsFullSizeInfo. 705 */ 706 static 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 */ 774 static 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 */ 668 844 NTSTATUS VBoxMRxQueryVolumeInfo(IN OUT PRX_CONTEXT RxContext) 669 845 { … … 692 868 { 693 869 case FileFsVolumeInformation: 694 {870 Log(("VBOXSF: VBoxMRxQueryVolumeInfo: FileFsVolumeInformation\n")); 695 871 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)); 701 875 return Status; 702 }703 876 704 877 case FileFsLabelInformation: … … 707 880 break; 708 881 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 709 890 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; 802 897 803 898 case FileFsDeviceInformation: -
trunk/src/VBox/Additions/WINNT/SharedFolders/driver/vbsf.h
r78471 r78487 122 122 * 123 123 * @{ */ 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; 127 127 /** @} */ 128 128 … … 130 130 * @{ */ 131 131 /** The RTTimeSystemNanoTS value when VolInfo was retrieved, 0 to force update. */ 132 uint64_t 132 uint64_t volatile nsVolInfoUpToDate; 133 133 /** Volume information. */ 134 SHFLVOLINFO 134 SHFLVOLINFO volatile VolInfo; 135 135 /** @} */ 136 136 } VBSFNTFCBEXT;
Note:
See TracChangeset
for help on using the changeset viewer.