mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 08:23:05 -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;
|
||||
}
|
||||
|
||||
/* helpers: directories/streams */
|
||||
static BOOLEAN AcquireDirectoryBuffer(PVOID *PDirBuffer,
|
||||
BOOLEAN Reset, PNTSTATUS PResult)
|
||||
{
|
||||
return FspFileSystemAcquireDirectoryBuffer(PDirBuffer, Reset, PResult);
|
||||
}
|
||||
static BOOLEAN FillDirectoryBuffer(PVOID *PDirBuffer,
|
||||
DirInfo *DirInfo, PNTSTATUS PResult)
|
||||
{
|
||||
return FspFileSystemFillDirectoryBuffer(PDirBuffer, DirInfo, PResult);
|
||||
}
|
||||
static VOID ReleaseDirectoryBuffer(PVOID *PDirBuffer)
|
||||
{
|
||||
FspFileSystemReleaseDirectoryBuffer(PDirBuffer);
|
||||
}
|
||||
static VOID ReadDirectoryBuffer(PVOID *PDirBuffer,
|
||||
/* helpers */
|
||||
NTSTATUS SeekableReadDirectory(
|
||||
PVOID FileNode,
|
||||
PVOID FileDesc,
|
||||
PWSTR Pattern,
|
||||
PWSTR Marker,
|
||||
PVOID Buffer, ULONG Length, PULONG PBytesTransferred)
|
||||
PVOID Buffer,
|
||||
ULONG Length,
|
||||
PULONG PBytesTransferred)
|
||||
{
|
||||
FspFileSystemReadDirectoryBuffer(PDirBuffer,
|
||||
Marker, Buffer, Length, 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;
|
||||
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 (!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);
|
||||
throw;
|
||||
}
|
||||
FspFileSystemReleaseDirectoryBuffer(PDirBuffer);
|
||||
}
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
FspFileSystemReadDirectoryBuffer(PDirBuffer, Marker, Buffer, Length, PBytesTransferred);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
static VOID DeleteDirectoryBuffer(PVOID *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(
|
||||
PWSTR FileName, PUINT32 PReparsePointIndex)
|
||||
{
|
||||
@ -288,6 +339,11 @@ public:
|
||||
CurrentReparseData, CurrentReparseDataSize,
|
||||
ReplaceReparseData, ReplaceReparseDataSize);
|
||||
}
|
||||
static BOOLEAN AddStreamInfo(StreamInfo *StreamInfo,
|
||||
PVOID Buffer, ULONG Length, PULONG PBytesTransferred)
|
||||
{
|
||||
return FspFileSystemAddStreamInfo(StreamInfo, Buffer, Length, PBytesTransferred);
|
||||
}
|
||||
|
||||
protected:
|
||||
/* operations */
|
||||
@ -460,6 +516,16 @@ protected:
|
||||
{
|
||||
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(
|
||||
PWSTR FileName,
|
||||
UINT32 ReparsePointIndex,
|
||||
|
@ -148,6 +148,13 @@ protected:
|
||||
PVOID Buffer,
|
||||
ULONG Length,
|
||||
PULONG PBytesTransferred);
|
||||
NTSTATUS ReadDirectoryEntry(
|
||||
PVOID FileNode,
|
||||
PVOID FileDesc,
|
||||
PWSTR Pattern,
|
||||
PWSTR Marker,
|
||||
PVOID *PContext,
|
||||
DirInfo *DirInfo);
|
||||
|
||||
private:
|
||||
PWSTR _Path;
|
||||
@ -729,8 +736,21 @@ NTSTATUS Ptfs::ReadDirectory(
|
||||
PWSTR Pattern,
|
||||
PWSTR Marker,
|
||||
PVOID Buffer,
|
||||
ULONG BufferLength,
|
||||
ULONG Length,
|
||||
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;
|
||||
HANDLE Handle = FileDesc->Handle;
|
||||
@ -738,16 +758,8 @@ NTSTATUS Ptfs::ReadDirectory(
|
||||
ULONG Length, PatternLength;
|
||||
HANDLE FindHandle;
|
||||
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 (AcquireDirectoryBuffer(&FileDesc->DirBuffer, 0 == Marker, &DirBufferResult))
|
||||
if (0 == *PContext)
|
||||
{
|
||||
if (0 == Pattern)
|
||||
Pattern = L"*";
|
||||
@ -755,14 +767,9 @@ NTSTATUS Ptfs::ReadDirectory(
|
||||
|
||||
Length = GetFinalPathNameByHandleW(Handle, FullPath, FULLPATH_SIZE - 1, 0);
|
||||
if (0 == Length)
|
||||
DirBufferResult = NtStatusFromWin32(GetLastError());
|
||||
else if (Length + 1 + PatternLength >= FULLPATH_SIZE)
|
||||
DirBufferResult = STATUS_OBJECT_NAME_INVALID;
|
||||
if (!NT_SUCCESS(DirBufferResult))
|
||||
{
|
||||
ReleaseDirectoryBuffer(&FileDesc->DirBuffer);
|
||||
return DirBufferResult;
|
||||
}
|
||||
return NtStatusFromWin32(GetLastError());
|
||||
if (Length + 1 + PatternLength >= FULLPATH_SIZE)
|
||||
return STATUS_OBJECT_NAME_INVALID;
|
||||
|
||||
if (L'\\' != FullPath[Length - 1])
|
||||
FullPath[Length++] = L'\\';
|
||||
@ -770,43 +777,37 @@ NTSTATUS Ptfs::ReadDirectory(
|
||||
FullPath[Length + PatternLength] = L'\0';
|
||||
|
||||
FindHandle = FindFirstFileW(FullPath, &FindData);
|
||||
if (INVALID_HANDLE_VALUE != FindHandle)
|
||||
if (INVALID_HANDLE_VALUE == FindHandle)
|
||||
return STATUS_NO_MORE_FILES;
|
||||
|
||||
*PContext = FindHandle;
|
||||
}
|
||||
else
|
||||
{
|
||||
FindHandle = *PContext;
|
||||
if (!FindNextFileW(FindHandle, &FindData))
|
||||
{
|
||||
do
|
||||
{
|
||||
memset(DirInfo, 0, sizeof *DirInfo);
|
||||
Length = (ULONG)wcslen(FindData.cFileName);
|
||||
DirInfo->Size = (UINT16)(FIELD_OFFSET(FileSystem::DirInfo, FileNameBuf) +
|
||||
Length * sizeof(WCHAR));
|
||||
DirInfo->FileInfo.FileAttributes = FindData.dwFileAttributes;
|
||||
DirInfo->FileInfo.ReparseTag = 0;
|
||||
DirInfo->FileInfo.FileSize =
|
||||
((UINT64)FindData.nFileSizeHigh << 32) | (UINT64)FindData.nFileSizeLow;
|
||||
DirInfo->FileInfo.AllocationSize = (DirInfo->FileInfo.FileSize + ALLOCATION_UNIT - 1)
|
||||
/ ALLOCATION_UNIT * ALLOCATION_UNIT;
|
||||
DirInfo->FileInfo.CreationTime = ((PLARGE_INTEGER)&FindData.ftCreationTime)->QuadPart;
|
||||
DirInfo->FileInfo.LastAccessTime = ((PLARGE_INTEGER)&FindData.ftLastAccessTime)->QuadPart;
|
||||
DirInfo->FileInfo.LastWriteTime = ((PLARGE_INTEGER)&FindData.ftLastWriteTime)->QuadPart;
|
||||
DirInfo->FileInfo.ChangeTime = DirInfo->FileInfo.LastWriteTime;
|
||||
DirInfo->FileInfo.IndexNumber = 0;
|
||||
DirInfo->FileInfo.HardLinks = 0;
|
||||
memcpy(DirInfo->FileNameBuf, FindData.cFileName, Length * sizeof(WCHAR));
|
||||
|
||||
if (!FillDirectoryBuffer(&FileDesc->DirBuffer, DirInfo, &DirBufferResult))
|
||||
break;
|
||||
} while (FindNextFileW(FindHandle, &FindData));
|
||||
|
||||
FindClose(FindHandle);
|
||||
return STATUS_NO_MORE_FILES;
|
||||
}
|
||||
|
||||
ReleaseDirectoryBuffer(&FileDesc->DirBuffer);
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(DirBufferResult))
|
||||
return DirBufferResult;
|
||||
|
||||
ReadDirectoryBuffer(&FileDesc->DirBuffer,
|
||||
Marker, Buffer, BufferLength, PBytesTransferred);
|
||||
memset(DirInfo, 0, sizeof *DirInfo);
|
||||
Length = (ULONG)wcslen(FindData.cFileName);
|
||||
DirInfo->Size = (UINT16)(FIELD_OFFSET(FileSystem::DirInfo, FileNameBuf) + Length * sizeof(WCHAR));
|
||||
DirInfo->FileInfo.FileAttributes = FindData.dwFileAttributes;
|
||||
DirInfo->FileInfo.ReparseTag = 0;
|
||||
DirInfo->FileInfo.FileSize =
|
||||
((UINT64)FindData.nFileSizeHigh << 32) | (UINT64)FindData.nFileSizeLow;
|
||||
DirInfo->FileInfo.AllocationSize = (DirInfo->FileInfo.FileSize + ALLOCATION_UNIT - 1)
|
||||
/ ALLOCATION_UNIT * ALLOCATION_UNIT;
|
||||
DirInfo->FileInfo.CreationTime = ((PLARGE_INTEGER)&FindData.ftCreationTime)->QuadPart;
|
||||
DirInfo->FileInfo.LastAccessTime = ((PLARGE_INTEGER)&FindData.ftLastAccessTime)->QuadPart;
|
||||
DirInfo->FileInfo.LastWriteTime = ((PLARGE_INTEGER)&FindData.ftLastWriteTime)->QuadPart;
|
||||
DirInfo->FileInfo.ChangeTime = DirInfo->FileInfo.LastWriteTime;
|
||||
DirInfo->FileInfo.IndexNumber = 0;
|
||||
DirInfo->FileInfo.HardLinks = 0;
|
||||
memcpy(DirInfo->FileNameBuf, FindData.cFileName, Length * sizeof(WCHAR));
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user