mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 00:43:00 -05:00
tst: memfs: MEMFS_NAMED_STREAMS macro
This commit is contained in:
parent
dfd6cbbde1
commit
87b2d4ca4c
@ -22,6 +22,11 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <VersionHelpers.h>
|
#include <VersionHelpers.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define the MEMFS_NAMED_STREAMS macro to include named streams support.
|
||||||
|
*/
|
||||||
|
//#define MEMFS_NAMED_STREAMS
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Define the DEBUG_BUFFER_CHECK macro on Windows 8 or above. This includes
|
* Define the DEBUG_BUFFER_CHECK macro on Windows 8 or above. This includes
|
||||||
* a check for the Write buffer to ensure that it is read-only.
|
* a check for the Write buffer to ensure that it is read-only.
|
||||||
@ -48,14 +53,18 @@ int MemfsFileNameCompare(PWSTR a, PWSTR b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
BOOLEAN MemfsFileNameHasPrefix(PWSTR a, PWSTR b, BOOLEAN AllowStreams)
|
BOOLEAN MemfsFileNameHasPrefix(PWSTR a, PWSTR b)
|
||||||
{
|
{
|
||||||
size_t alen = wcslen(a);
|
size_t alen = wcslen(a);
|
||||||
size_t blen = wcslen(b);
|
size_t blen = wcslen(b);
|
||||||
|
|
||||||
return alen >= blen && 0 == memcmp(a, b, blen * sizeof(WCHAR)) &&
|
return alen >= blen && 0 == memcmp(a, b, blen * sizeof(WCHAR)) &&
|
||||||
(alen == blen || (1 == blen && L'\\' == b[0]) ||
|
(alen == blen || (1 == blen && L'\\' == b[0]) ||
|
||||||
(L'\\' == a[blen] || (AllowStreams && L':' == a[blen])));
|
#if defined(MEMFS_NAMED_STREAMS)
|
||||||
|
(L'\\' == a[blen] || L':' == a[blen]));
|
||||||
|
#else
|
||||||
|
(L'\\' == a[blen]));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct _MEMFS_FILE_NODE
|
typedef struct _MEMFS_FILE_NODE
|
||||||
@ -68,8 +77,9 @@ typedef struct _MEMFS_FILE_NODE
|
|||||||
SIZE_T ReparseDataSize;
|
SIZE_T ReparseDataSize;
|
||||||
PVOID ReparseData;
|
PVOID ReparseData;
|
||||||
ULONG RefCount;
|
ULONG RefCount;
|
||||||
/* stream support */
|
#if defined(MEMFS_NAMED_STREAMS)
|
||||||
struct _MEMFS_FILE_NODE *MainFileNode;
|
struct _MEMFS_FILE_NODE *MainFileNode;
|
||||||
|
#endif
|
||||||
} MEMFS_FILE_NODE;
|
} MEMFS_FILE_NODE;
|
||||||
|
|
||||||
struct MEMFS_FILE_NODE_LESS
|
struct MEMFS_FILE_NODE_LESS
|
||||||
@ -131,6 +141,7 @@ VOID MemfsFileNodeDelete(MEMFS_FILE_NODE *FileNode)
|
|||||||
static inline
|
static inline
|
||||||
VOID MemfsFileNodeGetFileInfo(MEMFS_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo)
|
VOID MemfsFileNodeGetFileInfo(MEMFS_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo)
|
||||||
{
|
{
|
||||||
|
#if defined(MEMFS_NAMED_STREAMS)
|
||||||
if (0 == FileNode->MainFileNode)
|
if (0 == FileNode->MainFileNode)
|
||||||
*FileInfo = FileNode->FileInfo;
|
*FileInfo = FileNode->FileInfo;
|
||||||
else
|
else
|
||||||
@ -141,6 +152,9 @@ VOID MemfsFileNodeGetFileInfo(MEMFS_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *Fi
|
|||||||
FileInfo->AllocationSize = FileNode->FileInfo.AllocationSize;
|
FileInfo->AllocationSize = FileNode->FileInfo.AllocationSize;
|
||||||
FileInfo->FileSize = FileNode->FileInfo.FileSize;
|
FileInfo->FileSize = FileNode->FileInfo.FileSize;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
*FileInfo = FileNode->FileInfo;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
@ -193,6 +207,7 @@ MEMFS_FILE_NODE *MemfsFileNodeMapGet(MEMFS_FILE_NODE_MAP *FileNodeMap, PWSTR Fil
|
|||||||
return iter->second;
|
return iter->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(MEMFS_NAMED_STREAMS)
|
||||||
static inline
|
static inline
|
||||||
MEMFS_FILE_NODE *MemfsFileNodeMapGetMain(MEMFS_FILE_NODE_MAP *FileNodeMap, PWSTR FileName0)
|
MEMFS_FILE_NODE *MemfsFileNodeMapGetMain(MEMFS_FILE_NODE_MAP *FileNodeMap, PWSTR FileName0)
|
||||||
{
|
{
|
||||||
@ -207,6 +222,7 @@ MEMFS_FILE_NODE *MemfsFileNodeMapGetMain(MEMFS_FILE_NODE_MAP *FileNodeMap, PWSTR
|
|||||||
return 0;
|
return 0;
|
||||||
return iter->second;
|
return iter->second;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
MEMFS_FILE_NODE *MemfsFileNodeMapGetParent(MEMFS_FILE_NODE_MAP *FileNodeMap, PWSTR FileName0,
|
MEMFS_FILE_NODE *MemfsFileNodeMapGetParent(MEMFS_FILE_NODE_MAP *FileNodeMap, PWSTR FileName0,
|
||||||
@ -282,12 +298,13 @@ BOOLEAN MemfsFileNodeMapEnumerateChildren(MEMFS_FILE_NODE_MAP *FileNodeMap, MEMF
|
|||||||
BOOLEAN IsDirectoryChild;
|
BOOLEAN IsDirectoryChild;
|
||||||
for (; FileNodeMap->end() != iter; ++iter)
|
for (; FileNodeMap->end() != iter; ++iter)
|
||||||
{
|
{
|
||||||
if (!MemfsFileNameHasPrefix(iter->second->FileName, FileNode->FileName, FALSE))
|
if (!MemfsFileNameHasPrefix(iter->second->FileName, FileNode->FileName))
|
||||||
break;
|
break;
|
||||||
FspPathSuffix(iter->second->FileName, &Remain, &Suffix, Root);
|
FspPathSuffix(iter->second->FileName, &Remain, &Suffix, Root);
|
||||||
IsDirectoryChild =
|
IsDirectoryChild = 0 == MemfsFileNameCompare(Remain, FileNode->FileName);
|
||||||
0 == MemfsFileNameCompare(Remain, FileNode->FileName) &&
|
#if defined(MEMFS_NAMED_STREAMS)
|
||||||
0 == wcschr(Suffix, L':');
|
IsDirectoryChild = IsDirectoryChild && 0 == wcschr(Suffix, L':');
|
||||||
|
#endif
|
||||||
FspPathCombine(iter->second->FileName, Suffix);
|
FspPathCombine(iter->second->FileName, Suffix);
|
||||||
if (IsDirectoryChild)
|
if (IsDirectoryChild)
|
||||||
{
|
{
|
||||||
@ -298,6 +315,7 @@ BOOLEAN MemfsFileNodeMapEnumerateChildren(MEMFS_FILE_NODE_MAP *FileNodeMap, MEMF
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(MEMFS_NAMED_STREAMS)
|
||||||
static inline
|
static inline
|
||||||
BOOLEAN MemfsFileNodeMapEnumerateNamedStreams(MEMFS_FILE_NODE_MAP *FileNodeMap, MEMFS_FILE_NODE *FileNode,
|
BOOLEAN MemfsFileNodeMapEnumerateNamedStreams(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)
|
||||||
@ -305,7 +323,7 @@ BOOLEAN MemfsFileNodeMapEnumerateNamedStreams(MEMFS_FILE_NODE_MAP *FileNodeMap,
|
|||||||
MEMFS_FILE_NODE_MAP::iterator iter = FileNodeMap->upper_bound(FileNode->FileName);
|
MEMFS_FILE_NODE_MAP::iterator iter = FileNodeMap->upper_bound(FileNode->FileName);
|
||||||
for (; FileNodeMap->end() != iter; ++iter)
|
for (; FileNodeMap->end() != iter; ++iter)
|
||||||
{
|
{
|
||||||
if (!MemfsFileNameHasPrefix(iter->second->FileName, FileNode->FileName, FALSE))
|
if (!MemfsFileNameHasPrefix(iter->second->FileName, FileNode->FileName))
|
||||||
break;
|
break;
|
||||||
if (L':' != iter->second->FileName[wcslen(FileNode->FileName)])
|
if (L':' != iter->second->FileName[wcslen(FileNode->FileName)])
|
||||||
break;
|
break;
|
||||||
@ -314,6 +332,7 @@ BOOLEAN MemfsFileNodeMapEnumerateNamedStreams(MEMFS_FILE_NODE_MAP *FileNodeMap,
|
|||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
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,
|
||||||
@ -323,7 +342,7 @@ BOOLEAN MemfsFileNodeMapEnumerateDescendants(MEMFS_FILE_NODE_MAP *FileNodeMap, M
|
|||||||
MEMFS_FILE_NODE_MAP::iterator iter = FileNodeMap->lower_bound(FileNode->FileName);
|
MEMFS_FILE_NODE_MAP::iterator iter = FileNodeMap->lower_bound(FileNode->FileName);
|
||||||
for (; FileNodeMap->end() != iter; ++iter)
|
for (; FileNodeMap->end() != iter; ++iter)
|
||||||
{
|
{
|
||||||
if (!MemfsFileNameHasPrefix(iter->second->FileName, FileNode->FileName, TRUE))
|
if (!MemfsFileNameHasPrefix(iter->second->FileName, FileNode->FileName))
|
||||||
break;
|
break;
|
||||||
if (!EnumFn(iter->second, Context))
|
if (!EnumFn(iter->second, Context))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -398,8 +417,10 @@ static NTSTATUS GetSecurityByName(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(MEMFS_NAMED_STREAMS)
|
||||||
if (0 != FileNode->MainFileNode)
|
if (0 != FileNode->MainFileNode)
|
||||||
FileNode = FileNode->MainFileNode;
|
FileNode = FileNode->MainFileNode;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (0 != PFileAttributes)
|
if (0 != PFileAttributes)
|
||||||
*PFileAttributes = FileNode->FileInfo.FileAttributes;
|
*PFileAttributes = FileNode->FileInfo.FileAttributes;
|
||||||
@ -451,7 +472,9 @@ static NTSTATUS Create(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
|
#if defined(MEMFS_NAMED_STREAMS)
|
||||||
FileNode->MainFileNode = MemfsFileNodeMapGetMain(Memfs->FileNodeMap, FileName);
|
FileNode->MainFileNode = MemfsFileNodeMapGetMain(Memfs->FileNodeMap, FileName);
|
||||||
|
#endif
|
||||||
|
|
||||||
FileNode->FileInfo.FileAttributes = (FileAttributes & FILE_ATTRIBUTE_DIRECTORY) ?
|
FileNode->FileInfo.FileAttributes = (FileAttributes & FILE_ATTRIBUTE_DIRECTORY) ?
|
||||||
FileAttributes : FileAttributes | FILE_ATTRIBUTE_ARCHIVE;
|
FileAttributes : FileAttributes | FILE_ATTRIBUTE_ARCHIVE;
|
||||||
@ -555,6 +578,7 @@ NTSTATUS Overwrite(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(MEMFS_NAMED_STREAMS)
|
||||||
typedef struct _MEMFS_CLEANUP_CONTEXT
|
typedef struct _MEMFS_CLEANUP_CONTEXT
|
||||||
{
|
{
|
||||||
MEMFS_FILE_NODE **FileNodes;
|
MEMFS_FILE_NODE **FileNodes;
|
||||||
@ -569,6 +593,7 @@ static BOOLEAN CleanupEnumFn(MEMFS_FILE_NODE *FileNode, PVOID Context0)
|
|||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static VOID Cleanup(FSP_FILE_SYSTEM *FileSystem,
|
static VOID Cleanup(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||||
@ -582,6 +607,7 @@ static VOID Cleanup(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
|
|
||||||
if (Delete && !MemfsFileNodeMapHasChild(Memfs->FileNodeMap, FileNode))
|
if (Delete && !MemfsFileNodeMapHasChild(Memfs->FileNodeMap, FileNode))
|
||||||
{
|
{
|
||||||
|
#if defined(MEMFS_NAMED_STREAMS)
|
||||||
MEMFS_CLEANUP_CONTEXT Context = { 0 };
|
MEMFS_CLEANUP_CONTEXT Context = { 0 };
|
||||||
ULONG Index;
|
ULONG Index;
|
||||||
|
|
||||||
@ -593,6 +619,7 @@ static VOID Cleanup(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
MemfsFileNodeMapRemove(Memfs->FileNodeMap, Context.FileNodes[Index]);
|
MemfsFileNodeMapRemove(Memfs->FileNodeMap, Context.FileNodes[Index]);
|
||||||
free(Context.FileNodes);
|
free(Context.FileNodes);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
MemfsFileNodeMapRemove(Memfs->FileNodeMap, FileNode);
|
MemfsFileNodeMapRemove(Memfs->FileNodeMap, FileNode);
|
||||||
}
|
}
|
||||||
@ -709,8 +736,10 @@ static NTSTATUS SetBasicInfo(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
{
|
{
|
||||||
MEMFS_FILE_NODE *FileNode = (MEMFS_FILE_NODE *)FileNode0;
|
MEMFS_FILE_NODE *FileNode = (MEMFS_FILE_NODE *)FileNode0;
|
||||||
|
|
||||||
|
#if defined(MEMFS_NAMED_STREAMS)
|
||||||
if (0 != FileNode->MainFileNode)
|
if (0 != FileNode->MainFileNode)
|
||||||
FileNode = FileNode->MainFileNode;
|
FileNode = FileNode->MainFileNode;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (INVALID_FILE_ATTRIBUTES != FileAttributes)
|
if (INVALID_FILE_ATTRIBUTES != FileAttributes)
|
||||||
FileNode->FileInfo.FileAttributes = FileAttributes;
|
FileNode->FileInfo.FileAttributes = FileAttributes;
|
||||||
@ -855,7 +884,7 @@ static NTSTATUS Rename(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
for (Index = 0; Context.Count > Index; Index++)
|
for (Index = 0; Context.Count > Index; Index++)
|
||||||
{
|
{
|
||||||
DescendantFileNode = Context.FileNodes[Index];
|
DescendantFileNode = Context.FileNodes[Index];
|
||||||
assert(MemfsFileNameHasPrefix(DescendantFileNode->FileName, FileNode->FileName, TRUE));
|
assert(MemfsFileNameHasPrefix(DescendantFileNode->FileName, FileNode->FileName));
|
||||||
if (MAX_PATH <= wcslen(DescendantFileNode->FileName) - FileNameLen + NewFileNameLen)
|
if (MAX_PATH <= wcslen(DescendantFileNode->FileName) - FileNameLen + NewFileNameLen)
|
||||||
{
|
{
|
||||||
Result = STATUS_OBJECT_NAME_INVALID;
|
Result = STATUS_OBJECT_NAME_INVALID;
|
||||||
@ -908,8 +937,10 @@ static NTSTATUS GetSecurity(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
{
|
{
|
||||||
MEMFS_FILE_NODE *FileNode = (MEMFS_FILE_NODE *)FileNode0;
|
MEMFS_FILE_NODE *FileNode = (MEMFS_FILE_NODE *)FileNode0;
|
||||||
|
|
||||||
|
#if defined(MEMFS_NAMED_STREAMS)
|
||||||
if (0 != FileNode->MainFileNode)
|
if (0 != FileNode->MainFileNode)
|
||||||
FileNode = FileNode->MainFileNode;
|
FileNode = FileNode->MainFileNode;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (FileNode->FileSecuritySize > *PSecurityDescriptorSize)
|
if (FileNode->FileSecuritySize > *PSecurityDescriptorSize)
|
||||||
{
|
{
|
||||||
@ -934,8 +965,10 @@ static NTSTATUS SetSecurity(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
SIZE_T FileSecuritySize;
|
SIZE_T FileSecuritySize;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
#if defined(MEMFS_NAMED_STREAMS)
|
||||||
if (0 != FileNode->MainFileNode)
|
if (0 != FileNode->MainFileNode)
|
||||||
FileNode = FileNode->MainFileNode;
|
FileNode = FileNode->MainFileNode;
|
||||||
|
#endif
|
||||||
|
|
||||||
Result = FspSetSecurityDescriptor(FileSystem, Request, FileNode->FileSecurity,
|
Result = FspSetSecurityDescriptor(FileSystem, Request, FileNode->FileSecurity,
|
||||||
&NewSecurityDescriptor);
|
&NewSecurityDescriptor);
|
||||||
@ -1164,6 +1197,7 @@ static NTSTATUS DeleteReparsePoint(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(MEMFS_NAMED_STREAMS)
|
||||||
typedef struct _MEMFS_GET_STREAM_INFO_CONTEXT
|
typedef struct _MEMFS_GET_STREAM_INFO_CONTEXT
|
||||||
{
|
{
|
||||||
PVOID Buffer;
|
PVOID Buffer;
|
||||||
@ -1224,6 +1258,7 @@ static NTSTATUS GetStreamInfo(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static FSP_FILE_SYSTEM_INTERFACE MemfsInterface =
|
static FSP_FILE_SYSTEM_INTERFACE MemfsInterface =
|
||||||
{
|
{
|
||||||
@ -1250,7 +1285,11 @@ static FSP_FILE_SYSTEM_INTERFACE MemfsInterface =
|
|||||||
GetReparsePoint,
|
GetReparsePoint,
|
||||||
SetReparsePoint,
|
SetReparsePoint,
|
||||||
DeleteReparsePoint,
|
DeleteReparsePoint,
|
||||||
|
#if defined(MEMFS_NAMED_STREAMS)
|
||||||
GetStreamInfo,
|
GetStreamInfo,
|
||||||
|
#else
|
||||||
|
0,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
NTSTATUS MemfsCreate(
|
NTSTATUS MemfsCreate(
|
||||||
@ -1313,7 +1352,9 @@ NTSTATUS MemfsCreate(
|
|||||||
VolumeParams.PersistentAcls = 1;
|
VolumeParams.PersistentAcls = 1;
|
||||||
VolumeParams.ReparsePoints = 1;
|
VolumeParams.ReparsePoints = 1;
|
||||||
VolumeParams.ReparsePointsAccessCheck = 0;
|
VolumeParams.ReparsePointsAccessCheck = 0;
|
||||||
|
#if defined(MEMFS_NAMED_STREAMS)
|
||||||
VolumeParams.NamedStreams = 1;
|
VolumeParams.NamedStreams = 1;
|
||||||
|
#endif
|
||||||
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