From 4a4dbe027a082e546512b5ccb2999753651a9a28 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Fri, 26 Nov 2021 13:53:43 +0100 Subject: Add a wrapper for the main function on Windows A macro and forward declaration are added to compat.h that rename the main() function programs using compat.h into sqfs_tools_main. An actual main() function is added to libcompat.a, that uses the shell API to get the UTF-16 command line arguments, convert them to UTF-8 and call sqfs_tools_main. Signed-off-by: David Oberhollenzer --- include/compat.h | 6 ++++ lib/compat/Makemodule.am | 1 + lib/compat/w32_wmain.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 lib/compat/w32_wmain.c 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 + */ +#include "config.h" +#include "compat.h" + +#include + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#include + +#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 -- cgit v1.2.3