summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2021-11-26 13:53:43 +0100
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2021-12-05 10:29:32 +0100
commit4a4dbe027a082e546512b5ccb2999753651a9a28 (patch)
treecbc2a9557fc9f7f2c40fe1d4dfe06672526bdad4
parent1901937e66baf95145b71e878220bf1a129d32fb (diff)
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 <david.oberhollenzer@sigma-star.at>
-rw-r--r--include/compat.h6
-rw-r--r--lib/compat/Makemodule.am1
-rw-r--r--lib/compat/w32_wmain.c82
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