mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 08:23:05 -05:00
tst: passthrough-fuse: multibyte support
This commit is contained in:
parent
e550e261f0
commit
8c9b8362b4
@ -52,7 +52,7 @@
|
|||||||
#define fi_setdirp(fi, dirp) (fi_setfh(fi, dirp, fi_dirbit))
|
#define fi_setdirp(fi, dirp) (fi_setfh(fi, dirp, fi_dirbit))
|
||||||
|
|
||||||
#define ptfs_impl_fullpath(n) \
|
#define ptfs_impl_fullpath(n) \
|
||||||
char full ## n[PATH_MAX]; \
|
char full ## n[PATH_MAX * 4]; \
|
||||||
if (!concat_path(((PTFS *)fuse_get_context()->private_data), n, full ## n))\
|
if (!concat_path(((PTFS *)fuse_get_context()->private_data), n, full ## n))\
|
||||||
return -ENAMETOOLONG; \
|
return -ENAMETOOLONG; \
|
||||||
n = full ## n
|
n = full ## n
|
||||||
|
@ -121,7 +121,7 @@ char *realpath(const char *path, char *resolved)
|
|||||||
|
|
||||||
if (0 == resolved)
|
if (0 == resolved)
|
||||||
{
|
{
|
||||||
result = malloc(PATH_MAX); /* sets errno */
|
result = malloc(PATH_MAX * 4); /* sets errno */
|
||||||
if (0 == result)
|
if (0 == result)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -129,15 +129,23 @@ char *realpath(const char *path, char *resolved)
|
|||||||
result = resolved;
|
result = resolved;
|
||||||
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
DWORD len = GetFullPathNameA(path, PATH_MAX, result, 0);
|
WCHAR PathBuf[PATH_MAX];
|
||||||
|
WCHAR ResultBuf[PATH_MAX];
|
||||||
|
if (0 < MultiByteToWideChar(CP_UTF8, 0, path, -1, PathBuf, PATH_MAX))
|
||||||
|
{
|
||||||
|
DWORD len = GetFullPathNameW(PathBuf, PATH_MAX, ResultBuf, 0);
|
||||||
if (0 == len)
|
if (0 == len)
|
||||||
err = GetLastError();
|
err = GetLastError();
|
||||||
else if (PATH_MAX < len)
|
else if (PATH_MAX < len)
|
||||||
err = ERROR_INVALID_PARAMETER;
|
err = ERROR_INVALID_PARAMETER;
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0, ResultBuf, -1, result, PATH_MAX * 4, 0, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
err = GetLastError();
|
||||||
|
|
||||||
if (0 == err)
|
if (0 == err)
|
||||||
{
|
{
|
||||||
HANDLE h = CreateFileA(result,
|
HANDLE h = CreateFileW(ResultBuf,
|
||||||
FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
0,
|
0,
|
||||||
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
||||||
@ -159,9 +167,33 @@ char *realpath(const char *path, char *resolved)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int uncpath(const char* path, WCHAR* buf, int nchar)
|
||||||
|
{
|
||||||
|
if (4 < nchar &&
|
||||||
|
0 < MultiByteToWideChar(CP_UTF8, 0, path, -1, &buf[4], nchar - 4))
|
||||||
|
{
|
||||||
|
buf[0] = L'\\';
|
||||||
|
buf[1] = L'\\';
|
||||||
|
buf[2] = L'?';
|
||||||
|
buf[3] = L'\\';
|
||||||
|
int i = 4;
|
||||||
|
while (buf[i])
|
||||||
|
{
|
||||||
|
if (L'/' == buf[i])
|
||||||
|
buf[i] = L'\\';
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 < nchar)
|
||||||
|
buf[0] = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int statvfs(const char *path, struct fuse_statvfs *stbuf)
|
int statvfs(const char *path, struct fuse_statvfs *stbuf)
|
||||||
{
|
{
|
||||||
char root[PATH_MAX];
|
WCHAR root[PATH_MAX];
|
||||||
DWORD
|
DWORD
|
||||||
VolumeSerialNumber,
|
VolumeSerialNumber,
|
||||||
MaxComponentLength,
|
MaxComponentLength,
|
||||||
@ -170,9 +202,11 @@ int statvfs(const char *path, struct fuse_statvfs *stbuf)
|
|||||||
NumberOfFreeClusters,
|
NumberOfFreeClusters,
|
||||||
TotalNumberOfClusters;
|
TotalNumberOfClusters;
|
||||||
|
|
||||||
if (!GetVolumePathNameA(path, root, PATH_MAX) ||
|
WCHAR PathBuf[PATH_MAX];
|
||||||
!GetVolumeInformationA(root, 0, 0, &VolumeSerialNumber, &MaxComponentLength, 0, 0, 0) ||
|
uncpath(path, PathBuf, PATH_MAX);
|
||||||
!GetDiskFreeSpaceA(root, &SectorsPerCluster, &BytesPerSector,
|
if (!GetVolumePathNameW(PathBuf, root, PATH_MAX) ||
|
||||||
|
!GetVolumeInformationW(root, 0, 0, &VolumeSerialNumber, &MaxComponentLength, 0, 0, 0) ||
|
||||||
|
!GetDiskFreeSpaceW(root, &SectorsPerCluster, &BytesPerSector,
|
||||||
&NumberOfFreeClusters, &TotalNumberOfClusters))
|
&NumberOfFreeClusters, &TotalNumberOfClusters))
|
||||||
{
|
{
|
||||||
return error();
|
return error();
|
||||||
@ -201,7 +235,9 @@ int open(const char *path, int oflag, ...)
|
|||||||
CREATE_NEW :
|
CREATE_NEW :
|
||||||
cd[(oflag & (_O_CREAT | _O_TRUNC)) >> 8];
|
cd[(oflag & (_O_CREAT | _O_TRUNC)) >> 8];
|
||||||
|
|
||||||
HANDLE h = CreateFileA(path,
|
WCHAR PathBuf[PATH_MAX];
|
||||||
|
uncpath(path, PathBuf, PATH_MAX);
|
||||||
|
HANDLE h = CreateFileW(PathBuf,
|
||||||
DesiredAccess, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
DesiredAccess, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
0/* default security */,
|
0/* default security */,
|
||||||
CreationDisposition, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0);
|
CreationDisposition, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0);
|
||||||
@ -325,7 +361,9 @@ int close(int fd)
|
|||||||
|
|
||||||
int getpath(const char *path, char *buf, size_t size)
|
int getpath(const char *path, char *buf, size_t size)
|
||||||
{
|
{
|
||||||
HANDLE h = CreateFileA(path,
|
WCHAR PathBuf[PATH_MAX];
|
||||||
|
uncpath(path, PathBuf, PATH_MAX);
|
||||||
|
HANDLE h = CreateFileW(PathBuf,
|
||||||
FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
0,
|
0,
|
||||||
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
||||||
@ -341,7 +379,9 @@ int getpath(const char *path, char *buf, size_t size)
|
|||||||
|
|
||||||
int lstat(const char *path, struct fuse_stat *stbuf)
|
int lstat(const char *path, struct fuse_stat *stbuf)
|
||||||
{
|
{
|
||||||
HANDLE h = CreateFileA(path,
|
WCHAR PathBuf[PATH_MAX];
|
||||||
|
uncpath(path, PathBuf, PATH_MAX);
|
||||||
|
HANDLE h = CreateFileW(PathBuf,
|
||||||
FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
0,
|
0,
|
||||||
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
||||||
@ -375,7 +415,9 @@ int lchflags(const char *path, uint32_t flags)
|
|||||||
if (0 == FileAttributes)
|
if (0 == FileAttributes)
|
||||||
FileAttributes = FILE_ATTRIBUTE_NORMAL;
|
FileAttributes = FILE_ATTRIBUTE_NORMAL;
|
||||||
|
|
||||||
if (!SetFileAttributesA(path, FileAttributes))
|
WCHAR PathBuf[PATH_MAX];
|
||||||
|
uncpath(path, PathBuf, PATH_MAX);
|
||||||
|
if (!SetFileAttributesW(PathBuf, FileAttributes))
|
||||||
return error();
|
return error();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -384,7 +426,9 @@ int lchflags(const char *path, uint32_t flags)
|
|||||||
|
|
||||||
int truncate(const char *path, fuse_off_t size)
|
int truncate(const char *path, fuse_off_t size)
|
||||||
{
|
{
|
||||||
HANDLE h = CreateFileA(path,
|
WCHAR PathBuf[PATH_MAX];
|
||||||
|
uncpath(path, PathBuf, PATH_MAX);
|
||||||
|
HANDLE h = CreateFileW(PathBuf,
|
||||||
FILE_WRITE_DATA, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
FILE_WRITE_DATA, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
0,
|
0,
|
||||||
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
||||||
@ -418,7 +462,9 @@ int utimensat(int dirfd, const char *path, const struct fuse_timespec times[2],
|
|||||||
/* ignore dirfd and assume that it is always AT_FDCWD */
|
/* ignore dirfd and assume that it is always AT_FDCWD */
|
||||||
/* ignore flag and assume that it is always AT_SYMLINK_NOFOLLOW */
|
/* ignore flag and assume that it is always AT_SYMLINK_NOFOLLOW */
|
||||||
|
|
||||||
HANDLE h = CreateFileA(path,
|
WCHAR PathBuf[PATH_MAX];
|
||||||
|
uncpath(path, PathBuf, PATH_MAX);
|
||||||
|
HANDLE h = CreateFileW(PathBuf,
|
||||||
FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
0,
|
0,
|
||||||
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
||||||
@ -448,7 +494,9 @@ int utimensat(int dirfd, const char *path, const struct fuse_timespec times[2],
|
|||||||
|
|
||||||
int setcrtime(const char *path, const struct fuse_timespec *tv)
|
int setcrtime(const char *path, const struct fuse_timespec *tv)
|
||||||
{
|
{
|
||||||
HANDLE h = CreateFileA(path,
|
WCHAR PathBuf[PATH_MAX];
|
||||||
|
uncpath(path, PathBuf, PATH_MAX);
|
||||||
|
HANDLE h = CreateFileW(PathBuf,
|
||||||
FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
0,
|
0,
|
||||||
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
||||||
@ -468,7 +516,9 @@ int setcrtime(const char *path, const struct fuse_timespec *tv)
|
|||||||
|
|
||||||
int unlink(const char *path)
|
int unlink(const char *path)
|
||||||
{
|
{
|
||||||
if (!DeleteFileA(path))
|
WCHAR PathBuf[PATH_MAX];
|
||||||
|
uncpath(path, PathBuf, PATH_MAX);
|
||||||
|
if (!DeleteFileW(PathBuf))
|
||||||
return error();
|
return error();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -476,7 +526,11 @@ int unlink(const char *path)
|
|||||||
|
|
||||||
int rename(const char *oldpath, const char *newpath)
|
int rename(const char *oldpath, const char *newpath)
|
||||||
{
|
{
|
||||||
if (!MoveFileExA(oldpath, newpath, MOVEFILE_REPLACE_EXISTING))
|
WCHAR OldPathBuf[PATH_MAX];
|
||||||
|
WCHAR NewPathBuf[PATH_MAX];
|
||||||
|
uncpath(oldpath, OldPathBuf, PATH_MAX);
|
||||||
|
uncpath(newpath, NewPathBuf, PATH_MAX);
|
||||||
|
if (!MoveFileExW(OldPathBuf, NewPathBuf, MOVEFILE_REPLACE_EXISTING))
|
||||||
return error();
|
return error();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -484,7 +538,9 @@ int rename(const char *oldpath, const char *newpath)
|
|||||||
|
|
||||||
static int lsetea(const char *path, PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength)
|
static int lsetea(const char *path, PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength)
|
||||||
{
|
{
|
||||||
HANDLE h = CreateFileA(path,
|
WCHAR PathBuf[PATH_MAX];
|
||||||
|
uncpath(path, PathBuf, PATH_MAX);
|
||||||
|
HANDLE h = CreateFileW(PathBuf,
|
||||||
FILE_WRITE_EA | SYNCHRONIZE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
FILE_WRITE_EA | SYNCHRONIZE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
0,
|
0,
|
||||||
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
||||||
@ -519,7 +575,9 @@ static int lgetea(const char *path,
|
|||||||
PFILE_GET_EA_INFORMATION GetEa, ULONG GetEaLength,
|
PFILE_GET_EA_INFORMATION GetEa, ULONG GetEaLength,
|
||||||
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength)
|
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength)
|
||||||
{
|
{
|
||||||
HANDLE h = CreateFileA(path,
|
WCHAR PathBuf[PATH_MAX];
|
||||||
|
uncpath(path, PathBuf, PATH_MAX);
|
||||||
|
HANDLE h = CreateFileW(PathBuf,
|
||||||
FILE_READ_EA | SYNCHRONIZE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
FILE_READ_EA | SYNCHRONIZE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
0,
|
0,
|
||||||
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
||||||
@ -711,7 +769,9 @@ int lremovexattr(const char *path, const char *name)
|
|||||||
|
|
||||||
int mkdir(const char *path, fuse_mode_t mode)
|
int mkdir(const char *path, fuse_mode_t mode)
|
||||||
{
|
{
|
||||||
if (!CreateDirectoryA(path, 0/* default security */))
|
WCHAR PathBuf[PATH_MAX];
|
||||||
|
uncpath(path, PathBuf, PATH_MAX);
|
||||||
|
if (!CreateDirectoryW(PathBuf, 0/* default security */))
|
||||||
return error();
|
return error();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -719,7 +779,9 @@ int mkdir(const char *path, fuse_mode_t mode)
|
|||||||
|
|
||||||
int rmdir(const char *path)
|
int rmdir(const char *path)
|
||||||
{
|
{
|
||||||
if (!RemoveDirectoryA(path))
|
WCHAR PathBuf[PATH_MAX];
|
||||||
|
uncpath(path, PathBuf, PATH_MAX);
|
||||||
|
if (!RemoveDirectoryW(PathBuf))
|
||||||
return error();
|
return error();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -727,7 +789,9 @@ int rmdir(const char *path)
|
|||||||
|
|
||||||
DIR *opendir(const char *path)
|
DIR *opendir(const char *path)
|
||||||
{
|
{
|
||||||
HANDLE h = CreateFileA(path,
|
WCHAR PathBuf[PATH_MAX];
|
||||||
|
uncpath(path, PathBuf, PATH_MAX);
|
||||||
|
HANDLE h = CreateFileW(PathBuf,
|
||||||
FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
0,
|
0,
|
||||||
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
||||||
@ -772,18 +836,20 @@ void rewinddir(DIR *dirp)
|
|||||||
|
|
||||||
struct dirent *readdir(DIR *dirp)
|
struct dirent *readdir(DIR *dirp)
|
||||||
{
|
{
|
||||||
WIN32_FIND_DATAA FindData;
|
WIN32_FIND_DATAW FindData;
|
||||||
struct fuse_stat *stbuf = &dirp->de.d_stat;
|
struct fuse_stat *stbuf = &dirp->de.d_stat;
|
||||||
|
|
||||||
if (INVALID_HANDLE_VALUE == dirp->fh)
|
if (INVALID_HANDLE_VALUE == dirp->fh)
|
||||||
{
|
{
|
||||||
dirp->fh = FindFirstFileA(dirp->path, &FindData);
|
WCHAR PathBuf[PATH_MAX];
|
||||||
|
uncpath(dirp->path, PathBuf, PATH_MAX);
|
||||||
|
dirp->fh = FindFirstFileW(PathBuf, &FindData);
|
||||||
if (INVALID_HANDLE_VALUE == dirp->fh)
|
if (INVALID_HANDLE_VALUE == dirp->fh)
|
||||||
return error0();
|
return error0();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!FindNextFileA(dirp->fh, &FindData))
|
if (!FindNextFileW(dirp->fh, &FindData))
|
||||||
{
|
{
|
||||||
if (ERROR_NO_MORE_FILES == GetLastError())
|
if (ERROR_NO_MORE_FILES == GetLastError())
|
||||||
return 0;
|
return 0;
|
||||||
@ -804,7 +870,7 @@ struct dirent *readdir(DIR *dirp)
|
|||||||
stbuf->st_flags = MapFileAttributesToFlags(FindData.dwFileAttributes);
|
stbuf->st_flags = MapFileAttributesToFlags(FindData.dwFileAttributes);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
strcpy(dirp->de.d_name, FindData.cFileName);
|
WideCharToMultiByte(CP_UTF8, 0, FindData.cFileName, -1, dirp->de.d_name, 255 * 4, 0, 0);
|
||||||
|
|
||||||
return &dirp->de;
|
return &dirp->de;
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ typedef struct _DIR DIR;
|
|||||||
struct dirent
|
struct dirent
|
||||||
{
|
{
|
||||||
struct fuse_stat d_stat;
|
struct fuse_stat d_stat;
|
||||||
char d_name[255];
|
char d_name[255 * 4];
|
||||||
};
|
};
|
||||||
|
|
||||||
char *realpath(const char *path, char *resolved);
|
char *realpath(const char *path, char *resolved);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user