mirror of
https://github.com/winfsp/winfsp.git
synced 2025-06-08 04:52:10 -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:
parent
fa388e57ad
commit
3a8ad9c8d7
@ -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;
|
||||||
RtlCopyMemory(ItemBuffer->Buffer, Buffer, Size);
|
try
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user