mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-30 19:48:38 -05:00 
			
		
		
		
	sys: create: FspFsvolCreate
Fix file name case after crossing a reparse point as per http://online.osr.com/ShowThread.cfm?link=287522
This commit is contained in:
		| @@ -69,6 +69,16 @@ FSP_DRIVER_DISPATCH FspCreate; | |||||||
| #pragma alloc_text(PAGE, FspCreate) | #pragma alloc_text(PAGE, FspCreate) | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * FSP_CREATE_REPARSE_POINT_ECP | ||||||
|  |  * | ||||||
|  |  * Define this macro to include code to fix file name case after crossing | ||||||
|  |  * a reparse point as per http://online.osr.com/ShowThread.cfm?link=287522. | ||||||
|  |  * Fixing this problem requires undocumented information; for this reason | ||||||
|  |  * this fix is EXPERIMENTAL. | ||||||
|  |  */ | ||||||
|  | #define FSP_CREATE_REPARSE_POINT_ECP | ||||||
|  |  | ||||||
| #define PREFIXW                         L"" FSP_FSCTL_VOLUME_PARAMS_PREFIX | #define PREFIXW                         L"" FSP_FSCTL_VOLUME_PARAMS_PREFIX | ||||||
| #define PREFIXW_SIZE                    (sizeof PREFIXW - sizeof(WCHAR)) | #define PREFIXW_SIZE                    (sizeof PREFIXW - sizeof(WCHAR)) | ||||||
|  |  | ||||||
| @@ -140,6 +150,12 @@ static NTSTATUS FspFsvolCreate( | |||||||
|      *     of the main file for a stream. In this case this is a reentrant open |      *     of the main file for a stream. In this case this is a reentrant open | ||||||
|      *     and we should be careful not to try to acquire the rename resource, |      *     and we should be careful not to try to acquire the rename resource, | ||||||
|      *     which is already acquired (otherwise DEADLOCK). |      *     which is already acquired (otherwise DEADLOCK). | ||||||
|  |      * | ||||||
|  |      *   - To determine whether this is an open after crossing a reparse point | ||||||
|  |      *     (e.g. when the file system is mounted as a directory). Unfortunately | ||||||
|  |      *     Windows does not preserve file name case in this case and sends us | ||||||
|  |      *     UPPERCASE file names, which results in all kinds of problems, esp. | ||||||
|  |      *     for case-sensitive file systems. | ||||||
|      */ |      */ | ||||||
|     ExtraCreateParameters = 0; |     ExtraCreateParameters = 0; | ||||||
|     Result = FsRtlGetEcpListFromIrp(Irp, &ExtraCreateParameters); |     Result = FsRtlGetEcpListFromIrp(Irp, &ExtraCreateParameters); | ||||||
| @@ -151,6 +167,51 @@ static NTSTATUS FspFsvolCreate( | |||||||
|                 &FspMainFileOpenEcpGuid, &ExtraCreateParameter, 0)) && |                 &FspMainFileOpenEcpGuid, &ExtraCreateParameter, 0)) && | ||||||
|             0 != ExtraCreateParameter && |             0 != ExtraCreateParameter && | ||||||
|             !FsRtlIsEcpFromUserMode(ExtraCreateParameter); |             !FsRtlIsEcpFromUserMode(ExtraCreateParameter); | ||||||
|  |  | ||||||
|  | #if defined(FSP_CREATE_REPARSE_POINT_ECP) | ||||||
|  |         // {73d5118a-88ba-439f-92f4-46d38952d250} | ||||||
|  |         static const GUID FspReparsePointEcpGuid = | ||||||
|  |             { 0x73d5118a, 0x88ba, 0x439f, { 0x92, 0xf4, 0x46, 0xd3, 0x89, 0x52, 0xd2, 0x50 } }; | ||||||
|  |         typedef struct _REPARSE_POINT_ECP | ||||||
|  |         { | ||||||
|  |             USHORT UnparsedNameLength; | ||||||
|  |             USHORT Flags; | ||||||
|  |             USHORT DeviceNameLength; | ||||||
|  |             PVOID Reserved; | ||||||
|  |             UNICODE_STRING Name; | ||||||
|  |         } REPARSE_POINT_ECP; | ||||||
|  |         REPARSE_POINT_ECP *ReparsePointEcp; | ||||||
|  |  | ||||||
|  |         ExtraCreateParameter = 0; | ||||||
|  |         ReparsePointEcp = | ||||||
|  |             NT_SUCCESS(FsRtlFindExtraCreateParameter(ExtraCreateParameters, | ||||||
|  |                 &FspReparsePointEcpGuid, &ExtraCreateParameter, 0)) && | ||||||
|  |             0 != ExtraCreateParameter && | ||||||
|  |             !FsRtlIsEcpFromUserMode(ExtraCreateParameter) ? | ||||||
|  |                 ExtraCreateParameter : 0; | ||||||
|  |         if (0 != ReparsePointEcp) | ||||||
|  |         { | ||||||
|  |             //DEBUGLOG("%hu %wZ", ReparsePointEcp->UnparsedNameLength, ReparsePointEcp->Name); | ||||||
|  |  | ||||||
|  |             UNICODE_STRING FileName = IrpSp->FileObject->FileName; | ||||||
|  |             if (0 != ReparsePointEcp->UnparsedNameLength && | ||||||
|  |                 FileName.Length == ReparsePointEcp->UnparsedNameLength && | ||||||
|  |                 ReparsePointEcp->Name.Length > ReparsePointEcp->UnparsedNameLength) | ||||||
|  |             { | ||||||
|  |                 /* | ||||||
|  |                  * If the ReparsePointEcp name and our file name differ only in case, | ||||||
|  |                  * go ahead and overwrite our file name. | ||||||
|  |                  */ | ||||||
|  |  | ||||||
|  |                 UNICODE_STRING UnparsedName; | ||||||
|  |                 UnparsedName.Length = UnparsedName.MaximumLength = ReparsePointEcp->UnparsedNameLength; | ||||||
|  |                 UnparsedName.Buffer = (PWCH)((UINT8 *)ReparsePointEcp->Name.Buffer + | ||||||
|  |                     (ReparsePointEcp->Name.Length - UnparsedName.Length)); | ||||||
|  |                 if (0 == FspFileNameCompare(&UnparsedName, &FileName, TRUE, 0)) | ||||||
|  |                     RtlMoveMemory(FileName.Buffer, UnparsedName.Buffer, UnparsedName.Length); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | #endif | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (!MainFileOpen) |     if (!MainFileOpen) | ||||||
|   | |||||||
| @@ -34,6 +34,7 @@ set dfl_tests=^ | |||||||
|     winfsp-tests-x64-flushpurge ^ |     winfsp-tests-x64-flushpurge ^ | ||||||
|     winfsp-tests-x64-mountpoint-drive ^ |     winfsp-tests-x64-mountpoint-drive ^ | ||||||
|     winfsp-tests-x64-mountpoint-dir ^ |     winfsp-tests-x64-mountpoint-dir ^ | ||||||
|  |     winfsp-tests-x64-mountpoint-dir-case-sensitive ^ | ||||||
|     winfsp-tests-x64-no-traverse ^ |     winfsp-tests-x64-no-traverse ^ | ||||||
|     winfsp-tests-x64-oplock ^ |     winfsp-tests-x64-oplock ^ | ||||||
|     winfsp-tests-x64-external ^ |     winfsp-tests-x64-external ^ | ||||||
| @@ -52,6 +53,7 @@ set dfl_tests=^ | |||||||
|     winfsp-tests-x86-flushpurge ^ |     winfsp-tests-x86-flushpurge ^ | ||||||
|     winfsp-tests-x86-mountpoint-drive ^ |     winfsp-tests-x86-mountpoint-drive ^ | ||||||
|     winfsp-tests-x86-mountpoint-dir ^ |     winfsp-tests-x86-mountpoint-dir ^ | ||||||
|  |     winfsp-tests-x86-mountpoint-dir-case-sensitive ^ | ||||||
|     winfsp-tests-x86-no-traverse ^ |     winfsp-tests-x86-no-traverse ^ | ||||||
|     winfsp-tests-x86-oplock ^ |     winfsp-tests-x86-oplock ^ | ||||||
|     winfsp-tests-x86-external ^ |     winfsp-tests-x86-external ^ | ||||||
| @@ -192,6 +194,11 @@ winfsp-tests-x64 --mountpoint=mymnt --case-insensitive | |||||||
| if !ERRORLEVEL! neq 0 goto fail | if !ERRORLEVEL! neq 0 goto fail | ||||||
| exit /b 0 | exit /b 0 | ||||||
|  |  | ||||||
|  | :winfsp-tests-x64-mountpoint-dir-case-sensitive | ||||||
|  | winfsp-tests-x64 --mountpoint=mymnt | ||||||
|  | if !ERRORLEVEL! neq 0 goto fail | ||||||
|  | exit /b 0 | ||||||
|  |  | ||||||
| :winfsp-tests-x64-no-traverse | :winfsp-tests-x64-no-traverse | ||||||
| winfsp-tests-x64 --no-traverse | winfsp-tests-x64 --no-traverse | ||||||
| if !ERRORLEVEL! neq 0 goto fail | if !ERRORLEVEL! neq 0 goto fail | ||||||
| @@ -227,6 +234,11 @@ winfsp-tests-x86 --mountpoint=mymnt --case-insensitive | |||||||
| if !ERRORLEVEL! neq 0 goto fail | if !ERRORLEVEL! neq 0 goto fail | ||||||
| exit /b 0 | exit /b 0 | ||||||
|  |  | ||||||
|  | :winfsp-tests-x86-mountpoint-dir-case-sensitive | ||||||
|  | winfsp-tests-x86 --mountpoint=mymnt | ||||||
|  | if !ERRORLEVEL! neq 0 goto fail | ||||||
|  | exit /b 0 | ||||||
|  |  | ||||||
| :winfsp-tests-x86-no-traverse | :winfsp-tests-x86-no-traverse | ||||||
| winfsp-tests-x86 --no-traverse | winfsp-tests-x86 --no-traverse | ||||||
| if !ERRORLEVEL! neq 0 goto fail | if !ERRORLEVEL! neq 0 goto fail | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user