sys,dll: GetDirInfoByName

This commit is contained in:
Bill Zissimopoulos 2017-09-25 19:46:36 -07:00
parent 3ede1a5c70
commit 34546def3c
4 changed files with 90 additions and 15 deletions

View File

@ -347,6 +347,7 @@ typedef struct
FSP_FSCTL_TRANSACT_BUF Pattern; FSP_FSCTL_TRANSACT_BUF Pattern;
FSP_FSCTL_TRANSACT_BUF Marker; FSP_FSCTL_TRANSACT_BUF Marker;
UINT32 CaseSensitive:1; /* FileName comparisons should be case-sensitive */ UINT32 CaseSensitive:1; /* FileName comparisons should be case-sensitive */
UINT32 PatternIsFileName:1; /* Pattern does not contain wildcards */
} QueryDirectory; } QueryDirectory;
struct struct
{ {

View File

@ -802,12 +802,32 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
NTSTATUS (*GetStreamInfo)(FSP_FILE_SYSTEM *FileSystem, NTSTATUS (*GetStreamInfo)(FSP_FILE_SYSTEM *FileSystem,
PVOID FileContext, PVOID Buffer, ULONG Length, PVOID FileContext, PVOID Buffer, ULONG Length,
PULONG PBytesTransferred); PULONG PBytesTransferred);
/**
* Get directory information for a single file or directory within a parent directory.
*
* @param FileSystem
* The file system on which this request is posted.
* @param FileContext
* The file context of the parent directory.
* @param FileName
* The name of the file or directory to get information for. This name is relative
* to the parent directory and is a single path component.
* @param DirInfo [out]
* Pointer to a structure that will receive the directory information on successful
* return from this call. This information includes the file name, but also file
* attributes, file times, etc.
* @return
* STATUS_SUCCESS or error code.
*/
NTSTATUS (*GetDirInfoByName)(FSP_FILE_SYSTEM *FileSystem,
PVOID FileContext, PWSTR FileName,
FSP_FSCTL_DIR_INFO *DirInfo);
/* /*
* This ensures that this interface will always contain 64 function pointers. * This ensures that this interface will always contain 64 function pointers.
* Please update when changing the interface as it is important for future compatibility. * Please update when changing the interface as it is important for future compatibility.
*/ */
NTSTATUS (*Reserved[40])(); NTSTATUS (*Reserved[39])();
} FSP_FILE_SYSTEM_INTERFACE; } FSP_FILE_SYSTEM_INTERFACE;
FSP_FSCTL_STATIC_ASSERT(sizeof(FSP_FILE_SYSTEM_INTERFACE) == 64 * sizeof(NTSTATUS (*)()), FSP_FSCTL_STATIC_ASSERT(sizeof(FSP_FILE_SYSTEM_INTERFACE) == 64 * sizeof(NTSTATUS (*)()),
"FSP_FILE_SYSTEM_INTERFACE must have 64 entries."); "FSP_FILE_SYSTEM_INTERFACE must have 64 entries.");

View File

@ -1121,6 +1121,39 @@ FSP_API NTSTATUS FspFileSystemOpSetVolumeInformation(FSP_FILE_SYSTEM *FileSystem
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static NTSTATUS FspFileSystemOpQueryDirectory_GetDirInfoByName(FSP_FILE_SYSTEM *FileSystem,
PVOID FileContext, PWSTR FileName, BOOLEAN HasMarker,
PVOID Buffer, ULONG Length, PULONG PBytesTransferred)
{
NTSTATUS Result;
union
{
FSP_FSCTL_DIR_INFO V;
UINT8 B[sizeof(FSP_FSCTL_DIR_INFO) + 255 * sizeof(WCHAR)];
} DirInfoBuf;
FSP_FSCTL_DIR_INFO *DirInfo = &DirInfoBuf.V;
memset(DirInfo, 0, sizeof *DirInfo);
if (!HasMarker)
{
Result = FileSystem->Interface->GetDirInfoByName(FileSystem,
FileContext, FileName, DirInfo);
if (!NT_SUCCESS(Result))
return Result;
if (FspFileSystemAddDirInfo(DirInfo, Buffer, Length, PBytesTransferred))
FspFileSystemAddDirInfo(0, Buffer, Length, PBytesTransferred);
}
else
{
Result = STATUS_SUCCESS;
FspFileSystemAddDirInfo(0, Buffer, Length, PBytesTransferred);
}
return Result;
}
FSP_API NTSTATUS FspFileSystemOpQueryDirectory(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpQueryDirectory(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{ {
@ -1131,15 +1164,25 @@ FSP_API NTSTATUS FspFileSystemOpQueryDirectory(FSP_FILE_SYSTEM *FileSystem,
return STATUS_INVALID_DEVICE_REQUEST; return STATUS_INVALID_DEVICE_REQUEST;
BytesTransferred = 0; BytesTransferred = 0;
Result = FileSystem->Interface->ReadDirectory(FileSystem, if (0 != FileSystem->Interface->GetDirInfoByName &&
(PVOID)ValOfFileContext(Request->Req.QueryDirectory), 0 != Request->Req.QueryDirectory.Pattern.Size && Request->Req.QueryDirectory.PatternIsFileName)
0 != Request->Req.QueryDirectory.Pattern.Size ? Result = FspFileSystemOpQueryDirectory_GetDirInfoByName(FileSystem,
(PWSTR)(Request->Buffer + Request->Req.QueryDirectory.Pattern.Offset) : 0, (PVOID)ValOfFileContext(Request->Req.QueryDirectory),
0 != Request->Req.QueryDirectory.Marker.Size ? (PWSTR)(Request->Buffer + Request->Req.QueryDirectory.Pattern.Offset),
(PWSTR)(Request->Buffer + Request->Req.QueryDirectory.Marker.Offset) : 0, 0 != Request->Req.QueryDirectory.Marker.Size,
(PVOID)Request->Req.QueryDirectory.Address, (PVOID)Request->Req.QueryDirectory.Address,
Request->Req.QueryDirectory.Length, Request->Req.QueryDirectory.Length,
&BytesTransferred); &BytesTransferred);
else
Result = FileSystem->Interface->ReadDirectory(FileSystem,
(PVOID)ValOfFileContext(Request->Req.QueryDirectory),
0 != Request->Req.QueryDirectory.Pattern.Size ?
(PWSTR)(Request->Buffer + Request->Req.QueryDirectory.Pattern.Offset) : 0,
0 != Request->Req.QueryDirectory.Marker.Size ?
(PWSTR)(Request->Buffer + Request->Req.QueryDirectory.Marker.Offset) : 0,
(PVOID)Request->Req.QueryDirectory.Address,
Request->Req.QueryDirectory.Length,
&BytesTransferred);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; return Result;

View File

@ -480,6 +480,7 @@ static NTSTATUS FspFsvolQueryDirectoryRetry(
PVOID DirInfoBuffer; PVOID DirInfoBuffer;
ULONG DirInfoSize; ULONG DirInfoSize;
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
BOOLEAN PassQueryDirectoryPattern, PatternIsFileName;
BOOLEAN Success; BOOLEAN Success;
ASSERT(FileNode == FileDesc->FileNode); ASSERT(FileNode == FileDesc->FileNode);
@ -566,10 +567,20 @@ static NTSTATUS FspFsvolQueryDirectoryRetry(
} }
/* create request */ /* create request */
PassQueryDirectoryPattern = PatternIsFileName = FALSE;
if (FsvolDeviceExtension->VolumeParams.PassQueryDirectoryPattern &&
FspFileDescDirectoryPatternMatchAll != FileDesc->DirectoryPattern.Buffer)
{
PassQueryDirectoryPattern = TRUE;
PatternIsFileName = !FsRtlDoesNameContainWildCards(&FileDesc->DirectoryPattern);
}
else if (!FsRtlDoesNameContainWildCards(&FileDesc->DirectoryPattern))
{
PassQueryDirectoryPattern = TRUE;
PatternIsFileName = TRUE;
}
Result = FspIopCreateRequestEx(Irp, 0, Result = FspIopCreateRequestEx(Irp, 0,
(FsvolDeviceExtension->VolumeParams.PassQueryDirectoryPattern && (PassQueryDirectoryPattern ? FileDesc->DirectoryPattern.Length + sizeof(WCHAR) : 0) +
FspFileDescDirectoryPatternMatchAll != FileDesc->DirectoryPattern.Buffer ?
FileDesc->DirectoryPattern.Length + sizeof(WCHAR) : 0) +
(FsvolDeviceExtension->VolumeParams.MaxComponentLength + 1) * sizeof(WCHAR), (FsvolDeviceExtension->VolumeParams.MaxComponentLength + 1) * sizeof(WCHAR),
FspFsvolQueryDirectoryRequestFini, &Request); FspFsvolQueryDirectoryRequestFini, &Request);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
@ -584,9 +595,9 @@ static NTSTATUS FspFsvolQueryDirectoryRetry(
Request->Req.QueryDirectory.Length = SystemBufferLength; Request->Req.QueryDirectory.Length = SystemBufferLength;
Request->Req.QueryDirectory.CaseSensitive = FileDesc->CaseSensitive; Request->Req.QueryDirectory.CaseSensitive = FileDesc->CaseSensitive;
if (FsvolDeviceExtension->VolumeParams.PassQueryDirectoryPattern && if (PassQueryDirectoryPattern)
FspFileDescDirectoryPatternMatchAll != FileDesc->DirectoryPattern.Buffer)
{ {
Request->Req.QueryDirectory.PatternIsFileName = PatternIsFileName;
Request->Req.QueryDirectory.Pattern.Offset = Request->Req.QueryDirectory.Pattern.Offset =
Request->FileName.Size; Request->FileName.Size;
Request->Req.QueryDirectory.Pattern.Size = Request->Req.QueryDirectory.Pattern.Size =