mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-30 19:48:38 -05:00 
			
		
		
		
	sys: refactor util.c into strutil.c; introduce FspIsNameInExpression to wrap FsRtlIsNameInExpression
This commit is contained in:
		| @@ -176,6 +176,7 @@ | |||||||
|     <ClCompile Include="..\..\src\sys\read.c" /> |     <ClCompile Include="..\..\src\sys\read.c" /> | ||||||
|     <ClCompile Include="..\..\src\sys\security.c" /> |     <ClCompile Include="..\..\src\sys\security.c" /> | ||||||
|     <ClCompile Include="..\..\src\sys\shutdown.c" /> |     <ClCompile Include="..\..\src\sys\shutdown.c" /> | ||||||
|  |     <ClCompile Include="..\..\src\sys\strutil.c" /> | ||||||
|     <ClCompile Include="..\..\src\sys\util.c" /> |     <ClCompile Include="..\..\src\sys\util.c" /> | ||||||
|     <ClCompile Include="..\..\src\sys\volinfo.c" /> |     <ClCompile Include="..\..\src\sys\volinfo.c" /> | ||||||
|     <ClCompile Include="..\..\src\sys\volume.c" /> |     <ClCompile Include="..\..\src\sys\volume.c" /> | ||||||
|   | |||||||
| @@ -92,6 +92,9 @@ | |||||||
|     <ClCompile Include="..\..\src\sys\callbacks.c"> |     <ClCompile Include="..\..\src\sys\callbacks.c"> | ||||||
|       <Filter>Source</Filter> |       <Filter>Source</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\..\src\sys\strutil.c"> | ||||||
|  |       <Filter>Source</Filter> | ||||||
|  |     </ClCompile> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ClInclude Include="..\..\src\sys\driver.h"> |     <ClInclude Include="..\..\src\sys\driver.h"> | ||||||
|   | |||||||
| @@ -118,7 +118,7 @@ static NTSTATUS FspFsvolQueryDirectoryCopy( | |||||||
|     PAGED_CODE(); |     PAGED_CODE(); | ||||||
|  |  | ||||||
|     NTSTATUS Result = STATUS_SUCCESS; |     NTSTATUS Result = STATUS_SUCCESS; | ||||||
|     BOOLEAN MatchAll = FspFileDescDirectoryPatternMatchAll == DirectoryPattern->Buffer; |     BOOLEAN MatchAll = FspFileDescDirectoryPatternMatchAll == DirectoryPattern->Buffer, Match; | ||||||
|     BOOLEAN Loop = TRUE, DirectoryOffsetFound = FALSE; |     BOOLEAN Loop = TRUE, DirectoryOffsetFound = FALSE; | ||||||
|     FSP_FSCTL_DIR_INFO *DirInfo = *PDirInfo; |     FSP_FSCTL_DIR_INFO *DirInfo = *PDirInfo; | ||||||
|     PUINT8 DirInfoEnd = (PUINT8)DirInfo + DirInfoSize; |     PUINT8 DirInfoEnd = (PUINT8)DirInfo + DirInfoSize; | ||||||
| @@ -182,7 +182,15 @@ static NTSTATUS FspFsvolQueryDirectoryCopy( | |||||||
|             /* CopyLength is the same as FileName.Length except on STATUS_BUFFER_OVERFLOW */ |             /* CopyLength is the same as FileName.Length except on STATUS_BUFFER_OVERFLOW */ | ||||||
|             CopyLength = FileName.Length; |             CopyLength = FileName.Length; | ||||||
|  |  | ||||||
|             if (MatchAll || FsRtlIsNameInExpression(DirectoryPattern, &FileName, CaseInsensitive, 0)) |             Match = MatchAll; | ||||||
|  |             if (!Match) | ||||||
|  |             { | ||||||
|  |                 Result = FspIsNameInExpression(DirectoryPattern, &FileName, CaseInsensitive, 0, &Match); | ||||||
|  |                 if (!NT_SUCCESS(Result)) | ||||||
|  |                     return Result; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if (Match) | ||||||
|             { |             { | ||||||
|                 if ((PUINT8)DestBuf + BaseInfoLen + CopyLength > DestBufEnd) |                 if ((PUINT8)DestBuf + BaseInfoLen + CopyLength > DestBufEnd) | ||||||
|                 { |                 { | ||||||
|   | |||||||
| @@ -428,17 +428,25 @@ BOOLEAN FspExpirationTimeValid2(UINT64 ExpirationTime, UINT64 CurrentTime) | |||||||
|     return CurrentTime < ExpirationTime; |     return CurrentTime < ExpirationTime; | ||||||
| } | } | ||||||
|  |  | ||||||
| /* utility */ | /* string utility */ | ||||||
| enum | enum | ||||||
| { | { | ||||||
|     FspUnicodePathStreamTypeNone        = 0, |     FspUnicodePathStreamTypeNone        = 0, | ||||||
|     FspUnicodePathStreamTypeData        = 1, |     FspUnicodePathStreamTypeData        = 1, | ||||||
| }; | }; | ||||||
| PVOID FspAllocatePoolMustSucceed(POOL_TYPE PoolType, SIZE_T Size, ULONG Tag); |  | ||||||
| PVOID FspAllocateIrpMustSucceed(CCHAR StackSize); |  | ||||||
| BOOLEAN FspUnicodePathIsValid(PUNICODE_STRING Path, PUNICODE_STRING StreamPart, PULONG StreamType); | BOOLEAN FspUnicodePathIsValid(PUNICODE_STRING Path, PUNICODE_STRING StreamPart, PULONG StreamType); | ||||||
| BOOLEAN FspUnicodePathIsValidPattern(PUNICODE_STRING Pattern); | BOOLEAN FspUnicodePathIsValidPattern(PUNICODE_STRING Pattern); | ||||||
| VOID FspUnicodePathSuffix(PUNICODE_STRING Path, PUNICODE_STRING Remain, PUNICODE_STRING Suffix); | VOID FspUnicodePathSuffix(PUNICODE_STRING Path, PUNICODE_STRING Remain, PUNICODE_STRING Suffix); | ||||||
|  | NTSTATUS FspIsNameInExpression( | ||||||
|  |     PUNICODE_STRING Expression, | ||||||
|  |     PUNICODE_STRING Name, | ||||||
|  |     BOOLEAN IgnoreCase, | ||||||
|  |     PWCH UpcaseTable, | ||||||
|  |     PBOOLEAN PResult); | ||||||
|  |  | ||||||
|  | /* utility */ | ||||||
|  | PVOID FspAllocatePoolMustSucceed(POOL_TYPE PoolType, SIZE_T Size, ULONG Tag); | ||||||
|  | PVOID FspAllocateIrpMustSucceed(CCHAR StackSize); | ||||||
| NTSTATUS FspCreateGuid(GUID *Guid); | NTSTATUS FspCreateGuid(GUID *Guid); | ||||||
| NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess, | NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess, | ||||||
|     PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject); |     PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject); | ||||||
|   | |||||||
							
								
								
									
										223
									
								
								src/sys/strutil.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										223
									
								
								src/sys/strutil.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,223 @@ | |||||||
|  | /** | ||||||
|  |  * @file sys/strutil.c | ||||||
|  |  * | ||||||
|  |  * @copyright 2015-2016 Bill Zissimopoulos | ||||||
|  |  */ | ||||||
|  | /* | ||||||
|  |  * This file is part of WinFsp. | ||||||
|  |  * | ||||||
|  |  * You can redistribute it and/or modify it under the terms of the GNU | ||||||
|  |  * General Public License version 3 as published by the Free Software | ||||||
|  |  * Foundation. | ||||||
|  |  * | ||||||
|  |  * Licensees holding a valid commercial license may use this file in | ||||||
|  |  * accordance with the commercial license agreement provided with the | ||||||
|  |  * software. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include <sys/driver.h> | ||||||
|  |  | ||||||
|  | BOOLEAN FspUnicodePathIsValid(PUNICODE_STRING Path, PUNICODE_STRING StreamPart, PULONG StreamType); | ||||||
|  | BOOLEAN FspUnicodePathIsValidPattern(PUNICODE_STRING Pattern); | ||||||
|  | VOID FspUnicodePathSuffix(PUNICODE_STRING Path, PUNICODE_STRING Remain, PUNICODE_STRING Suffix); | ||||||
|  | NTSTATUS FspIsNameInExpression( | ||||||
|  |     PUNICODE_STRING Expression, | ||||||
|  |     PUNICODE_STRING Name, | ||||||
|  |     BOOLEAN IgnoreCase, | ||||||
|  |     PWCH UpcaseTable, | ||||||
|  |     PBOOLEAN PResult); | ||||||
|  |  | ||||||
|  | #ifdef ALLOC_PRAGMA | ||||||
|  | #pragma alloc_text(PAGE, FspUnicodePathIsValid) | ||||||
|  | #pragma alloc_text(PAGE, FspUnicodePathIsValidPattern) | ||||||
|  | #pragma alloc_text(PAGE, FspUnicodePathSuffix) | ||||||
|  | #pragma alloc_text(PAGE, FspIsNameInExpression) | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | BOOLEAN FspUnicodePathIsValid(PUNICODE_STRING Path, PUNICODE_STRING StreamPart, PULONG StreamType) | ||||||
|  | { | ||||||
|  |     PAGED_CODE(); | ||||||
|  |  | ||||||
|  |     /* if StreamPart is not NULL, StreamType must also be not NULL */ | ||||||
|  |     ASSERT(0 == StreamPart || 0 != StreamType); | ||||||
|  |  | ||||||
|  |     if (0 != Path->Length % sizeof(WCHAR)) | ||||||
|  |         return FALSE; | ||||||
|  |  | ||||||
|  |     PWSTR PathBgn, PathEnd, PathPtr, StreamTypeStr = 0; | ||||||
|  |     UCHAR Flags = FSRTL_NTFS_LEGAL; | ||||||
|  |     ULONG Colons = 0; | ||||||
|  |     WCHAR Char; | ||||||
|  |  | ||||||
|  |     PathBgn = Path->Buffer; | ||||||
|  |     PathEnd = (PWSTR)((PUINT8)PathBgn + Path->Length); | ||||||
|  |     PathPtr = PathBgn; | ||||||
|  |  | ||||||
|  |     while (PathEnd > PathPtr) | ||||||
|  |     { | ||||||
|  |         Char = *PathPtr; | ||||||
|  |  | ||||||
|  |         if (L'\\' == Char) | ||||||
|  |         { | ||||||
|  |             /* stream names can only appear as the last path component */ | ||||||
|  |             if (0 < Colons) | ||||||
|  |                 return FALSE; | ||||||
|  |  | ||||||
|  |             PathPtr++; | ||||||
|  |  | ||||||
|  |             /* don't like multiple backslashes */ | ||||||
|  |             if (PathEnd > PathPtr && L'\\' == *PathPtr) | ||||||
|  |                 return FALSE; | ||||||
|  |         } | ||||||
|  |         else if (L':' == Char) | ||||||
|  |         { | ||||||
|  |             if (0 == StreamPart) | ||||||
|  |                 return FALSE; | ||||||
|  |  | ||||||
|  |             /* | ||||||
|  |              * Where are the docs on legal stream names? | ||||||
|  |              */ | ||||||
|  |  | ||||||
|  |             /* stream characters now allowed */ | ||||||
|  |             Flags = FSRTL_NTFS_STREAM_LEGAL; | ||||||
|  |  | ||||||
|  |             PathPtr++; | ||||||
|  |             Colons++; | ||||||
|  |  | ||||||
|  |             if (1 == Colons) | ||||||
|  |             { | ||||||
|  |                 /* first time through: set up StreamPart */ | ||||||
|  |                 StreamPart->Length = StreamPart->MaximumLength = (USHORT) | ||||||
|  |                     ((PUINT8)PathEnd - (PUINT8)PathPtr); | ||||||
|  |                 StreamPart->Buffer = PathPtr; | ||||||
|  |             } | ||||||
|  |             else if (2 == Colons) | ||||||
|  |             { | ||||||
|  |                 /* second time through: fix StreamPart length to not include 2nd colon */ | ||||||
|  |                 StreamPart->Length = (USHORT) | ||||||
|  |                     ((PUINT8)PathPtr - (PUINT8)StreamPart->Buffer - sizeof(WCHAR)); | ||||||
|  |  | ||||||
|  |                 StreamTypeStr = PathPtr; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else if (0x80 > Char && !FsRtlTestAnsiCharacter(Char, TRUE, FALSE, Flags)) | ||||||
|  |             return FALSE; | ||||||
|  |         else | ||||||
|  |             PathPtr++; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* if we had no colons the path is valid */ | ||||||
|  |     if (0 == Colons) | ||||||
|  |         return TRUE; | ||||||
|  |  | ||||||
|  |     ASSERT(0 != StreamPart && 0 != StreamType); | ||||||
|  |  | ||||||
|  |     *StreamType = FspUnicodePathStreamTypeNone; | ||||||
|  |  | ||||||
|  |     /* if we had no stream type the path is valid if there was an actual stream name */ | ||||||
|  |     if (0 == StreamTypeStr) | ||||||
|  |         return 0 != StreamPart->Length; | ||||||
|  |  | ||||||
|  |     /* if we had a stream type the path is valid if the stream type was "$DATA" only */ | ||||||
|  |     if (StreamTypeStr + 5 == PathEnd && | ||||||
|  |         L'$' == StreamTypeStr[0] && | ||||||
|  |         L'D' == StreamTypeStr[1] && | ||||||
|  |         L'A' == StreamTypeStr[2] && | ||||||
|  |         L'T' == StreamTypeStr[3] && | ||||||
|  |         L'A' == StreamTypeStr[4]) | ||||||
|  |     { | ||||||
|  |         *StreamType = FspUnicodePathStreamTypeData; | ||||||
|  |         return TRUE; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return FALSE; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | BOOLEAN FspUnicodePathIsValidPattern(PUNICODE_STRING Path) | ||||||
|  | { | ||||||
|  |     PAGED_CODE(); | ||||||
|  |  | ||||||
|  |     if (0 != Path->Length % sizeof(WCHAR)) | ||||||
|  |         return FALSE; | ||||||
|  |  | ||||||
|  |     PWSTR PathBgn, PathEnd, PathPtr; | ||||||
|  |     WCHAR Char; | ||||||
|  |  | ||||||
|  |     PathBgn = Path->Buffer; | ||||||
|  |     PathEnd = (PWSTR)((PUINT8)PathBgn + Path->Length); | ||||||
|  |     PathPtr = PathBgn; | ||||||
|  |  | ||||||
|  |     while (PathEnd > PathPtr) | ||||||
|  |     { | ||||||
|  |         Char = *PathPtr; | ||||||
|  |  | ||||||
|  |         /* | ||||||
|  |          * A pattern is allowed to have wildcards. It cannot consist of multiple | ||||||
|  |          * path components (have a backslash) and it cannot reference a stream (have | ||||||
|  |          * a colon). | ||||||
|  |          */ | ||||||
|  |  | ||||||
|  |         if (L'\\' == Char) | ||||||
|  |             return FALSE; | ||||||
|  |         else if (L':' == Char) | ||||||
|  |             return FALSE; | ||||||
|  |         else if (0x80 > Char && !FsRtlTestAnsiCharacter(Char, TRUE, TRUE, FSRTL_NTFS_LEGAL)) | ||||||
|  |             return FALSE; | ||||||
|  |         else | ||||||
|  |             PathPtr++; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return TRUE; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | VOID FspUnicodePathSuffix(PUNICODE_STRING Path, PUNICODE_STRING Remain, PUNICODE_STRING Suffix) | ||||||
|  | { | ||||||
|  |     PAGED_CODE(); | ||||||
|  |  | ||||||
|  |     PWSTR PathBgn, PathEnd, PathPtr, RemainEnd, SuffixBgn; | ||||||
|  |  | ||||||
|  |     PathBgn = Path->Buffer; | ||||||
|  |     PathEnd = (PWSTR)((PUINT8)PathBgn + Path->Length); | ||||||
|  |     PathPtr = PathBgn; | ||||||
|  |  | ||||||
|  |     RemainEnd = PathEnd; | ||||||
|  |     SuffixBgn = PathEnd; | ||||||
|  |  | ||||||
|  |     while (PathEnd > PathPtr) | ||||||
|  |         if (L'\\' == *PathPtr) | ||||||
|  |         { | ||||||
|  |             RemainEnd = PathPtr++; | ||||||
|  |             for (; PathEnd > PathPtr && L'\\' == *PathPtr; PathPtr++) | ||||||
|  |                 ; | ||||||
|  |             SuffixBgn = PathPtr; | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |             PathPtr++; | ||||||
|  |  | ||||||
|  |     Remain->Length = Remain->MaximumLength = (USHORT)((PUINT8)RemainEnd - (PUINT8)PathBgn); | ||||||
|  |     Remain->Buffer = PathBgn; | ||||||
|  |     if (0 == Remain->Length && PathBgn < PathEnd && L'\\' == *PathBgn) | ||||||
|  |         Remain->Length = Remain->MaximumLength = sizeof(WCHAR); | ||||||
|  |     Suffix->Length = Suffix->MaximumLength = (USHORT)((PUINT8)PathEnd - (PUINT8)SuffixBgn); | ||||||
|  |     Suffix->Buffer = SuffixBgn; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | NTSTATUS FspIsNameInExpression( | ||||||
|  |     PUNICODE_STRING Expression, | ||||||
|  |     PUNICODE_STRING Name, | ||||||
|  |     BOOLEAN IgnoreCase, | ||||||
|  |     PWCH UpcaseTable, | ||||||
|  |     PBOOLEAN PResult) | ||||||
|  | { | ||||||
|  |     PAGED_CODE(); | ||||||
|  |  | ||||||
|  |     try | ||||||
|  |     { | ||||||
|  |         *PResult = FsRtlIsNameInExpression(Expression, Name, IgnoreCase, UpcaseTable); | ||||||
|  |         return STATUS_SUCCESS; | ||||||
|  |     } | ||||||
|  |     except (EXCEPTION_EXECUTE_HANDLER) | ||||||
|  |     { | ||||||
|  |         return GetExceptionCode(); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										174
									
								
								src/sys/util.c
									
									
									
									
									
								
							
							
						
						
									
										174
									
								
								src/sys/util.c
									
									
									
									
									
								
							| @@ -17,9 +17,6 @@ | |||||||
|  |  | ||||||
| #include <sys/driver.h> | #include <sys/driver.h> | ||||||
|  |  | ||||||
| BOOLEAN FspUnicodePathIsValid(PUNICODE_STRING Path, PUNICODE_STRING StreamPart, PULONG StreamType); |  | ||||||
| BOOLEAN FspUnicodePathIsValidPattern(PUNICODE_STRING Pattern); |  | ||||||
| VOID FspUnicodePathSuffix(PUNICODE_STRING Path, PUNICODE_STRING Remain, PUNICODE_STRING Suffix); |  | ||||||
| NTSTATUS FspCreateGuid(GUID *Guid); | NTSTATUS FspCreateGuid(GUID *Guid); | ||||||
| NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess, | NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess, | ||||||
|     PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject); |     PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject); | ||||||
| @@ -88,9 +85,6 @@ PVOID FspIrpHookContext(PVOID Context); | |||||||
| NTSTATUS FspIrpHookNext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context); | NTSTATUS FspIrpHookNext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context); | ||||||
|  |  | ||||||
| #ifdef ALLOC_PRAGMA | #ifdef ALLOC_PRAGMA | ||||||
| #pragma alloc_text(PAGE, FspUnicodePathIsValid) |  | ||||||
| #pragma alloc_text(PAGE, FspUnicodePathIsValidPattern) |  | ||||||
| #pragma alloc_text(PAGE, FspUnicodePathSuffix) |  | ||||||
| #pragma alloc_text(PAGE, FspCreateGuid) | #pragma alloc_text(PAGE, FspCreateGuid) | ||||||
| #pragma alloc_text(PAGE, FspGetDeviceObjectPointer) | #pragma alloc_text(PAGE, FspGetDeviceObjectPointer) | ||||||
| #pragma alloc_text(PAGE, FspSendSetInformationIrp) | #pragma alloc_text(PAGE, FspSendSetInformationIrp) | ||||||
| @@ -171,174 +165,6 @@ PVOID FspAllocateIrpMustSucceed(CCHAR StackSize) | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| BOOLEAN FspUnicodePathIsValid(PUNICODE_STRING Path, PUNICODE_STRING StreamPart, PULONG StreamType) |  | ||||||
| { |  | ||||||
|     PAGED_CODE(); |  | ||||||
|  |  | ||||||
|     /* if StreamPart is not NULL, StreamType must also be not NULL */ |  | ||||||
|     ASSERT(0 == StreamPart || 0 != StreamType); |  | ||||||
|  |  | ||||||
|     if (0 != Path->Length % sizeof(WCHAR)) |  | ||||||
|         return FALSE; |  | ||||||
|  |  | ||||||
|     PWSTR PathBgn, PathEnd, PathPtr, StreamTypeStr = 0; |  | ||||||
|     UCHAR Flags = FSRTL_NTFS_LEGAL; |  | ||||||
|     ULONG Colons = 0; |  | ||||||
|     WCHAR Char; |  | ||||||
|  |  | ||||||
|     PathBgn = Path->Buffer; |  | ||||||
|     PathEnd = (PWSTR)((PUINT8)PathBgn + Path->Length); |  | ||||||
|     PathPtr = PathBgn; |  | ||||||
|  |  | ||||||
|     while (PathEnd > PathPtr) |  | ||||||
|     { |  | ||||||
|         Char = *PathPtr; |  | ||||||
|  |  | ||||||
|         if (L'\\' == Char) |  | ||||||
|         { |  | ||||||
|             /* stream names can only appear as the last path component */ |  | ||||||
|             if (0 < Colons) |  | ||||||
|                 return FALSE; |  | ||||||
|  |  | ||||||
|             PathPtr++; |  | ||||||
|  |  | ||||||
|             /* don't like multiple backslashes */ |  | ||||||
|             if (PathEnd > PathPtr && L'\\' == *PathPtr) |  | ||||||
|                 return FALSE; |  | ||||||
|         } |  | ||||||
|         else if (L':' == Char) |  | ||||||
|         { |  | ||||||
|             if (0 == StreamPart) |  | ||||||
|                 return FALSE; |  | ||||||
|  |  | ||||||
|             /* |  | ||||||
|              * Where are the docs on legal stream names? |  | ||||||
|              */ |  | ||||||
|  |  | ||||||
|             /* stream characters now allowed */ |  | ||||||
|             Flags = FSRTL_NTFS_STREAM_LEGAL; |  | ||||||
|  |  | ||||||
|             PathPtr++; |  | ||||||
|             Colons++; |  | ||||||
|  |  | ||||||
|             if (1 == Colons) |  | ||||||
|             { |  | ||||||
|                 /* first time through: set up StreamPart */ |  | ||||||
|                 StreamPart->Length = StreamPart->MaximumLength = (USHORT) |  | ||||||
|                     ((PUINT8)PathEnd - (PUINT8)PathPtr); |  | ||||||
|                 StreamPart->Buffer = PathPtr; |  | ||||||
|             } |  | ||||||
|             else if (2 == Colons) |  | ||||||
|             { |  | ||||||
|                 /* second time through: fix StreamPart length to not include 2nd colon */ |  | ||||||
|                 StreamPart->Length = (USHORT) |  | ||||||
|                     ((PUINT8)PathPtr - (PUINT8)StreamPart->Buffer - sizeof(WCHAR)); |  | ||||||
|  |  | ||||||
|                 StreamTypeStr = PathPtr; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         else if (0x80 > Char && !FsRtlTestAnsiCharacter(Char, TRUE, FALSE, Flags)) |  | ||||||
|             return FALSE; |  | ||||||
|         else |  | ||||||
|             PathPtr++; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /* if we had no colons the path is valid */ |  | ||||||
|     if (0 == Colons) |  | ||||||
|         return TRUE; |  | ||||||
|  |  | ||||||
|     ASSERT(0 != StreamPart && 0 != StreamType); |  | ||||||
|  |  | ||||||
|     *StreamType = FspUnicodePathStreamTypeNone; |  | ||||||
|  |  | ||||||
|     /* if we had no stream type the path is valid if there was an actual stream name */ |  | ||||||
|     if (0 == StreamTypeStr) |  | ||||||
|         return 0 != StreamPart->Length; |  | ||||||
|  |  | ||||||
|     /* if we had a stream type the path is valid if the stream type was "$DATA" only */ |  | ||||||
|     if (StreamTypeStr + 5 == PathEnd && |  | ||||||
|         L'$' == StreamTypeStr[0] && |  | ||||||
|         L'D' == StreamTypeStr[1] && |  | ||||||
|         L'A' == StreamTypeStr[2] && |  | ||||||
|         L'T' == StreamTypeStr[3] && |  | ||||||
|         L'A' == StreamTypeStr[4]) |  | ||||||
|     { |  | ||||||
|         *StreamType = FspUnicodePathStreamTypeData; |  | ||||||
|         return TRUE; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     return FALSE; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| BOOLEAN FspUnicodePathIsValidPattern(PUNICODE_STRING Path) |  | ||||||
| { |  | ||||||
|     PAGED_CODE(); |  | ||||||
|  |  | ||||||
|     if (0 != Path->Length % sizeof(WCHAR)) |  | ||||||
|         return FALSE; |  | ||||||
|  |  | ||||||
|     PWSTR PathBgn, PathEnd, PathPtr; |  | ||||||
|     WCHAR Char; |  | ||||||
|  |  | ||||||
|     PathBgn = Path->Buffer; |  | ||||||
|     PathEnd = (PWSTR)((PUINT8)PathBgn + Path->Length); |  | ||||||
|     PathPtr = PathBgn; |  | ||||||
|  |  | ||||||
|     while (PathEnd > PathPtr) |  | ||||||
|     { |  | ||||||
|         Char = *PathPtr; |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * A pattern is allowed to have wildcards. It cannot consist of multiple |  | ||||||
|          * path components (have a backslash) and it cannot reference a stream (have |  | ||||||
|          * a colon). |  | ||||||
|          */ |  | ||||||
|  |  | ||||||
|         if (L'\\' == Char) |  | ||||||
|             return FALSE; |  | ||||||
|         else if (L':' == Char) |  | ||||||
|             return FALSE; |  | ||||||
|         else if (0x80 > Char && !FsRtlTestAnsiCharacter(Char, TRUE, TRUE, FSRTL_NTFS_LEGAL)) |  | ||||||
|             return FALSE; |  | ||||||
|         else |  | ||||||
|             PathPtr++; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     return TRUE; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| VOID FspUnicodePathSuffix(PUNICODE_STRING Path, PUNICODE_STRING Remain, PUNICODE_STRING Suffix) |  | ||||||
| { |  | ||||||
|     PAGED_CODE(); |  | ||||||
|  |  | ||||||
|     PWSTR PathBgn, PathEnd, PathPtr, RemainEnd, SuffixBgn; |  | ||||||
|  |  | ||||||
|     PathBgn = Path->Buffer; |  | ||||||
|     PathEnd = (PWSTR)((PUINT8)PathBgn + Path->Length); |  | ||||||
|     PathPtr = PathBgn; |  | ||||||
|  |  | ||||||
|     RemainEnd = PathEnd; |  | ||||||
|     SuffixBgn = PathEnd; |  | ||||||
|  |  | ||||||
|     while (PathEnd > PathPtr) |  | ||||||
|         if (L'\\' == *PathPtr) |  | ||||||
|         { |  | ||||||
|             RemainEnd = PathPtr++; |  | ||||||
|             for (; PathEnd > PathPtr && L'\\' == *PathPtr; PathPtr++) |  | ||||||
|                 ; |  | ||||||
|             SuffixBgn = PathPtr; |  | ||||||
|         } |  | ||||||
|         else |  | ||||||
|             PathPtr++; |  | ||||||
|  |  | ||||||
|     Remain->Length = Remain->MaximumLength = (USHORT)((PUINT8)RemainEnd - (PUINT8)PathBgn); |  | ||||||
|     Remain->Buffer = PathBgn; |  | ||||||
|     if (0 == Remain->Length && PathBgn < PathEnd && L'\\' == *PathBgn) |  | ||||||
|         Remain->Length = Remain->MaximumLength = sizeof(WCHAR); |  | ||||||
|     Suffix->Length = Suffix->MaximumLength = (USHORT)((PUINT8)PathEnd - (PUINT8)SuffixBgn); |  | ||||||
|     Suffix->Buffer = SuffixBgn; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| NTSTATUS FspCreateGuid(GUID *Guid) | NTSTATUS FspCreateGuid(GUID *Guid) | ||||||
| { | { | ||||||
|     PAGED_CODE(); |     PAGED_CODE(); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user