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

View File

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

View File

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