aboutsummaryrefslogtreecommitdiffstats
path: root/src/gpgme-w32spawn.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2009-06-12 16:58:45 +0000
committerWerner Koch <[email protected]>2009-06-12 16:58:45 +0000
commit148f51bb3e6e592333250ef73f2b801a10734083 (patch)
tree08ea4fe8f7b9009372821e9b28e41df294b248d8 /src/gpgme-w32spawn.c
parentFix possible assert in the card edit. (diff)
downloadgpgme-148f51bb3e6e592333250ef73f2b801a10734083.tar.gz
gpgme-148f51bb3e6e592333250ef73f2b801a10734083.zip
Improved W32 SetForegroundWindow hacks.
Diffstat (limited to 'src/gpgme-w32spawn.c')
-rw-r--r--src/gpgme-w32spawn.c101
1 files changed, 82 insertions, 19 deletions
diff --git a/src/gpgme-w32spawn.c b/src/gpgme-w32spawn.c
index f132a8fc..6f7c609a 100644
--- a/src/gpgme-w32spawn.c
+++ b/src/gpgme-w32spawn.c
@@ -34,6 +34,13 @@
#include <process.h>
#include <windows.h>
+/* Flag values as used by gpgme. */
+#define IOSPAWN_FLAG_ALLOW_SET_FG 1
+
+
+/* Name of this program. */
+#define PGM "gpgme-w32spawn"
+
struct spawn_fd_item_s
@@ -101,7 +108,7 @@ build_commandline (char **argv)
int
-my_spawn (char **argv, struct spawn_fd_item_s *fd_list)
+my_spawn (char **argv, struct spawn_fd_item_s *fd_list, unsigned int flags)
{
SECURITY_ATTRIBUTES sec_attr;
PROCESS_INFORMATION pi =
@@ -127,7 +134,7 @@ my_spawn (char **argv, struct spawn_fd_item_s *fd_list)
i = 0;
while (argv[i])
{
- fprintf (stderr, "argv[%2i] = %s\n", i, argv[i]);
+ fprintf (stderr, PGM": argv[%2i] = %s\n", i, argv[i]);
i++;
}
@@ -147,7 +154,7 @@ my_spawn (char **argv, struct spawn_fd_item_s *fd_list)
si.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
si.hStdError = GetStdHandle (STD_ERROR_HANDLE);
- fprintf (stderr, "spawning: %s\n", arg_string);
+ fprintf (stderr, PGM": spawning: %s\n", arg_string);
for (i = 0; fd_list[i].handle != -1; i++)
{
@@ -156,19 +163,19 @@ my_spawn (char **argv, struct spawn_fd_item_s *fd_list)
{
si.hStdInput = (HANDLE) fd_list[i].peer_name;
duped_stdin = 1;
- fprintf (stderr, "dup 0x%x to stdin\n", fd_list[i].peer_name);
+ fprintf (stderr, PGM": dup 0x%x to stdin\n", fd_list[i].peer_name);
}
else if (fd_list[i].dup_to == 1)
{
si.hStdOutput = (HANDLE) fd_list[i].peer_name;
duped_stdout = 1;
- fprintf (stderr, "dup 0x%x to stdout\n", fd_list[i].peer_name);
+ fprintf (stderr, PGM": dup 0x%x to stdout\n", fd_list[i].peer_name);
}
else if (fd_list[i].dup_to == 2)
{
si.hStdError = (HANDLE) fd_list[i].peer_name;
duped_stderr = 1;
- fprintf (stderr, "dup 0x%x to stderr\n", fd_list[i].peer_name);
+ fprintf (stderr, PGM":dup 0x%x to stderr\n", fd_list[i].peer_name);
}
}
@@ -231,6 +238,33 @@ my_spawn (char **argv, struct spawn_fd_item_s *fd_list)
for (i = 0; fd_list[i].handle != -1; i++)
CloseHandle ((HANDLE) fd_list[i].handle);
+
+ if (flags & IOSPAWN_FLAG_ALLOW_SET_FG)
+ {
+ static int initialized;
+ static BOOL (WINAPI * func)(DWORD);
+ void *handle;
+
+ if (!initialized)
+ {
+ /* Available since W2000; thus we dynload it. */
+ initialized = 1;
+ handle = LoadLibrary ("user32.dll");
+ if (handle)
+ {
+ func = GetProcAddress (handle, "AllowSetForegroundWindow");
+ if (!func)
+ FreeLibrary (handle);
+ }
+ }
+
+ if (func)
+ {
+ int rc = func (pi.dwProcessId);
+ fprintf (stderr, PGM": AllowSetForegroundWindow(%d): rc=%d\n",
+ (int)pi.dwProcessId, rc);
+ }
+ }
ResumeThread (pi.hThread);
CloseHandle (pi.hThread);
@@ -244,12 +278,13 @@ my_spawn (char **argv, struct spawn_fd_item_s *fd_list)
int
translate_get_from_file (const char *trans_file,
- struct spawn_fd_item_s *fd_list)
+ struct spawn_fd_item_s *fd_list,
+ unsigned int *r_flags)
{
/* Hold roughly MAX_TRANS triplets of 64 bit numbers in hex
notation: "0xFEDCBA9876543210". 10*19*4 - 1 = 759. This plans
ahead for a time when a HANDLE is 64 bit. */
-#define BUFFER_MAX 800
+#define BUFFER_MAX 810
char line[BUFFER_MAX + 1];
char *linep;
@@ -257,6 +292,8 @@ translate_get_from_file (const char *trans_file,
int res;
int fd;
+ *r_flags = 0;
+
fd = open (trans_file, O_RDONLY);
if (fd < 0)
return -1;
@@ -269,10 +306,12 @@ translate_get_from_file (const char *trans_file,
line[BUFFER_MAX] = '\0';
linep = strchr (line, '\n');
- if (linep > line && linep[-1] == '\r')
- linep--;
- *linep = '\0';
-
+ if (linep)
+ {
+ if (linep > line && linep[-1] == '\r')
+ linep--;
+ *linep = '\0';
+ }
linep = line;
/* Now start to read mapping pairs. */
@@ -289,6 +328,21 @@ translate_get_from_file (const char *trans_file,
linep++;
if (*linep == '\0')
break;
+ if (!idx && *linep == '~')
+ {
+ /* Spawn flags have been passed. */
+ linep++;
+ *r_flags = strtoul (linep, &tail, 0);
+ if (tail == NULL || ! (*tail == '\0' || isspace (*tail)))
+ break;
+ linep = tail;
+
+ while (isspace (*((unsigned char *)linep)))
+ linep++;
+ if (*linep == '\0')
+ break;
+ }
+
from = strtoul (linep, &tail, 0);
if (tail == NULL || ! (*tail == '\0' || isspace (*tail)))
break;
@@ -339,13 +393,14 @@ translate_get_from_file (const char *trans_file,
FD_LIST (which must be MAX_TRANS+1 large). */
char **
translate_handles (const char *trans_file, const char * const *argv,
- struct spawn_fd_item_s *fd_list)
+ struct spawn_fd_item_s *fd_list, unsigned int *r_flags)
{
int res;
int idx;
+ int n_args;
char **args;
- res = translate_get_from_file (trans_file, fd_list);
+ res = translate_get_from_file (trans_file, fd_list, r_flags);
if (res < 0)
return NULL;
@@ -359,6 +414,7 @@ translate_handles (const char *trans_file, const char * const *argv,
return NULL;
}
args[idx] = NULL;
+ n_args = idx;
for (idx = 0; fd_list[idx].handle != -1; idx++)
{
@@ -369,6 +425,12 @@ translate_handles (const char *trans_file, const char * const *argv,
if (aidx == 0)
continue;
+ if (aidx >= n_args)
+ {
+ fprintf (stderr, PGM": translation file does not match args\n");
+ return NULL;
+ }
+
args[aidx] = malloc (sizeof (buf));
/* We currently disable translation for stdin/stdout/stderr. We
assume that the spawned program handles 0/1/2 specially
@@ -394,6 +456,7 @@ main (int argc, const char * const *argv)
int rc = 0;
char **argv_spawn;
struct spawn_fd_item_s fd_list[MAX_TRANS + 1];
+ unsigned int flags;
if (argc < 3)
{
@@ -401,7 +464,7 @@ main (int argc, const char * const *argv)
goto leave;
}
- argv_spawn = translate_handles (argv[1], &argv[2], fd_list);
+ argv_spawn = translate_handles (argv[1], &argv[2], fd_list, &flags);
if (!argv_spawn)
{
rc = 2;
@@ -411,10 +474,10 @@ main (int argc, const char * const *argv)
/* Using execv does not replace the existing program image, but
spawns a new one and daemonizes it, confusing the command line
interpreter. So we have to use spawnv. */
- rc = my_spawn (argv_spawn, fd_list);
+ rc = my_spawn (argv_spawn, fd_list, flags);
if (rc < 0)
{
- fprintf (stderr, "gpgwrap: executing `%s' failed: %s\n",
+ fprintf (stderr, PGM": executing `%s' failed: %s\n",
argv[0], strerror (errno));
rc = 2;
goto leave;
@@ -422,12 +485,12 @@ main (int argc, const char * const *argv)
leave:
if (rc)
- fprintf (stderr, "gpg-w32spawn: internal error\n");
+ fprintf (stderr, PGM": internal error\n");
/* Always try to delete the temporary file. */
if (argc >= 2)
{
if (DeleteFile (argv[1]) == 0)
- fprintf (stderr, "Failed to delete %s: ec=%ld\n",
+ fprintf (stderr, PGM": failed to delete %s: ec=%ld\n",
argv[1], GetLastError ());
}
return rc;