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:
@ -580,58 +580,6 @@ VOID MemfsFileNodeMapEnumerateFree(MEMFS_FILE_NODE_MAP_ENUM_CONTEXT *Context)
|
||||
free(Context->FileNodes);
|
||||
}
|
||||
|
||||
typedef std::unordered_map<UINT64, std::wstring> MEMFS_DIR_DESC;
|
||||
|
||||
static inline
|
||||
NTSTATUS MemfsDirDescCreate(MEMFS_DIR_DESC **PDirDesc)
|
||||
{
|
||||
*PDirDesc = 0;
|
||||
try
|
||||
{
|
||||
*PDirDesc = new MEMFS_DIR_DESC;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
}
|
||||
|
||||
static inline
|
||||
VOID MemfsDirDescDelete(MEMFS_DIR_DESC *DirDesc)
|
||||
{
|
||||
delete DirDesc;
|
||||
}
|
||||
|
||||
static inline
|
||||
VOID MemfsDirDescReset(MEMFS_DIR_DESC *DirDesc)
|
||||
{
|
||||
DirDesc->clear();
|
||||
}
|
||||
|
||||
static inline
|
||||
PWSTR MemfsDirDescGetFileName(MEMFS_DIR_DESC *DirDesc, UINT64 Offset)
|
||||
{
|
||||
MEMFS_DIR_DESC::iterator iter = DirDesc->find(Offset);
|
||||
if (iter == DirDesc->end())
|
||||
return 0;
|
||||
return const_cast<PWSTR>(iter->second.c_str());
|
||||
}
|
||||
|
||||
static inline
|
||||
NTSTATUS MemfsDirDescInsertFileName(MEMFS_DIR_DESC *DirDesc, UINT64 Offset, PWSTR FileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
DirDesc->insert(MEMFS_DIR_DESC::value_type(Offset, FileName));
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* FSP_FILE_SYSTEM_INTERFACE
|
||||
*/
|
||||
@ -745,7 +693,6 @@ static NTSTATUS Create(FSP_FILE_SYSTEM *FileSystem,
|
||||
#endif
|
||||
MEMFS_FILE_NODE *FileNode;
|
||||
MEMFS_FILE_NODE *ParentNode;
|
||||
MEMFS_DIR_DESC *DirDesc = 0;
|
||||
NTSTATUS Result;
|
||||
BOOLEAN Inserted;
|
||||
|
||||
@ -794,20 +741,9 @@ static NTSTATUS Create(FSP_FILE_SYSTEM *FileSystem,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (CreateOptions & FILE_DIRECTORY_FILE)
|
||||
{
|
||||
Result = MemfsDirDescCreate(&DirDesc);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
}
|
||||
|
||||
Result = MemfsFileNodeCreate(FileName, &FileNode);
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
if (0 != DirDesc)
|
||||
MemfsDirDescDelete(DirDesc);
|
||||
return Result;
|
||||
}
|
||||
|
||||
#if defined(MEMFS_NAMED_STREAMS)
|
||||
FileNode->MainFileNode = MemfsFileNodeMapGetMain(Memfs->FileNodeMap, FileName);
|
||||
@ -823,8 +759,6 @@ static NTSTATUS Create(FSP_FILE_SYSTEM *FileSystem,
|
||||
if (0 == FileNode->FileSecurity)
|
||||
{
|
||||
MemfsFileNodeDelete(FileNode);
|
||||
if (0 != DirDesc)
|
||||
MemfsDirDescDelete(DirDesc);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
memcpy(FileNode->FileSecurity, SecurityDescriptor, FileNode->FileSecuritySize);
|
||||
@ -837,8 +771,6 @@ static NTSTATUS Create(FSP_FILE_SYSTEM *FileSystem,
|
||||
if (0 == FileNode->FileData)
|
||||
{
|
||||
MemfsFileNodeDelete(FileNode);
|
||||
if (0 != DirDesc)
|
||||
MemfsDirDescDelete(DirDesc);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
}
|
||||
@ -847,8 +779,6 @@ static NTSTATUS Create(FSP_FILE_SYSTEM *FileSystem,
|
||||
if (!NT_SUCCESS(Result) || !Inserted)
|
||||
{
|
||||
MemfsFileNodeDelete(FileNode);
|
||||
if (0 != DirDesc)
|
||||
MemfsDirDescDelete(DirDesc);
|
||||
if (NT_SUCCESS(Result))
|
||||
Result = STATUS_OBJECT_NAME_COLLISION; /* should not happen! */
|
||||
return Result;
|
||||
@ -869,9 +799,6 @@ static NTSTATUS Create(FSP_FILE_SYSTEM *FileSystem,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* since we now use dir descriptors to quickly retrieve dir contents, place it in UserContext2 */
|
||||
FspFileSystemGetOperationContext()->Response->Rsp.Create.Opened.UserContext2 = (UINT_PTR)DirDesc;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -881,7 +808,6 @@ static NTSTATUS Open(FSP_FILE_SYSTEM *FileSystem,
|
||||
{
|
||||
MEMFS *Memfs = (MEMFS *)FileSystem->UserContext;
|
||||
MEMFS_FILE_NODE *FileNode;
|
||||
MEMFS_DIR_DESC *DirDesc = 0;
|
||||
NTSTATUS Result;
|
||||
|
||||
if (MEMFS_MAX_PATH <= wcslen(FileName))
|
||||
@ -895,13 +821,6 @@ static NTSTATUS Open(FSP_FILE_SYSTEM *FileSystem,
|
||||
return Result;
|
||||
}
|
||||
|
||||
if (0 != (FileNode->FileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
Result = MemfsDirDescCreate(&DirDesc);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
}
|
||||
|
||||
MemfsFileNodeReference(FileNode);
|
||||
*PFileNode = FileNode;
|
||||
MemfsFileNodeGetFileInfo(FileNode, FileInfo);
|
||||
@ -917,9 +836,6 @@ static NTSTATUS Open(FSP_FILE_SYSTEM *FileSystem,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* since we now use dir descriptors to quickly retrieve dir contents, place it in UserContext2 */
|
||||
FspFileSystemGetOperationContext()->Response->Rsp.Create.Opened.UserContext2 = (UINT_PTR)DirDesc;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1025,13 +941,8 @@ static VOID Close(FSP_FILE_SYSTEM *FileSystem,
|
||||
{
|
||||
MEMFS *Memfs = (MEMFS *)FileSystem->UserContext;
|
||||
MEMFS_FILE_NODE *FileNode = (MEMFS_FILE_NODE *)FileNode0;
|
||||
MEMFS_DIR_DESC *DirDesc = (MEMFS_DIR_DESC *)(UINT_PTR)
|
||||
FspFileSystemGetOperationContext()->Request->Req.Close.UserContext2;
|
||||
|
||||
MemfsFileNodeDereference(FileNode);
|
||||
|
||||
if (0 != DirDesc)
|
||||
MemfsDirDescDelete(DirDesc);
|
||||
}
|
||||
|
||||
static NTSTATUS Read(FSP_FILE_SYSTEM *FileSystem,
|
||||
@ -1394,14 +1305,11 @@ static NTSTATUS SetSecurity(FSP_FILE_SYSTEM *FileSystem,
|
||||
typedef struct _MEMFS_READ_DIRECTORY_CONTEXT
|
||||
{
|
||||
PVOID Buffer;
|
||||
UINT64 Offset;
|
||||
ULONG Length;
|
||||
PULONG PBytesTransferred;
|
||||
BOOLEAN OffsetFound;
|
||||
MEMFS_DIR_DESC *DirDesc;
|
||||
} MEMFS_READ_DIRECTORY_CONTEXT;
|
||||
|
||||
static BOOLEAN AddDirInfo(MEMFS_DIR_DESC *DirDesc, MEMFS_FILE_NODE *FileNode, PWSTR FileName,
|
||||
static BOOLEAN AddDirInfo(MEMFS_FILE_NODE *FileNode, PWSTR FileName,
|
||||
PVOID Buffer, ULONG Length, PULONG PBytesTransferred)
|
||||
{
|
||||
UINT8 DirInfoBuf[sizeof(FSP_FSCTL_DIR_INFO) + sizeof FileNode->FileName];
|
||||
@ -1414,14 +1322,11 @@ static BOOLEAN AddDirInfo(MEMFS_DIR_DESC *DirDesc, MEMFS_FILE_NODE *FileNode, PW
|
||||
FspPathSuffix(FileNode->FileName, &Remain, &Suffix, Root);
|
||||
FileName = Suffix;
|
||||
FspPathCombine(FileNode->FileName, Suffix);
|
||||
|
||||
MemfsDirDescInsertFileName(DirDesc, FileNode->FileInfo.IndexNumber, FileName);
|
||||
}
|
||||
|
||||
memset(DirInfo->Padding, 0, sizeof DirInfo->Padding);
|
||||
DirInfo->Size = (UINT16)(sizeof(FSP_FSCTL_DIR_INFO) + wcslen(FileName) * sizeof(WCHAR));
|
||||
DirInfo->FileInfo = FileNode->FileInfo;
|
||||
DirInfo->NextOffset = FileNode->FileInfo.IndexNumber;
|
||||
memcpy(DirInfo->FileNameBuf, FileName, DirInfo->Size - sizeof(FSP_FSCTL_DIR_INFO));
|
||||
|
||||
return FspFileSystemAddDirInfo(DirInfo, Buffer, Length, PBytesTransferred);
|
||||
@ -1431,39 +1336,24 @@ static BOOLEAN ReadDirectoryEnumFn(MEMFS_FILE_NODE *FileNode, PVOID Context0)
|
||||
{
|
||||
MEMFS_READ_DIRECTORY_CONTEXT *Context = (MEMFS_READ_DIRECTORY_CONTEXT *)Context0;
|
||||
|
||||
if (0 != Context->Offset && !Context->OffsetFound)
|
||||
{
|
||||
Context->OffsetFound = FileNode->FileInfo.IndexNumber == Context->Offset;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return AddDirInfo(Context->DirDesc, FileNode, 0,
|
||||
return AddDirInfo(FileNode, 0,
|
||||
Context->Buffer, Context->Length, Context->PBytesTransferred);
|
||||
}
|
||||
|
||||
static NTSTATUS ReadDirectory(FSP_FILE_SYSTEM *FileSystem,
|
||||
PVOID FileNode0, PVOID Buffer, UINT64 Offset, ULONG Length,
|
||||
PWSTR Pattern,
|
||||
PVOID FileNode0, PVOID Buffer, ULONG Length,
|
||||
PWSTR Pattern, PWSTR Marker,
|
||||
PULONG PBytesTransferred)
|
||||
{
|
||||
MEMFS *Memfs = (MEMFS *)FileSystem->UserContext;
|
||||
MEMFS_FILE_NODE *FileNode = (MEMFS_FILE_NODE *)FileNode0;
|
||||
MEMFS_DIR_DESC *DirDesc = (MEMFS_DIR_DESC *)(UINT_PTR)
|
||||
FspFileSystemGetOperationContext()->Request->Req.QueryDirectory.UserContext2;
|
||||
MEMFS_FILE_NODE *ParentNode;
|
||||
MEMFS_READ_DIRECTORY_CONTEXT Context;
|
||||
PWSTR PrevFileName = 0;
|
||||
NTSTATUS Result;
|
||||
|
||||
Context.Buffer = Buffer;
|
||||
Context.Offset = Offset;
|
||||
Context.Length = Length;
|
||||
Context.PBytesTransferred = PBytesTransferred;
|
||||
Context.OffsetFound = FALSE;
|
||||
Context.DirDesc = DirDesc;
|
||||
|
||||
if (0 == Offset)
|
||||
MemfsDirDescReset(DirDesc);
|
||||
|
||||
if (L'\0' != FileNode->FileName[1])
|
||||
{
|
||||
@ -1473,25 +1363,20 @@ static NTSTATUS ReadDirectory(FSP_FILE_SYSTEM *FileSystem,
|
||||
if (0 == ParentNode)
|
||||
return Result;
|
||||
|
||||
if (0 == Offset)
|
||||
if (!AddDirInfo(DirDesc, FileNode, L".", Buffer, Length, PBytesTransferred))
|
||||
return STATUS_SUCCESS;
|
||||
if (0 == Offset || FileNode->FileInfo.IndexNumber == Offset)
|
||||
if (0 == Marker)
|
||||
{
|
||||
Context.OffsetFound = FileNode->FileInfo.IndexNumber == Context.Offset;
|
||||
|
||||
if (!AddDirInfo(DirDesc, ParentNode, L"..", Buffer, Length, PBytesTransferred))
|
||||
if (!AddDirInfo(FileNode, L".", Buffer, Length, PBytesTransferred))
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
if (0 == Marker || (L'.' == Marker[0] && L'\0' == Marker[1]))
|
||||
{
|
||||
if (!AddDirInfo(ParentNode, L"..", Buffer, Length, PBytesTransferred))
|
||||
return STATUS_SUCCESS;
|
||||
Marker = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 != Context.Offset && !Context.OffsetFound)
|
||||
{
|
||||
PrevFileName = MemfsDirDescGetFileName(DirDesc, Offset);
|
||||
Context.OffsetFound = 0 != PrevFileName;
|
||||
}
|
||||
|
||||
if (MemfsFileNodeMapEnumerateChildren(Memfs->FileNodeMap, FileNode, PrevFileName,
|
||||
if (MemfsFileNodeMapEnumerateChildren(Memfs->FileNodeMap, FileNode, Marker,
|
||||
ReadDirectoryEnumFn, &Context))
|
||||
FspFileSystemAddDirInfo(0, Buffer, Length, PBytesTransferred);
|
||||
|
||||
|
Reference in New Issue
Block a user