- Timestamp:
- May 3, 2019 3:02:54 AM (6 years ago)
- Location:
- trunk/src/VBox/Additions/WINNT/SharedFolders/driver
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/SharedFolders/driver/info.cpp
r78366 r78368 22 22 #include "vbsf.h" 23 23 #include <iprt/err.h> 24 25 extern "C" NTSTATUS NTAPI RxSetEndOfFileInfo(PRX_CONTEXT, PIRP, PFCB, PFOBX); 24 26 25 27 … … 1833 1835 * db 4 ; 75 FileCaseSensitiveInformationForceAccessCheck, - for the i/o manager, w10-1809. 1834 1836 */ 1835 switch ( RxContext->Info.FileInformationClass)1837 switch ((int)RxContext->Info.FileInformationClass) 1836 1838 { 1837 1839 /* … … 1944 1946 * will hide calls which does not change the size from us. This is of course not 1945 1947 * the case for non-local file systems, as the server is the only which up-to-date 1946 * information. Don't see an easy way of working around it, so ignoring it for now. 1948 * information. 1949 * 1950 * We work around this either by modifying FCB.Header.FileSize slightly when it equals 1951 * the new size. This is either done below in the FileEndOfFileInformation + 4096 case, 1952 * or when using older WDK libs in VBoxHookMjSetInformation. The FCB is locked 1953 * exclusivly while we operate with the incorrect Header.FileSize value, which should 1954 * prevent anyone else from making use of it till it has been updated again. 1955 * 1947 1956 */ 1948 1957 case FileEndOfFileInformation: … … 1958 1967 break; 1959 1968 } 1969 1970 #if 0 /* This only works for more recent versions of the RDBSS library, not for the one we're using (WDK 7600.16385.1). */ 1971 /* 1972 * HACK ALERT! This is FileEndOfFileInformation after it passed thru 1973 * VBoxHookMjSetInformation so we can twiddle the cached file size in 1974 * the FCB to ensure the set EOF request always reaches the host. 1975 * 1976 * Note! We have to call thru RxSetEndOfFileInfo to benefit from its 1977 * update logic and avoid needing to replicate that code. 1978 */ 1979 case FileEndOfFileInformation + 4096: 1980 { 1981 PFILE_END_OF_FILE_INFORMATION pInfo = (PFILE_END_OF_FILE_INFORMATION)RxContext->Info.Buffer; 1982 Log(("VBOXSF: MrxSetFileInfo: FileEndOfFileInformation+4096: new EndOfFile 0x%RX64, FileSize = 0x%RX64\n", 1983 pInfo->EndOfFile.QuadPart, capFcb->Header.FileSize.QuadPart)); 1984 1985 /* Undo the change from VBoxHookMjSetInformation: */ 1986 Assert(RxContext->CurrentIrpSp); 1987 RxContext->CurrentIrpSp->Parameters.SetFile.FileInformationClass = FileEndOfFileInformation; 1988 RxContext->Info.FileInformationClass = FileEndOfFileInformation; 1989 1990 /* Tweak the size if necessary and forward the call. */ 1991 int64_t const cbOldSize = capFcb->Header.FileSize.QuadPart; 1992 if ( pInfo->EndOfFile.QuadPart != cbOldSize 1993 || !(capFcb->FcbState & FCB_STATE_PAGING_FILE)) 1994 { 1995 Status = RxSetEndOfFileInfo(RxContext, RxContext->CurrentIrp, (PFCB)capFcb, (PFOBX)capFobx); 1996 Log(("VBOXSF: MrxSetFileInfo: FileEndOfFileInformation+4096: Status 0x%08X\n", 1997 Status)); 1998 } 1999 else 2000 { 2001 int64_t const cbHackedSize = cbOldSize ? cbOldSize - 1 : 1; 2002 capFcb->Header.FileSize.QuadPart = cbHackedSize; 2003 Status = RxSetEndOfFileInfo(RxContext, RxContext->CurrentIrp, (PFCB)capFcb, (PFOBX)capFobx); 2004 if ( !NT_SUCCESS(Status) 2005 && capFcb->Header.FileSize.QuadPart == cbHackedSize) 2006 capFcb->Header.FileSize.QuadPart = cbOldSize; 2007 else 2008 Assert( capFcb->Header.FileSize.QuadPart != cbHackedSize 2009 || pVBoxFobx->Info.cbObject == cbHackedSize); 2010 Log(("VBOXSF: MrxSetFileInfo: FileEndOfFileInformation+4096: Status 0x%08X (tweaked)\n", 2011 Status)); 2012 } 2013 break; 2014 } 2015 #endif 1960 2016 1961 2017 /// @todo FileModeInformation ? -
trunk/src/VBox/Additions/WINNT/SharedFolders/driver/vbsf.cpp
r78355 r78368 492 492 } 493 493 494 /** 495 * Intercepts IRP_MJ_SET_INFORMATION to workaround a RDBSS quirk in the 496 * FileEndOfFileInformation handling. 497 * 498 * We will add 4096 to the FileEndOfFileInformation function value and pick it 499 * up in VBoxMRxSetFileInfo after RxCommonSetInformation has done the necessary 500 * locking. If we find that the desired file size matches the cached one, just 501 * issue the call directly, otherwise subtract 4096 and call the 502 * RxSetEndOfFileInfo worker. 503 */ 504 static NTSTATUS VBoxHookMjSetInformation(PDEVICE_OBJECT pDevObj, PIRP pIrp) 505 { 506 PMRX_VBOX_DEVICE_EXTENSION pDevExt = (PMRX_VBOX_DEVICE_EXTENSION)((PBYTE)pDevObj + sizeof(RDBSS_DEVICE_OBJECT)); 507 PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp); 508 PFILE_OBJECT pFileObj = pStack->FileObject; 509 NTSTATUS rcNt; 510 511 Log(("VBOXSF: VBoxHookMjSetInformation: pDevObj %p, pDevExt %p, pFileObj %p, FileInformationClass %d, Length %#x\n", 512 pDevObj, pDevObj->DeviceExtension, pFileObj, pStack->Parameters.SetFile.FileInformationClass, pStack->Parameters.SetFile.Length)); 513 if (pFileObj) 514 Log2(("VBOXSF: VBoxHookMjSetInformation: FileName=%.*ls\n", pFileObj->FileName.Length / sizeof(WCHAR), pFileObj->FileName.Buffer)); 515 516 /* 517 * Setting EOF info? 518 */ 519 if (pStack->Parameters.SetFile.FileInformationClass == FileEndOfFileInformation) 520 { 521 #if 0 /* This only works for more recent versions of the RDBSS library, not for the one we're using (WDK 7600.16385.1). */ 522 pStack->Parameters.SetFile.FileInformationClass = (FILE_INFORMATION_CLASS)(FileEndOfFileInformation + 4096); 523 rcNt = pDevExt->pfnRDBSSSetInformation(pDevObj, pIrp); 524 Log(("VBOXSF: VBoxHookMjSetInformation: returns %#x (hacked)\n", rcNt)); 525 return rcNt; 526 #else 527 /* 528 * For the older WDK, we have to detect the same-size situation up front and hack 529 * it here instead of in VBoxMRxSetFileInfo. This means we need to lock the FCB 530 * before modifying the Fcb.Header.FileSize value and ASSUME the locking is 531 * reentrant and nothing else happens during RDBSS dispatching wrt that... 532 */ 533 PMRX_FCB pFcb = (PMRX_FCB)pFileObj->FsContext; 534 if ( (NODE_TYPE_CODE)pFcb->Header.NodeTypeCode == RDBSS_NTC_STORAGE_TYPE_FILE 535 && pIrp->AssociatedIrp.SystemBuffer != NULL 536 && pStack->Parameters.SetFile.Length >= sizeof(FILE_END_OF_FILE_INFORMATION)) 537 { 538 LONGLONG cbFileNew = -42; 539 __try 540 { 541 cbFileNew = ((PFILE_END_OF_FILE_INFORMATION)pIrp->AssociatedIrp.SystemBuffer)->EndOfFile.QuadPart; 542 } 543 __except(EXCEPTION_EXECUTE_HANDLER) 544 { 545 cbFileNew = -42; 546 } 547 if ( cbFileNew >= 0 548 && pFcb->Header.FileSize.QuadPart == cbFileNew 549 && !(pFcb->FcbState & FCB_STATE_PAGING_FILE)) 550 { 551 /* Now exclusivly lock the FCB like RxCommonSetInformation would do 552 to reduce chances of races and of anyone else grabbing the value 553 while it's incorrect on purpose. */ 554 NTSTATUS rcNtLock = RxAcquireExclusiveFcb(NULL, (PFCB)pFcb); 555 if (NT_SUCCESS(rcNtLock)) 556 { 557 if (pFcb->Header.FileSize.QuadPart == cbFileNew) 558 { 559 int64_t const cbHackedSize = cbFileNew ? cbFileNew - 1 : 1; 560 pFcb->Header.FileSize.QuadPart = cbHackedSize; 561 rcNt = pDevExt->pfnRDBSSSetInformation(pDevObj, pIrp); 562 if ( !NT_SUCCESS(rcNt) 563 && pFcb->Header.FileSize.QuadPart == cbHackedSize) 564 pFcb->Header.FileSize.QuadPart = cbFileNew; 565 # ifdef VBOX_STRICT 566 else 567 { 568 PMRX_FOBX pFobx = (PMRX_FOBX)pFileObj->FsContext2; 569 PMRX_VBOX_FOBX pVBoxFobX = VBoxMRxGetFileObjectExtension(pFobx); 570 Assert( pFcb->Header.FileSize.QuadPart != cbHackedSize 571 || (pVBoxFobX && pVBoxFobX->Info.cbObject == cbHackedSize)); 572 } 573 # endif 574 RxReleaseFcb(NULL, pFcb); 575 Log(("VBOXSF: VBoxHookMjSetInformation: returns %#x (hacked, cbFileNew=%#RX64)\n", rcNt, cbFileNew)); 576 return rcNt; 577 } 578 RxReleaseFcb(NULL, pFcb); 579 } 580 } 581 } 582 #endif 583 } 584 585 /* 586 * No hack needed. 587 */ 588 rcNt = pDevExt->pfnRDBSSSetInformation(pDevObj, pIrp); 589 Log(("VBOXSF: VBoxHookMjSetInformation: returns %#x\n", rcNt)); 590 return rcNt; 591 } 592 494 593 NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, 495 594 IN PUNICODE_STRING RegistryPath) … … 649 748 pDeviceExtension->pfnRDBSSCreate = DriverObject->MajorFunction[IRP_MJ_CREATE]; 650 749 DriverObject->MajorFunction[IRP_MJ_CREATE] = VBoxHookMjCreate; 750 751 /* Intercept IRP_MJ_SET_INFORMATION to ensure we call the host for all 752 * FileEndOfFileInformation requestes, even if the new size matches the 753 * old one. We don't know if someone else might have modified the file 754 * size cached in the FCB since the last time we update it. 755 */ 756 pDeviceExtension->pfnRDBSSSetInformation = DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION]; 757 DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = VBoxHookMjSetInformation; 651 758 652 759 -
trunk/src/VBox/Additions/WINNT/SharedFolders/driver/vbsf.h
r78366 r78368 82 82 /** Saved pointer to the original IRP_MJ_CREATE handler. */ 83 83 NTSTATUS (NTAPI * pfnRDBSSCreate)(PDEVICE_OBJECT pDevObj, PIRP pIrp); 84 /** Saved pointer to the original IRP_MJ_SET_INFORMATION handler. */ 85 NTSTATUS (NTAPI * pfnRDBSSSetInformation)(PDEVICE_OBJECT pDevObj, PIRP pIrp); 84 86 85 87 } MRX_VBOX_DEVICE_EXTENSION, *PMRX_VBOX_DEVICE_EXTENSION;
Note:
See TracChangeset
for help on using the changeset viewer.