summaryrefslogtreecommitdiff
path: root/filesystem-win.c
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2022-07-29 16:45:46 -0400
committerpommicket <pommicket@gmail.com>2022-07-29 16:45:46 -0400
commit3f6c3bfd1bf2baebb49a68d3b463f6b414555d73 (patch)
tree93aa0932affac394bfd63bee556abed20a2d3075 /filesystem-win.c
parent12cc45bfcaa4c866f4509b6324a424048f3ddd29 (diff)
fixed non-ascii path handling on windows
Diffstat (limited to 'filesystem-win.c')
-rw-r--r--filesystem-win.c51
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;
}