mirror of
https://github.com/winfsp/winfsp.git
synced 2025-06-14 15:52:47 -05:00
sys,dll: ReadDirectory: add Marker, remove Offset
This commit is contained in:
135
src/sys/dirctl.c
135
src/sys/dirctl.c
@ -28,7 +28,7 @@
|
||||
|
||||
static NTSTATUS FspFsvolQueryDirectoryCopy(
|
||||
PUNICODE_STRING DirectoryPattern, BOOLEAN CaseInsensitive,
|
||||
UINT64 DirectoryOffset, PUINT64 PDirectoryOffset,
|
||||
PUNICODE_STRING DirectoryMarker, PUNICODE_STRING DirectoryMarkerOut,
|
||||
FILE_INFORMATION_CLASS FileInformationClass, BOOLEAN ReturnSingleEntry,
|
||||
FSP_FSCTL_DIR_INFO **PDirInfo, ULONG DirInfoSize,
|
||||
PVOID DestBuf, PULONG PDestLen);
|
||||
@ -74,9 +74,6 @@ FSP_DRIVER_DISPATCH FspDirectoryControl;
|
||||
#pragma alloc_text(PAGE, FspDirectoryControl)
|
||||
#endif
|
||||
|
||||
#define FILE_INDEX_FROM_OFFSET(v) ((ULONG)(v))
|
||||
#define OFFSET_FROM_FILE_INDEX(v) ((UINT64)(v))
|
||||
|
||||
enum
|
||||
{
|
||||
/* QueryDirectory */
|
||||
@ -94,7 +91,7 @@ enum
|
||||
|
||||
static NTSTATUS FspFsvolQueryDirectoryCopy(
|
||||
PUNICODE_STRING DirectoryPattern, BOOLEAN CaseInsensitive,
|
||||
UINT64 DirectoryOffset, PUINT64 PDirectoryOffset,
|
||||
PUNICODE_STRING DirectoryMarker, PUNICODE_STRING DirectoryMarkerOut,
|
||||
FILE_INFORMATION_CLASS FileInformationClass, BOOLEAN ReturnSingleEntry,
|
||||
FSP_FSCTL_DIR_INFO **PDirInfo, ULONG DirInfoSize,
|
||||
PVOID DestBuf, PULONG PDestLen)
|
||||
@ -104,7 +101,7 @@ static NTSTATUS FspFsvolQueryDirectoryCopy(
|
||||
{\
|
||||
TYPE InfoStruct = { 0 }, *Info = &InfoStruct;\
|
||||
Info->NextEntryOffset = 0;\
|
||||
Info->FileIndex = FILE_INDEX_FROM_OFFSET(DirInfo->NextOffset);\
|
||||
Info->FileIndex = 0;\
|
||||
Info->FileNameLength = FileName.Length;\
|
||||
__VA_ARGS__\
|
||||
Info = DestBuf;\
|
||||
@ -128,7 +125,7 @@ static NTSTATUS FspFsvolQueryDirectoryCopy(
|
||||
|
||||
NTSTATUS Result = STATUS_SUCCESS;
|
||||
BOOLEAN MatchAll = FspFileDescDirectoryPatternMatchAll == DirectoryPattern->Buffer, Match;
|
||||
BOOLEAN Loop = TRUE, DirectoryOffsetFound = FALSE;
|
||||
BOOLEAN Loop = TRUE, DirectoryMarkerFound = FALSE;
|
||||
FSP_FSCTL_DIR_INFO *DirInfo = *PDirInfo;
|
||||
PUINT8 DirInfoEnd = (PUINT8)DirInfo + DirInfoSize;
|
||||
PUINT8 DestBufBgn = (PUINT8)DestBuf;
|
||||
@ -178,16 +175,18 @@ static NTSTATUS FspFsvolQueryDirectoryCopy(
|
||||
break;
|
||||
}
|
||||
|
||||
if (0 != DirectoryOffset && !DirectoryOffsetFound)
|
||||
{
|
||||
DirectoryOffsetFound = DirInfo->NextOffset == DirectoryOffset;
|
||||
continue;
|
||||
}
|
||||
|
||||
FileName.Length =
|
||||
FileName.MaximumLength = (USHORT)(DirInfoSize - sizeof(FSP_FSCTL_DIR_INFO));
|
||||
FileName.Buffer = DirInfo->FileNameBuf;
|
||||
|
||||
if (0 != DirectoryMarker && 0 != DirectoryMarker->Buffer &&
|
||||
!DirectoryMarkerFound)
|
||||
{
|
||||
DirectoryMarkerFound = 0 == FspFileNameCompare(
|
||||
&FileName, DirectoryMarker, CaseInsensitive, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* CopyLength is the same as FileName.Length except on STATUS_BUFFER_OVERFLOW */
|
||||
CopyLength = FileName.Length;
|
||||
|
||||
@ -223,7 +222,6 @@ static NTSTATUS FspFsvolQueryDirectoryCopy(
|
||||
*(PULONG)PrevDestBuf = (ULONG)((PUINT8)DestBuf - (PUINT8)PrevDestBuf);
|
||||
PrevDestBuf = DestBuf;
|
||||
|
||||
*PDirectoryOffset = DirInfo->NextOffset;
|
||||
*PDestLen = (ULONG)((PUINT8)DestBuf + BaseInfoLen + CopyLength - DestBufBgn);
|
||||
|
||||
switch (FileInformationClass)
|
||||
@ -265,6 +263,9 @@ static NTSTATUS FspFsvolQueryDirectoryCopy(
|
||||
break;
|
||||
}
|
||||
|
||||
DirectoryMarkerOut->Length = DirectoryMarkerOut->MaximumLength = FileName.Length;
|
||||
DirectoryMarkerOut->Buffer = (PVOID)((PUINT8)DestBuf + BaseInfoLen);
|
||||
|
||||
DestBuf = (PVOID)((PUINT8)DestBuf +
|
||||
FSP_FSCTL_ALIGN_UP(BaseInfoLen + CopyLength, sizeof(LONGLONG)));
|
||||
|
||||
@ -273,7 +274,7 @@ static NTSTATUS FspFsvolQueryDirectoryCopy(
|
||||
Loop = FALSE;
|
||||
}
|
||||
else
|
||||
*PDirectoryOffset = DirInfo->NextOffset;
|
||||
*DirectoryMarkerOut = FileName;
|
||||
}
|
||||
}
|
||||
except (EXCEPTION_EXECUTE_HANDLER)
|
||||
@ -315,7 +316,7 @@ static NTSTATUS FspFsvolQueryDirectoryCopyCache(
|
||||
NTSTATUS Result;
|
||||
BOOLEAN CaseInsensitive = !FileDesc->CaseSensitive;
|
||||
PUNICODE_STRING DirectoryPattern = &FileDesc->DirectoryPattern;
|
||||
UINT64 DirectoryOffset = FileDesc->DirectoryOffset;
|
||||
UNICODE_STRING DirectoryMarker = FileDesc->DirectoryMarker;
|
||||
PUINT8 DirInfoBgn = (PUINT8)DirInfo;
|
||||
PUINT8 DirInfoEnd = (PUINT8)DirInfo + DirInfoSize;
|
||||
|
||||
@ -323,17 +324,20 @@ static NTSTATUS FspFsvolQueryDirectoryCopyCache(
|
||||
DirInfoSize = (ULONG)(DirInfoEnd - (PUINT8)DirInfo);
|
||||
|
||||
Result = FspFsvolQueryDirectoryCopy(DirectoryPattern, CaseInsensitive,
|
||||
0 != FileDesc->DirInfoCacheHint ? 0 : DirectoryOffset, &DirectoryOffset,
|
||||
0 != FileDesc->DirInfoCacheHint ? 0 : &FileDesc->DirectoryMarker, &DirectoryMarker,
|
||||
FileInformationClass, ReturnSingleEntry,
|
||||
&DirInfo, DirInfoSize,
|
||||
DestBuf, PDestLen);
|
||||
|
||||
if (NT_SUCCESS(Result))
|
||||
{
|
||||
if (0 != *PDestLen)
|
||||
FileDesc->DirectoryHasSuchFile = TRUE;
|
||||
FileDesc->DirectoryOffset = DirectoryOffset;
|
||||
FileDesc->DirInfoCacheHint = (ULONG)((PUINT8)DirInfo - DirInfoBgn);
|
||||
Result = FspFileDescSetDirectoryMarker(FileDesc, &DirectoryMarker);
|
||||
if (NT_SUCCESS(Result))
|
||||
{
|
||||
if (0 != *PDestLen)
|
||||
FileDesc->DirectoryHasSuchFile = TRUE;
|
||||
FileDesc->DirInfoCacheHint = (ULONG)((PUINT8)DirInfo - DirInfoBgn);
|
||||
}
|
||||
}
|
||||
else if (STATUS_NO_MORE_FILES == Result && !FileDesc->DirectoryHasSuchFile)
|
||||
Result = STATUS_NO_SUCH_FILE;
|
||||
@ -354,7 +358,7 @@ static NTSTATUS FspFsvolQueryDirectoryCopyInPlace(
|
||||
NTSTATUS Result;
|
||||
BOOLEAN CaseInsensitive = !FileDesc->CaseSensitive;
|
||||
PUNICODE_STRING DirectoryPattern = &FileDesc->DirectoryPattern;
|
||||
UINT64 DirectoryOffset = FileDesc->DirectoryOffset;
|
||||
UNICODE_STRING DirectoryMarker = FileDesc->DirectoryMarker;
|
||||
|
||||
ASSERT(DirInfo == DestBuf);
|
||||
FSP_FSCTL_STATIC_ASSERT(
|
||||
@ -363,16 +367,19 @@ static NTSTATUS FspFsvolQueryDirectoryCopyInPlace(
|
||||
"FSP_FSCTL_DIR_INFO must be bigger than FILE_ID_BOTH_DIR_INFORMATION");
|
||||
|
||||
Result = FspFsvolQueryDirectoryCopy(DirectoryPattern, CaseInsensitive,
|
||||
0, &DirectoryOffset,
|
||||
0, &DirectoryMarker,
|
||||
FileInformationClass, ReturnSingleEntry,
|
||||
&DirInfo, DirInfoSize,
|
||||
DestBuf, PDestLen);
|
||||
|
||||
if (NT_SUCCESS(Result))
|
||||
{
|
||||
if (0 != *PDestLen)
|
||||
FileDesc->DirectoryHasSuchFile = TRUE;
|
||||
FileDesc->DirectoryOffset = DirectoryOffset;
|
||||
Result = FspFileDescSetDirectoryMarker(FileDesc, &DirectoryMarker);
|
||||
if (NT_SUCCESS(Result))
|
||||
{
|
||||
if (0 != *PDestLen)
|
||||
FileDesc->DirectoryHasSuchFile = TRUE;
|
||||
}
|
||||
}
|
||||
else if (STATUS_NO_MORE_FILES == Result && !FileDesc->DirectoryHasSuchFile)
|
||||
Result = STATUS_NO_SUCH_FILE;
|
||||
@ -442,7 +449,7 @@ static NTSTATUS FspFsvolQueryDirectoryRetry(
|
||||
* counter-productive to try to read more than we need.
|
||||
*/
|
||||
#define GetSystemBufferLengthMaybeCached()\
|
||||
(0 != FsvolDeviceExtension->VolumeParams.FileInfoTimeout && 0 == FileDesc->DirectoryOffset) ||\
|
||||
(0 != FsvolDeviceExtension->VolumeParams.FileInfoTimeout && 0 == FileDesc->DirectoryMarker.Buffer) ||\
|
||||
FspFileDescDirectoryPatternMatchAll != FileDesc->DirectoryPattern.Buffer ?\
|
||||
FspFsvolDeviceDirInfoCacheItemSizeMax : Length
|
||||
#define GetSystemBufferLengthNonCached()\
|
||||
@ -463,7 +470,7 @@ static NTSTATUS FspFsvolQueryDirectoryRetry(
|
||||
BOOLEAN ReturnSingleEntry = BooleanFlagOn(IrpSp->Flags, SL_RETURN_SINGLE_ENTRY);
|
||||
FILE_INFORMATION_CLASS FileInformationClass = IrpSp->Parameters.QueryDirectory.FileInformationClass;
|
||||
PUNICODE_STRING FileName = IrpSp->Parameters.QueryDirectory.FileName;
|
||||
ULONG FileIndex = IrpSp->Parameters.QueryDirectory.FileIndex;
|
||||
//ULONG FileIndex = IrpSp->Parameters.QueryDirectory.FileIndex;
|
||||
PVOID Buffer = 0 != Irp->AssociatedIrp.SystemBuffer ?
|
||||
Irp->AssociatedIrp.SystemBuffer : Irp->UserBuffer;
|
||||
ULONG Length = IrpSp->Parameters.QueryDirectory.Length;
|
||||
@ -511,27 +518,14 @@ static NTSTATUS FspFsvolQueryDirectoryRetry(
|
||||
Request = 0;
|
||||
}
|
||||
|
||||
/* set the DirectoryPattern in the FileDesc */
|
||||
Result = FspFileDescResetDirectoryPattern(FileDesc, FileName,
|
||||
RestartScan && 0 != FileName && 0 != FileName->Length);
|
||||
/* reset the FileDesc */
|
||||
Result = FspFileDescResetDirectory(FileDesc, FileName, RestartScan, IndexSpecified);
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
FspFileNodeRelease(FileNode, Full);
|
||||
return Result;
|
||||
}
|
||||
|
||||
/* determine where to (re)start */
|
||||
if (IndexSpecified)
|
||||
{
|
||||
FileDesc->DirectoryHasSuchFile = FALSE;
|
||||
FileDesc->DirectoryOffset = OFFSET_FROM_FILE_INDEX(FileIndex);
|
||||
}
|
||||
else if (RestartScan)
|
||||
{
|
||||
FileDesc->DirectoryHasSuchFile = FALSE;
|
||||
FileDesc->DirectoryOffset = 0;
|
||||
}
|
||||
|
||||
/* see if the required information is still in the cache and valid! */
|
||||
if (FspFileNodeReferenceDirInfo(FileNode, &DirInfoBuffer, &DirInfoSize))
|
||||
{
|
||||
@ -571,8 +565,9 @@ static NTSTATUS FspFsvolQueryDirectoryRetry(
|
||||
|
||||
/* create request */
|
||||
Result = FspIopCreateRequestEx(Irp, 0,
|
||||
FspFileDescDirectoryPatternMatchAll != FileDesc->DirectoryPattern.Buffer ?
|
||||
FileDesc->DirectoryPattern.Length + sizeof(WCHAR) : 0,
|
||||
(FspFileDescDirectoryPatternMatchAll != FileDesc->DirectoryPattern.Buffer ?
|
||||
FileDesc->DirectoryPattern.Length + sizeof(WCHAR) : 0) +
|
||||
(FsvolDeviceExtension->VolumeParams.MaxComponentLength + 1) * sizeof(WCHAR),
|
||||
FspFsvolQueryDirectoryRequestFini, &Request);
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
@ -583,19 +578,37 @@ static NTSTATUS FspFsvolQueryDirectoryRetry(
|
||||
Request->Kind = FspFsctlTransactQueryDirectoryKind;
|
||||
Request->Req.QueryDirectory.UserContext = FileNode->UserContext;
|
||||
Request->Req.QueryDirectory.UserContext2 = FileDesc->UserContext2;
|
||||
Request->Req.QueryDirectory.Offset = FileDesc->DirectoryOffset;
|
||||
Request->Req.QueryDirectory.Length = SystemBufferLength;
|
||||
Request->Req.QueryDirectory.CaseSensitive = FileDesc->CaseSensitive;
|
||||
|
||||
if (FspFileDescDirectoryPatternMatchAll != FileDesc->DirectoryPattern.Buffer)
|
||||
{
|
||||
Request->Req.QueryDirectory.Pattern.Offset = Request->FileName.Size;
|
||||
Request->Req.QueryDirectory.Pattern.Offset =
|
||||
Request->FileName.Size;
|
||||
Request->Req.QueryDirectory.Pattern.Size =
|
||||
FileDesc->DirectoryPattern.Length + sizeof(WCHAR);
|
||||
RtlCopyMemory(Request->Buffer + Request->FileName.Size,
|
||||
RtlCopyMemory(Request->Buffer + Request->Req.QueryDirectory.Pattern.Offset,
|
||||
FileDesc->DirectoryPattern.Buffer, FileDesc->DirectoryPattern.Length);
|
||||
*(PWSTR)(Request->Buffer + Request->FileName.Size + FileDesc->DirectoryPattern.Length) =
|
||||
L'\0';
|
||||
*(PWSTR)(Request->Buffer +
|
||||
Request->Req.QueryDirectory.Pattern.Offset +
|
||||
FileDesc->DirectoryPattern.Length) = L'\0';
|
||||
}
|
||||
|
||||
if (0 != FileDesc->DirectoryMarker.Buffer)
|
||||
{
|
||||
ASSERT(
|
||||
FsvolDeviceExtension->VolumeParams.MaxComponentLength >=
|
||||
FileDesc->DirectoryMarker.Length);
|
||||
|
||||
Request->Req.QueryDirectory.Marker.Offset =
|
||||
Request->FileName.Size + Request->Req.QueryDirectory.Pattern.Size;
|
||||
Request->Req.QueryDirectory.Marker.Size =
|
||||
FileDesc->DirectoryMarker.Length + sizeof(WCHAR);
|
||||
RtlCopyMemory(Request->Buffer + Request->Req.QueryDirectory.Marker.Offset,
|
||||
FileDesc->DirectoryMarker.Buffer, FileDesc->DirectoryMarker.Length);
|
||||
*(PWSTR)(Request->Buffer +
|
||||
Request->Req.QueryDirectory.Marker.Offset +
|
||||
FileDesc->DirectoryMarker.Length) = L'\0';
|
||||
}
|
||||
|
||||
FspFileNodeSetOwner(FileNode, Full, Request);
|
||||
@ -885,7 +898,6 @@ NTSTATUS FspFsvolDirectoryControlComplete(
|
||||
BOOLEAN Success;
|
||||
|
||||
ASSERT(FileNode == FileDesc->FileNode);
|
||||
ASSERT(Request->Req.QueryDirectory.Offset == FileDesc->DirectoryOffset);
|
||||
|
||||
if (0 == Response->IoStatus.Information)
|
||||
{
|
||||
@ -913,7 +925,7 @@ NTSTATUS FspFsvolDirectoryControlComplete(
|
||||
FSP_RETURN();
|
||||
}
|
||||
|
||||
if (0 == FileDesc->DirectoryOffset &&
|
||||
if (0 == Request->Req.QueryDirectory.Marker.Size &&
|
||||
FspFileNodeTrySetDirInfo(FileNode,
|
||||
Irp->AssociatedIrp.SystemBuffer,
|
||||
(ULONG)Response->IoStatus.Information,
|
||||
@ -952,7 +964,24 @@ NTSTATUS FspFsvolDirectoryControlComplete(
|
||||
FspIopResetRequest(Request, FspFsvolQueryDirectoryRequestFini);
|
||||
|
||||
Request->Req.QueryDirectory.Address = 0;
|
||||
Request->Req.QueryDirectory.Offset = FileDesc->DirectoryOffset;
|
||||
Request->Req.QueryDirectory.Marker.Offset = 0;
|
||||
Request->Req.QueryDirectory.Marker.Size = 0;
|
||||
if (0 != FileDesc->DirectoryMarker.Buffer)
|
||||
{
|
||||
ASSERT(
|
||||
FsvolDeviceExtension->VolumeParams.MaxComponentLength >=
|
||||
FileDesc->DirectoryMarker.Length);
|
||||
|
||||
Request->Req.QueryDirectory.Marker.Offset =
|
||||
Request->FileName.Size + Request->Req.QueryDirectory.Pattern.Size;
|
||||
Request->Req.QueryDirectory.Marker.Size =
|
||||
FileDesc->DirectoryMarker.Length + sizeof(WCHAR);
|
||||
RtlCopyMemory(Request->Buffer + Request->Req.QueryDirectory.Marker.Offset,
|
||||
FileDesc->DirectoryMarker.Buffer, FileDesc->DirectoryMarker.Length);
|
||||
*(PWSTR)(Request->Buffer +
|
||||
Request->Req.QueryDirectory.Marker.Offset +
|
||||
FileDesc->DirectoryMarker.Length) = L'\0';
|
||||
}
|
||||
|
||||
FspFileNodeSetOwner(FileNode, Full, Request);
|
||||
FspIopRequestContext(Request, RequestIrp) = Irp;
|
||||
|
@ -1231,7 +1231,7 @@ typedef struct
|
||||
DidSetCreationTime:1, DidSetLastAccessTime:1, DidSetLastWriteTime:1, DidSetChangeTime:1,
|
||||
DirectoryHasSuchFile:1;
|
||||
UNICODE_STRING DirectoryPattern;
|
||||
UINT64 DirectoryOffset;
|
||||
UNICODE_STRING DirectoryMarker;
|
||||
UINT64 DirInfo;
|
||||
ULONG DirInfoCacheHint;
|
||||
/* stream support */
|
||||
@ -1362,8 +1362,10 @@ VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action
|
||||
NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp);
|
||||
NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc);
|
||||
VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc);
|
||||
NTSTATUS FspFileDescResetDirectoryPattern(FSP_FILE_DESC *FileDesc,
|
||||
PUNICODE_STRING FileName, BOOLEAN Reset);
|
||||
NTSTATUS FspFileDescResetDirectory(FSP_FILE_DESC *FileDesc,
|
||||
PUNICODE_STRING FileName, BOOLEAN RestartScan, BOOLEAN IndexSpecified);
|
||||
NTSTATUS FspFileDescSetDirectoryMarker(FSP_FILE_DESC *FileDesc,
|
||||
PUNICODE_STRING FileName);
|
||||
NTSTATUS FspMainFileOpen(
|
||||
PDEVICE_OBJECT FsvolDeviceObject,
|
||||
PDEVICE_OBJECT DeviceObjectHint,
|
||||
|
@ -84,8 +84,10 @@ NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp);
|
||||
static NTSTATUS FspFileNodeCompleteLockIrp(PVOID Context, PIRP Irp);
|
||||
NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc);
|
||||
VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc);
|
||||
NTSTATUS FspFileDescResetDirectoryPattern(FSP_FILE_DESC *FileDesc,
|
||||
PUNICODE_STRING FileName, BOOLEAN Reset);
|
||||
NTSTATUS FspFileDescResetDirectory(FSP_FILE_DESC *FileDesc,
|
||||
PUNICODE_STRING FileName, BOOLEAN RestartScan, BOOLEAN IndexSpecified);
|
||||
NTSTATUS FspFileDescSetDirectoryMarker(FSP_FILE_DESC *FileDesc,
|
||||
PUNICODE_STRING FileName);
|
||||
NTSTATUS FspMainFileOpen(
|
||||
PDEVICE_OBJECT FsvolDeviceObject,
|
||||
PDEVICE_OBJECT DeviceObjectHint,
|
||||
@ -147,7 +149,8 @@ VOID FspFileNodeOplockComplete(PVOID Context, PIRP Irp);
|
||||
#pragma alloc_text(PAGE, FspFileNodeCompleteLockIrp)
|
||||
#pragma alloc_text(PAGE, FspFileDescCreate)
|
||||
#pragma alloc_text(PAGE, FspFileDescDelete)
|
||||
#pragma alloc_text(PAGE, FspFileDescResetDirectoryPattern)
|
||||
#pragma alloc_text(PAGE, FspFileDescResetDirectory)
|
||||
#pragma alloc_text(PAGE, FspFileDescSetDirectoryMarker)
|
||||
#pragma alloc_text(PAGE, FspMainFileOpen)
|
||||
#pragma alloc_text(PAGE, FspMainFileClose)
|
||||
#pragma alloc_text(PAGE, FspFileNodeOplockPrepare)
|
||||
@ -1984,15 +1987,19 @@ VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc)
|
||||
RtlFreeUnicodeString(&FileDesc->DirectoryPattern);
|
||||
}
|
||||
|
||||
if (0 != FileDesc->DirectoryMarker.Buffer)
|
||||
FspFree(FileDesc->DirectoryMarker.Buffer);
|
||||
|
||||
FspFree(FileDesc);
|
||||
}
|
||||
|
||||
NTSTATUS FspFileDescResetDirectoryPattern(FSP_FILE_DESC *FileDesc,
|
||||
PUNICODE_STRING FileName, BOOLEAN Reset)
|
||||
NTSTATUS FspFileDescResetDirectory(FSP_FILE_DESC *FileDesc,
|
||||
PUNICODE_STRING FileName, BOOLEAN RestartScan, BOOLEAN IndexSpecified)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
if (Reset || 0 == FileDesc->DirectoryPattern.Buffer)
|
||||
if (0 == FileDesc->DirectoryPattern.Buffer ||
|
||||
(RestartScan && 0 != FileName && 0 != FileName->Length))
|
||||
{
|
||||
UNICODE_STRING DirectoryPattern;
|
||||
|
||||
@ -2029,7 +2036,51 @@ NTSTATUS FspFileDescResetDirectoryPattern(FSP_FILE_DESC *FileDesc,
|
||||
}
|
||||
|
||||
FileDesc->DirectoryPattern = DirectoryPattern;
|
||||
FileDesc->DirectoryHasSuchFile = FALSE;
|
||||
|
||||
if (0 != FileDesc->DirectoryMarker.Buffer)
|
||||
{
|
||||
FspFree(FileDesc->DirectoryMarker.Buffer);
|
||||
FileDesc->DirectoryMarker.Buffer = 0;
|
||||
}
|
||||
}
|
||||
else if (IndexSpecified && 0 != FileName && 0 != FileName->Length)
|
||||
{
|
||||
NTSTATUS Result;
|
||||
|
||||
Result = FspFileDescSetDirectoryMarker(FileDesc, FileName);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
|
||||
FileDesc->DirectoryHasSuchFile = FALSE;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS FspFileDescSetDirectoryMarker(FSP_FILE_DESC *FileDesc,
|
||||
PUNICODE_STRING FileName)
|
||||
{
|
||||
if (&FileDesc->DirectoryMarker == FileName)
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension =
|
||||
FspFsvolDeviceExtension(FileDesc->FileNode->FsvolDeviceObject);
|
||||
UNICODE_STRING DirectoryMarker;
|
||||
|
||||
if (FsvolDeviceExtension->VolumeParams.MaxComponentLength < FileName->Length)
|
||||
return STATUS_OBJECT_NAME_INVALID;
|
||||
|
||||
DirectoryMarker.Length = DirectoryMarker.MaximumLength = FileName->Length;
|
||||
DirectoryMarker.Buffer = FspAlloc(FileName->Length);
|
||||
if (0 == DirectoryMarker.Buffer)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
RtlCopyMemory(DirectoryMarker.Buffer, FileName->Buffer, FileName->Length);
|
||||
|
||||
if (0 != FileDesc->DirectoryMarker.Buffer)
|
||||
FspFree(FileDesc->DirectoryMarker.Buffer);
|
||||
|
||||
FileDesc->DirectoryMarker = DirectoryMarker;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
Reference in New Issue
Block a user