mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 00:43:00 -05:00
tst: memfs: implement GetStreamInfo
This commit is contained in:
parent
cc408b71e1
commit
fb9b798d3d
@ -266,6 +266,23 @@ BOOLEAN MemfsFileNodeMapEnumerateChildren(MEMFS_FILE_NODE_MAP *FileNodeMap, MEMF
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
BOOLEAN MemfsFileNodeMapEnumerateNamedStreams(MEMFS_FILE_NODE_MAP *FileNodeMap, MEMFS_FILE_NODE *FileNode,
|
||||||
|
BOOLEAN (*EnumFn)(MEMFS_FILE_NODE *, PVOID), PVOID Context)
|
||||||
|
{
|
||||||
|
MEMFS_FILE_NODE_MAP::iterator iter = FileNodeMap->upper_bound(FileNode->FileName);
|
||||||
|
for (; FileNodeMap->end() != iter; ++iter)
|
||||||
|
{
|
||||||
|
if (!MemfsFileNameHasPrefix(iter->second->FileName, FileNode->FileName, FALSE))
|
||||||
|
break;
|
||||||
|
if (L':' != iter->second->FileName[wcslen(FileNode->FileName)])
|
||||||
|
break;
|
||||||
|
if (!EnumFn(iter->second, Context))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
BOOLEAN MemfsFileNodeMapEnumerateDescendants(MEMFS_FILE_NODE_MAP *FileNodeMap, MEMFS_FILE_NODE *FileNode,
|
BOOLEAN MemfsFileNodeMapEnumerateDescendants(MEMFS_FILE_NODE_MAP *FileNodeMap, MEMFS_FILE_NODE *FileNode,
|
||||||
BOOLEAN (*EnumFn)(MEMFS_FILE_NODE *, PVOID), PVOID Context)
|
BOOLEAN (*EnumFn)(MEMFS_FILE_NODE *, PVOID), PVOID Context)
|
||||||
@ -1072,6 +1089,67 @@ static NTSTATUS DeleteReparsePoint(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct _MEMFS_GET_STREAM_INFO_CONTEXT
|
||||||
|
{
|
||||||
|
PVOID Buffer;
|
||||||
|
ULONG Length;
|
||||||
|
PULONG PBytesTransferred;
|
||||||
|
} MEMFS_GET_STREAM_INFO_CONTEXT;
|
||||||
|
|
||||||
|
static BOOLEAN AddStreamInfo(MEMFS_FILE_NODE *FileNode,
|
||||||
|
PVOID Buffer, ULONG Length, PULONG PBytesTransferred)
|
||||||
|
{
|
||||||
|
UINT8 StreamInfoBuf[sizeof(FSP_FSCTL_STREAM_INFO) + sizeof FileNode->FileName];
|
||||||
|
FSP_FSCTL_STREAM_INFO *StreamInfo = (FSP_FSCTL_STREAM_INFO *)StreamInfoBuf;
|
||||||
|
PWSTR StreamName;
|
||||||
|
|
||||||
|
StreamName = wcschr(FileNode->FileName, L':');
|
||||||
|
if (0 != StreamName)
|
||||||
|
StreamName++;
|
||||||
|
else
|
||||||
|
StreamName = L"";
|
||||||
|
|
||||||
|
StreamInfo->Size = (UINT16)(sizeof(FSP_FSCTL_STREAM_INFO) + wcslen(StreamName) * sizeof(WCHAR));
|
||||||
|
StreamInfo->StreamSize = FileNode->FileInfo.FileSize;
|
||||||
|
StreamInfo->StreamAllocationSize = FileNode->FileInfo.AllocationSize;
|
||||||
|
memcpy(StreamInfo->StreamNameBuf, StreamName, StreamInfo->Size - sizeof(FSP_FSCTL_STREAM_INFO));
|
||||||
|
|
||||||
|
return FspFileSystemAddStreamInfo(StreamInfo, Buffer, Length, PBytesTransferred);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOLEAN GetStreamInfoEnumFn(MEMFS_FILE_NODE *FileNode, PVOID Context0)
|
||||||
|
{
|
||||||
|
MEMFS_GET_STREAM_INFO_CONTEXT *Context = (MEMFS_GET_STREAM_INFO_CONTEXT *)Context0;
|
||||||
|
|
||||||
|
return AddStreamInfo(FileNode,
|
||||||
|
Context->Buffer, Context->Length, Context->PBytesTransferred);
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS GetStreamInfo(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||||
|
PVOID FileNode0, PVOID Buffer, ULONG Length,
|
||||||
|
PULONG PBytesTransferred)
|
||||||
|
{
|
||||||
|
MEMFS *Memfs = (MEMFS *)FileSystem->UserContext;
|
||||||
|
MEMFS_FILE_NODE *FileNode = (MEMFS_FILE_NODE *)FileNode0;
|
||||||
|
MEMFS_GET_STREAM_INFO_CONTEXT Context;
|
||||||
|
|
||||||
|
Context.Buffer = Buffer;
|
||||||
|
Context.Length = Length;
|
||||||
|
Context.PBytesTransferred = PBytesTransferred;
|
||||||
|
|
||||||
|
if (0 == (FileNode->FileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
|
||||||
|
!AddStreamInfo(FileNode, Buffer, Length, PBytesTransferred))
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
|
if (MemfsFileNodeMapEnumerateNamedStreams(Memfs->FileNodeMap, FileNode, GetStreamInfoEnumFn, &Context))
|
||||||
|
FspFileSystemAddStreamInfo(0, Buffer, Length, PBytesTransferred);
|
||||||
|
|
||||||
|
/* ???: how to handle out of response buffer condition? */
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static FSP_FILE_SYSTEM_INTERFACE MemfsInterface =
|
static FSP_FILE_SYSTEM_INTERFACE MemfsInterface =
|
||||||
{
|
{
|
||||||
GetVolumeInfo,
|
GetVolumeInfo,
|
||||||
@ -1097,6 +1175,7 @@ static FSP_FILE_SYSTEM_INTERFACE MemfsInterface =
|
|||||||
GetReparsePoint,
|
GetReparsePoint,
|
||||||
SetReparsePoint,
|
SetReparsePoint,
|
||||||
DeleteReparsePoint,
|
DeleteReparsePoint,
|
||||||
|
GetStreamInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
NTSTATUS MemfsCreate(
|
NTSTATUS MemfsCreate(
|
||||||
@ -1159,6 +1238,7 @@ NTSTATUS MemfsCreate(
|
|||||||
VolumeParams.PersistentAcls = 1;
|
VolumeParams.PersistentAcls = 1;
|
||||||
VolumeParams.ReparsePoints = 1;
|
VolumeParams.ReparsePoints = 1;
|
||||||
VolumeParams.ReparsePointsAccessCheck = 0;
|
VolumeParams.ReparsePointsAccessCheck = 0;
|
||||||
|
VolumeParams.NamedStreams = 1;
|
||||||
VolumeParams.PostCleanupOnDeleteOnly = 1;
|
VolumeParams.PostCleanupOnDeleteOnly = 1;
|
||||||
if (0 != VolumePrefix)
|
if (0 != VolumePrefix)
|
||||||
wcscpy_s(VolumeParams.Prefix, sizeof VolumeParams.Prefix / sizeof(WCHAR), VolumePrefix);
|
wcscpy_s(VolumeParams.Prefix, sizeof VolumeParams.Prefix / sizeof(WCHAR), VolumePrefix);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user