diff --git a/inc/winfsp/winfsp.h b/inc/winfsp/winfsp.h index e8d8969b..cc677ff6 100644 --- a/inc/winfsp/winfsp.h +++ b/inc/winfsp/winfsp.h @@ -1195,8 +1195,20 @@ FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor( FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions( PSECURITY_DESCRIPTOR SecurityDescriptor, PUINT32 PUid, PUINT32 PGid, PUINT32 PMode); -FSP_API NTSTATUS FspPosixMapWindowsToPosixPath(PWSTR WindowsPath, char **PPosixPath); -FSP_API NTSTATUS FspPosixMapPosixToWindowsPath(const char *PosixPath, PWSTR *PWindowsPath); +FSP_API NTSTATUS FspPosixMapWindowsToPosixPathEx(PWSTR WindowsPath, char **PPosixPath, + BOOLEAN Translate); +FSP_API NTSTATUS FspPosixMapPosixToWindowsPathEx(const char *PosixPath, PWSTR *PWindowsPath, + BOOLEAN Translate); +static inline +NTSTATUS FspPosixMapWindowsToPosixPath(PWSTR WindowsPath, char **PPosixPath) +{ + return FspPosixMapWindowsToPosixPathEx(WindowsPath, PPosixPath, TRUE); +} +static inline +NTSTATUS FspPosixMapPosixToWindowsPath(const char *PosixPath, PWSTR *PWindowsPath) +{ + return FspPosixMapPosixToWindowsPathEx(PosixPath, PWindowsPath, TRUE); +} FSP_API VOID FspPosixDeletePath(void *Path); /* diff --git a/src/dll/fuse/fuse_intf.c b/src/dll/fuse/fuse_intf.c index 6d6cc7b4..9c5b8860 100644 --- a/src/dll/fuse/fuse_intf.c +++ b/src/dll/fuse/fuse_intf.c @@ -1999,6 +1999,7 @@ static NTSTATUS fsp_fuse_intf_SetReparsePoint(FSP_FILE_SYSTEM *FileSystem, } else { + /* the PATH is in POSIX format (UTF-16 encoding) */ ReparseTargetPath = (PVOID)(ReparseData->GenericReparseBuffer.DataBuffer + 8); ReparseTargetPathLength = ReparseData->ReparseDataLength - 8; } @@ -2010,7 +2011,8 @@ static NTSTATUS fsp_fuse_intf_SetReparsePoint(FSP_FILE_SYSTEM *FileSystem, * From this point forward we must jump to the EXIT label on failure. */ - Result = FspPosixMapWindowsToPosixPath(TargetPath, &PosixTargetPath); + Result = FspPosixMapWindowsToPosixPathEx(TargetPath, &PosixTargetPath, + IO_REPARSE_TAG_SYMLINK == ReparseData->ReparseTag); if (!NT_SUCCESS(Result)) goto exit; @@ -2029,7 +2031,7 @@ static NTSTATUS fsp_fuse_intf_SetReparsePoint(FSP_FILE_SYSTEM *FileSystem, } else { - switch (*(PULONG)ReparseData->GenericReparseBuffer.DataBuffer) + switch (*(PUINT64)ReparseData->GenericReparseBuffer.DataBuffer) { case NFS_SPECFILE_FIFO: Mode = (Mode & ~0170000) | 0010000; diff --git a/src/dll/posix.c b/src/dll/posix.c index 1848c867..194d4e91 100644 --- a/src/dll/posix.c +++ b/src/dll/posix.c @@ -805,7 +805,8 @@ static UINT32 FspPosixInvalidPathChars[4] = 0x00000008, }; -FSP_API NTSTATUS FspPosixMapWindowsToPosixPath(PWSTR WindowsPath, char **PPosixPath) +FSP_API NTSTATUS FspPosixMapWindowsToPosixPathEx(PWSTR WindowsPath, char **PPosixPath, + BOOLEAN Translate) { NTSTATUS Result; ULONG Size; @@ -828,25 +829,28 @@ FSP_API NTSTATUS FspPosixMapWindowsToPosixPath(PWSTR WindowsPath, char **PPosixP if (0 == Size) goto lasterror; - for (p = PosixPath, q = p; *p; p++) + if (Translate) { - unsigned char c = *p; - - if ('\\' == c) - *q++ = '/'; - /* encode characters in the Unicode private use area: U+F0XX -> XX */ - else if (0xef == c && 0x80 == (0xfc & p[1]) && 0x80 == (0xc0 & p[2])) + for (p = PosixPath, q = p; *p; p++) { - c = ((p[1] & 0x3) << 6) | (p[2] & 0x3f); - if (128 > c && (FspPosixInvalidPathChars[c >> 5] & (0x80000000 >> (c & 0x1f)))) - *q++ = c, p += 2; + unsigned char c = *p; + + if ('\\' == c) + *q++ = '/'; + /* encode characters in the Unicode private use area: U+F0XX -> XX */ + else if (0xef == c && 0x80 == (0xfc & p[1]) && 0x80 == (0xc0 & p[2])) + { + c = ((p[1] & 0x3) << 6) | (p[2] & 0x3f); + if (128 > c && (FspPosixInvalidPathChars[c >> 5] & (0x80000000 >> (c & 0x1f)))) + *q++ = c, p += 2; + else + *q++ = *p++, *q++ = *p++, *q++ = *p; + } else - *q++ = *p++, *q++ = *p++, *q++ = *p; + *q++ = c; } - else - *q++ = c; + *q = '\0'; } - *q = '\0'; *PPosixPath = PosixPath; @@ -863,7 +867,8 @@ lasterror: goto exit; } -FSP_API NTSTATUS FspPosixMapPosixToWindowsPath(const char *PosixPath, PWSTR *PWindowsPath) +FSP_API NTSTATUS FspPosixMapPosixToWindowsPathEx(const char *PosixPath, PWSTR *PWindowsPath, + BOOLEAN Translate) { NTSTATUS Result; ULONG Size; @@ -886,14 +891,17 @@ FSP_API NTSTATUS FspPosixMapPosixToWindowsPath(const char *PosixPath, PWSTR *PWi if (0 == Size) goto lasterror; - for (p = WindowsPath; *p; p++) + if (Translate) { - WCHAR c = *p; + for (p = WindowsPath; *p; p++) + { + WCHAR c = *p; - if (L'/' == c) - *p = L'\\'; - else if (128 > c && (FspPosixInvalidPathChars[c >> 5] & (0x80000000 >> (c & 0x1f)))) - *p |= 0xf000; + if (L'/' == c) + *p = L'\\'; + else if (128 > c && (FspPosixInvalidPathChars[c >> 5] & (0x80000000 >> (c & 0x1f)))) + *p |= 0xf000; + } } *PWindowsPath = WindowsPath;