mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 08:53:01 -05:00
inc: winfsp.hpp: FileSystem: ReadDirectoryEntry and friends
This commit is contained in:
parent
4c102ab57c
commit
8787f2c528
@ -236,44 +236,95 @@ public:
|
|||||||
return _FileSystem;
|
return _FileSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* helpers: directories/streams */
|
/* helpers */
|
||||||
static BOOLEAN AcquireDirectoryBuffer(PVOID *PDirBuffer,
|
NTSTATUS SeekableReadDirectory(
|
||||||
BOOLEAN Reset, PNTSTATUS PResult)
|
PVOID FileNode,
|
||||||
|
PVOID FileDesc,
|
||||||
|
PWSTR Pattern,
|
||||||
|
PWSTR Marker,
|
||||||
|
PVOID Buffer,
|
||||||
|
ULONG Length,
|
||||||
|
PULONG PBytesTransferred)
|
||||||
{
|
{
|
||||||
return FspFileSystemAcquireDirectoryBuffer(PDirBuffer, Reset, PResult);
|
PVOID Context = 0;
|
||||||
}
|
union
|
||||||
static BOOLEAN FillDirectoryBuffer(PVOID *PDirBuffer,
|
|
||||||
DirInfo *DirInfo, PNTSTATUS PResult)
|
|
||||||
{
|
{
|
||||||
return FspFileSystemFillDirectoryBuffer(PDirBuffer, DirInfo, PResult);
|
UINT8 B[FIELD_OFFSET(FileSystem::DirInfo, FileNameBuf) + MAX_PATH * sizeof(WCHAR)];
|
||||||
|
FileSystem::DirInfo D;
|
||||||
|
} DirInfoBuf;
|
||||||
|
FileSystem::DirInfo *DirInfo = &DirInfoBuf.D;
|
||||||
|
NTSTATUS Result = STATUS_SUCCESS;
|
||||||
|
*PBytesTransferred = 0;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
Result = ReadDirectoryEntry(FileNode, FileDesc, Pattern, Marker, &Context, DirInfo);
|
||||||
|
if (STATUS_NO_MORE_FILES == Result)
|
||||||
|
{
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
static VOID ReleaseDirectoryBuffer(PVOID *PDirBuffer)
|
if (!NT_SUCCESS(Result))
|
||||||
|
break;
|
||||||
|
if (!FspFileSystemAddDirInfo(DirInfo, Buffer, Length, PBytesTransferred))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
NTSTATUS BufferedReadDirectory(
|
||||||
|
PVOID *PDirBuffer,
|
||||||
|
PVOID FileNode,
|
||||||
|
PVOID FileDesc,
|
||||||
|
PWSTR Pattern,
|
||||||
|
PWSTR Marker,
|
||||||
|
PVOID Buffer,
|
||||||
|
ULONG Length,
|
||||||
|
PULONG PBytesTransferred)
|
||||||
|
{
|
||||||
|
PVOID Context = 0;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
UINT8 B[FIELD_OFFSET(FileSystem::DirInfo, FileNameBuf) + MAX_PATH * sizeof(WCHAR)];
|
||||||
|
FileSystem::DirInfo D;
|
||||||
|
} DirInfoBuf;
|
||||||
|
FileSystem::DirInfo *DirInfo = &DirInfoBuf.D;
|
||||||
|
NTSTATUS Result = STATUS_SUCCESS;
|
||||||
|
*PBytesTransferred = 0;
|
||||||
|
if (FspFileSystemAcquireDirectoryBuffer(PDirBuffer, 0 == Marker, &Result))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
Result = ReadDirectoryEntry(FileNode, FileDesc, Pattern, Marker, &Context, DirInfo);
|
||||||
|
if (STATUS_NO_MORE_FILES == Result)
|
||||||
|
{
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
break;
|
||||||
|
if (!FspFileSystemFillDirectoryBuffer(PDirBuffer, DirInfo, &Result))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
{
|
{
|
||||||
FspFileSystemReleaseDirectoryBuffer(PDirBuffer);
|
FspFileSystemReleaseDirectoryBuffer(PDirBuffer);
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
static VOID ReadDirectoryBuffer(PVOID *PDirBuffer,
|
FspFileSystemReleaseDirectoryBuffer(PDirBuffer);
|
||||||
PWSTR Marker,
|
}
|
||||||
PVOID Buffer, ULONG Length, PULONG PBytesTransferred)
|
if (!NT_SUCCESS(Result))
|
||||||
{
|
return Result;
|
||||||
FspFileSystemReadDirectoryBuffer(PDirBuffer,
|
FspFileSystemReadDirectoryBuffer(PDirBuffer, Marker, Buffer, Length, PBytesTransferred);
|
||||||
Marker, Buffer, Length, PBytesTransferred);
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
static VOID DeleteDirectoryBuffer(PVOID *PDirBuffer)
|
static VOID DeleteDirectoryBuffer(PVOID *PDirBuffer)
|
||||||
{
|
{
|
||||||
FspFileSystemDeleteDirectoryBuffer(PDirBuffer);
|
FspFileSystemDeleteDirectoryBuffer(PDirBuffer);
|
||||||
}
|
}
|
||||||
static BOOLEAN AddDirInfo(DirInfo *DirInfo,
|
|
||||||
PVOID Buffer, ULONG Length, PULONG PBytesTransferred)
|
|
||||||
{
|
|
||||||
return FspFileSystemAddDirInfo(DirInfo, Buffer, Length, PBytesTransferred);
|
|
||||||
}
|
|
||||||
static BOOLEAN AddStreamInfo(StreamInfo *StreamInfo,
|
|
||||||
PVOID Buffer, ULONG Length, PULONG PBytesTransferred)
|
|
||||||
{
|
|
||||||
return FspFileSystemAddStreamInfo(StreamInfo, Buffer, Length, PBytesTransferred);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* helpers: reparse points */
|
|
||||||
BOOLEAN FindReparsePoint(
|
BOOLEAN FindReparsePoint(
|
||||||
PWSTR FileName, PUINT32 PReparsePointIndex)
|
PWSTR FileName, PUINT32 PReparsePointIndex)
|
||||||
{
|
{
|
||||||
@ -288,6 +339,11 @@ public:
|
|||||||
CurrentReparseData, CurrentReparseDataSize,
|
CurrentReparseData, CurrentReparseDataSize,
|
||||||
ReplaceReparseData, ReplaceReparseDataSize);
|
ReplaceReparseData, ReplaceReparseDataSize);
|
||||||
}
|
}
|
||||||
|
static BOOLEAN AddStreamInfo(StreamInfo *StreamInfo,
|
||||||
|
PVOID Buffer, ULONG Length, PULONG PBytesTransferred)
|
||||||
|
{
|
||||||
|
return FspFileSystemAddStreamInfo(StreamInfo, Buffer, Length, PBytesTransferred);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* operations */
|
/* operations */
|
||||||
@ -460,6 +516,16 @@ protected:
|
|||||||
{
|
{
|
||||||
return STATUS_INVALID_DEVICE_REQUEST;
|
return STATUS_INVALID_DEVICE_REQUEST;
|
||||||
}
|
}
|
||||||
|
virtual NTSTATUS ReadDirectoryEntry(
|
||||||
|
PVOID FileNode,
|
||||||
|
PVOID FileDesc,
|
||||||
|
PWSTR Pattern,
|
||||||
|
PWSTR Marker,
|
||||||
|
PVOID *PContext,
|
||||||
|
DirInfo *DirInfo)
|
||||||
|
{
|
||||||
|
return STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
}
|
||||||
virtual NTSTATUS ResolveReparsePoints(
|
virtual NTSTATUS ResolveReparsePoints(
|
||||||
PWSTR FileName,
|
PWSTR FileName,
|
||||||
UINT32 ReparsePointIndex,
|
UINT32 ReparsePointIndex,
|
||||||
|
@ -148,6 +148,13 @@ protected:
|
|||||||
PVOID Buffer,
|
PVOID Buffer,
|
||||||
ULONG Length,
|
ULONG Length,
|
||||||
PULONG PBytesTransferred);
|
PULONG PBytesTransferred);
|
||||||
|
NTSTATUS ReadDirectoryEntry(
|
||||||
|
PVOID FileNode,
|
||||||
|
PVOID FileDesc,
|
||||||
|
PWSTR Pattern,
|
||||||
|
PWSTR Marker,
|
||||||
|
PVOID *PContext,
|
||||||
|
DirInfo *DirInfo);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PWSTR _Path;
|
PWSTR _Path;
|
||||||
@ -729,8 +736,21 @@ NTSTATUS Ptfs::ReadDirectory(
|
|||||||
PWSTR Pattern,
|
PWSTR Pattern,
|
||||||
PWSTR Marker,
|
PWSTR Marker,
|
||||||
PVOID Buffer,
|
PVOID Buffer,
|
||||||
ULONG BufferLength,
|
ULONG Length,
|
||||||
PULONG PBytesTransferred)
|
PULONG PBytesTransferred)
|
||||||
|
{
|
||||||
|
PtfsFileDesc *FileDesc = (PtfsFileDesc *)FileDesc0;
|
||||||
|
return BufferedReadDirectory(&FileDesc->DirBuffer,
|
||||||
|
FileNode, FileDesc, Pattern, Marker, Buffer, Length, PBytesTransferred);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS Ptfs::ReadDirectoryEntry(
|
||||||
|
PVOID FileNode,
|
||||||
|
PVOID FileDesc0,
|
||||||
|
PWSTR Pattern,
|
||||||
|
PWSTR Marker,
|
||||||
|
PVOID *PContext,
|
||||||
|
DirInfo *DirInfo)
|
||||||
{
|
{
|
||||||
PtfsFileDesc *FileDesc = (PtfsFileDesc *)FileDesc0;
|
PtfsFileDesc *FileDesc = (PtfsFileDesc *)FileDesc0;
|
||||||
HANDLE Handle = FileDesc->Handle;
|
HANDLE Handle = FileDesc->Handle;
|
||||||
@ -738,16 +758,8 @@ NTSTATUS Ptfs::ReadDirectory(
|
|||||||
ULONG Length, PatternLength;
|
ULONG Length, PatternLength;
|
||||||
HANDLE FindHandle;
|
HANDLE FindHandle;
|
||||||
WIN32_FIND_DATAW FindData;
|
WIN32_FIND_DATAW FindData;
|
||||||
union
|
|
||||||
{
|
|
||||||
UINT8 B[FIELD_OFFSET(FileSystem::DirInfo, FileNameBuf) + MAX_PATH * sizeof(WCHAR)];
|
|
||||||
FileSystem::DirInfo D;
|
|
||||||
} DirInfoBuf;
|
|
||||||
FileSystem::DirInfo *DirInfo = &DirInfoBuf.D;
|
|
||||||
NTSTATUS DirBufferResult;
|
|
||||||
|
|
||||||
DirBufferResult = STATUS_SUCCESS;
|
if (0 == *PContext)
|
||||||
if (AcquireDirectoryBuffer(&FileDesc->DirBuffer, 0 == Marker, &DirBufferResult))
|
|
||||||
{
|
{
|
||||||
if (0 == Pattern)
|
if (0 == Pattern)
|
||||||
Pattern = L"*";
|
Pattern = L"*";
|
||||||
@ -755,14 +767,9 @@ NTSTATUS Ptfs::ReadDirectory(
|
|||||||
|
|
||||||
Length = GetFinalPathNameByHandleW(Handle, FullPath, FULLPATH_SIZE - 1, 0);
|
Length = GetFinalPathNameByHandleW(Handle, FullPath, FULLPATH_SIZE - 1, 0);
|
||||||
if (0 == Length)
|
if (0 == Length)
|
||||||
DirBufferResult = NtStatusFromWin32(GetLastError());
|
return NtStatusFromWin32(GetLastError());
|
||||||
else if (Length + 1 + PatternLength >= FULLPATH_SIZE)
|
if (Length + 1 + PatternLength >= FULLPATH_SIZE)
|
||||||
DirBufferResult = STATUS_OBJECT_NAME_INVALID;
|
return STATUS_OBJECT_NAME_INVALID;
|
||||||
if (!NT_SUCCESS(DirBufferResult))
|
|
||||||
{
|
|
||||||
ReleaseDirectoryBuffer(&FileDesc->DirBuffer);
|
|
||||||
return DirBufferResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (L'\\' != FullPath[Length - 1])
|
if (L'\\' != FullPath[Length - 1])
|
||||||
FullPath[Length++] = L'\\';
|
FullPath[Length++] = L'\\';
|
||||||
@ -770,14 +777,24 @@ NTSTATUS Ptfs::ReadDirectory(
|
|||||||
FullPath[Length + PatternLength] = L'\0';
|
FullPath[Length + PatternLength] = L'\0';
|
||||||
|
|
||||||
FindHandle = FindFirstFileW(FullPath, &FindData);
|
FindHandle = FindFirstFileW(FullPath, &FindData);
|
||||||
if (INVALID_HANDLE_VALUE != FindHandle)
|
if (INVALID_HANDLE_VALUE == FindHandle)
|
||||||
|
return STATUS_NO_MORE_FILES;
|
||||||
|
|
||||||
|
*PContext = FindHandle;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
do
|
FindHandle = *PContext;
|
||||||
|
if (!FindNextFileW(FindHandle, &FindData))
|
||||||
{
|
{
|
||||||
|
FindClose(FindHandle);
|
||||||
|
return STATUS_NO_MORE_FILES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
memset(DirInfo, 0, sizeof *DirInfo);
|
memset(DirInfo, 0, sizeof *DirInfo);
|
||||||
Length = (ULONG)wcslen(FindData.cFileName);
|
Length = (ULONG)wcslen(FindData.cFileName);
|
||||||
DirInfo->Size = (UINT16)(FIELD_OFFSET(FileSystem::DirInfo, FileNameBuf) +
|
DirInfo->Size = (UINT16)(FIELD_OFFSET(FileSystem::DirInfo, FileNameBuf) + Length * sizeof(WCHAR));
|
||||||
Length * sizeof(WCHAR));
|
|
||||||
DirInfo->FileInfo.FileAttributes = FindData.dwFileAttributes;
|
DirInfo->FileInfo.FileAttributes = FindData.dwFileAttributes;
|
||||||
DirInfo->FileInfo.ReparseTag = 0;
|
DirInfo->FileInfo.ReparseTag = 0;
|
||||||
DirInfo->FileInfo.FileSize =
|
DirInfo->FileInfo.FileSize =
|
||||||
@ -792,22 +809,6 @@ NTSTATUS Ptfs::ReadDirectory(
|
|||||||
DirInfo->FileInfo.HardLinks = 0;
|
DirInfo->FileInfo.HardLinks = 0;
|
||||||
memcpy(DirInfo->FileNameBuf, FindData.cFileName, Length * sizeof(WCHAR));
|
memcpy(DirInfo->FileNameBuf, FindData.cFileName, Length * sizeof(WCHAR));
|
||||||
|
|
||||||
if (!FillDirectoryBuffer(&FileDesc->DirBuffer, DirInfo, &DirBufferResult))
|
|
||||||
break;
|
|
||||||
} while (FindNextFileW(FindHandle, &FindData));
|
|
||||||
|
|
||||||
FindClose(FindHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReleaseDirectoryBuffer(&FileDesc->DirBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(DirBufferResult))
|
|
||||||
return DirBufferResult;
|
|
||||||
|
|
||||||
ReadDirectoryBuffer(&FileDesc->DirBuffer,
|
|
||||||
Marker, Buffer, BufferLength, PBytesTransferred);
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user