[PATCH 1/2] programs/wineconsole: use wmain as entry point
Eric Pouech
eric.pouech at gmail.com
Wed Apr 27 07:52:25 CDT 2022
Signed-off-by: Eric Pouech <eric.pouech at gmail.com>
---
programs/wineconsole/Makefile.in | 3 -
programs/wineconsole/wineconsole.c | 95 ++++++++++++++++++++++++++++++++++--
2 files changed, 91 insertions(+), 7 deletions(-)
diff --git a/programs/wineconsole/Makefile.in b/programs/wineconsole/Makefile.in
index b859ef8a27a..08ad51d2b6a 100644
--- a/programs/wineconsole/Makefile.in
+++ b/programs/wineconsole/Makefile.in
@@ -1,6 +1,5 @@
MODULE = wineconsole.exe
-IMPORTS = advapi32
-DELAYIMPORTS = comctl32 user32 gdi32
+DELAYIMPORTS = user32
EXTRADLLFLAGS = -mwindows -municode
diff --git a/programs/wineconsole/wineconsole.c b/programs/wineconsole/wineconsole.c
index 1924bf791e6..c703127c238 100644
--- a/programs/wineconsole/wineconsole.c
+++ b/programs/wineconsole/wineconsole.c
@@ -32,14 +32,101 @@
WINE_DEFAULT_DEBUG_CHANNEL(console);
-int WINAPI wWinMain( HINSTANCE inst, HINSTANCE prev, WCHAR *cmdline, INT show )
+static const unsigned int EC_INTERNAL = 255; /* value of exit_code for internal errors */
+
+/***********************************************************************
+ * build_command_line
+ *
+ * Build the command line of a process from the argv array.
+ * (copied from dlls/ntdll/unix/env.c)
+ *
+ * We must quote and escape characters so that the argv array can be rebuilt
+ * from the command line:
+ * - spaces and tabs must be quoted
+ * 'a b' -> '"a b"'
+ * - quotes must be escaped
+ * '"' -> '\"'
+ * - if '\'s are followed by a '"', they must be doubled and followed by '\"',
+ * resulting in an odd number of '\' followed by a '"'
+ * '\"' -> '\\\"'
+ * '\\"' -> '\\\\\"'
+ * - '\'s are followed by the closing '"' must be doubled,
+ * resulting in an even number of '\' followed by a '"'
+ * ' \' -> '" \\"'
+ * ' \\' -> '" \\\\"'
+ * - '\'s that are not followed by a '"' can be left as is
+ * 'a\b' == 'a\b'
+ * 'a\\b' == 'a\\b'
+ */
+static WCHAR *build_command_line( WCHAR **wargv )
+{
+ int len;
+ WCHAR **arg, *ret;
+ LPWSTR p;
+
+ len = 1;
+ for (arg = wargv; *arg; arg++) len += 3 + 2 * wcslen( *arg );
+ if (!(ret = malloc( len * sizeof(WCHAR) ))) return NULL;
+
+ p = ret;
+ for (arg = wargv; *arg; arg++)
+ {
+ BOOL has_space, has_quote;
+ int i, bcount;
+ WCHAR *a;
+
+ /* check for quotes and spaces in this argument (first arg is always quoted) */
+ has_space = (arg == wargv) || !**arg || wcschr( *arg, ' ' ) || wcschr( *arg, '\t' );
+ has_quote = wcschr( *arg, '"' ) != NULL;
+
+ /* now transfer it to the command line */
+ if (has_space) *p++ = '"';
+ if (has_quote || has_space)
+ {
+ bcount = 0;
+ for (a = *arg; *a; a++)
+ {
+ if (*a == '\\') bcount++;
+ else
+ {
+ if (*a == '"') /* double all the '\\' preceding this '"', plus one */
+ for (i = 0; i <= bcount; i++) *p++ = '\\';
+ bcount = 0;
+ }
+ *p++ = *a;
+ }
+ }
+ else
+ {
+ wcscpy( p, *arg );
+ p += wcslen( p );
+ }
+ if (has_space)
+ {
+ /* Double all the '\' preceding the closing quote */
+ for (i = 0; i < bcount; i++) *p++ = '\\';
+ *p++ = '"';
+ }
+ *p++ = ' ';
+ }
+ if (p > ret) p--; /* remove last space */
+ *p = 0;
+ if (p - ret >= 32767)
+ {
+ ERR( "command line too long (%Iu)\n", p - ret );
+ exit( EC_INTERNAL );
+ }
+ return ret;
+}
+
+int wmain( int argc, WCHAR *argv[] )
{
STARTUPINFOW startup = { sizeof(startup) };
PROCESS_INFORMATION info;
- WCHAR *cmd = cmdline;
+ WCHAR *cmd;
DWORD exit_code;
- static WCHAR default_cmd[] = L"cmd";
+ cmd = argc > 1 ? build_command_line( &argv[1] ) : wcsdup( L"cmd.exe" );
FreeConsole(); /* make sure we're not connected to inherited console */
if (!AllocConsole())
@@ -48,8 +135,6 @@ int WINAPI wWinMain( HINSTANCE inst, HINSTANCE prev, WCHAR *cmdline, INT show )
return 1;
}
- if (!*cmd) cmd = default_cmd;
-
startup.dwFlags = STARTF_USESTDHANDLES;
startup.hStdInput = CreateFileW( L"CONIN$", GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, 0, 0 );
More information about the wine-devel
mailing list