diff options
author | pommicket <pommicket@gmail.com> | 2022-07-29 16:45:46 -0400 |
---|---|---|
committer | pommicket <pommicket@gmail.com> | 2022-07-29 16:45:46 -0400 |
commit | 3f6c3bfd1bf2baebb49a68d3b463f6b414555d73 (patch) | |
tree | 93aa0932affac394bfd63bee556abed20a2d3075 /filesystem-win.c | |
parent | 12cc45bfcaa4c866f4509b6324a424048f3ddd29 (diff) |
fixed non-ascii path handling on windows
Diffstat (limited to 'filesystem-win.c')
-rw-r--r-- | filesystem-win.c | 51 |
1 files changed, 32 insertions, 19 deletions
diff --git a/filesystem-win.c b/filesystem-win.c index a16dc6b..dc17eaf 100644 --- a/filesystem-win.c +++ b/filesystem-win.c @@ -13,7 +13,11 @@ static FsType windows_file_attributes_to_type(DWORD attrs) { } FsType fs_path_type(char const *path) { - return windows_file_attributes_to_type(GetFileAttributesA(path)); + WCHAR wide_path[4100]; + if (MultiByteToWideChar(CP_UTF8, 0, path, -1, wide_path, sizeof wide_path) == 0) { + return FS_NON_EXISTENT; + } + return windows_file_attributes_to_type(GetFileAttributesW(wide_path)); } FsPermission fs_path_permission(char const *path) { @@ -28,39 +32,46 @@ bool fs_file_exists(char const *path) { } FsDirectoryEntry **fs_list_directory(char const *dirname) { - char file_pattern[256] = {0}; + char file_pattern[1000] = {0}; FsDirectoryEntry **files = NULL; - WIN32_FIND_DATA find_data; + WIN32_FIND_DATAW find_data; HANDLE fhandle; assert(*dirname); sprintf_s(file_pattern, sizeof file_pattern, "%s%s*", dirname, dirname[strlen(dirname) - 1] == PATH_SEPARATOR ? "" : PATH_SEPARATOR_STR); - fhandle = FindFirstFileA(file_pattern, &find_data); + wchar_t wide_pattern[1024] = {0}; + MultiByteToWideChar(CP_UTF8, 0, file_pattern, -1, wide_pattern, sizeof wide_pattern - 1); + + fhandle = FindFirstFileW(wide_pattern, &find_data); if (fhandle != INVALID_HANDLE_VALUE) { // first, figure out number of files int nfiles = 1, idx = 0; - while (FindNextFile(fhandle, &find_data)) { + while (FindNextFileW(fhandle, &find_data)) { ++nfiles; } FindClose(fhandle); // now, fill out files array files = calloc(nfiles + 1, sizeof *files); if (files) { - fhandle = FindFirstFileA(file_pattern, &find_data); + fhandle = FindFirstFileW(wide_pattern, &find_data); if (fhandle != INVALID_HANDLE_VALUE) { do { if (idx < nfiles) { - const char *filename = find_data.cFileName; - size_t len = strlen(filename); - FsDirectoryEntry *entry = calloc(1, sizeof *entry + len + 1); + LPWSTR wide_filename = find_data.cFileName; + size_t wide_len = wcslen(wide_filename); + size_t cap = 4 * wide_len + 4; + FsDirectoryEntry *entry = calloc(1, sizeof *entry + cap); + + if (entry) { + if (WideCharToMultiByte(CP_UTF8, 0, wide_filename, (int)wide_len, entry->name, (int)cap - 1, NULL, NULL) == 0) + break; DWORD attrs = find_data.dwFileAttributes; entry->type = windows_file_attributes_to_type(attrs); - memcpy(entry->name, filename, len); files[idx++] = entry; } else break; // stop now } - } while (FindNextFile(fhandle, &find_data)); + } while (FindNextFileW(fhandle, &find_data)); FindClose(fhandle); } } @@ -69,7 +80,11 @@ FsDirectoryEntry **fs_list_directory(char const *dirname) { } int fs_mkdir(char const *path) { - if (CreateDirectoryA(path, NULL)) { + WCHAR wide_path[4100]; + if (MultiByteToWideChar(CP_UTF8, 0, path, -1, wide_path, sizeof wide_path) == 0) + return -1; + + if (CreateDirectoryW(wide_path, NULL)) { // directory created successfully return 1; } else { @@ -82,12 +97,10 @@ int fs_mkdir(char const *path) { int fs_get_cwd(char *buf, size_t buflen) { assert(buf && buflen); - DWORD pathlen = GetCurrentDirectory((DWORD)buflen, buf); - if (pathlen == 0) { - return -1; - } else if (pathlen < buflen) { // it's confusing, but this is < and not <= - return 1; - } else { + wchar_t wide_path[4100]; + DWORD wide_pathlen = GetCurrentDirectoryW(sizeof wide_path - 1, wide_path); + if (wide_pathlen == 0) return -1; + if (WideCharToMultiByte(CP_UTF8, 0, wide_path, (int)wide_pathlen, buf, (int)buflen, NULL, NULL) == 0) return 0; - } + return 1; } |