diff options
-rw-r--r-- | include/compat.h | 6 | ||||
-rw-r--r-- | lib/compat/Makemodule.am | 1 | ||||
-rw-r--r-- | lib/compat/w32_wmain.c | 82 |
3 files changed, 89 insertions, 0 deletions
diff --git a/include/compat.h b/include/compat.h index e82f2ad..59133c9 100644 --- a/include/compat.h +++ b/include/compat.h @@ -227,4 +227,10 @@ WCHAR *path_to_windows(const char *input); int fnmatch(const char *, const char *, int); #endif +#if defined(_WIN32) || defined(__WINDOWS__) +#define main sqfs_tools_main + +extern int sqfs_tools_main(int argc, char **argv); +#endif + #endif /* COMPAT_H */ diff --git a/lib/compat/Makemodule.am b/lib/compat/Makemodule.am index 6ea0750..f9dce2e 100644 --- a/lib/compat/Makemodule.am +++ b/lib/compat/Makemodule.am @@ -3,6 +3,7 @@ libcompat_a_SOURCES += lib/compat/strndup.c lib/compat/mockups.c libcompat_a_SOURCES += lib/compat/chdir.c include/compat.h libcompat_a_SOURCES += lib/compat/path_to_windows.c libcompat_a_SOURCES += lib/compat/w32_perror.c +libcompat_a_SOURCES += lib/compat/w32_wmain.c libcompat_a_SOURCES += lib/compat/fnmatch.c libcompat_a_SOURCES += lib/compat/getopt.c libcompat_a_SOURCES += lib/compat/getopt_long.c diff --git a/lib/compat/w32_wmain.c b/lib/compat/w32_wmain.c new file mode 100644 index 0000000..4245d1c --- /dev/null +++ b/lib/compat/w32_wmain.c @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * w32_wmain.c + * + * Copyright (C) 2021 David Oberhollenzer <goliath@infraroot.at> + */ +#include "config.h" +#include "compat.h" + +#include <stdio.h> + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <shellapi.h> + +#undef main + +int main(int argc, char **argv) +{ + WCHAR *cmdline, **argList; + int i, ret, utf8_argc; + char **utf8_argv; + (void)argc; + (void)argv; + + /* get the UTF-16 encoded command line arguments */ + cmdline = GetCommandLineW(); + argList = CommandLineToArgvW(cmdline, &utf8_argc); + if (argList == NULL) + goto fail_oom; + + /* convert to UTF-8 */ + utf8_argv = calloc(sizeof(utf8_argv[0]), utf8_argc); + if (utf8_argv == NULL) + goto fail_oom; + + for (i = 0; i < utf8_argc; ++i) { + DWORD length = WideCharToMultiByte(CP_UTF8, 0, argList[i], + -1, NULL, 0, NULL, NULL); + if (length <= 0) + goto fail_conv; + + utf8_argv[i] = calloc(1, length + 1); + if (utf8_argv[i] == NULL) + goto fail_oom; + + WideCharToMultiByte(CP_UTF8, 0, argList[i], -1, + utf8_argv[i], length + 1, NULL, NULL); + utf8_argv[i][length] = '\0'; + } + + LocalFree(argList); + argList = NULL; + + /* call the actual main function */ + ret = sqfs_tools_main(utf8_argc, utf8_argv); + + /* cleanup */ + for (i = 0; i < utf8_argc; ++i) + free(utf8_argv[i]); + + free(utf8_argv); + return ret; +fail_conv: + w32_perror("Converting UTF-16 argument to UTF-8"); + goto fail; +fail_oom: + fputs("out of memory\n", stderr); + goto fail; +fail: + if (utf8_argv != NULL) { + for (i = 0; i < utf8_argc; ++i) + free(utf8_argv[i]); + free(utf8_argv); + } + if (argList != NULL) { + LocalFree(argList); + } + return EXIT_FAILURE; +} +#endif |