diff --git a/inc/winfsp/winfsp.h b/inc/winfsp/winfsp.h index e8de888e..74260f1f 100644 --- a/inc/winfsp/winfsp.h +++ b/inc/winfsp/winfsp.h @@ -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); diff --git a/src/dll/fsop.c b/src/dll/fsop.c index f0f88268..aaa6010c 100644 --- a/src/dll/fsop.c +++ b/src/dll/fsop.c @@ -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; } diff --git a/src/dll/fuse/fuse_intf.c b/src/dll/fuse/fuse_intf.c index 36a73659..bf9a41ab 100644 --- a/src/dll/fuse/fuse_intf.c +++ b/src/dll/fuse/fuse_intf.c @@ -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; diff --git a/tst/memfs/memfs.cpp b/tst/memfs/memfs.cpp index c3252afe..f6d3173b 100644 --- a/tst/memfs/memfs.cpp +++ b/tst/memfs/memfs.cpp @@ -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)