1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-01-03 12:11:33 +01:00

try to control inherited HANDLE for new Windows.

Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
NIIBE Yutaka 2022-11-18 14:29:13 +09:00
parent 4736debd01
commit f5eb3710b4
No known key found for this signature in database
GPG Key ID: 640114AF89DE6054
2 changed files with 100 additions and 36 deletions

View File

@ -33,6 +33,8 @@
#if !defined(HAVE_W32_SYSTEM)
#error This code is only used on W32.
#else
#define _WIN32_WINNT 0x602
#endif
#include <stdio.h>
@ -63,9 +65,11 @@
#include "util.h"
#include "i18n.h"
#include "sysutils.h"
#define NEED_STRUCT_SPAWN_CB_ARG
#include "exechelp.h"
#include <windows.h>
#include <processthreadsapi.h>
/* Define to 1 do enable debugging. */
#define DEBUG_W32_SPAWN 0
@ -1098,13 +1102,14 @@ spawn_detached (gnupg_process_t process,
{
SECURITY_ATTRIBUTES sec_attr;
PROCESS_INFORMATION pi = { NULL, 0, 0, 0 };
STARTUPINFOW si;
STARTUPINFOEXW si;
int cr_flags;
wchar_t *wcmdline = NULL;
wchar_t *wpgmname = NULL;
int ask_inherit = 0;
BOOL ask_inherit = FALSE;
gpg_err_code_t ec;
int ret;
struct spawn_cb_arg sca;
ec = gnupg_access (pgmname, X_OK);
if (ec)
@ -1114,23 +1119,23 @@ spawn_detached (gnupg_process_t process,
return ec;
}
if (spawn_cb)
ask_inherit = (*spawn_cb) (spawn_cb_arg);
memset (&si, 0, sizeof si);
sca.plpAttributeList = &si.lpAttributeList;
sca.arg = spawn_cb_arg;
sca.hd[0] = INVALID_HANDLE_VALUE;
if (spawn_cb && (*spawn_cb) (&sca))
ask_inherit = TRUE;
/* Prepare security attributes. */
memset (&sec_attr, 0, sizeof sec_attr );
sec_attr.nLength = sizeof sec_attr;
if (ask_inherit)
sec_attr.bInheritHandle = TRUE;
else
sec_attr.bInheritHandle = FALSE;
sec_attr.bInheritHandle = FALSE;
/* Start the process. */
memset (&si, 0, sizeof si);
si.cb = sizeof (si);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE;
si.StartupInfo.cb = sizeof (si);
si.StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
si.StartupInfo.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE;
cr_flags = (CREATE_DEFAULT_ERROR_MODE
| GetPriorityClass (GetCurrentProcess ())
@ -1149,11 +1154,11 @@ spawn_detached (gnupg_process_t process,
wcmdline, /* Command line arguments. */
&sec_attr, /* Process security attributes. */
&sec_attr, /* Thread security attributes. */
FALSE, /* Inherit handles. */
ask_inherit, /* Inherit handles. */
cr_flags, /* Creation flags. */
NULL, /* Environment. */
NULL, /* Use current drive/directory. */
&si, /* Startup information. */
(STARTUPINFOW *)&si, /* Startup information. */
&pi /* Returns process information. */
);
if (!ret)
@ -1169,6 +1174,8 @@ spawn_detached (gnupg_process_t process,
xfree (cmdline);
return GPG_ERR_GENERAL;
}
if (si.lpAttributeList)
DeleteProcThreadAttributeList (si.lpAttributeList);
xfree (wpgmname);
xfree (wcmdline);
xfree (cmdline);
@ -1202,16 +1209,18 @@ gnupg_process_spawn (const char *pgmname, const char *argv[],
gnupg_process_t process;
SECURITY_ATTRIBUTES sec_attr;
PROCESS_INFORMATION pi = { NULL, 0, 0, 0 };
STARTUPINFOW si;
STARTUPINFOEXW si;
int cr_flags;
char *cmdline;
wchar_t *wcmdline = NULL;
wchar_t *wpgmname = NULL;
int ret;
int ask_inherit = 0;
BOOL ask_inherit = FALSE;
HANDLE hd_in[2];
HANDLE hd_out[2];
HANDLE hd_err[2];
struct spawn_cb_arg sca;
int i;
check_syscall_func ();
@ -1224,7 +1233,10 @@ gnupg_process_spawn (const char *pgmname, const char *argv[],
process = xtrymalloc (sizeof (struct gnupg_process));
if (process == NULL)
return gpg_err_code_from_syserror ();
{
xfree (cmdline);
return gpg_err_code_from_syserror ();
}
process->pgmname = pgmname;
process->flags = flags;
@ -1324,26 +1336,67 @@ gnupg_process_spawn (const char *pgmname, const char *argv[],
hd_err[1] = GetStdHandle (STD_ERROR_HANDLE);
}
if (spawn_cb)
ask_inherit = (*spawn_cb) (spawn_cb_arg);
memset (&si, 0, sizeof si);
sca.plpAttributeList = &si.lpAttributeList;
sca.arg = spawn_cb_arg;
i = 0;
if (hd_in[0] != INVALID_HANDLE_VALUE)
sca.hd[i++] = hd_in[0];
if (hd_out[1] != INVALID_HANDLE_VALUE)
sca.hd[i++] = hd_out[1];
if (hd_err[1] != INVALID_HANDLE_VALUE)
sca.hd[i++] = hd_err[1];
sca.hd[i] = INVALID_HANDLE_VALUE;
if (spawn_cb && (*spawn_cb) (&sca))
ask_inherit = TRUE;
else if (i != 0)
{
SIZE_T attr_list_size = 0;
InitializeProcThreadAttributeList (NULL, 1, 0, &attr_list_size);
si.lpAttributeList = xtrymalloc (attr_list_size);
if (si.lpAttributeList == NULL)
{
if (hd_in[0] != INVALID_HANDLE_VALUE)
CloseHandle (hd_in[0]);
if (hd_in[1] != INVALID_HANDLE_VALUE)
CloseHandle (hd_in[1]);
if (hd_out[0] != INVALID_HANDLE_VALUE)
CloseHandle (hd_out[0]);
if (hd_out[1] != INVALID_HANDLE_VALUE)
CloseHandle (hd_out[1]);
if (hd_err[0] != INVALID_HANDLE_VALUE)
CloseHandle (hd_err[0]);
if (hd_err[1] != INVALID_HANDLE_VALUE)
CloseHandle (hd_err[1]);
xfree (wpgmname);
xfree (wcmdline);
xfree (process);
xfree (cmdline);
return gpg_err_code_from_syserror ();
}
InitializeProcThreadAttributeList (si.lpAttributeList, 1, 0,
&attr_list_size);
UpdateProcThreadAttribute (si.lpAttributeList, 0,
PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
sca.hd, sizeof (HANDLE) * i, NULL, NULL);
ask_inherit = TRUE;
}
/* Prepare security attributes. */
memset (&sec_attr, 0, sizeof sec_attr );
sec_attr.nLength = sizeof sec_attr;
if (ask_inherit)
sec_attr.bInheritHandle = TRUE;
else
sec_attr.bInheritHandle = FALSE;
sec_attr.bInheritHandle = FALSE;
/* Start the process. */
memset (&si, 0, sizeof si);
si.cb = sizeof (si);
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_HIDE;
si.hStdInput = hd_in[0];
si.hStdOutput = hd_out[1];
si.hStdError = hd_err[1];
si.StartupInfo.cb = sizeof (si);
si.StartupInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.StartupInfo.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_HIDE;
si.StartupInfo.hStdInput = hd_in[0];
si.StartupInfo.hStdOutput = hd_out[1];
si.StartupInfo.hStdError = hd_err[1];
log_debug ("CreateProcess, path='%s' cmdline='%s'\n",
pgmname, cmdline);
@ -1355,15 +1408,15 @@ gnupg_process_spawn (const char *pgmname, const char *argv[],
else if (!(wcmdline = utf8_to_wchar (cmdline)))
ret = 0;
else
ret = CreateProcessW (wpgmname, /* Program to start. */
wcmdline, /* Command line arguments. */
ret = CreateProcessW (wpgmname, /* Program to start. */
wcmdline, /* Command line arguments. */
&sec_attr, /* Process security attributes. */
&sec_attr, /* Thread security attributes. */
TRUE, /* Inherit handles. */
ask_inherit, /* Inherit handles. */
cr_flags, /* Creation flags. */
NULL, /* Environment. */
NULL, /* Use current drive/directory. */
&si, /* Startup information. */
(STARTUPINFOW *)&si, /* Startup information. */
&pi /* Returns process information. */
);
if (!ret)
@ -1393,6 +1446,8 @@ gnupg_process_spawn (const char *pgmname, const char *argv[],
return GPG_ERR_GENERAL;
}
if (si.lpAttributeList)
DeleteProcThreadAttributeList (si.lpAttributeList);
xfree (wpgmname);
xfree (wcmdline);
xfree (cmdline);

View File

@ -210,6 +210,15 @@ gpg_error_t gnupg_spawn_process_detached (const char *pgmname,
/* The opaque type for a subprocess. */
typedef struct gnupg_process *gnupg_process_t;
#ifdef HAVE_W32_SYSTEM
#ifdef NEED_STRUCT_SPAWN_CB_ARG
struct spawn_cb_arg {
void *plpAttributeList;
HANDLE hd[16];
void *arg;
};
#endif
#endif
/* Internal flag to ihnerit file descriptor/handle */
#define GNUPG_PROCESS_INHERIT_FILE (1 << 0)