diff --git a/nob.c b/nob.c index 58c0500..20a258e 100644 --- a/nob.c +++ b/nob.c @@ -172,6 +172,10 @@ extern "C" { } #endif +#ifdef _WIN32 +#include "ConsoleApi2.h" +#endif // _WIN32 + int main(int argc, char **argv) { #ifdef _WIN32 diff --git a/nob.h b/nob.h index 2735a93..8248d00 100644 --- a/nob.h +++ b/nob.h @@ -313,9 +313,10 @@ typedef struct { struct { #ifdef _WIN32 - WIN32_FIND_DATA win32_data; + WIN32_FIND_DATAW win32_data; HANDLE win32_hFind; bool win32_init; + char utf8_name[MAX_PATH]; #else DIR *posix_dir; struct dirent *posix_ent; @@ -1013,7 +1014,6 @@ NOBDEF char *nob_win32_error_message(DWORD err) { return win32ErrMsg; } - #endif // _WIN32 // The implementation idea is stolen from https://github.com/zhiayang/nabs @@ -1960,7 +1960,15 @@ NOBDEF bool nob_dir_entry_open(const char *dir_path, Nob_Dir_Entry *dir) #ifdef _WIN32 size_t temp_mark = nob_temp_save(); char *buffer = nob_temp_sprintf("%s\\*", dir_path); - dir->nob__private.win32_hFind = FindFirstFile(buffer, &dir->nob__private.win32_data); + + WCHAR utf16_buffer[MAX_PATH]; + int n = MultiByteToWideChar(CP_UTF8, 0, buffer, -1, utf16_buffer, sizeof(utf16_buffer)); + if(n == 0){ + nob_log(NOB_ERROR, "Could not convert dir_path name from utf8 to utf16: %s", nob_win32_error_message(GetLastError())); + return false; + } + + dir->nob__private.win32_hFind = FindFirstFileW(utf16_buffer, &dir->nob__private.win32_data); nob_temp_rewind(temp_mark); if (dir->nob__private.win32_hFind == INVALID_HANDLE_VALUE) { @@ -1984,17 +1992,29 @@ NOBDEF bool nob_dir_entry_next(Nob_Dir_Entry *dir) #ifdef _WIN32 if (!dir->nob__private.win32_init) { dir->nob__private.win32_init = true; - dir->name = dir->nob__private.win32_data.cFileName; + + int n = WideCharToMultiByte(CP_UTF8, 0, dir->nob__private.win32_data.cFileName, -1, dir->nob__private.utf8_name, sizeof(dir->nob__private.utf8_name), NULL, NULL); + if(n == 0){ + nob_log(NOB_ERROR, "Could not convert path name from utf16 to utf8: %s", nob_win32_error_message(GetLastError())); + return false; + } + dir->name = dir->nob__private.utf8_name; return true; } - if (!FindNextFile(dir->nob__private.win32_hFind, &dir->nob__private.win32_data)) { + if (!FindNextFileW(dir->nob__private.win32_hFind, &dir->nob__private.win32_data)) { if (GetLastError() == ERROR_NO_MORE_FILES) return false; nob_log(NOB_ERROR, "Could not read next directory entry: %s", nob_win32_error_message(GetLastError())); dir->error = true; return false; } - dir->name = dir->nob__private.win32_data.cFileName; + + int n = WideCharToMultiByte(CP_UTF8, 0, dir->nob__private.win32_data.cFileName, -1, dir->nob__private.utf8_name, sizeof(dir->nob__private.utf8_name), NULL, NULL); + if(n == 0){ + nob_log(NOB_ERROR, "Could not convert path name from utf16 to utf8: %s", nob_win32_error_message(GetLastError())); + return false; + } + dir->name = dir->nob__private.utf8_name; #else errno = 0; dir->nob__private.posix_ent = readdir(dir->nob__private.posix_dir); @@ -2714,18 +2734,37 @@ NOBDEF int nob_file_exists(const char *file_path) NOBDEF const char *nob_get_current_dir_temp(void) { #ifdef _WIN32 - DWORD nBufferLength = GetCurrentDirectory(0, NULL); + DWORD nBufferLength = GetCurrentDirectoryW(0, NULL); if (nBufferLength == 0) { nob_log(NOB_ERROR, "could not get current directory: %s", nob_win32_error_message(GetLastError())); return NULL; } - char *buffer = (char*) nob_temp_alloc(nBufferLength); - if (GetCurrentDirectory(nBufferLength, buffer) == 0) { + LPWSTR utf16_buffer; + utf16_buffer = (LPWSTR) nob_temp_alloc(nBufferLength*sizeof(*utf16_buffer)); + + if (GetCurrentDirectoryW(nBufferLength, utf16_buffer) == 0) { nob_log(NOB_ERROR, "could not get current directory: %s", nob_win32_error_message(GetLastError())); return NULL; } + + int nUtf8BufferLength = WideCharToMultiByte(CP_UTF8, 0, utf16_buffer, nBufferLength, NULL, 0, NULL, NULL); + if(nUtf8BufferLength == 0){ + nob_log(NOB_ERROR, "Could not determine utf8 path size: %s", nob_win32_error_message(GetLastError())); + return NULL; + } + + char* buffer; + buffer = (char*) nob_temp_alloc(nUtf8BufferLength*sizeof(*buffer)); + + nUtf8BufferLength = WideCharToMultiByte(CP_UTF8, 0, utf16_buffer, nBufferLength, buffer, nUtf8BufferLength, NULL, NULL); + if(nBufferLength == 0){ + nob_log(NOB_ERROR, "Could not convert utf16 path to utf8: %s", nob_win32_error_message(GetLastError())); + return NULL; + } + + return buffer; #else char *buffer = (char*) nob_temp_alloc(PATH_MAX);