dll: reparse points: allow file system to provide directory symlink behavior

This commit is contained in:
Bill Zissimopoulos 2016-08-22 00:04:49 -07:00
parent fee75590a8
commit 981e60643f
4 changed files with 27 additions and 18 deletions

View File

@ -1071,7 +1071,8 @@ FSP_API BOOLEAN FspFileSystemAddDirInfo(FSP_FSCTL_DIR_INFO *DirInfo,
*/
FSP_API BOOLEAN FspFileSystemFindReparsePoint(FSP_FILE_SYSTEM *FileSystem,
NTSTATUS (*GetReparsePointByName)(
FSP_FILE_SYSTEM *FileSystem, PVOID Context, PWSTR FileName, PVOID Buffer, PSIZE_T PSize),
FSP_FILE_SYSTEM *FileSystem, PVOID Context,
PWSTR FileName, BOOLEAN IsDirectory, PVOID Buffer, PSIZE_T PSize),
PVOID Context,
PWSTR FileName, PUINT32 PReparsePointIndex);
/**
@ -1119,7 +1120,8 @@ FSP_API BOOLEAN FspFileSystemFindReparsePoint(FSP_FILE_SYSTEM *FileSystem,
*/
FSP_API NTSTATUS FspFileSystemResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem,
NTSTATUS (*GetReparsePointByName)(
FSP_FILE_SYSTEM *FileSystem, PVOID Context, PWSTR FileName, PVOID Buffer, PSIZE_T PSize),
FSP_FILE_SYSTEM *FileSystem, PVOID Context,
PWSTR FileName, BOOLEAN IsDirectory, PVOID Buffer, PSIZE_T PSize),
PVOID Context,
PWSTR FileName, UINT32 ReparsePointIndex, BOOLEAN OpenReparsePoint,
PIO_STATUS_BLOCK PIoStatus, PVOID Buffer, PSIZE_T PSize);

View File

@ -1045,11 +1045,12 @@ FSP_API BOOLEAN FspFileSystemAddDirInfo(FSP_FSCTL_DIR_INFO *DirInfo,
FSP_API BOOLEAN FspFileSystemFindReparsePoint(FSP_FILE_SYSTEM *FileSystem,
NTSTATUS (*GetReparsePointByName)(
FSP_FILE_SYSTEM *FileSystem, PVOID Context, PWSTR FileName, PVOID Buffer, PSIZE_T PSize),
FSP_FILE_SYSTEM *FileSystem, PVOID Context,
PWSTR FileName, BOOLEAN IsDirectory, PVOID Buffer, PSIZE_T PSize),
PVOID Context,
PWSTR FileName, PUINT32 PReparsePointIndex)
{
PWSTR p, lastp;
WCHAR *p, *lastp;
NTSTATUS Result;
p = FileName;
@ -1066,7 +1067,7 @@ FSP_API BOOLEAN FspFileSystemFindReparsePoint(FSP_FILE_SYSTEM *FileSystem,
}
*p = L'\0';
Result = GetReparsePointByName(FileSystem, Context, FileName, 0, 0);
Result = GetReparsePointByName(FileSystem, Context, FileName, TRUE, 0, 0);
*p = L'\\';
if (!NT_SUCCESS(Result))
@ -1085,7 +1086,8 @@ FSP_API BOOLEAN FspFileSystemFindReparsePoint(FSP_FILE_SYSTEM *FileSystem,
FSP_API NTSTATUS FspFileSystemResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem,
NTSTATUS (*GetReparsePointByName)(
FSP_FILE_SYSTEM *FileSystem, PVOID Context, PWSTR FileName, PVOID Buffer, PSIZE_T PSize),
FSP_FILE_SYSTEM *FileSystem, PVOID Context,
PWSTR FileName, BOOLEAN IsDirectory, PVOID Buffer, PSIZE_T PSize),
PVOID Context,
PWSTR FileName, UINT32 ReparsePointIndex, BOOLEAN OpenReparsePoint,
PIO_STATUS_BLOCK PIoStatus, PVOID Buffer, PSIZE_T PSize)
@ -1158,17 +1160,17 @@ FSP_API NTSTATUS FspFileSystemResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem,
}
c = *p;
*p = '\0';
*p = L'\0';
if (FileSystem->ReparsePointsSymlinkOnly)
{
Size = FSP_FSCTL_TRANSACT_PATH_SIZEMAX;
Result = GetReparsePointByName(FileSystem, Context, TargetPath,
Result = GetReparsePointByName(FileSystem, Context, TargetPath, '\0' != c,
ReparseData->SymbolicLinkReparseBuffer.PathBuffer, &Size);
}
else
{
Size = sizeof ReparseDataBuf;
Result = GetReparsePointByName(FileSystem, Context, TargetPath,
Result = GetReparsePointByName(FileSystem, Context, TargetPath, '\0' != c,
ReparseData, &Size);
}
*p = c;
@ -1178,7 +1180,8 @@ FSP_API NTSTATUS FspFileSystemResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem,
continue;
else if (!NT_SUCCESS(Result))
{
if (STATUS_OBJECT_NAME_NOT_FOUND == Result && '\0' != c)
if ((STATUS_OBJECT_NAME_NOT_FOUND == Result && '\0' != c) ||
STATUS_NOT_A_DIRECTORY == Result)
Result = STATUS_OBJECT_PATH_NOT_FOUND;
return Result;
}

View File

@ -448,8 +448,8 @@ exit:
}
static NTSTATUS fsp_fuse_intf_GetReparsePointByName(
FSP_FILE_SYSTEM *FileSystem,
PVOID Context, PWSTR FileName, PVOID Buffer, PSIZE_T PSize);
FSP_FILE_SYSTEM *FileSystem, PVOID Context,
PWSTR FileName, BOOLEAN IsDirectory, PVOID Buffer, PSIZE_T PSize);
static NTSTATUS fsp_fuse_intf_GetVolumeInfo(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request,
@ -1599,8 +1599,8 @@ static NTSTATUS fsp_fuse_intf_ResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem,
}
static NTSTATUS fsp_fuse_intf_GetReparsePointByName(
FSP_FILE_SYSTEM *FileSystem,
PVOID Context, PWSTR FileName, PVOID Buffer, PSIZE_T PSize)
FSP_FILE_SYSTEM *FileSystem, PVOID Context,
PWSTR FileName, BOOLEAN IsDirectory, PVOID Buffer, PSIZE_T PSize)
{
struct fuse *f = FileSystem->UserContext;
char *PosixPath = 0;

View File

@ -276,8 +276,8 @@ BOOLEAN MemfsFileNodeMapEnumerateDescendants(MEMFS_FILE_NODE_MAP *FileNodeMap, M
}
static NTSTATUS GetReparsePointByName(
FSP_FILE_SYSTEM *FileSystem,
PVOID Context, PWSTR FileName, PVOID Buffer, PSIZE_T PSize);
FSP_FILE_SYSTEM *FileSystem, PVOID Context,
PWSTR FileName, BOOLEAN IsDirectory, PVOID Buffer, PSIZE_T PSize);
static NTSTATUS SetFileSize(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request,
@ -954,8 +954,8 @@ static NTSTATUS ResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem,
}
static NTSTATUS GetReparsePointByName(
FSP_FILE_SYSTEM *FileSystem,
PVOID Context, PWSTR FileName, PVOID Buffer, PSIZE_T PSize)
FSP_FILE_SYSTEM *FileSystem, PVOID Context,
PWSTR FileName, BOOLEAN IsDirectory, PVOID Buffer, PSIZE_T PSize)
{
MEMFS *Memfs = (MEMFS *)FileSystem->UserContext;
MEMFS_FILE_NODE *FileNode;
@ -967,6 +967,10 @@ static NTSTATUS GetReparsePointByName(
if (0 == (FileNode->FileInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT))
return STATUS_NOT_A_REPARSE_POINT;
if (IsDirectory &&
0 == (FileNode->FileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY))
return STATUS_NOT_A_DIRECTORY;
if (0 != Buffer)
{
if (FileNode->ReparseDataSize > *PSize)