mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-18 14:17:03 +01:00
try to control inherited HANDLE for new Windows.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
4736debd01
commit
f5eb3710b4
@ -33,6 +33,8 @@
|
|||||||
|
|
||||||
#if !defined(HAVE_W32_SYSTEM)
|
#if !defined(HAVE_W32_SYSTEM)
|
||||||
#error This code is only used on W32.
|
#error This code is only used on W32.
|
||||||
|
#else
|
||||||
|
#define _WIN32_WINNT 0x602
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -63,9 +65,11 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
#include "sysutils.h"
|
#include "sysutils.h"
|
||||||
|
#define NEED_STRUCT_SPAWN_CB_ARG
|
||||||
#include "exechelp.h"
|
#include "exechelp.h"
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <processthreadsapi.h>
|
||||||
|
|
||||||
/* Define to 1 do enable debugging. */
|
/* Define to 1 do enable debugging. */
|
||||||
#define DEBUG_W32_SPAWN 0
|
#define DEBUG_W32_SPAWN 0
|
||||||
@ -1098,13 +1102,14 @@ spawn_detached (gnupg_process_t process,
|
|||||||
{
|
{
|
||||||
SECURITY_ATTRIBUTES sec_attr;
|
SECURITY_ATTRIBUTES sec_attr;
|
||||||
PROCESS_INFORMATION pi = { NULL, 0, 0, 0 };
|
PROCESS_INFORMATION pi = { NULL, 0, 0, 0 };
|
||||||
STARTUPINFOW si;
|
STARTUPINFOEXW si;
|
||||||
int cr_flags;
|
int cr_flags;
|
||||||
wchar_t *wcmdline = NULL;
|
wchar_t *wcmdline = NULL;
|
||||||
wchar_t *wpgmname = NULL;
|
wchar_t *wpgmname = NULL;
|
||||||
int ask_inherit = 0;
|
BOOL ask_inherit = FALSE;
|
||||||
gpg_err_code_t ec;
|
gpg_err_code_t ec;
|
||||||
int ret;
|
int ret;
|
||||||
|
struct spawn_cb_arg sca;
|
||||||
|
|
||||||
ec = gnupg_access (pgmname, X_OK);
|
ec = gnupg_access (pgmname, X_OK);
|
||||||
if (ec)
|
if (ec)
|
||||||
@ -1114,23 +1119,23 @@ spawn_detached (gnupg_process_t process,
|
|||||||
return ec;
|
return ec;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spawn_cb)
|
memset (&si, 0, sizeof si);
|
||||||
ask_inherit = (*spawn_cb) (spawn_cb_arg);
|
|
||||||
|
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. */
|
/* Prepare security attributes. */
|
||||||
memset (&sec_attr, 0, sizeof sec_attr );
|
memset (&sec_attr, 0, sizeof sec_attr );
|
||||||
sec_attr.nLength = sizeof sec_attr;
|
sec_attr.nLength = sizeof sec_attr;
|
||||||
|
sec_attr.bInheritHandle = FALSE;
|
||||||
if (ask_inherit)
|
|
||||||
sec_attr.bInheritHandle = TRUE;
|
|
||||||
else
|
|
||||||
sec_attr.bInheritHandle = FALSE;
|
|
||||||
|
|
||||||
/* Start the process. */
|
/* Start the process. */
|
||||||
memset (&si, 0, sizeof si);
|
si.StartupInfo.cb = sizeof (si);
|
||||||
si.cb = sizeof (si);
|
si.StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
|
||||||
si.dwFlags = STARTF_USESHOWWINDOW;
|
si.StartupInfo.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE;
|
||||||
si.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE;
|
|
||||||
|
|
||||||
cr_flags = (CREATE_DEFAULT_ERROR_MODE
|
cr_flags = (CREATE_DEFAULT_ERROR_MODE
|
||||||
| GetPriorityClass (GetCurrentProcess ())
|
| GetPriorityClass (GetCurrentProcess ())
|
||||||
@ -1149,11 +1154,11 @@ spawn_detached (gnupg_process_t process,
|
|||||||
wcmdline, /* Command line arguments. */
|
wcmdline, /* Command line arguments. */
|
||||||
&sec_attr, /* Process security attributes. */
|
&sec_attr, /* Process security attributes. */
|
||||||
&sec_attr, /* Thread security attributes. */
|
&sec_attr, /* Thread security attributes. */
|
||||||
FALSE, /* Inherit handles. */
|
ask_inherit, /* Inherit handles. */
|
||||||
cr_flags, /* Creation flags. */
|
cr_flags, /* Creation flags. */
|
||||||
NULL, /* Environment. */
|
NULL, /* Environment. */
|
||||||
NULL, /* Use current drive/directory. */
|
NULL, /* Use current drive/directory. */
|
||||||
&si, /* Startup information. */
|
(STARTUPINFOW *)&si, /* Startup information. */
|
||||||
&pi /* Returns process information. */
|
&pi /* Returns process information. */
|
||||||
);
|
);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
@ -1169,6 +1174,8 @@ spawn_detached (gnupg_process_t process,
|
|||||||
xfree (cmdline);
|
xfree (cmdline);
|
||||||
return GPG_ERR_GENERAL;
|
return GPG_ERR_GENERAL;
|
||||||
}
|
}
|
||||||
|
if (si.lpAttributeList)
|
||||||
|
DeleteProcThreadAttributeList (si.lpAttributeList);
|
||||||
xfree (wpgmname);
|
xfree (wpgmname);
|
||||||
xfree (wcmdline);
|
xfree (wcmdline);
|
||||||
xfree (cmdline);
|
xfree (cmdline);
|
||||||
@ -1202,16 +1209,18 @@ gnupg_process_spawn (const char *pgmname, const char *argv[],
|
|||||||
gnupg_process_t process;
|
gnupg_process_t process;
|
||||||
SECURITY_ATTRIBUTES sec_attr;
|
SECURITY_ATTRIBUTES sec_attr;
|
||||||
PROCESS_INFORMATION pi = { NULL, 0, 0, 0 };
|
PROCESS_INFORMATION pi = { NULL, 0, 0, 0 };
|
||||||
STARTUPINFOW si;
|
STARTUPINFOEXW si;
|
||||||
int cr_flags;
|
int cr_flags;
|
||||||
char *cmdline;
|
char *cmdline;
|
||||||
wchar_t *wcmdline = NULL;
|
wchar_t *wcmdline = NULL;
|
||||||
wchar_t *wpgmname = NULL;
|
wchar_t *wpgmname = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
int ask_inherit = 0;
|
BOOL ask_inherit = FALSE;
|
||||||
HANDLE hd_in[2];
|
HANDLE hd_in[2];
|
||||||
HANDLE hd_out[2];
|
HANDLE hd_out[2];
|
||||||
HANDLE hd_err[2];
|
HANDLE hd_err[2];
|
||||||
|
struct spawn_cb_arg sca;
|
||||||
|
int i;
|
||||||
|
|
||||||
check_syscall_func ();
|
check_syscall_func ();
|
||||||
|
|
||||||
@ -1224,7 +1233,10 @@ gnupg_process_spawn (const char *pgmname, const char *argv[],
|
|||||||
|
|
||||||
process = xtrymalloc (sizeof (struct gnupg_process));
|
process = xtrymalloc (sizeof (struct gnupg_process));
|
||||||
if (process == NULL)
|
if (process == NULL)
|
||||||
return gpg_err_code_from_syserror ();
|
{
|
||||||
|
xfree (cmdline);
|
||||||
|
return gpg_err_code_from_syserror ();
|
||||||
|
}
|
||||||
|
|
||||||
process->pgmname = pgmname;
|
process->pgmname = pgmname;
|
||||||
process->flags = flags;
|
process->flags = flags;
|
||||||
@ -1324,26 +1336,67 @@ gnupg_process_spawn (const char *pgmname, const char *argv[],
|
|||||||
hd_err[1] = GetStdHandle (STD_ERROR_HANDLE);
|
hd_err[1] = GetStdHandle (STD_ERROR_HANDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spawn_cb)
|
memset (&si, 0, sizeof si);
|
||||||
ask_inherit = (*spawn_cb) (spawn_cb_arg);
|
|
||||||
|
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. */
|
/* Prepare security attributes. */
|
||||||
memset (&sec_attr, 0, sizeof sec_attr );
|
memset (&sec_attr, 0, sizeof sec_attr );
|
||||||
sec_attr.nLength = sizeof sec_attr;
|
sec_attr.nLength = sizeof sec_attr;
|
||||||
|
sec_attr.bInheritHandle = FALSE;
|
||||||
if (ask_inherit)
|
|
||||||
sec_attr.bInheritHandle = TRUE;
|
|
||||||
else
|
|
||||||
sec_attr.bInheritHandle = FALSE;
|
|
||||||
|
|
||||||
/* Start the process. */
|
/* Start the process. */
|
||||||
memset (&si, 0, sizeof si);
|
si.StartupInfo.cb = sizeof (si);
|
||||||
si.cb = sizeof (si);
|
si.StartupInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
|
||||||
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
|
si.StartupInfo.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_HIDE;
|
||||||
si.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_HIDE;
|
si.StartupInfo.hStdInput = hd_in[0];
|
||||||
si.hStdInput = hd_in[0];
|
si.StartupInfo.hStdOutput = hd_out[1];
|
||||||
si.hStdOutput = hd_out[1];
|
si.StartupInfo.hStdError = hd_err[1];
|
||||||
si.hStdError = hd_err[1];
|
|
||||||
|
|
||||||
log_debug ("CreateProcess, path='%s' cmdline='%s'\n",
|
log_debug ("CreateProcess, path='%s' cmdline='%s'\n",
|
||||||
pgmname, cmdline);
|
pgmname, cmdline);
|
||||||
@ -1355,15 +1408,15 @@ gnupg_process_spawn (const char *pgmname, const char *argv[],
|
|||||||
else if (!(wcmdline = utf8_to_wchar (cmdline)))
|
else if (!(wcmdline = utf8_to_wchar (cmdline)))
|
||||||
ret = 0;
|
ret = 0;
|
||||||
else
|
else
|
||||||
ret = CreateProcessW (wpgmname, /* Program to start. */
|
ret = CreateProcessW (wpgmname, /* Program to start. */
|
||||||
wcmdline, /* Command line arguments. */
|
wcmdline, /* Command line arguments. */
|
||||||
&sec_attr, /* Process security attributes. */
|
&sec_attr, /* Process security attributes. */
|
||||||
&sec_attr, /* Thread security attributes. */
|
&sec_attr, /* Thread security attributes. */
|
||||||
TRUE, /* Inherit handles. */
|
ask_inherit, /* Inherit handles. */
|
||||||
cr_flags, /* Creation flags. */
|
cr_flags, /* Creation flags. */
|
||||||
NULL, /* Environment. */
|
NULL, /* Environment. */
|
||||||
NULL, /* Use current drive/directory. */
|
NULL, /* Use current drive/directory. */
|
||||||
&si, /* Startup information. */
|
(STARTUPINFOW *)&si, /* Startup information. */
|
||||||
&pi /* Returns process information. */
|
&pi /* Returns process information. */
|
||||||
);
|
);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
@ -1393,6 +1446,8 @@ gnupg_process_spawn (const char *pgmname, const char *argv[],
|
|||||||
return GPG_ERR_GENERAL;
|
return GPG_ERR_GENERAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (si.lpAttributeList)
|
||||||
|
DeleteProcThreadAttributeList (si.lpAttributeList);
|
||||||
xfree (wpgmname);
|
xfree (wpgmname);
|
||||||
xfree (wcmdline);
|
xfree (wcmdline);
|
||||||
xfree (cmdline);
|
xfree (cmdline);
|
||||||
|
@ -210,6 +210,15 @@ gpg_error_t gnupg_spawn_process_detached (const char *pgmname,
|
|||||||
|
|
||||||
/* The opaque type for a subprocess. */
|
/* The opaque type for a subprocess. */
|
||||||
typedef struct gnupg_process *gnupg_process_t;
|
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 */
|
/* Internal flag to ihnerit file descriptor/handle */
|
||||||
#define GNUPG_PROCESS_INHERIT_FILE (1 << 0)
|
#define GNUPG_PROCESS_INHERIT_FILE (1 << 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user