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; diff --git a/g10/exec.c b/g10/exec.c index f63904b39..f612c850a 100644 --- a/g10/exec.c +++ b/g10/exec.c @@ -107,28 +107,36 @@ w32_system(const char *command) else { char *string; + wchar_t *wstring; PROCESS_INFORMATION pi; - STARTUPINFO si; + STARTUPINFOW si; /* We must use a copy of the command as CreateProcess modifies * this argument. */ string = xstrdup (command); + wstring = utf8_to_wchar (string); + xfree (string); + if (!wstring) + return -1; memset (&pi, 0, sizeof(pi)); memset (&si, 0, sizeof(si)); si.cb = sizeof (si); - if (!CreateProcess (NULL, string, NULL, NULL, FALSE, - DETACHED_PROCESS, - NULL, NULL, &si, &pi)) - return -1; + if (!CreateProcessW (NULL, wstring, NULL, NULL, FALSE, + DETACHED_PROCESS, + NULL, NULL, &si, &pi)) + { + xfree (wstring); + return -1; + } /* Wait for the child to exit */ WaitForSingleObject (pi.hProcess, INFINITE); CloseHandle (pi.hProcess); CloseHandle (pi.hThread); - xfree (string); + xfree (wstring); } return 0;