Merge pull request #476 from zeho11/patch-1

dll: fuse: correct error handling when name exceeds limit
This commit is contained in:
Bill Zissimopoulos 2022-12-16 22:29:37 +00:00 committed by GitHub
commit 760c2acded
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 228 additions and 66 deletions

View File

@ -1949,18 +1949,16 @@ int fsp_fuse_intf_AddDirInfo(void *buf, const char *name,
SizeW = MultiByteToWideChar(CP_UTF8, 0, name, SizeA, DirInfo->FileNameBuf, 255);
if (0 == SizeW)
{
fsp_fuse_intf_LogBadDirInfo(filedesc->PosixPath, name,
"MultiByteToWideChar failed");
return 0;
}
else if (255 == SizeW)
{
if (255 < MultiByteToWideChar(CP_UTF8, 0, name, SizeA, NULL, 0))
if (ERROR_INSUFFICIENT_BUFFER == GetLastError())
{
fsp_fuse_intf_LogBadDirInfo(filedesc->PosixPath, name,
"too long");
return 0;
}
fsp_fuse_intf_LogBadDirInfo(filedesc->PosixPath, name,
"MultiByteToWideChar failed");
return 0;
}
memset(DirInfo, 0, sizeof *DirInfo);

View File

@ -52,7 +52,7 @@
#define fi_setdirp(fi, dirp) (fi_setfh(fi, dirp, fi_dirbit))
#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))\
return -ENAMETOOLONG; \
n = full ## n

View File

@ -121,7 +121,7 @@ char *realpath(const char *path, char *resolved)
if (0 == resolved)
{
result = malloc(PATH_MAX); /* sets errno */
result = malloc(PATH_MAX * 4); /* sets errno */
if (0 == result)
return 0;
}
@ -129,15 +129,23 @@ char *realpath(const char *path, char *resolved)
result = resolved;
int err = 0;
DWORD len = GetFullPathNameA(path, PATH_MAX, result, 0);
if (0 == len)
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)
err = GetLastError();
else if (PATH_MAX < len)
err = ERROR_INVALID_PARAMETER;
WideCharToMultiByte(CP_UTF8, 0, ResultBuf, -1, result, PATH_MAX * 4, 0, 0);
}
else
err = GetLastError();
else if (PATH_MAX < len)
err = ERROR_INVALID_PARAMETER;
if (0 == err)
{
HANDLE h = CreateFileA(result,
HANDLE h = CreateFileW(ResultBuf,
FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
0,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
@ -159,9 +167,33 @@ char *realpath(const char *path, char *resolved)
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)
{
char root[PATH_MAX];
WCHAR root[PATH_MAX];
DWORD
VolumeSerialNumber,
MaxComponentLength,
@ -170,9 +202,11 @@ int statvfs(const char *path, struct fuse_statvfs *stbuf)
NumberOfFreeClusters,
TotalNumberOfClusters;
if (!GetVolumePathNameA(path, root, PATH_MAX) ||
!GetVolumeInformationA(root, 0, 0, &VolumeSerialNumber, &MaxComponentLength, 0, 0, 0) ||
!GetDiskFreeSpaceA(root, &SectorsPerCluster, &BytesPerSector,
WCHAR PathBuf[PATH_MAX];
uncpath(path, PathBuf, PATH_MAX);
if (!GetVolumePathNameW(PathBuf, root, PATH_MAX) ||
!GetVolumeInformationW(root, 0, 0, &VolumeSerialNumber, &MaxComponentLength, 0, 0, 0) ||
!GetDiskFreeSpaceW(root, &SectorsPerCluster, &BytesPerSector,
&NumberOfFreeClusters, &TotalNumberOfClusters))
{
return error();
@ -201,7 +235,9 @@ int open(const char *path, int oflag, ...)
CREATE_NEW :
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,
0/* default security */,
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)
{
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,
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)
{
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,
0,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
@ -375,7 +415,9 @@ int lchflags(const char *path, uint32_t flags)
if (0 == FileAttributes)
FileAttributes = FILE_ATTRIBUTE_NORMAL;
if (!SetFileAttributesA(path, FileAttributes))
WCHAR PathBuf[PATH_MAX];
uncpath(path, PathBuf, PATH_MAX);
if (!SetFileAttributesW(PathBuf, FileAttributes))
return error();
#endif
@ -384,7 +426,9 @@ int lchflags(const char *path, uint32_t flags)
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,
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 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,
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)
{
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,
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)
{
if (!DeleteFileA(path))
WCHAR PathBuf[PATH_MAX];
uncpath(path, PathBuf, PATH_MAX);
if (!DeleteFileW(PathBuf))
return error();
return 0;
@ -476,7 +526,11 @@ int unlink(const char *path)
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 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)
{
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,
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_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,
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)
{
if (!CreateDirectoryA(path, 0/* default security */))
WCHAR PathBuf[PATH_MAX];
uncpath(path, PathBuf, PATH_MAX);
if (!CreateDirectoryW(PathBuf, 0/* default security */))
return error();
return 0;
@ -719,7 +779,9 @@ int mkdir(const char *path, fuse_mode_t mode)
int rmdir(const char *path)
{
if (!RemoveDirectoryA(path))
WCHAR PathBuf[PATH_MAX];
uncpath(path, PathBuf, PATH_MAX);
if (!RemoveDirectoryW(PathBuf))
return error();
return 0;
@ -727,7 +789,9 @@ int rmdir(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,
0,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
@ -772,18 +836,20 @@ void rewinddir(DIR *dirp)
struct dirent *readdir(DIR *dirp)
{
WIN32_FIND_DATAA FindData;
WIN32_FIND_DATAW FindData;
struct fuse_stat *stbuf = &dirp->de.d_stat;
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)
return error0();
}
else
{
if (!FindNextFileA(dirp->fh, &FindData))
if (!FindNextFileW(dirp->fh, &FindData))
{
if (ERROR_NO_MORE_FILES == GetLastError())
return 0;
@ -804,7 +870,7 @@ struct dirent *readdir(DIR *dirp)
stbuf->st_flags = MapFileAttributesToFlags(FindData.dwFileAttributes);
#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;
}

View File

@ -38,7 +38,7 @@ typedef struct _DIR DIR;
struct dirent
{
struct fuse_stat d_stat;
char d_name[255];
char d_name[255 * 4];
};
char *realpath(const char *path, char *resolved);

View File

@ -49,7 +49,7 @@
#define fi_setdirp(fi, dirp) (fi_setfh(fi, dirp, fi_dirbit))
#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))\
return -ENAMETOOLONG; \
n = full ## n

View File

@ -121,7 +121,7 @@ char *realpath(const char *path, char *resolved)
if (0 == resolved)
{
result = malloc(PATH_MAX); /* sets errno */
result = malloc(PATH_MAX * 4); /* sets errno */
if (0 == result)
return 0;
}
@ -129,15 +129,23 @@ char *realpath(const char *path, char *resolved)
result = resolved;
int err = 0;
DWORD len = GetFullPathNameA(path, PATH_MAX, result, 0);
if (0 == len)
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)
err = GetLastError();
else if (PATH_MAX < len)
err = ERROR_INVALID_PARAMETER;
WideCharToMultiByte(CP_UTF8, 0, ResultBuf, -1, result, PATH_MAX * 4, 0, 0);
}
else
err = GetLastError();
else if (PATH_MAX < len)
err = ERROR_INVALID_PARAMETER;
if (0 == err)
{
HANDLE h = CreateFileA(result,
HANDLE h = CreateFileW(ResultBuf,
FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
0,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
@ -159,9 +167,33 @@ char *realpath(const char *path, char *resolved)
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)
{
char root[PATH_MAX];
WCHAR root[PATH_MAX];
DWORD
VolumeSerialNumber,
MaxComponentLength,
@ -170,9 +202,11 @@ int statvfs(const char *path, struct fuse_statvfs *stbuf)
NumberOfFreeClusters,
TotalNumberOfClusters;
if (!GetVolumePathNameA(path, root, PATH_MAX) ||
!GetVolumeInformationA(root, 0, 0, &VolumeSerialNumber, &MaxComponentLength, 0, 0, 0) ||
!GetDiskFreeSpaceA(root, &SectorsPerCluster, &BytesPerSector,
WCHAR PathBuf[PATH_MAX];
uncpath(path, PathBuf, PATH_MAX);
if (!GetVolumePathNameW(PathBuf, root, PATH_MAX) ||
!GetVolumeInformationW(root, 0, 0, &VolumeSerialNumber, &MaxComponentLength, 0, 0, 0) ||
!GetDiskFreeSpaceW(root, &SectorsPerCluster, &BytesPerSector,
&NumberOfFreeClusters, &TotalNumberOfClusters))
{
return error();
@ -201,7 +235,9 @@ int open(const char *path, int oflag, ...)
CREATE_NEW :
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,
0/* default security */,
CreationDisposition, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0);
@ -305,7 +341,9 @@ int close(int fd)
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,
0,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
@ -339,7 +377,9 @@ int lchflags(const char *path, uint32_t flags)
if (0 == FileAttributes)
FileAttributes = FILE_ATTRIBUTE_NORMAL;
if (!SetFileAttributesA(path, FileAttributes))
WCHAR PathBuf[PATH_MAX];
uncpath(path, PathBuf, PATH_MAX);
if (!SetFileAttributesW(PathBuf, FileAttributes))
return error();
#endif
@ -348,7 +388,9 @@ int lchflags(const char *path, uint32_t flags)
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,
0,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
@ -382,7 +424,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 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,
0,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
@ -412,7 +456,9 @@ int utimensat(int dirfd, const char *path, const struct fuse_timespec times[2],
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,
0,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
@ -432,7 +478,9 @@ int setcrtime(const char *path, const struct fuse_timespec *tv)
int unlink(const char *path)
{
if (!DeleteFileA(path))
WCHAR PathBuf[PATH_MAX];
uncpath(path, PathBuf, PATH_MAX);
if (!DeleteFileW(PathBuf))
return error();
return 0;
@ -440,7 +488,11 @@ int unlink(const char *path)
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 0;
@ -448,7 +500,9 @@ int rename(const char *oldpath, const char *newpath)
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,
0,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
@ -483,7 +537,9 @@ static int lgetea(const char *path,
PFILE_GET_EA_INFORMATION GetEa, ULONG GetEaLength,
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,
0,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
@ -675,7 +731,9 @@ int lremovexattr(const char *path, const char *name)
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 0;
@ -683,7 +741,9 @@ int mkdir(const char *path, fuse_mode_t mode)
int rmdir(const char *path)
{
if (!RemoveDirectoryA(path))
WCHAR PathBuf[PATH_MAX];
uncpath(path, PathBuf, PATH_MAX);
if (!RemoveDirectoryW(PathBuf))
return error();
return 0;
@ -691,7 +751,9 @@ int rmdir(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,
0,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
@ -736,18 +798,20 @@ void rewinddir(DIR *dirp)
struct dirent *readdir(DIR *dirp)
{
WIN32_FIND_DATAA FindData;
WIN32_FIND_DATAW FindData;
struct fuse_stat *stbuf = &dirp->de.d_stat;
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)
return error0();
}
else
{
if (!FindNextFileA(dirp->fh, &FindData))
if (!FindNextFileW(dirp->fh, &FindData))
{
if (ERROR_NO_MORE_FILES == GetLastError())
return 0;
@ -768,7 +832,7 @@ struct dirent *readdir(DIR *dirp)
stbuf->st_flags = MapFileAttributesToFlags(FindData.dwFileAttributes);
#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;
}

View File

@ -38,7 +38,7 @@ typedef struct _DIR DIR;
struct dirent
{
struct fuse_stat d_stat;
char d_name[255];
char d_name[255 * 4];
};
char *realpath(const char *path, char *resolved);

View File

@ -576,6 +576,40 @@ static void querydir_namelen_dotest(ULONG Flags, PWSTR Prefix, PWSTR Drive)
ASSERT(INVALID_HANDLE_VALUE == Handle);
ASSERT(ERROR_INVALID_NAME == GetLastError());
for (P = FilePathBgn, EndP = P + MaxComponentLength - 1; EndP > P; P++)
*P = (P - FilePathBgn) % 10 + 0x3041;
*P = L'\0';
Handle = CreateFileW(FilePath,
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0);
ASSERT(INVALID_HANDLE_VALUE != Handle);
querydir_namelen_exists(FilePath);
Success = CloseHandle(Handle);
ASSERT(Success);
for (P = FilePathBgn, EndP = P + MaxComponentLength; EndP > P; P++)
*P = (P - FilePathBgn) % 10 + 0x3041;
*P = L'\0';
Handle = CreateFileW(FilePath,
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0);
ASSERT(INVALID_HANDLE_VALUE != Handle);
querydir_namelen_exists(FilePath);
Success = CloseHandle(Handle);
ASSERT(Success);
for (P = FilePathBgn, EndP = P + MaxComponentLength + 1; EndP > P; P++)
*P = (P - FilePathBgn) % 10 + 0x3041;
*P = L'\0';
Handle = CreateFileW(FilePath,
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0);
ASSERT(INVALID_HANDLE_VALUE == Handle);
ASSERT(ERROR_INVALID_NAME == GetLastError());
memfs_stop(memfs);
}