Changeset 78471 in vbox for trunk/src/VBox/Additions/WINNT/SharedFolders
- Timestamp:
- May 12, 2019 4:32:53 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
r78383 r78471 522 522 } 523 523 524 /** 525 * Updates VBSFNTFCBEXT::VolInfo. 526 */ 527 static NTSTATUS vbsfNtUpdateFcbVolInfo(PVBSFNTFCBEXT pVBoxFcbX, PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension, 528 PMRX_VBOX_FOBX pVBoxFobx) 529 { 530 NTSTATUS rcNt; 531 VBOXSFVOLINFOREQ *pReq = (VBOXSFVOLINFOREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq)); 532 if (pReq) 533 { 534 int vrc = VbglR0SfHostReqQueryVolInfo(pNetRootExtension->map.root, pReq, pVBoxFobx->hFile); 535 if (RT_SUCCESS(vrc)) 536 { 537 pVBoxFcbX->VolInfo = pReq->VolInfo; 538 pVBoxFcbX->nsVolInfoUpToDate = RTTimeSystemNanoTS(); 539 rcNt = STATUS_SUCCESS; 540 } 541 else 542 rcNt = vbsfNtVBoxStatusToNt(vrc); 543 VbglR0PhysHeapFree(pReq); 544 } 545 else 546 rcNt = STATUS_INSUFFICIENT_RESOURCES; 547 return rcNt; 548 } 549 550 551 /** 552 * Handles NtQueryVolumeInformationFile / FileFsVolumeInformation 553 */ 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) 561 { 562 /* 563 * NtQueryVolumeInformationFile should've checked the minimum buffer size 564 * but just in case. 565 */ 566 AssertReturnStmt(cbInfo >= RT_UOFFSETOF(FILE_FS_VOLUME_INFORMATION, VolumeLabel), 567 pRxContext->InformationToReturn = RT_UOFFSETOF(FILE_FS_VOLUME_INFORMATION, VolumeLabel), 568 STATUS_BUFFER_TOO_SMALL); 569 570 /* 571 * Get up-to-date serial number. 572 * 573 * If we have a unixy host, we'll get additional unix attributes and the 574 * serial number is the same as INodeIdDevice. 575 * 576 * Note! Because it's possible that the host has mount points within the 577 * shared folder as well as symbolic links pointing out files or 578 * directories outside the tree, we cannot just cache the serial 579 * number in the net root extension data and skip querying it here. 580 * 581 * OTOH, only we don't report inode info from the host, so the only 582 * thing the serial number can be used for is to cache/whatever 583 * volume space information. So, we should probably provide a 584 * shortcut here via mount option, registry and guest properties. 585 */ 586 /** @todo Make See OTOH above wrt. one serial per net root. */ 587 uint64_t nsNow = RTTimeSystemNanoTS(); 588 if ( pVBoxFobx->Info.Attr.enmAdditional == SHFLFSOBJATTRADD_UNIX 589 && pVBoxFobx->Info.Attr.u.Unix.INodeIdDevice != 0 590 && pVBoxFobx->nsUpToDate - nsNow < RT_NS_100US /** @todo implement proper TTL */) 591 pInfo->VolumeSerialNumber = pVBoxFobx->Info.Attr.u.Unix.INodeIdDevice; 592 else if (pVBoxFcbX->nsVolInfoUpToDate - nsNow < RT_NS_100MS /** @todo implement proper volume info TTL */ ) 593 pInfo->VolumeSerialNumber = pVBoxFcbX->VolInfo.ulSerial; 594 else 595 { 596 /* Must fetch the info. */ 597 NTSTATUS Status = vbsfNtUpdateFcbVolInfo(pVBoxFcbX, pNetRootExtension, pVBoxFobx); 598 if (NT_SUCCESS(Status)) 599 pInfo->VolumeSerialNumber = pVBoxFcbX->VolInfo.ulSerial; 600 else 601 return Status; 602 } 603 Log(("VBOXSF: VBoxMRxQueryVolumeInfo: FileFsVolumeInformation: VolumeSerialNumber=%#010RX32\n", pInfo->VolumeSerialNumber)); 604 605 /* 606 * Fill in the static info. 607 */ 608 pInfo->VolumeCreationTime.QuadPart = 0; 609 pInfo->SupportsObjects = FALSE; 610 611 /* 612 * The volume label. 613 * 614 * We may get queries with insufficient buffer space for the whole (or any) 615 * volume label. In those cases we're to return STATUS_BUFFER_OVERFLOW, 616 * return the returned number of bytes in Ios.Information and set the 617 * VolumeLabelLength to the actual length (rather than the returned). At 618 * least this is was FAT and NTFS does (however, it is not what the NulMrx 619 * sample from the 6.1.6001.18002 does). 620 * 621 * Note! VolumeLabelLength is a byte count. 622 * Note! NTFS does not include a terminator, so neither do we. 623 */ 624 uint32_t const cbShareName = pNetRoot->pNetRootName->Length 625 - pNetRoot->pSrvCall->pSrvCallName->Length 626 - sizeof(WCHAR) /* Remove the leading backslash. */; 627 uint32_t const cbVolLabel = VBOX_VOLNAME_PREFIX_SIZE + cbShareName; 628 pInfo->VolumeLabelLength = cbVolLabel; 629 630 WCHAR const *pwcShareName = &pNetRoot->pNetRootName->Buffer[pNetRoot->pSrvCall->pSrvCallName->Length / sizeof(WCHAR) + 1]; 631 uint32_t cbCopied = RT_UOFFSETOF(FILE_FS_VOLUME_INFORMATION, VolumeLabel); 632 NTSTATUS Status; 633 if (cbInfo >= cbCopied + cbVolLabel) 634 { 635 memcpy(pInfo->VolumeLabel, VBOX_VOLNAME_PREFIX, VBOX_VOLNAME_PREFIX_SIZE); 636 memcpy(&pInfo->VolumeLabel[VBOX_VOLNAME_PREFIX_SIZE / sizeof(WCHAR)], pwcShareName, cbShareName); 637 cbCopied += cbVolLabel; 638 Status = STATUS_SUCCESS; 639 Log(("VBOXSF: VBoxMRxQueryVolumeInfo: FileFsVolumeInformation: full result (%#x)\n", cbCopied)); 640 } 641 else 642 { 643 if (cbInfo > cbCopied) 644 { 645 uint32_t cbLeft = cbInfo - cbCopied; 646 memcpy(pInfo->VolumeLabel, VBOX_VOLNAME_PREFIX, RT_MIN(cbLeft, VBOX_VOLNAME_PREFIX_SIZE)); 647 if (cbLeft > VBOX_VOLNAME_PREFIX_SIZE) 648 memcpy(&pInfo->VolumeLabel[VBOX_VOLNAME_PREFIX_SIZE / sizeof(WCHAR)], pwcShareName, cbShareName); 649 Log(("VBOXSF: VBoxMRxQueryVolumeInfo: FileFsVolumeInformation: partial result (%#x, needed %#x)\n", 650 cbCopied, cbCopied + cbVolLabel)); 651 cbCopied = cbInfo; 652 } 653 else 654 Log(("VBOXSF: VBoxMRxQueryVolumeInfo: FileFsVolumeInformation: partial result no label (%#x, needed %#x)\n", 655 cbCopied, cbCopied + cbVolLabel)); 656 Status = STATUS_BUFFER_OVERFLOW; 657 } 658 659 /* 660 * Update the return length in the context. 661 */ 662 pRxContext->Info.LengthRemaining = cbInfo - cbCopied; 663 pRxContext->InformationToReturn = cbCopied; /* whatever */ 664 665 return Status; 666 } 667 524 668 NTSTATUS VBoxMRxQueryVolumeInfo(IN OUT PRX_CONTEXT RxContext) 525 669 { … … 549 693 case FileFsVolumeInformation: 550 694 { 551 PFILE_FS_VOLUME_INFORMATION pInfo = (PFILE_FS_VOLUME_INFORMATION)pInfoBuffer; 552 553 PMRX_NET_ROOT pNetRoot = capFcb->pNetRoot; 554 PMRX_SRV_CALL pSrvCall = pNetRoot->pSrvCall; 555 556 PWCHAR pRootName; 557 ULONG cbRootName; 558 559 PSHFLVOLINFO pShflVolInfo; 560 uint32_t cbHGCMBuffer; 561 uint8_t *pHGCMBuffer; 562 int vrc; 563 564 Log(("VBOXSF: MrxQueryVolumeInfo: FileFsVolumeInformation\n")); 565 566 if (!pVBoxFobx) 567 { 568 Log(("VBOXSF: MrxQueryVolumeInfo: pVBoxFobx is NULL!\n")); 569 Status = STATUS_INVALID_PARAMETER; 570 break; 571 } 572 573 cbRootName = pNetRoot->pNetRootName->Length - pSrvCall->pSrvCallName->Length; 574 cbRootName -= sizeof(WCHAR); /* Remove the leading backslash. */ 575 pRootName = pNetRoot->pNetRootName->Buffer + (pSrvCall->pSrvCallName->Length / sizeof(WCHAR)); 576 pRootName++; /* Remove the leading backslash. */ 577 578 Log(("VBOXSF: MrxQueryVolumeInfo: FileFsVolumeInformation: Root name = %.*ls, %d bytes\n", 579 cbRootName / sizeof(WCHAR), pRootName, cbRootName)); 580 581 cbToCopy = FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION, VolumeLabel); 582 583 cbString = VBOX_VOLNAME_PREFIX_SIZE; 584 cbString += cbRootName; 585 cbString += sizeof(WCHAR); 586 587 Log(("VBOXSF: MrxQueryVolumeInfo: FileFsVolumeInformation: cbToCopy %d, cbString %d\n", 588 cbToCopy, cbString)); 589 590 if (cbInfoBuffer < cbToCopy) 591 { 592 Status = STATUS_BUFFER_TOO_SMALL; 593 break; 594 } 595 596 RtlZeroMemory(pInfo, cbToCopy); 597 598 /* Query serial number. */ 599 cbHGCMBuffer = sizeof(SHFLVOLINFO); 600 pHGCMBuffer = (uint8_t *)vbsfNtAllocNonPagedMem(cbHGCMBuffer); 601 if (!pHGCMBuffer) 602 { 603 Status = STATUS_INSUFFICIENT_RESOURCES; 604 break; 605 } 606 607 vrc = VbglR0SfFsInfo(&g_SfClient, &pNetRootExtension->map, pVBoxFobx->hFile, 608 SHFL_INFO_GET | SHFL_INFO_VOLUME, &cbHGCMBuffer, (PSHFLDIRINFO)pHGCMBuffer); 609 610 if (vrc != VINF_SUCCESS) 611 { 612 Status = vbsfNtVBoxStatusToNt(vrc); 613 vbsfNtFreeNonPagedMem(pHGCMBuffer); 614 break; 615 } 616 617 pShflVolInfo = (PSHFLVOLINFO)pHGCMBuffer; 618 pInfo->VolumeSerialNumber = pShflVolInfo->ulSerial; 619 vbsfNtFreeNonPagedMem(pHGCMBuffer); 620 621 pInfo->VolumeCreationTime.QuadPart = 0; 622 pInfo->SupportsObjects = FALSE; 623 624 if (cbInfoBuffer >= cbToCopy + cbString) 625 { 626 RtlCopyMemory(&pInfo->VolumeLabel[0], 627 VBOX_VOLNAME_PREFIX, 628 VBOX_VOLNAME_PREFIX_SIZE); 629 RtlCopyMemory(&pInfo->VolumeLabel[VBOX_VOLNAME_PREFIX_SIZE / sizeof(WCHAR)], 630 pRootName, 631 cbRootName); 632 pInfo->VolumeLabel[cbString / sizeof(WCHAR) - 1] = 0; 633 } 634 else 635 { 636 cbString = cbInfoBuffer - cbToCopy; 637 638 RtlCopyMemory(&pInfo->VolumeLabel[0], 639 VBOX_VOLNAME_PREFIX, 640 RT_MIN(cbString, VBOX_VOLNAME_PREFIX_SIZE)); 641 if (cbString > VBOX_VOLNAME_PREFIX_SIZE) 642 { 643 RtlCopyMemory(&pInfo->VolumeLabel[VBOX_VOLNAME_PREFIX_SIZE / sizeof(WCHAR)], 644 pRootName, 645 cbString - VBOX_VOLNAME_PREFIX_SIZE); 646 } 647 } 648 649 pInfo->VolumeLabelLength = cbString; 650 651 cbToCopy += cbString; 652 653 Log(("VBOXSF: MrxQueryVolumeInfo: FileFsVolumeInformation: VolumeLabelLength %d\n", 654 pInfo->VolumeLabelLength)); 655 656 Status = STATUS_SUCCESS; 657 break; 695 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)); 701 return Status; 658 702 } 659 703 … … 1747 1791 Log(("VBOXSF: vbsfNtRename: FileNameLength = %#x (%d), FileName = %.*ls\n", 1748 1792 cbFilename, cbFilename, cbFilename / sizeof(WCHAR), &pRenameInfo->FileName[0])); 1793 1794 /** @todo Add new function that also closes the handle, like for remove, saving a host call. */ 1749 1795 1750 1796 /* Must close the file before renaming it! */ -
trunk/src/VBox/Additions/WINNT/SharedFolders/driver/vbsf.h
r78468 r78471 125 125 PMRX_VBOX_FOBX pFobxLastWriteTime; 126 126 PMRX_VBOX_FOBX pFobxChangeTime; 127 /** @} */ 128 129 /** @name Cached volume info. 130 * @{ */ 131 /** The RTTimeSystemNanoTS value when VolInfo was retrieved, 0 to force update. */ 132 uint64_t nsVolInfoUpToDate; 133 /** Volume information. */ 134 SHFLVOLINFO VolInfo; 127 135 /** @} */ 128 136 } VBSFNTFCBEXT;
Note:
See TracChangeset
for help on using the changeset viewer.