fix: use wide-char Windows APIs for non-ASCII filenames
This commit is contained in:
+46
-1
@@ -13,7 +13,7 @@
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#include <windows.h>
|
||||
#define MKDIR(path) _mkdir(path)
|
||||
#include <wchar.h>
|
||||
#define PROGRAM_NAME "funpack.exe"
|
||||
#else
|
||||
#include <time.h>
|
||||
@@ -21,6 +21,42 @@
|
||||
#define PROGRAM_NAME "funpack"
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
static wchar_t *utf8_to_wide(const char *s)
|
||||
{
|
||||
int wlen = MultiByteToWideChar(CP_UTF8, 0, s, -1, NULL, 0);
|
||||
wchar_t *w;
|
||||
|
||||
if (wlen <= 0)
|
||||
return NULL;
|
||||
w = malloc((size_t)wlen * sizeof(wchar_t));
|
||||
if (!w)
|
||||
return NULL;
|
||||
MultiByteToWideChar(CP_UTF8, 0, s, -1, w, wlen);
|
||||
return w;
|
||||
}
|
||||
|
||||
static int win_mkdir(const char *path)
|
||||
{
|
||||
wchar_t *wpath = utf8_to_wide(path);
|
||||
int ok;
|
||||
|
||||
if (!wpath)
|
||||
return -1;
|
||||
ok = CreateDirectoryW(wpath, NULL);
|
||||
free(wpath);
|
||||
if (ok)
|
||||
return 0;
|
||||
if (GetLastError() == ERROR_ALREADY_EXISTS) {
|
||||
errno = EEXIST;
|
||||
return -1;
|
||||
}
|
||||
errno = 0;
|
||||
return -1;
|
||||
}
|
||||
#define MKDIR(path) win_mkdir(path)
|
||||
#endif
|
||||
|
||||
static double now_seconds(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
@@ -168,6 +204,9 @@ static int extract_entry(const char *out_dir, const fpk_entry_t *entry,
|
||||
{
|
||||
char *full_path = join_path(out_dir, entry->path);
|
||||
FILE *fp;
|
||||
#ifdef _WIN32
|
||||
wchar_t *wpath;
|
||||
#endif
|
||||
|
||||
if (strchr(entry->path, '/') != NULL) {
|
||||
char *dir_part = dup_str(full_path);
|
||||
@@ -182,7 +221,13 @@ static int extract_entry(const char *out_dir, const fpk_entry_t *entry,
|
||||
free(dir_part);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
wpath = utf8_to_wide(full_path);
|
||||
fp = wpath ? _wfopen(wpath, L"wb") : NULL;
|
||||
free(wpath);
|
||||
#else
|
||||
fp = fopen(full_path, "wb");
|
||||
#endif
|
||||
if (!fp) {
|
||||
fprintf(stderr, "funpack: cannot create: %s\n", full_path);
|
||||
free(full_path);
|
||||
|
||||
Reference in New Issue
Block a user