fsctl: FSP_FSCTL_TRANSACT_REQ: add Req.QueryDirectory.Pattern

This commit is contained in:
Bill Zissimopoulos 2016-04-21 11:49:11 -07:00
parent f1693af6a3
commit 1bf28bdfa4
5 changed files with 24 additions and 8 deletions

View File

@ -273,6 +273,7 @@ typedef struct
UINT64 Address;
UINT64 Offset;
UINT32 Length;
FSP_FSCTL_TRANSACT_BUF Pattern;
} QueryDirectory;
struct
{

View File

@ -534,6 +534,10 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
* two entries returned by ReadDirectory should always be the "." and ".." entries.
* @param Length
* Length of data to read.
* @param Pattern
* The pattern to match against files in this directory. Can be NULL. The file system
* can choose to ignore this parameter as the FSD will always perform its own pattern
* matching on the returned results.
* @param PBytesTransferred [out]
* Pointer to a memory location that will receive the actual number of bytes read.
* @return
@ -545,6 +549,7 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
NTSTATUS (*ReadDirectory)(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request,
PVOID FileNode, PVOID Buffer, UINT64 Offset, ULONG Length,
PWSTR Pattern,
PULONG PBytesTransferred);
} FSP_FILE_SYSTEM_INTERFACE;
typedef struct _FSP_FILE_SYSTEM

View File

@ -630,6 +630,8 @@ FSP_API NTSTATUS FspFileSystemOpQueryDirectory(FSP_FILE_SYSTEM *FileSystem,
(PVOID)Request->Req.QueryDirectory.Address,
Request->Req.QueryDirectory.Offset,
Request->Req.QueryDirectory.Length,
0 != Request->Req.QueryDirectory.Pattern.Size ?
(PWSTR)(Request->Buffer + Request->Req.QueryDirectory.Pattern.Offset) : 0,
&BytesTransferred);
if (!NT_SUCCESS(Result))
return Result;

View File

@ -398,13 +398,6 @@ static NTSTATUS FspFsvolQueryDirectoryRetry(
* - If the requsted DirectoryPattern is the MatchAll pattern then we set
* the SystemBufferLength to the requested (IRP) length as it is actually
* counter-productive to try to read more than we need.
*
* Note that we have made the decision not to forward the directory pattern
* to user mode and instead do all pattern matching in kernel mode. The
* primary reason for this decision was considerations about the DirInfo meta
* cache. If it is determined that this was a bad decision in the future,
* we can always start sending the directory pattern to user mode under some
* circumstances (e.g. when doing non-cached reads).
*/
#define GetSystemBufferLengthMaybeCached()\
(0 != FsvolDeviceExtension->VolumeParams.FileInfoTimeout && 0 == FileDesc->DirectoryOffset) ||\
@ -534,7 +527,10 @@ static NTSTATUS FspFsvolQueryDirectoryRetry(
}
/* create request */
Result = FspIopCreateRequestEx(Irp, 0, 0, FspFsvolQueryDirectoryRequestFini, &Request);
Result = FspIopCreateRequestEx(Irp, 0,
FspFileDescDirectoryPatternMatchAll != FileDesc->DirectoryPattern.Buffer ?
FileDesc->DirectoryPattern.Length + sizeof(WCHAR) : 0,
FspFsvolQueryDirectoryRequestFini, &Request);
if (!NT_SUCCESS(Result))
{
FspFileNodeRelease(FileNode, Full);
@ -547,6 +543,17 @@ static NTSTATUS FspFsvolQueryDirectoryRetry(
Request->Req.QueryDirectory.Offset = FileDesc->DirectoryOffset;
Request->Req.QueryDirectory.Length = SystemBufferLength;
if (FspFileDescDirectoryPatternMatchAll != FileDesc->DirectoryPattern.Buffer)
{
Request->Req.QueryDirectory.Pattern.Offset = Request->FileName.Size;
Request->Req.QueryDirectory.Pattern.Size =
FileDesc->DirectoryPattern.Length + sizeof(WCHAR);
RtlCopyMemory(Request->Buffer + Request->FileName.Size,
FileDesc->DirectoryPattern.Buffer, FileDesc->DirectoryPattern.Length);
*(PWSTR)(Request->Buffer + Request->FileName.Size + FileDesc->DirectoryPattern.Length) =
L'\0';
}
FspFileNodeSetOwner(FileNode, Full, Request);
FspIopRequestContext(Request, RequestFileNode) = FileNode;

View File

@ -878,6 +878,7 @@ static BOOLEAN ReadDirectoryEnumFn(MEMFS_FILE_NODE *FileNode, PVOID Context0)
static NTSTATUS ReadDirectory(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request,
PVOID FileNode0, PVOID Buffer, UINT64 Offset, ULONG Length,
PWSTR Pattern,
PULONG PBytesTransferred)
{
MEMFS *Memfs = (MEMFS *)FileSystem->UserContext;