From 9264c2710b64e565982d77410169a3253563a647 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 9 Mar 2021 08:58:09 +0100 Subject: Support Unicode when starting servers on Windows. * src/assuan-socket.c (utf8_to_wchar): Rename to (_assuan_utf8_to_wchar): this and give global scope. * src/system-w32.c (__assuan_spawn): Use CreateProcessW. -- GnuPG-bug-id: 4398 --- src/assuan-defs.h | 1 + src/assuan-socket.c | 8 ++++---- src/system-w32.c | 48 +++++++++++++++++++++++++++++++----------------- 3 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/assuan-defs.h b/src/assuan-defs.h index e56d7b1..e7ca918 100644 --- a/src/assuan-defs.h +++ b/src/assuan-defs.h @@ -354,6 +354,7 @@ int _assuan_sock_get_nonce (assuan_context_t ctx, struct sockaddr *addr, int _assuan_sock_check_nonce (assuan_context_t ctx, assuan_fd_t fd, assuan_sock_nonce_t *nonce); #ifdef HAVE_W32_SYSTEM +wchar_t *_assuan_utf8_to_wchar (const char *string); int _assuan_sock_wsa2errno (int err); #endif diff --git a/src/assuan-socket.c b/src/assuan-socket.c index 9a24f1a..97b2312 100644 --- a/src/assuan-socket.c +++ b/src/assuan-socket.c @@ -215,8 +215,8 @@ delete_cygwin_fd (assuan_fd_t sockfd) } -static wchar_t * -utf8_to_wchar (const char *string) +wchar_t * +_assuan_utf8_to_wchar (const char *string) { int n; size_t nbytes; @@ -260,7 +260,7 @@ MyCreateFile (LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwSharedMode, HANDLE result; int err; - filename = utf8_to_wchar (lpFileName); + filename = _assuan_utf8_to_wchar (lpFileName); if (!filename) return INVALID_HANDLE_VALUE; @@ -278,7 +278,7 @@ MyDeleteFile (LPCSTR lpFileName) wchar_t *filename; int result, err; - filename = utf8_to_wchar (lpFileName); + filename = _assuan_utf8_to_wchar (lpFileName); if (!filename) return 0; diff --git a/src/system-w32.c b/src/system-w32.c index 9547ce0..a0e9a98 100644 --- a/src/system-w32.c +++ b/src/system-w32.c @@ -419,11 +419,14 @@ __assuan_spawn (assuan_context_t ctx, pid_t *r_pid, const char *name, 0, /* Returns pid. */ 0 /* Returns tid. */ }; - STARTUPINFO si; + STARTUPINFOW si; assuan_fd_t fd; assuan_fd_t *fdp; char *cmdline; + wchar_t *wcmdline = NULL; + wchar_t *wname = NULL; HANDLE nullfd = INVALID_HANDLE_VALUE; + int rc; /* fixme: Actually we should set the "_assuan_pipe_connect_pid" env variable. However this requires us to write a full environment @@ -478,26 +481,35 @@ __assuan_spawn (assuan_context_t ctx, pid_t *r_pid, const char *name, /* Note: We inherit all handles flagged as inheritable. This seems to be a security flaw but there seems to be no way of selecting handles to inherit. A fix for this would be to use a helper - process like we have in gpgme. */ + process like we have in gpgme. + Take care: CreateProcessW may modify wpgmname */ /* _assuan_log_printf ("CreateProcess, path=`%s' cmdline=`%s'\n", */ /* name, cmdline); */ - if (!CreateProcess (name, /* Program to start. */ - cmdline, /* Command line arguments. */ - &sec_attr, /* Process security attributes. */ - &sec_attr, /* Thread security attributes. */ - TRUE, /* Inherit handles. */ - (CREATE_DEFAULT_ERROR_MODE - | ((flags & 128)? DETACHED_PROCESS : 0) - | GetPriorityClass (GetCurrentProcess ()) - | CREATE_SUSPENDED), /* Creation flags. */ - NULL, /* Environment. */ - NULL, /* Use current drive/directory. */ - &si, /* Startup information. */ - &pi /* Returns process information. */ - )) + if (name && !(wname = _assuan_utf8_to_wchar (name))) + rc = 0; + else if (!(wcmdline = _assuan_utf8_to_wchar (cmdline))) + rc = 0; + else + rc = CreateProcessW (wname, /* Program to start. */ + wcmdline, /* Command line arguments. */ + &sec_attr, /* Process security attributes. */ + &sec_attr, /* Thread security attributes. */ + TRUE, /* Inherit handles. */ + (CREATE_DEFAULT_ERROR_MODE + | ((flags & 128)? DETACHED_PROCESS : 0) + | GetPriorityClass (GetCurrentProcess ()) + | CREATE_SUSPENDED), /* Creation flags. */ + NULL, /* Environment. */ + NULL, /* Use current drive/directory. */ + &si, /* Startup information. */ + &pi /* Returns process information. */ + ); + if (!rc) { TRACE1 (ctx, ASSUAN_LOG_SYSIO, "pipe_connect_w32", ctx, - "CreateProcess failed: %s", _assuan_w32_strerror (ctx, -1)); + "CreateProcess failed%s: %s", _assuan_w32_strerror (ctx, -1)); + free (wname); + free (wcmdline); _assuan_free (ctx, cmdline); if (nullfd != INVALID_HANDLE_VALUE) CloseHandle (nullfd); @@ -506,6 +518,8 @@ __assuan_spawn (assuan_context_t ctx, pid_t *r_pid, const char *name, return -1; } + free (wname); + free (wcmdline); _assuan_free (ctx, cmdline); if (nullfd != INVALID_HANDLE_VALUE) CloseHandle (nullfd); -- cgit v1.2.1