From cf2f6d8a3f0594c03c383b4989a3041e9c4536d7 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 8 Mar 2021 21:26:16 +0100 Subject: w32: Change spawn functions to use Unicode version of CreateProcess. * common/exechelp-w32.c (gnupg_spawn_process): Change to use CreateProcessW. (gnupg_spawn_process_fd): Ditto. (gnupg_spawn_process_detached): Ditto. * g10/exec.c (w32_system): Ditto. -- GnuPG-bug-id: 4398 We do not use this weirdo CREATE_UNICODE_ENVIRONMENT flag because it does not make any sense to have non-ASCII names in the environment. I can't imagine why this should be used at all and rationale for this API features is, well, sparse. --- common/exechelp-w32.c | 144 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 97 insertions(+), 47 deletions(-) (limited to 'common/exechelp-w32.c') diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c index a7897cbfc..0988b9054 100644 --- a/common/exechelp-w32.c +++ b/common/exechelp-w32.c @@ -424,9 +424,11 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], 0, /* Returns pid. */ 0 /* Returns tid. */ }; - STARTUPINFO si; + STARTUPINFOW si; int cr_flags; char *cmdline; + wchar_t *wcmdline = NULL; + wchar_t *wpgmname = NULL; HANDLE inpipe[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}; HANDLE outpipe[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}; HANDLE errpipe[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}; @@ -436,7 +438,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], HANDLE nullhd[3] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}; - int i; + int i, rc; es_syshd_t syshd; gpg_err_source_t errsource = default_errsource; int nonblock = !!(flags & GNUPG_SPAWN_NONBLOCK); @@ -574,20 +576,34 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], | ((flags & GNUPG_SPAWN_DETACHED)? DETACHED_PROCESS : 0) | GetPriorityClass (GetCurrentProcess ()) | CREATE_SUSPENDED); -/* log_debug ("CreateProcess, path='%s' cmdline='%s'\n", pgmname, cmdline); */ - if (!CreateProcess (pgmname, /* Program to start. */ - cmdline, /* Command line arguments. */ - &sec_attr, /* Process security attributes. */ - &sec_attr, /* Thread security attributes. */ - TRUE, /* Inherit handles. */ - cr_flags, /* Creation flags. */ - NULL, /* Environment. */ - NULL, /* Use current drive/directory. */ - &si, /* Startup information. */ - &pi /* Returns process information. */ - )) + /* log_debug ("CreateProcess, path='%s' cmdline='%s'\n", */ + /* pgmname, cmdline); */ + /* Take care: CreateProcessW may modify wpgmname */ + if (!(wpgmname = utf8_to_wchar (pgmname))) + rc = 0; + else if (!(wcmdline = utf8_to_wchar (cmdline))) + rc = 0; + else + rc = CreateProcessW (wpgmname, /* Program to start. */ + wcmdline, /* Command line arguments. */ + &sec_attr, /* Process security attributes. */ + &sec_attr, /* Thread security attributes. */ + TRUE, /* Inherit handles. */ + cr_flags, /* Creation flags. */ + NULL, /* Environment. */ + NULL, /* Use current drive/directory. */ + &si, /* Startup information. */ + &pi /* Returns process information. */ + ); + if (!rc) { - log_error ("CreateProcess failed: %s\n", w32_strerror (-1)); + if (!wpgmname || !wcmdline) + log_error ("CreateProcess failed (utf8_to_wchar): %s\n", + strerror (errno)); + else + log_error ("CreateProcess failed: %s\n", w32_strerror (-1)); + xfree (wpgmname); + xfree (wcmdline); xfree (cmdline); if (infp) es_fclose (infp); @@ -609,6 +625,8 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], CloseHandle (errpipe[1]); return gpg_err_make (errsource, GPG_ERR_GENERAL); } + xfree (wpgmname); + xfree (wcmdline); xfree (cmdline); cmdline = NULL; @@ -670,9 +688,11 @@ gnupg_spawn_process_fd (const char *pgmname, const char *argv[], gpg_error_t err; SECURITY_ATTRIBUTES sec_attr; PROCESS_INFORMATION pi = { NULL, 0, 0, 0 }; - STARTUPINFO si; + STARTUPINFOW si; char *cmdline; - int i; + wchar_t *wcmdline = NULL; + wchar_t *wpgmname = NULL; + int i, rc; HANDLE stdhd[3]; /* Setup return values. */ @@ -700,25 +720,38 @@ gnupg_spawn_process_fd (const char *pgmname, const char *argv[], si.hStdError = errfd == -1? stdhd[2] : (void*)_get_osfhandle (errfd); /* log_debug ("CreateProcess, path='%s' cmdline='%s'\n", pgmname, cmdline); */ - if (!CreateProcess (pgmname, /* Program to start. */ - cmdline, /* Command line arguments. */ - &sec_attr, /* Process security attributes. */ - &sec_attr, /* Thread security attributes. */ - TRUE, /* Inherit handles. */ - (CREATE_DEFAULT_ERROR_MODE - | GetPriorityClass (GetCurrentProcess ()) - | CREATE_SUSPENDED | DETACHED_PROCESS), - NULL, /* Environment. */ - NULL, /* Use current drive/directory. */ - &si, /* Startup information. */ - &pi /* Returns process information. */ - )) + /* Take care: CreateProcessW may modify wpgmname */ + if (!(wpgmname = utf8_to_wchar (pgmname))) + rc = 0; + else if (!(wcmdline = utf8_to_wchar (cmdline))) + rc = 0; + else + rc = CreateProcessW (wpgmname, /* Program to start. */ + wcmdline, /* Command line arguments. */ + &sec_attr, /* Process security attributes. */ + &sec_attr, /* Thread security attributes. */ + TRUE, /* Inherit handles. */ + (CREATE_DEFAULT_ERROR_MODE + | GetPriorityClass (GetCurrentProcess ()) + | CREATE_SUSPENDED | DETACHED_PROCESS), + NULL, /* Environment. */ + NULL, /* Use current drive/directory. */ + &si, /* Startup information. */ + &pi /* Returns process information. */ + ); + if (!rc) { - log_error ("CreateProcess failed: %s\n", w32_strerror (-1)); + if (!wpgmname || !wcmdline) + log_error ("CreateProcess failed (utf8_to_wchar): %s\n", + strerror (errno)); + else + log_error ("CreateProcess failed: %s\n", w32_strerror (-1)); err = my_error (GPG_ERR_GENERAL); } else err = 0; + xfree (wpgmname); + xfree (wcmdline); xfree (cmdline); for (i=0; i < 3; i++) if (stdhd[i] != INVALID_HANDLE_VALUE) @@ -862,12 +895,14 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[], 0, /* Returns pid. */ 0 /* Returns tid. */ }; - STARTUPINFO si; + STARTUPINFOW si; int cr_flags; char *cmdline; + wchar_t *wcmdline = NULL; + wchar_t *wpgmname = NULL; BOOL in_job = FALSE; gpg_err_code_t ec; - + int rc; /* We don't use ENVP. */ (void)envp; @@ -939,24 +974,39 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[], } } -/* log_debug ("CreateProcess(detached), path='%s' cmdline='%s'\n", */ -/* pgmname, cmdline); */ - if (!CreateProcess (pgmname, /* Program to start. */ - cmdline, /* Command line arguments. */ - &sec_attr, /* Process security attributes. */ - &sec_attr, /* Thread security attributes. */ - FALSE, /* Inherit handles. */ - cr_flags, /* Creation flags. */ - NULL, /* Environment. */ - NULL, /* Use current drive/directory. */ - &si, /* Startup information. */ - &pi /* Returns process information. */ - )) + /* log_debug ("CreateProcess(detached), path='%s' cmdline='%s'\n", */ + /* pgmname, cmdline); */ + /* Take care: CreateProcessW may modify wpgmname */ + if (!(wpgmname = utf8_to_wchar (pgmname))) + rc = 0; + else if (!(wcmdline = utf8_to_wchar (cmdline))) + rc = 0; + else + rc = CreateProcessW (wpgmname, /* Program to start. */ + wcmdline, /* Command line arguments. */ + &sec_attr, /* Process security attributes. */ + &sec_attr, /* Thread security attributes. */ + FALSE, /* Inherit handles. */ + cr_flags, /* Creation flags. */ + NULL, /* Environment. */ + NULL, /* Use current drive/directory. */ + &si, /* Startup information. */ + &pi /* Returns process information. */ + ); + if (!rc) { - log_error ("CreateProcess(detached) failed: %s\n", w32_strerror (-1)); + if (!wpgmname || !wcmdline) + log_error ("CreateProcess failed (utf8_to_wchar): %s\n", + strerror (errno)); + else + log_error ("CreateProcess(detached) failed: %s\n", w32_strerror (-1)); + xfree (wpgmname); + xfree (wcmdline); xfree (cmdline); return my_error (GPG_ERR_GENERAL); } + xfree (wpgmname); + xfree (wcmdline); xfree (cmdline); cmdline = NULL; -- cgit v1.2.3