mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-30 19:48:38 -05:00 
			
		
		
		
	sys: QueryDirectory stability:
- FspMetaCacheAddItem now handles exceptions during copy from fs buffer - FspFsvolQueryDirectoryLengthMax is correct max length for QueryDirectory
This commit is contained in:
		| @@ -74,6 +74,12 @@ enum | |||||||
|     RequestProcess                      = 3, |     RequestProcess                      = 3, | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | enum | ||||||
|  | { | ||||||
|  |     FspFsvolQueryDirectoryLengthMax     = | ||||||
|  |         FspFsvolDeviceDirInfoCacheItemSizeMax - FspMetaCacheItemHeaderSize, | ||||||
|  | }; | ||||||
|  |  | ||||||
| static NTSTATUS FspFsvolQueryDirectoryCopy( | static NTSTATUS FspFsvolQueryDirectoryCopy( | ||||||
|     PUNICODE_STRING DirectoryPattern, BOOLEAN CaseInsensitive, |     PUNICODE_STRING DirectoryPattern, BOOLEAN CaseInsensitive, | ||||||
|     PUNICODE_STRING DirectoryMarker, PUNICODE_STRING DirectoryMarkerOut, |     PUNICODE_STRING DirectoryMarker, PUNICODE_STRING DirectoryMarkerOut, | ||||||
| @@ -544,7 +550,7 @@ static NTSTATUS FspFsvolQueryDirectoryRetry( | |||||||
|     QueryDirectoryLengthMin = sizeof(FSP_FSCTL_DIR_INFO) + |     QueryDirectoryLengthMin = sizeof(FSP_FSCTL_DIR_INFO) + | ||||||
|         FsvolDeviceExtension->VolumeParams.MaxComponentLength * sizeof(WCHAR); |         FsvolDeviceExtension->VolumeParams.MaxComponentLength * sizeof(WCHAR); | ||||||
|     QueryDirectoryLengthMin = FSP_FSCTL_ALIGN_UP(QueryDirectoryLengthMin, 8); |     QueryDirectoryLengthMin = FSP_FSCTL_ALIGN_UP(QueryDirectoryLengthMin, 8); | ||||||
|     ASSERT(QueryDirectoryLengthMin < FspFsvolDeviceDirInfoCacheItemSizeMax); |     ASSERT(QueryDirectoryLengthMin < FspFsvolQueryDirectoryLengthMax); | ||||||
|     if (0 != FsvolDeviceExtension->VolumeParams.FileInfoTimeout && |     if (0 != FsvolDeviceExtension->VolumeParams.FileInfoTimeout && | ||||||
|         0 == FileDesc->DirectoryMarker.Buffer) |         0 == FileDesc->DirectoryMarker.Buffer) | ||||||
|     { |     { | ||||||
| @@ -557,11 +563,11 @@ static NTSTATUS FspFsvolQueryDirectoryRetry( | |||||||
|             QueryDirectoryLength = FSP_FSCTL_ALIGN_UP(QueryDirectoryLength, 8); |             QueryDirectoryLength = FSP_FSCTL_ALIGN_UP(QueryDirectoryLength, 8); | ||||||
|             if (QueryDirectoryLength < QueryDirectoryLengthMin) |             if (QueryDirectoryLength < QueryDirectoryLengthMin) | ||||||
|                 QueryDirectoryLength = QueryDirectoryLengthMin; |                 QueryDirectoryLength = QueryDirectoryLengthMin; | ||||||
|             else if (QueryDirectoryLength > FspFsvolDeviceDirInfoCacheItemSizeMax) |             else if (QueryDirectoryLength > FspFsvolQueryDirectoryLengthMax) | ||||||
|                 QueryDirectoryLength = FspFsvolDeviceDirInfoCacheItemSizeMax; |                 QueryDirectoryLength = FspFsvolQueryDirectoryLengthMax; | ||||||
|         } |         } | ||||||
|         else |         else | ||||||
|             QueryDirectoryLength = FspFsvolDeviceDirInfoCacheItemSizeMax; |             QueryDirectoryLength = FspFsvolQueryDirectoryLengthMax; | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
| @@ -575,11 +581,11 @@ static NTSTATUS FspFsvolQueryDirectoryRetry( | |||||||
|             QueryDirectoryLength = FSP_FSCTL_ALIGN_UP(QueryDirectoryLength, 8); |             QueryDirectoryLength = FSP_FSCTL_ALIGN_UP(QueryDirectoryLength, 8); | ||||||
|             if (QueryDirectoryLength < QueryDirectoryLengthMin) |             if (QueryDirectoryLength < QueryDirectoryLengthMin) | ||||||
|                 QueryDirectoryLength = QueryDirectoryLengthMin; |                 QueryDirectoryLength = QueryDirectoryLengthMin; | ||||||
|             else if (QueryDirectoryLength > FspFsvolDeviceDirInfoCacheItemSizeMax) |             else if (QueryDirectoryLength > FspFsvolQueryDirectoryLengthMax) | ||||||
|                 QueryDirectoryLength = FspFsvolDeviceDirInfoCacheItemSizeMax; |                 QueryDirectoryLength = FspFsvolQueryDirectoryLengthMax; | ||||||
|         } |         } | ||||||
|         else |         else | ||||||
|             QueryDirectoryLength = FspFsvolDeviceDirInfoCacheItemSizeMax; |             QueryDirectoryLength = FspFsvolQueryDirectoryLengthMax; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     Request->Kind = FspFsctlTransactQueryDirectoryKind; |     Request->Kind = FspFsctlTransactQueryDirectoryKind; | ||||||
|   | |||||||
| @@ -837,6 +837,10 @@ PIRP FspIoqNextCompleteIrp(FSP_IOQ *Ioq, PIRP BoundaryIrp); | |||||||
| ULONG FspIoqRetriedIrpCount(FSP_IOQ *Ioq); | ULONG FspIoqRetriedIrpCount(FSP_IOQ *Ioq); | ||||||
|  |  | ||||||
| /* meta cache */ | /* meta cache */ | ||||||
|  | enum | ||||||
|  | { | ||||||
|  |     FspMetaCacheItemHeaderSize = MEMORY_ALLOCATION_ALIGNMENT, | ||||||
|  | }; | ||||||
| typedef struct | typedef struct | ||||||
| { | { | ||||||
|     KSPIN_LOCK SpinLock; |     KSPIN_LOCK SpinLock; | ||||||
|   | |||||||
| @@ -33,6 +33,8 @@ typedef struct | |||||||
|     ULONG Size; |     ULONG Size; | ||||||
|     __declspec(align(MEMORY_ALLOCATION_ALIGNMENT)) UINT8 Buffer[]; |     __declspec(align(MEMORY_ALLOCATION_ALIGNMENT)) UINT8 Buffer[]; | ||||||
| } FSP_META_CACHE_ITEM_BUFFER; | } FSP_META_CACHE_ITEM_BUFFER; | ||||||
|  | FSP_FSCTL_STATIC_ASSERT(FIELD_OFFSET(FSP_META_CACHE_ITEM_BUFFER, Buffer) == FspMetaCacheItemHeaderSize, | ||||||
|  |     "FspMetaCacheItemHeaderSize must match offset of FSP_META_CACHE_ITEM_BUFFER::Buffer"); | ||||||
|  |  | ||||||
| static inline VOID FspMetaCacheDereferenceItem(FSP_META_CACHE_ITEM *Item) | static inline VOID FspMetaCacheDereferenceItem(FSP_META_CACHE_ITEM *Item) | ||||||
| { | { | ||||||
| @@ -218,7 +220,16 @@ UINT64 FspMetaCacheAddItem(FSP_META_CACHE *MetaCache, PCVOID Buffer, ULONG Size) | |||||||
|     Item->RefCount = 1; |     Item->RefCount = 1; | ||||||
|     ItemBuffer->Item = Item; |     ItemBuffer->Item = Item; | ||||||
|     ItemBuffer->Size = Size; |     ItemBuffer->Size = Size; | ||||||
|  |     try | ||||||
|  |     { | ||||||
|         RtlCopyMemory(ItemBuffer->Buffer, Buffer, Size); |         RtlCopyMemory(ItemBuffer->Buffer, Buffer, Size); | ||||||
|  |     } | ||||||
|  |     except (EXCEPTION_EXECUTE_HANDLER) | ||||||
|  |     { | ||||||
|  |         FspFree(ItemBuffer); | ||||||
|  |         FspFree(Item); | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|     KeAcquireSpinLock(&MetaCache->SpinLock, &Irql); |     KeAcquireSpinLock(&MetaCache->SpinLock, &Irql); | ||||||
|     if (MetaCache->ItemCount >= MetaCache->MetaCapacity) |     if (MetaCache->ItemCount >= MetaCache->MetaCapacity) | ||||||
|         FspMetaCacheRemoveExpiredItemAtDpcLevel(MetaCache, (UINT64)-1LL); |         FspMetaCacheRemoveExpiredItemAtDpcLevel(MetaCache, (UINT64)-1LL); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user