mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-31 12:08:41 -05:00 
			
		
		
		
	sys: FspUnicodePathIsValid, FspUnicodePathIsValidPattern
This commit is contained in:
		| @@ -618,7 +618,7 @@ static NTSTATUS FspFsvolQueryDirectory( | ||||
|         return STATUS_INVALID_PARAMETER; | ||||
|  | ||||
|     /* check that FileName is valid (if supplied) */ | ||||
|     if (0 != FileName && !FspUnicodePathIsValid(FileName, FALSE)) | ||||
|     if (0 != FileName && !FspUnicodePathIsValidPattern(FileName)) | ||||
|         return STATUS_INVALID_PARAMETER; | ||||
|  | ||||
|     /* is this an allowed file information class? */ | ||||
|   | ||||
| @@ -426,6 +426,7 @@ BOOLEAN FspExpirationTimeValid2(UINT64 ExpirationTime, UINT64 CurrentTime) | ||||
| PVOID FspAllocatePoolMustSucceed(POOL_TYPE PoolType, SIZE_T Size, ULONG Tag); | ||||
| PVOID FspAllocateIrpMustSucceed(CCHAR StackSize); | ||||
| BOOLEAN FspUnicodePathIsValid(PUNICODE_STRING Path, BOOLEAN AllowStreams); | ||||
| BOOLEAN FspUnicodePathIsValidPattern(PUNICODE_STRING Pattern); | ||||
| VOID FspUnicodePathSuffix(PUNICODE_STRING Path, PUNICODE_STRING Remain, PUNICODE_STRING Suffix); | ||||
| NTSTATUS FspCreateGuid(GUID *Guid); | ||||
| NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess, | ||||
|   | ||||
| @@ -18,6 +18,7 @@ | ||||
| #include <sys/driver.h> | ||||
|  | ||||
| BOOLEAN FspUnicodePathIsValid(PUNICODE_STRING Path, BOOLEAN AllowStreams); | ||||
| BOOLEAN FspUnicodePathIsValidPattern(PUNICODE_STRING Pattern); | ||||
| VOID FspUnicodePathSuffix(PUNICODE_STRING Path, PUNICODE_STRING Remain, PUNICODE_STRING Suffix); | ||||
| NTSTATUS FspCreateGuid(GUID *Guid); | ||||
| NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess, | ||||
| @@ -88,6 +89,7 @@ NTSTATUS FspIrpHookNext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context); | ||||
|  | ||||
| #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, FspGetDeviceObjectPointer) | ||||
| @@ -171,30 +173,91 @@ PVOID FspAllocateIrpMustSucceed(CCHAR StackSize) | ||||
|  | ||||
| BOOLEAN FspUnicodePathIsValid(PUNICODE_STRING Path, BOOLEAN AllowStreams) | ||||
| { | ||||
|     /* this does NOT check if the Path contains invalid file name chars (*, ?, etc.) */ | ||||
|  | ||||
|     PAGED_CODE(); | ||||
|  | ||||
|     if (0 != Path->Length % sizeof(WCHAR)) | ||||
|         return FALSE; | ||||
|  | ||||
|     PWSTR PathBgn, PathEnd, PathPtr; | ||||
|     UCHAR Flags = FSRTL_NTFS_LEGAL; | ||||
|     WCHAR Char; | ||||
|  | ||||
|     PathBgn = Path->Buffer; | ||||
|     PathEnd = (PWSTR)((PUINT8)PathBgn + Path->Length); | ||||
|     PathPtr = PathBgn; | ||||
|  | ||||
|     while (PathEnd > PathPtr) | ||||
|         if (L'\\' == *PathPtr) | ||||
|     { | ||||
|         Char = *PathPtr; | ||||
|  | ||||
|         if (L'\\' == Char) | ||||
|         { | ||||
|             /* stream names can only appear as the last path component */ | ||||
|             if (BooleanFlagOn(Flags, FSRTL_OLE_LEGAL)) | ||||
|                 return FALSE; | ||||
|  | ||||
|             PathPtr++; | ||||
|  | ||||
|             /* don't like multiple backslashes */ | ||||
|             if (PathEnd > PathPtr && L'\\' == *PathPtr) | ||||
|                 return FALSE; | ||||
|         } | ||||
|         else if (!AllowStreams && L':' == *PathPtr) | ||||
|         else if (L':' == Char) | ||||
|         { | ||||
|             if (!AllowStreams) | ||||
|                 return FALSE; | ||||
|  | ||||
|             /* | ||||
|              * Where are the docs on legal stream names? | ||||
|              */ | ||||
|  | ||||
|             PathPtr++; | ||||
|  | ||||
|             /* stream characters now allowed */ | ||||
|             SetFlag(Flags, FSRTL_OLE_LEGAL); | ||||
|         } | ||||
|         else if (0x80 > Char && !FsRtlTestAnsiCharacter(Char, TRUE, FALSE, Flags)) | ||||
|             return FALSE; | ||||
|         else | ||||
|             PathPtr++; | ||||
|     } | ||||
|  | ||||
|     return TRUE; | ||||
| } | ||||
|  | ||||
| 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; | ||||
| } | ||||
|   | ||||
| @@ -68,6 +68,24 @@ void create_dotest(ULONG Flags, PWSTR Prefix) | ||||
|         ASSERT(ERROR_INVALID_NAME == GetLastError()); | ||||
|     } | ||||
|  | ||||
|     /* invalid chars (wildcards) not allowed */ | ||||
|     StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0*", | ||||
|         Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); | ||||
|  | ||||
|     Handle = CreateFileW(FilePath, | ||||
|         GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0); | ||||
|     ASSERT(INVALID_HANDLE_VALUE == Handle); | ||||
|     ASSERT(ERROR_INVALID_NAME == GetLastError()); | ||||
|  | ||||
|     /* stream names can only appear as the last path component */ | ||||
|     StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\DOESNOTEXIST:foo\\file0*", | ||||
|         Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); | ||||
|  | ||||
|     Handle = CreateFileW(FilePath, | ||||
|         GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0); | ||||
|     ASSERT(INVALID_HANDLE_VALUE == Handle); | ||||
|     ASSERT(ERROR_INVALID_NAME == GetLastError()); | ||||
|  | ||||
|     StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1", | ||||
|         Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user