aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog34
-rw-r--r--src/Makefile.am15
-rw-r--r--src/assuan-defs.h1
-rw-r--r--src/assuan-pipe-connect.c8
-rw-r--r--src/assuan.h.in (renamed from src/assuan.h)12
-rw-r--r--src/gpgcedev.c183
-rw-r--r--src/libassuan.def2
-rw-r--r--src/mkheader.c192
-rw-r--r--src/system-w32.c27
-rw-r--r--src/system-w32ce.c425
-rw-r--r--src/system.c16
-rw-r--r--src/sysutils.c81
12 files changed, 687 insertions, 309 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 1d5ff2e..6034272 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,39 @@
+2010-03-22 Werner Koch <[email protected]>
+
+ * Makefile.am (mkheader, assuan.h): Build header file.
+ * mkheader.c: New.
+ * assuan.h: Rename to assuan.h.in.
+
+2010-03-18 Werner Koch <[email protected]>
+
+ * libassuan.def (_assuan_w32ce_prepare_pipe)
+ (_assuan_w32ce_finish_pipe): New
+ * gpgcedev.c (struct opnctx_s): Replace HD by RVID.
+ (GPGCEDEV_IOCTL_SET_HANDLE): Remove.
+ (GPGCEDEV_IOCTL_GET_RVID): New.
+ (create_rendezvous_id): New.
+ (get_new_opnctx): Init the RVID.
+ (set_handle): Remove.
+ (find_and_lock_opnctx, make_pipe, GPG_IOControl): Change to new
+ method.
+ * system-w32ce.c (_assuan_w32ce_prepare_pipe)
+ (_assuan_w32ce_finish_pipe): New.
+ (_assuan_w32ce_create_pipe): Re-implement using the new functions.
+ (__assuan_pipe): Create an inheritable pipe.
+ (build_w32_commandline): New arg FD2_ISNULL.
+ * system.c (_assuan_close_inheritable): New.
+ * assuan-pipe-connect.c (pipe_connect): Use the new function.
+
+ * sysutils.c (_assuan_w32ce_create_pipe): Move to system-w32ce.c.
+
2010-03-16 Werner Koch <[email protected]>
+ * system-w32ce.c (build_w32_commandline): Add args to pass the
+ special options for the standard descriptors.
+ (utf8_to_wchar, free_wchar): New.
+ (__assuan_spawn): Adjust for changes. Convert strings for
+ CreateProcess to wchar_t.
+
* system.c: For better readability move platform dependend code to ..
* system-posix.c, system-w32.c, system-w32ce.c: .. New.
* Makefile.am (common_sources): Account for this change.
diff --git a/src/Makefile.am b/src/Makefile.am
index c946f11..6723648 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,5 +1,5 @@
# Assuan Makefile
-# Copyright (C) 2001, 2002, 2003, 2009 Free Software Foundation, Inc.
+# Copyright (C) 2001, 2002, 2003, 2009, 2010 Free Software Foundation, Inc.
#
# This file is part of Assuan.
#
@@ -18,7 +18,7 @@
## Process this file with automake to produce Makefile.in
EXTRA_DIST = libassuan-config.in libassuan.m4 libassuan.vers \
- versioninfo.rc.in libassuan.def
+ versioninfo.rc.in libassuan.def mkheader.c
INCLUDES = -I.. -I$(top_srcdir)/include
bin_SCRIPTS = libassuan-config
@@ -37,8 +37,12 @@ else
libassuan_version_script_cmd =
endif
+CLEANFILES = mkheader assuan.h
+
+BUILT_SOURCES = assuan.h
common_sources = \
+ assuan.h.in assuan.h w32ce-add.h \
assuan-defs.h \
assuan.c context.c system.c \
debug.c debug.h conversion.c sysutils.c \
@@ -121,3 +125,10 @@ libgpgcedev_la_DEPENDENCIES = gpgcedev.def
gpgcemgr_SOURCES = gpgcemgr.c
gpgcemgr_CPPFLAGS = $(AM_CPPFLAGS)
endif
+
+mkheader: mkheader.c Makefile
+ $(CC_FOR_BUILD) -I. -I$(srcdir) -o $@ $(srcdir)/mkheader.c
+
+assuan.h: assuan.h.in mkheader w32ce-add.h
+ ./mkheader $(host_os) $(srcdir)/assuan.h.in >$@
+
diff --git a/src/assuan-defs.h b/src/assuan-defs.h
index dd91f09..63f0d10 100644
--- a/src/assuan-defs.h
+++ b/src/assuan-defs.h
@@ -230,6 +230,7 @@ void _assuan_free (assuan_context_t ctx, void *ptr);
void _assuan_usleep (assuan_context_t ctx, unsigned int usec);
int _assuan_pipe (assuan_context_t ctx, assuan_fd_t fd[2], int inherit_idx);
int _assuan_close (assuan_context_t ctx, assuan_fd_t fd);
+int _assuan_close_inheritable (assuan_context_t ctx, assuan_fd_t fd);
ssize_t _assuan_read (assuan_context_t ctx, assuan_fd_t fd, void *buffer,
size_t size);
ssize_t _assuan_write (assuan_context_t ctx, assuan_fd_t fd, const void *buffer,
diff --git a/src/assuan-pipe-connect.c b/src/assuan-pipe-connect.c
index dec8ccc..4eccdde 100644
--- a/src/assuan-pipe-connect.c
+++ b/src/assuan-pipe-connect.c
@@ -175,7 +175,7 @@ pipe_connect (assuan_context_t ctx,
if (_assuan_pipe (ctx, wp, 0) < 0)
{
_assuan_close (ctx, rp[0]);
- _assuan_close (ctx, rp[1]);
+ _assuan_close_inheritable (ctx, rp[1]);
return _assuan_error (ctx, gpg_err_code_from_syserror ());
}
@@ -197,8 +197,8 @@ pipe_connect (assuan_context_t ctx,
}
/* Close the stdin/stdout child fds in the parent. */
- _assuan_close (ctx, rp[1]);
- _assuan_close (ctx, wp[0]);
+ _assuan_close_inheritable (ctx, rp[1]);
+ _assuan_close_inheritable (ctx, wp[0]);
ctx->engine.release = _assuan_client_release;
ctx->engine.readfnc = _assuan_simple_read;
@@ -393,7 +393,7 @@ socketpair_connect (assuan_context_t ctx,
environment variables are set. To let the caller detect whether the
child or the parent continues, the child returns "client" or
"server" in *ARGV (but it is sufficient to check only the first
- character). */
+ character). This feature is only available on POSIX platforms. */
gpg_error_t
assuan_pipe_connect (assuan_context_t ctx,
const char *name, const char *argv[],
diff --git a/src/assuan.h b/src/assuan.h.in
index c275287..91b75ab 100644
--- a/src/assuan.h
+++ b/src/assuan.h.in
@@ -1,4 +1,4 @@
-/* assuan.h - Definitions for the Assuan IPC library
+/* assuan.h - Definitions for the Assuan IPC library -*- c -*-
Copyright (C) 2001, 2002, 2003, 2005, 2007, 2008, 2009,
2010 Free Software Foundation, Inc.
@@ -16,6 +16,8 @@
You should have received a copy of the GNU Lesser General Public
License along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+ @configure_input@
*/
#ifndef ASSUAN_H
@@ -639,13 +641,7 @@ int __assuan_socketpair (assuan_context_t ctx, int _namespace, int style,
extern struct assuan_system_hooks _assuan_system_pth;
#define ASSUAN_SYSTEM_PTH &_assuan_system_pth
-#ifdef __MINGW32CE__
-/* FIXME: Include this code only if build for this platform. */
-DWORD _assuan_w32ce_create_pipe (HANDLE *read_hd, HANDLE *write_hd,
- LPSECURITY_ATTRIBUTES sec_attr, DWORD size);
-#define CreatePipe(a,b,c,d) _assuan_w32ce_create_pipe ((a),(b),(c),(d))
-
-#endif /*__MINGW32CE__*/
+@include:w32ce-add@
#ifdef __cplusplus
}
diff --git a/src/gpgcedev.c b/src/gpgcedev.c
index 763ab29..fe9c80a 100644
--- a/src/gpgcedev.c
+++ b/src/gpgcedev.c
@@ -17,6 +17,7 @@
License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+
#include <stdio.h>
#include <stdarg.h>
#include <windows.h>
@@ -35,19 +36,21 @@
#endif /*IOCTL_PSL_NOTIFY*/
-/* The IOCTL used to tell the device about the handle.
+/* The IOCTL to return the rendezvous id of the handle.
- The required inbuf parameter is the address of a variable holding
- the handle. */
-#define GPGCEDEV_IOCTL_SET_HANDLE \
+ The required outbuf parameter is the address of a variable to store
+ the rendezvous ID, which is a LONG value. */
+#define GPGCEDEV_IOCTL_GET_RVID \
CTL_CODE (FILE_DEVICE_STREAMS, 2048, METHOD_BUFFERED, FILE_ANY_ACCESS)
/* The IOCTL used to create the pipe.
- The caller sends this IOCTL to the read handle. The required inbuf
- parameter is the address of variable holding the write handle.
- Note that the SET_HANDLE IOCTLs must have been used prior to this
- one. */
+ The caller sends this IOCTL to the read or the write handle. The
+ required inbuf parameter is address of a variable holding the
+ rendezvous id of the pipe's other end. There is one possible
+ problem with eocdde: If a pipe is kept in non-rendezvous state
+ until after the rendezvous ids overflow, it is possible that the
+ wrong end will be used. However this is not a realistic scenario. */
#define GPGCEDEV_IOCTL_MAKE_PIPE \
CTL_CODE (FILE_DEVICE_STREAMS, 2049, METHOD_BUFFERED, FILE_ANY_ACCESS)
@@ -62,7 +65,7 @@ struct opnctx_s
other context; i.e. a pipe has been
established. */
int is_write; /* True if this is the write end of the pipe. */
- HANDLE hd; /* The system's handle object or INVALID_HANDLE_VALUE. */
+ LONG rvid; /* The unique rendezvous identifier. */
DWORD access_code;/* Value from OpenFile. */
DWORD share_mode; /* Value from OpenFile. */
CRITICAL_SECTION critsect; /* Lock for all operations. */
@@ -118,6 +121,19 @@ log_debug (const char *fmt, ...)
}
+/* Return a new rendezvous next command id. Command Ids are used to group
+ resources of one command. We will never return an RVID of 0. */
+static LONG
+create_rendezvous_id (void)
+{
+ static LONG rendezvous_id;
+ LONG rvid;
+
+ while (!(rvid = InterlockedIncrement (&rendezvous_id)))
+ ;
+ return rvid;
+}
+
/* Return a new opnctx handle and mark it as used. Returns NULL and
@@ -152,8 +168,7 @@ get_new_opnctx (void)
}
opnctx = opnctx_table + idx;
opnctx->assoc = NULL;
- opnctx->hd = INVALID_HANDLE_VALUE;
- opnctx->assoc = 0;
+ opnctx->rvid = create_rendezvous_id ();
opnctx->buffer_size = 512;
opnctx->buffer = malloc (opnctx->buffer_size);
if (!opnctx->buffer)
@@ -173,36 +188,45 @@ get_new_opnctx (void)
leave:
LeaveCriticalSection (&opnctx_table_cs);
- log_debug ("get_new_opnctx -> %p\n", opnctx);
+ if (opnctx)
+ log_debug ("get_new_opnctx -> %p (rvid=%ld)\n", opnctx, opnctx->rvid);
+ else
+ log_debug ("get_new_opnctx -> failed\n");
return opnctx;
}
-/* Find the OPNCTX for handle HD. */
+/* Find the OPNCTX object with the rendezvous id RVID. */
static opnctx_t
-find_and_lock_opnctx (HANDLE hd)
+find_and_lock_opnctx (LONG rvid)
{
opnctx_t result = NULL;
int idx;
EnterCriticalSection (&opnctx_table_cs);
for (idx=0; idx < opnctx_table_size; idx++)
- if (opnctx_table[idx].inuse && opnctx_table[idx].hd == hd)
+ if (opnctx_table[idx].inuse && opnctx_table[idx].rvid == rvid)
{
result = opnctx_table + idx;
break;
}
LeaveCriticalSection (&opnctx_table_cs);
if (!result)
- SetLastError (ERROR_INVALID_HANDLE);
+ {
+ SetLastError (ERROR_INVALID_HANDLE);
+ log_debug ("find_opnctx -> invalid rendezvous id\n");
+ }
else if (TryEnterCriticalSection (&result->critsect))
- result->locked++;
+ {
+ result->locked++;
+ log_debug ("find_opnctx -> %p (rvid=%ld)\n", result, result->rvid);
+ }
else
{
SetLastError (ERROR_BUSY);
result = NULL;
+ log_debug ("find_opnctx -> busy\n");
}
- log_debug ("find_opnctx -> %p\n", result);
return result;
}
@@ -353,14 +377,10 @@ GPG_Close (DWORD opnctx_arg)
for (idx=0; idx < opnctx_table_size; idx++)
if (opnctx_table[idx].inuse && (opnctx_table + idx) == opnctx)
{
- if (opnctx->hd != INVALID_HANDLE_VALUE)
+ if (opnctx->assoc)
{
- if (opnctx->assoc)
- {
- opnctx->assoc->assoc = NULL;
- opnctx->assoc = NULL;
- }
- opnctx->hd = INVALID_HANDLE_VALUE;
+ opnctx->assoc->assoc = NULL;
+ opnctx->assoc = NULL;
}
if (opnctx->locked)
{
@@ -419,7 +439,7 @@ GPG_Read (DWORD opnctx_arg, void *buffer, DWORD count)
SetLastError (ERROR_INVALID_ACCESS);
goto leave;
}
- if (rctx->hd == INVALID_HANDLE_VALUE || !rctx->assoc)
+ if (!rctx->assoc)
{
SetLastError (ERROR_BROKEN_PIPE);
goto leave;
@@ -490,7 +510,7 @@ GPG_Write (DWORD opnctx_arg, const void *buffer, DWORD count)
SetLastError (ERROR_INVALID_ACCESS);
goto leave;
}
- if (wctx->hd == INVALID_HANDLE_VALUE || !wctx->assoc)
+ if (!wctx->assoc)
{
SetLastError (ERROR_BROKEN_PIPE);
goto leave;
@@ -546,79 +566,78 @@ GPG_Seek (DWORD opnctx, long amount, WORD type)
static BOOL
-set_handle (opnctx_t opnctx, HANDLE hd)
-{
- log_debug (" set_handle(%p, hd=%p)\n", opnctx, hd);
- if (opnctx->hd != INVALID_HANDLE_VALUE)
- {
- SetLastError (ERROR_ALREADY_ASSIGNED);
- return FALSE;
- }
- opnctx->hd = hd;
- return TRUE;
-}
-
-static BOOL
-make_pipe (opnctx_t rctx, HANDLE hd)
+make_pipe (opnctx_t ctx, LONG rvid)
{
BOOL result = FALSE;
- opnctx_t wctx = NULL;
+ opnctx_t peerctx = NULL;
- log_debug (" make_pipe(%p, hd=%p)\n", rctx, hd);
- if (rctx->hd == INVALID_HANDLE_VALUE)
- {
- SetLastError (ERROR_NOT_READY);
- goto leave;
- }
- if (rctx->assoc)
+ log_debug (" make_pipe(%p, rvid=%ld)\n", ctx, rvid);
+ if (ctx->assoc)
{
SetLastError (ERROR_ALREADY_ASSIGNED);
goto leave;
}
- if (!(rctx->access_code & GENERIC_READ))
- {
- SetLastError (ERROR_INVALID_ACCESS);
- goto leave;
- }
- wctx = find_and_lock_opnctx (hd);
- if (!wctx)
+ peerctx = find_and_lock_opnctx (rvid);
+ if (!peerctx)
{
SetLastError (ERROR_NOT_FOUND);
goto leave;
}
- if (wctx == rctx)
+ if (peerctx == ctx)
{
SetLastError (ERROR_INVALID_TARGET_HANDLE);
goto leave;
}
- if (wctx->hd == INVALID_HANDLE_VALUE)
+ if (peerctx->assoc)
{
- SetLastError (ERROR_NOT_READY);
+ SetLastError (ERROR_ALREADY_ASSIGNED);
goto leave;
}
- if (wctx->assoc)
+
+ if ((ctx->access_code & GENERIC_READ))
{
- SetLastError (ERROR_ALREADY_ASSIGNED);
- goto leave;
+ /* Check that the peer is a write end. */
+ if (!(peerctx->access_code & GENERIC_WRITE))
+ {
+ SetLastError (ERROR_INVALID_ACCESS);
+ goto leave;
+ }
+ peerctx->space_available = CreateEvent (NULL, FALSE, FALSE, NULL);
+ peerctx->data_available = CreateEvent (NULL, FALSE, FALSE, NULL);
+
+ ctx->assoc = peerctx;
+ peerctx->assoc = ctx;
+ ctx->is_write = 0;
+ peerctx->is_write = 1;
+ result = TRUE;
+ }
+ else if ((ctx->access_code & GENERIC_WRITE))
+ {
+ /* Check that the peer is a read end. */
+ if (!(peerctx->access_code & GENERIC_READ))
+ {
+ SetLastError (ERROR_INVALID_ACCESS);
+ goto leave;
+ }
+ ctx->space_available = CreateEvent (NULL, FALSE, FALSE, NULL);
+ ctx->data_available = CreateEvent (NULL, FALSE, FALSE, NULL);
+
+ ctx->assoc = peerctx;
+ peerctx->assoc = ctx;
+ ctx->is_write = 1;
+ peerctx->is_write = 0;
+ result = TRUE;
}
- if (!(wctx->access_code & GENERIC_WRITE))
+ else
{
SetLastError (ERROR_INVALID_ACCESS);
goto leave;
}
- wctx->space_available = CreateEvent (NULL, FALSE, FALSE, NULL);
- wctx->data_available = CreateEvent (NULL, FALSE, FALSE, NULL);
-
- rctx->assoc = wctx;
- wctx->assoc = rctx;
- rctx->is_write = 0;
- wctx->is_write = 1;
- result = TRUE;
leave:
- if (wctx)
- unlock_opnctx (wctx);
+ if (peerctx)
+ unlock_opnctx (peerctx);
return result;
}
@@ -629,6 +648,7 @@ GPG_IOControl (DWORD opnctx_arg, DWORD code, void *inbuf, DWORD inbuflen,
{
opnctx_t opnctx = (opnctx_t)opnctx_arg;
BOOL result = FALSE;
+ LONG rvid;
log_debug ("GPG_IOControl(%p, %d)\n", (void*)opnctx, code);
if (!validate_and_lock_opnctx (opnctx, LOCK_TRY))
@@ -636,25 +656,28 @@ GPG_IOControl (DWORD opnctx_arg, DWORD code, void *inbuf, DWORD inbuflen,
switch (code)
{
- case GPGCEDEV_IOCTL_SET_HANDLE:
- if (!opnctx || !inbuf || inbuflen < sizeof (HANDLE)
- || outbuf || outbuflen || actualoutlen )
+ case GPGCEDEV_IOCTL_GET_RVID:
+ if (!opnctx || inbuf || inbuflen
+ || !outbuf || outbuflen < sizeof (LONG))
{
SetLastError (ERROR_INVALID_PARAMETER);
goto leave;
}
- if (set_handle (opnctx, *(HANDLE*)inbuf))
- result = TRUE;
+ memcpy (outbuf, &opnctx->rvid, sizeof (LONG));
+ if (actualoutlen)
+ *actualoutlen = sizeof (LONG);
+ result = TRUE;
break;
case GPGCEDEV_IOCTL_MAKE_PIPE:
- if (!opnctx || !inbuf || inbuflen < sizeof (HANDLE)
+ if (!opnctx || !inbuf || inbuflen < sizeof (LONG)
|| outbuf || outbuflen || actualoutlen )
{
SetLastError (ERROR_INVALID_PARAMETER);
goto leave;
}
- if (make_pipe (opnctx, *(HANDLE*)inbuf))
+ memcpy (&rvid, inbuf, sizeof (LONG));
+ if (make_pipe (opnctx, rvid))
result = TRUE;
break;
diff --git a/src/libassuan.def b/src/libassuan.def
index ba8ed8d..59aba41 100644
--- a/src/libassuan.def
+++ b/src/libassuan.def
@@ -99,6 +99,8 @@ EXPORTS
assuan_set_sock_nonce @78
_assuan_w32ce_create_pipe @79
assuan_free @80
+ _assuan_w32ce_prepare_pipe @81
+ _assuan_w32ce_finish_pipe @82
; END
diff --git a/src/mkheader.c b/src/mkheader.c
new file mode 100644
index 0000000..22cdc94
--- /dev/null
+++ b/src/mkheader.c
@@ -0,0 +1,192 @@
+/* mkheader.c - Create a header file for libassuan.
+ * Copyright (C) 2010 Free Software Foundation, Inc.
+ *
+ * This file is free software; as a special exception the author gives
+ * unlimited permission to copy and/or distribute it, with or without
+ * modifications, as long as this notice is preserved.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#define PGM "mkheader"
+
+#define LINESIZE 1024
+
+static const char *host_os;
+static char *srcdir;
+
+
+/* Include the file NAME form the source directory. The included file
+ is not further expanded. It may have comments indicated by a
+ double hash masrk at the begin of a line. */
+static void
+include_file (const char *fname, int lnr, const char *name)
+{
+ FILE *fp;
+ char *incfname;
+ char line[LINESIZE];
+
+ incfname = malloc (strlen (srcdir) + strlen (name) + 1);
+ if (!incfname)
+ {
+ fputs (PGM ": out of core\n", stderr);
+ exit (1);
+ }
+ strcpy (incfname, srcdir);
+ strcat (incfname, name);
+
+ fp = fopen (incfname, "r");
+ if (!fp)
+ {
+ fprintf (stderr, "%s:%d: error including `%s': %s\n",
+ fname, lnr, incfname, strerror (errno));
+ exit (1);
+ }
+
+ while (fgets (line, LINESIZE, fp))
+ {
+ if (line[0] != '#' && line[1] != '#')
+ fputs (line, stdout);
+ }
+ if (ferror (fp))
+ {
+ fprintf (stderr, "%s:%d: error reading `%s': %s\n",
+ fname, lnr, incfname, strerror (errno));
+ exit (1);
+ }
+ fclose (fp);
+ free (incfname);
+}
+
+
+static int
+write_special (const char *fname, int lnr, const char *tag)
+{
+ if (!strcmp (tag, "include:w32ce-add"))
+ {
+ if (!strcmp (host_os, "mingw32ce"))
+ include_file (fname, lnr, "w32ce-add.h");
+ }
+ else
+ return 0; /* Unknown tag. */
+
+ return 1; /* Tag processed. */
+}
+
+
+int
+main (int argc, char **argv)
+{
+ FILE *fp;
+ char line[LINESIZE];
+ int lnr = 0;
+ const char *fname, *s;
+ char *p1, *p2;
+
+ if (argc)
+ {
+ argc--; argv++;
+ }
+
+ if (argc != 2)
+ {
+ fputs ("usage: " PGM " host_os template.h\n", stderr);
+ return 1;
+ }
+ host_os = argv[0];
+ fname = argv[1];
+
+ srcdir = malloc (strlen (fname) + 2 + 1);
+ if (!srcdir)
+ {
+ fputs (PGM ": out of core\n", stderr);
+ return 1;
+ }
+ strcpy (srcdir, fname);
+ p1 = strrchr (srcdir, '/');
+ if (p1)
+ p1[1] = 0;
+ else
+ strcpy (srcdir, "./");
+
+ fp = fopen (fname, "r");
+ if (!fp)
+ {
+ fprintf (stderr, "%s:%d: can't open file: %s",
+ fname, lnr, strerror (errno));
+ return 1;
+ }
+
+ while (fgets (line, LINESIZE, fp))
+ {
+ size_t n = strlen (line);
+
+ lnr++;
+ if (!n || line[n-1] != '\n')
+ {
+ fprintf (stderr,
+ "%s:%d: trailing linefeed missing, line too long or "
+ "embedded Nul character", fname, lnr);
+ break;
+ }
+ line[--n] = 0;
+
+ p1 = strchr (line, '@');
+ p2 = p1? strchr (p1+1, '@') : NULL;
+ if (!p1 || !p2 || p2-p1 == 1)
+ {
+ puts (line);
+ continue;
+ }
+ *p1++ = 0;
+ *p2++ = 0;
+ fputs (line, stdout);
+
+ if (!strcmp (p1, "configure_input"))
+ {
+ s = strrchr (fname, '/');
+ printf ("Do not edit. Generated from %s by %s for %s.",
+ s? s+1 : fname, PGM, host_os);
+ }
+ else if (!write_special (fname, lnr, p1))
+ {
+ putchar ('@');
+ fputs (p1, stdout);
+ putchar ('@');
+ }
+
+ fputs (p2, stdout);
+ putchar ('\n');
+ }
+
+ if (ferror (fp))
+ {
+ fprintf (stderr, "%s:%d: error reading file: %s\n",
+ fname, lnr, strerror (errno));
+ return 1;
+ }
+
+ fputs ("/*\n"
+ "Local Variables:\n"
+ "buffer-read-only: t\n"
+ "End:\n"
+ "*/\n", stdout);
+
+ if (ferror (stdout))
+ {
+ fprintf (stderr, PGM ": error writing stdout: %s\n", strerror (errno));
+ return 1;
+ }
+
+ fclose (fp);
+
+ return 0;
+}
diff --git a/src/system-w32.c b/src/system-w32.c
index 31da194..85f0e40 100644
--- a/src/system-w32.c
+++ b/src/system-w32.c
@@ -64,6 +64,33 @@ __assuan_usleep (assuan_context_t ctx, unsigned int usec)
+/* Three simple wrappers, only used because thes function are named in
+ the def file. */
+HANDLE
+_assuan_w32ce_prepare_pipe (int *r_rvid, int write_end)
+{
+ (void)r_rvid;
+ (void)write_end;
+ return INVALID_HANDLE_VALUE;
+}
+
+HANDLE
+_assuan_w32ce_finish_pipe (int rvid, int write_end)
+{
+ (void)rvid;
+ (void)write_end;
+ return INVALID_HANDLE_VALUE;
+}
+
+DWORD
+_assuan_w32ce_create_pipe (HANDLE *read_hd, HANDLE *write_hd,
+ LPSECURITY_ATTRIBUTES sec_attr, DWORD size)
+{
+ return CreatePipe (read_hd, write_hd, sec_attr, size);
+}
+
+
+
/* Create a pipe with one inheritable end. Default implementation. */
int
__assuan_pipe (assuan_context_t ctx, assuan_fd_t fd[2], int inherit_idx)
diff --git a/src/system-w32ce.c b/src/system-w32ce.c
index ce0796c..1ecb4d8 100644
--- a/src/system-w32ce.c
+++ b/src/system-w32ce.c
@@ -27,26 +27,72 @@
#include <time.h>
#include <fcntl.h>
#include <windows.h>
+#include <winioctl.h>
+#include <devload.h>
#include "assuan-defs.h"
#include "debug.h"
+#define GPGCEDEV_IOCTL_GET_RVID \
+ CTL_CODE (FILE_DEVICE_STREAMS, 2048, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define GPGCEDEV_IOCTL_MAKE_PIPE \
+ CTL_CODE (FILE_DEVICE_STREAMS, 2049, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+
+
-assuan_fd_t
-assuan_fdopen (int fd)
+static wchar_t *
+utf8_to_wchar (const char *string)
{
- assuan_fd_t ifd = (assuan_fd_t)fd;
- assuan_fd_t ofd;
+ int n;
+ size_t nbytes;
+ wchar_t *result;
+
+ if (!string)
+ return NULL;
- if (! DuplicateHandle(GetCurrentProcess(), ifd,
- GetCurrentProcess(), &ofd, 0,
- TRUE, DUPLICATE_SAME_ACCESS))
+ n = MultiByteToWideChar (CP_UTF8, 0, string, -1, NULL, 0);
+ if (n < 0)
{
- gpg_err_set_errno (EIO);
- return ASSUAN_INVALID_FD;
+ gpg_err_set_errno (EINVAL);
+ return NULL;
+ }
+
+ nbytes = (size_t)(n+1) * sizeof(*result);
+ if (nbytes / sizeof(*result) != (n+1))
+ {
+ gpg_err_set_errno (ENOMEM);
+ return NULL;
+ }
+ result = malloc (nbytes);
+ if (!result)
+ return NULL;
+
+ n = MultiByteToWideChar (CP_UTF8, 0, string, -1, result, n);
+ if (n < 0)
+ {
+ free (result);
+ gpg_err_set_errno (EINVAL);
+ result = NULL;
}
- return ofd;
+ return result;
+}
+
+/* Convenience function. */
+static void
+free_wchar (wchar_t *string)
+{
+ if (string)
+ free (string);
+}
+
+
+
+assuan_fd_t
+assuan_fdopen (int fd)
+{
+ return (assuan_fd_t)fd;
}
@@ -56,60 +102,149 @@ assuan_fdopen (int fd)
void
__assuan_usleep (assuan_context_t ctx, unsigned int usec)
{
- if (!usec)
- return;
-
- Sleep (usec / 1000);
+ if (usec)
+ Sleep (usec / 1000);
}
-/* Create a pipe with one inheritable end. Default implementation. */
-int
-__assuan_pipe (assuan_context_t ctx, assuan_fd_t fd[2], int inherit_idx)
+/* Prepare a pipe. Returns a handle which is, depending on WRITE_END,
+ will either act the read or as the write end of the pipe. The
+ other value returned is a rendezvous id used to complete the pipe
+ creation with _assuan_w32ce_finish_pipe. The rendezvous id may be
+ passed to another process and that process may finish the pipe
+ creation. This creates the interprocess pipe. The rendezvous id
+ is not a handle but a plain number; there is no release function
+ and care should be taken not to pass it to a function expecting a
+ handle. */
+HANDLE
+_assuan_w32ce_prepare_pipe (int *r_rvid, int write_end)
{
- HANDLE rh;
- HANDLE wh;
- HANDLE th;
- SECURITY_ATTRIBUTES sec_attr;
+ HANDLE hd;
+ LONG rvid;
+
+ ActivateDevice (L"Drivers\\GnuPG_Device", 0);
+
+ /* Note: Using "\\$device\\GPG1" should be identical to "GPG1:".
+ However this returns an invalid parameter error without having
+ called GPG_Init in the driver. The docs mention something about
+ RegisterAFXEx but that API is not documented. */
+ hd = CreateFile (L"GPG1:", write_end? GENERIC_WRITE : GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hd != INVALID_HANDLE_VALUE)
+ {
+ if (!DeviceIoControl (hd, GPGCEDEV_IOCTL_GET_RVID,
+ NULL, 0, &rvid, sizeof rvid, NULL, NULL))
+ {
+ DWORD lastrc = GetLastError ();
+ CloseHandle (hd);
+ hd = INVALID_HANDLE_VALUE;
+ SetLastError (lastrc);
+ }
+ else
+ *r_rvid = rvid;
+ }
+
+ return hd;
+}
+
- memset (&sec_attr, 0, sizeof (sec_attr));
- sec_attr.nLength = sizeof (sec_attr);
- sec_attr.bInheritHandle = FALSE;
+/* Create a pipe. WRITE_END shall have the opposite value of the one
+ pssed to _assuan_w32ce_prepare_pipe; see there for more
+ details. */
+HANDLE
+_assuan_w32ce_finish_pipe (int rvid, int write_end)
+{
+ HANDLE hd;
- if (!CreatePipe (&rh, &wh, &sec_attr, 0))
+ hd = CreateFile (L"GPG1:", write_end? GENERIC_WRITE : GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL);
+ if (hd != INVALID_HANDLE_VALUE)
{
- TRACE1 (ctx, ASSUAN_LOG_SYSIO, "__assuan_pipe", ctx,
- "CreatePipe failed: %s", _assuan_w32_strerror (ctx, -1));
- gpg_err_set_errno (EIO);
- return -1;
+ if (!DeviceIoControl (hd, GPGCEDEV_IOCTL_MAKE_PIPE,
+ &rvid, sizeof rvid, NULL, 0, NULL, NULL))
+ {
+ DWORD lastrc = GetLastError ();
+ CloseHandle (hd);
+ hd = INVALID_HANDLE_VALUE;
+ SetLastError (lastrc);
+ }
+ }
+
+ return hd;
+}
+
+
+/* WindowsCE does not provide a pipe feature. However we need
+ something like a pipe to convey data between processes and in some
+ cases within a process. This replacement is not only used by
+ libassuan but exported and thus usable by gnupg and gpgme as well. */
+DWORD
+_assuan_w32ce_create_pipe (HANDLE *read_hd, HANDLE *write_hd,
+ LPSECURITY_ATTRIBUTES sec_attr, DWORD size)
+{
+ HANDLE hd[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE};
+ int rvid;
+ int rc = 0;
+
+ hd[0] = _assuan_w32ce_prepare_pipe (&rvid, 0);
+ if (hd[0] != INVALID_HANDLE_VALUE)
+ {
+ hd[1] = _assuan_w32ce_finish_pipe (rvid, 1);
+ if (hd[1] != INVALID_HANDLE_VALUE)
+ rc = 1;
+ else
+ {
+ DWORD lastrc = GetLastError ();
+ CloseHandle (hd[0]);
+ hd[0] = INVALID_HANDLE_VALUE;
+ SetLastError (lastrc);
+ }
}
+
+ *read_hd = hd[0];
+ *write_hd = hd[1];
+ return rc;
+}
+
- if (! DuplicateHandle (GetCurrentProcess(), (inherit_idx == 0) ? rh : wh,
- GetCurrentProcess(), &th, 0,
- TRUE, DUPLICATE_SAME_ACCESS ))
+/* Create a pipe with one inheritable end. Default implementation.
+ If INHERIT_IDX is 0, the read end of the pipe is made inheritable;
+ with INHERIT_IDX is 1 the write end will be inheritable. The
+ question now is how we create an inheritable pipe end under windows
+ CE were handles are process local objects? The trick we employ is
+ to defer the actual creation to the other end: We create an
+ incomplete pipe and pass a rendezvous id to the other end
+ (process). The other end now uses the rendezvous id to lookup the
+ pipe in our device driver, creates a new handle and uses that one
+ to finally establish the pipe. */
+int
+__assuan_pipe (assuan_context_t ctx, assuan_fd_t fd[2], int inherit_idx)
+{
+ HANDLE hd;
+ int rvid;
+
+ hd = _assuan_w32ce_prepare_pipe (&rvid, !inherit_idx);
+ if (hd == INVALID_HANDLE_VALUE)
{
TRACE1 (ctx, ASSUAN_LOG_SYSIO, "__assuan_pipe", ctx,
- "DuplicateHandle failed: %s", _assuan_w32_strerror (ctx, -1));
- CloseHandle (rh);
- CloseHandle (wh);
+ "CreatePipe failed: %s", _assuan_w32_strerror (ctx, -1));
gpg_err_set_errno (EIO);
return -1;
}
- if (inherit_idx == 0)
+
+ if (inherit_idx)
{
- CloseHandle (rh);
- rh = th;
+ fd[0] = hd;
+ fd[1] = (void*)rvid;
}
else
{
- CloseHandle (wh);
- wh = th;
+ fd[0] = (void*)rvid;
+ fd[1] = hd;
}
-
- fd[0] = rh;
- fd[1] = wh;
-
return 0;
}
@@ -143,9 +278,13 @@ __assuan_read (assuan_context_t ctx, assuan_fd_t fd, void *buffer, size_t size)
read if recv detects that it is not a network socket. */
int res;
+ TRACE_BEG3 (ctx, ASSUAN_LOG_SYSIO, "__assuan_read", ctx,
+ "fd=0x%x, buffer=%p, size=%i", fd, buffer, size);
+
res = recv (HANDLE2SOCKET (fd), buffer, size, 0);
if (res == -1)
{
+ TRACE_LOG1 ("recv failed: rc=%d", (int)WSAGetLastError ());
switch (WSAGetLastError ())
{
case WSAENOTSOCK:
@@ -155,6 +294,7 @@ __assuan_read (assuan_context_t ctx, assuan_fd_t fd, void *buffer, size_t size)
res = ReadFile (fd, buffer, size, &nread, NULL);
if (! res)
{
+ TRACE_LOG1 ("ReadFile failed: rc=%d", (int)GetLastError ());
switch (GetLastError ())
{
case ERROR_BROKEN_PIPE:
@@ -184,7 +324,7 @@ __assuan_read (assuan_context_t ctx, assuan_fd_t fd, void *buffer, size_t size)
break;
}
}
- return res;
+ return TRACE_SYSRES (res);
}
@@ -198,14 +338,19 @@ __assuan_write (assuan_context_t ctx, assuan_fd_t fd, const void *buffer,
write if send detects that it is not a network socket. */
int res;
- res = send (HANDLE2SOCKET (fd), buffer, size, 0);
+ TRACE_BEG3 (ctx, ASSUAN_LOG_SYSIO, "__assuan_write", ctx,
+ "fd=0x%x, buffer=%p, size=%i", fd, buffer, size);
+
+ res = send ((int)fd, buffer, size, 0);
if (res == -1 && WSAGetLastError () == WSAENOTSOCK)
{
DWORD nwrite;
+ TRACE_LOG ("send call failed - trying WriteFile");
res = WriteFile (fd, buffer, size, &nwrite, NULL);
if (! res)
{
+ TRACE_LOG1 ("WriteFile failed: rc=%d", (int)GetLastError ());
switch (GetLastError ())
{
case ERROR_BROKEN_PIPE:
@@ -222,7 +367,9 @@ __assuan_write (assuan_context_t ctx, assuan_fd_t fd, const void *buffer,
else
res = (int) nwrite;
}
- return res;
+ else if (res == -1)
+ TRACE_LOG1 ("send call failed: rc=%d", (int)GetLastError ());
+ return TRACE_SYSRES (res);
}
@@ -253,17 +400,43 @@ __assuan_sendmsg (assuan_context_t ctx, assuan_fd_t fd, assuan_msghdr_t msg,
CMDLINE gets the address of a newly allocated string. */
static int
build_w32_commandline (assuan_context_t ctx, const char * const *argv,
- char **cmdline)
+ assuan_fd_t fd0, assuan_fd_t fd1, assuan_fd_t fd2,
+ int fd2_isnull,
+ char **cmdline)
{
int i, n;
const char *s;
char *buf, *p;
+ char fdbuf[3*30];
+ p = fdbuf;
+ *p = 0;
+ if (fd0 != ASSUAN_INVALID_FD)
+ {
+ snprintf (p, 25, "-&S0=%d ", (int)fd0);
+ p += strlen (p);
+ }
+ if (fd1 != ASSUAN_INVALID_FD)
+ {
+ snprintf (p, 25, "-&S1=%d ", (int)fd1);
+ p += strlen (p);
+ }
+ if (fd2 != ASSUAN_INVALID_FD)
+ {
+ if (fd2_isnull)
+ strcpy (p, "-&S2=null ");
+ else
+ snprintf (p, 25, "-&S2=%d ", (int)fd2);
+ p += strlen (p);
+ }
+
*cmdline = NULL;
- n = 0;
+ n = strlen (fdbuf);
for (i=0; (s = argv[i]); i++)
{
- n += strlen (s) + 1 + 2; /* (1 space, 2 quoting */
+ if (!i)
+ continue; /* Ignore argv[0]. */
+ n += strlen (s) + 1 + 2; /* (1 space, 2 quoting) */
for (; *s; s++)
if (*s == '\"')
n++; /* Need to double inner quotes. */
@@ -274,10 +447,14 @@ build_w32_commandline (assuan_context_t ctx, const char * const *argv,
if (! buf)
return -1;
+ p = stpcpy (p, fdbuf);
for (i = 0; argv[i]; i++)
{
- if (i)
+ if (!i)
+ continue; /* Ignore argv[0]. */
+ if (i > 1)
p = stpcpy (p, " ");
+
if (! *argv[i]) /* Empty string. */
p = stpcpy (p, "\"\"");
else if (strpbrk (argv[i], " \t\n\v\f\""))
@@ -296,7 +473,7 @@ build_w32_commandline (assuan_context_t ctx, const char * const *argv,
p = stpcpy (p, argv[i]);
}
- *cmdline= buf;
+ *cmdline = buf;
return 0;
}
@@ -309,7 +486,6 @@ __assuan_spawn (assuan_context_t ctx, pid_t *r_pid, const char *name,
void (*atfork) (void *opaque, int reserved),
void *atforkvalue, unsigned int flags)
{
- SECURITY_ATTRIBUTES sec_attr;
PROCESS_INFORMATION pi =
{
NULL, /* Returns process handle. */
@@ -317,117 +493,95 @@ __assuan_spawn (assuan_context_t ctx, pid_t *r_pid, const char *name,
0, /* Returns pid. */
0 /* Returns tid. */
};
- STARTUPINFO si;
assuan_fd_t fd;
assuan_fd_t *fdp;
+ assuan_fd_t fd_err;
+ int fd_err_isnull = 0;
char *cmdline;
- HANDLE nullfd = INVALID_HANDLE_VALUE;
-
- /* fixme: Actually we should set the "_assuan_pipe_connect_pid" env
- variable. However this requires us to write a full environment
- handler, because the strings are expected in sorted order. The
- suggestion given in the MS Reference Library, to save the old
- value, changeit, create proces and restore it, is not thread
- safe. */
- /* Build the command line. */
- if (build_w32_commandline (ctx, argv, &cmdline))
- return -1;
+ /* Dup stderr to /dev/null unless it is in the list of FDs to be
+ passed to the child. Well we don't actually open nul because
+ that is not available on Windows, but use our hack for it.
+ Because an RVID of 0 is an invalid value and HANDLES will never
+ have this value either, we test for this as well. */
- /* Start the process. */
- memset (&sec_attr, 0, sizeof sec_attr);
- sec_attr.nLength = sizeof sec_attr;
- sec_attr.bInheritHandle = FALSE;
-
- memset (&si, 0, sizeof si);
- si.cb = sizeof (si);
- si.dwFlags = STARTF_USESTDHANDLES;
- /* FIXME: Dup to nul if ASSUAN_INVALID_FD. */
- si.hStdInput = fd_in;
- si.hStdOutput = fd_out;
+ /* FIXME: CHECKOUT WHAT TO DO WITH STDERR HERE. WE NEED TO DEFINE
+ WHETHER THE FD_CHILD_LIST HAS HANDLES OR RENDEZVOUS IDS. */
- /* Dup stderr to /dev/null unless it is in the list of FDs to be
- passed to the child. */
fd = assuan_fd_from_posix_fd (fileno (stderr));
fdp = fd_child_list;
if (fdp)
{
- for (; *fdp != ASSUAN_INVALID_FD && *fdp != fd; fdp++)
+ for (; *fdp != ASSUAN_INVALID_FD && *fdp != 0 && *fdp != fd; fdp++)
;
}
if (!fdp || *fdp == ASSUAN_INVALID_FD)
+ fd_err_isnull = 1;
+ fd_err = fd;
+
+ if (build_w32_commandline (ctx, argv, fd_in, fd_out, fd_err, fd_err_isnull,
+ &cmdline))
{
- nullfd = CreateFileW (L"nul", GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, 0, NULL);
- if (nullfd == INVALID_HANDLE_VALUE)
- {
- TRACE1 (ctx, ASSUAN_LOG_SYSIO, "__assuan_spawn", ctx,
- "can't open `nul': %s", _assuan_w32_strerror (ctx, -1));
- _assuan_free (ctx, cmdline);
- gpg_err_set_errno (EIO);
- return -1;
- }
- si.hStdError = nullfd;
+ return -1;
}
- else
- si.hStdError = fd;
-
- /* 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. */
- /* _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
- | CREATE_SUSPENDED), /* Creation flags. */
- NULL, /* Environment. */
- NULL, /* Use current drive/directory. */
- &si, /* Startup information. */
- &pi /* Returns process information. */
- ))
- {
- TRACE1 (ctx, ASSUAN_LOG_SYSIO, "pipe_connect_w32", ctx,
- "CreateProcess failed: %s", _assuan_w32_strerror (ctx, -1));
- _assuan_free (ctx, cmdline);
- if (nullfd != INVALID_HANDLE_VALUE)
- CloseHandle (nullfd);
- gpg_err_set_errno (EIO);
+ TRACE2 (ctx, ASSUAN_LOG_SYSIO, "__assuan_spawn", ctx,
+ "path=`%s' cmdline=`%s'", name, cmdline);
+
+ {
+ wchar_t *wcmdline, *wname;
+
+ wcmdline = utf8_to_wchar (cmdline);
+ _assuan_free (ctx, cmdline);
+ if (!wcmdline)
return -1;
- }
- _assuan_free (ctx, cmdline);
- if (nullfd != INVALID_HANDLE_VALUE)
- CloseHandle (nullfd);
+ wname = utf8_to_wchar (name);
+ if (!wname)
+ {
+ free_wchar (wcmdline);
+ return -1;
+ }
+
+ if (!CreateProcess (wname, /* Program to start. */
+ wcmdline, /* Command line arguments. */
+ NULL, /* (not supported) */
+ NULL, /* (not supported) */
+ FALSE, /* (not supported) */
+ (CREATE_SUSPENDED), /* Creation flags. */
+ NULL, /* (not supported) */
+ NULL, /* (not supported) */
+ NULL, /* (not supported) */
+ &pi /* Returns process information.*/
+ ))
+ {
+ TRACE1 (ctx, ASSUAN_LOG_SYSIO, "__assuan_spawn", ctx,
+ "CreateProcess failed: %s", _assuan_w32_strerror (ctx, -1));
+ free_wchar (wname);
+ free_wchar (wcmdline);
+ gpg_err_set_errno (EIO);
+ return -1;
+ }
+ free_wchar (wname);
+ free_wchar (wcmdline);
+ }
ResumeThread (pi.hThread);
- CloseHandle (pi.hThread);
- /* _assuan_log_printf ("CreateProcess ready: hProcess=%p hThread=%p" */
- /* " dwProcessID=%d dwThreadId=%d\n", */
- /* pi.hProcess, pi.hThread, */
- /* (int) pi.dwProcessId, (int) pi.dwThreadId); */
+ TRACE4 (ctx, ASSUAN_LOG_SYSIO, "__assuan_spawn", ctx,
+ "CreateProcess ready: hProcess=%p hThread=%p"
+ " dwProcessID=%d dwThreadId=%d\n",
+ pi.hProcess, pi.hThread, (int) pi.dwProcessId, (int) pi.dwThreadId);
+ CloseHandle (pi.hThread);
+
*r_pid = (pid_t) pi.hProcess;
-
- /* No need to modify peer process, as we don't change the handle
- names. However this also means we are not safe, as we inherit
- too many handles. Should use approach similar to gpgme and glib
- using a helper process. */
-
return 0;
}
-/* FIXME: Add some sort of waitpid function that covers GPGME and
- gpg-agent's use of assuan. */
static pid_t
__assuan_waitpid (assuan_context_t ctx, pid_t pid, int nowait,
int *status, int options)
@@ -446,6 +600,7 @@ __assuan_socketpair (assuan_context_t ctx, int namespace, int style,
return -1;
}
+
/* The default system hooks for assuan contexts. */
struct assuan_system_hooks _assuan_system_hooks =
diff --git a/src/system.c b/src/system.c
index 22d7a0b..1f180e9 100644
--- a/src/system.c
+++ b/src/system.c
@@ -170,6 +170,22 @@ _assuan_close (assuan_context_t ctx, assuan_fd_t fd)
}
+/* Same as assuan_close but used for the inheritable end of a
+ pipe. */
+int
+_assuan_close_inheritable (assuan_context_t ctx, assuan_fd_t fd)
+{
+ TRACE1 (ctx, ASSUAN_LOG_SYSIO, "_assuan_close", ctx,
+ "fd=0x%x", fd);
+
+#ifdef HAVE_W32CE_SYSTEM
+ return 0; /* Nothing to do because it is a rendezvous id. */
+#else
+ return (ctx->system.close) (ctx, fd);
+#endif
+}
+
+
ssize_t
_assuan_read (assuan_context_t ctx, assuan_fd_t fd, void *buffer, size_t size)
diff --git a/src/sysutils.c b/src/sysutils.c
index c7e20a8..1760f44 100644
--- a/src/sysutils.c
+++ b/src/sysutils.c
@@ -34,17 +34,9 @@
#include "assuan-defs.h"
-#ifdef HAVE_W32CE_SYSTEM
-#define GPGCEDEV_IOCTL_SET_HANDLE \
- CTL_CODE (FILE_DEVICE_STREAMS, 2048, METHOD_BUFFERED, FILE_ANY_ACCESS)
-#define GPGCEDEV_IOCTL_MAKE_PIPE \
- CTL_CODE (FILE_DEVICE_STREAMS, 2049, METHOD_BUFFERED, FILE_ANY_ACCESS)
-#endif /*HAVE_W32CE_SYSTEM*/
-
-
/* This is actually a dummy function to make sure that is module is
- not empty. Sokme compilers barf on that. */
+ not empty. Some compilers barf on empty modules. */
const char *
_assuan_sysutils_blurb (void)
{
@@ -141,74 +133,3 @@ _assuan_getenv (const char *name)
}
#endif /*HAVE_W32CE_SYSTEM*/
-
-#ifdef HAVE_W32_SYSTEM
-/* WindowsCE does not provide a pipe feature. However we need
- something like a pipe to convey data between processes and in some
- cases within a process. This replacement is not only used by
- libassuan but exported and thus usable by gnupg and gpgme as well. */
-DWORD
-_assuan_w32ce_create_pipe (HANDLE *read_hd, HANDLE *write_hd,
- LPSECURITY_ATTRIBUTES sec_attr, DWORD size)
-{
-#ifdef HAVE_W32CE_SYSTEM
- HANDLE hd[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE};
-
- *read_hd = *write_hd = INVALID_HANDLE_VALUE;
-
- ActivateDevice (L"Drivers\\GnuPG_Device", 0);
-
- /* Note: Using "\\$device\\GPG1" should be identical to "GPG1:".
- However this returns an invalid parameter error without having
- called GPG_Init in the driver. The docs mention something about
- RegisterAFXEx but that API is not documented. */
- hd[0] = CreateFile (L"GPG1:", GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (hd[0] == INVALID_HANDLE_VALUE)
- return 0;
-
- if (!DeviceIoControl (hd[0], GPGCEDEV_IOCTL_SET_HANDLE,
- &hd[0], sizeof hd[0], NULL, 0, NULL, NULL))
- fprintf (stderr, "GPGCEDEV_IOCTL_SET_HANDLE(0) failed: %d\n",
- (int)GetLastError ());
-
- hd[1] = CreateFile (L"GPG1:", GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL);
- if (hd[1] == INVALID_HANDLE_VALUE)
- {
- DWORD lasterr = GetLastError ();
- CloseHandle (hd[0]);
- SetLastError (lasterr);
- return 0;
- }
- if (!DeviceIoControl (hd[1], GPGCEDEV_IOCTL_SET_HANDLE,
- &hd[1], sizeof hd[1], NULL, 0, NULL, NULL))
- fprintf (stderr, "GPGCEDEV_IOCTL_SET_HANDLE(1) failed: %d\n",
- (int)GetLastError ());
-
- if (!DeviceIoControl (hd[0], GPGCEDEV_IOCTL_MAKE_PIPE,
- &hd[1], sizeof hd[1], NULL, 0, NULL, NULL))
- {
- fprintf (stderr, "GPGCEDEV_IOCTL_MAKE_PIPE failed: %d\n",
- (int)GetLastError ());
- if (hd[0] != INVALID_HANDLE_VALUE)
- CloseHandle (hd[0]);
- if (hd[1] != INVALID_HANDLE_VALUE)
- CloseHandle (hd[1]);
- return 0;
- }
- else
- {
- *read_hd = hd[0];
- *write_hd = hd[1];
- return 1;
- }
-#else /*!HAVE_W32CE_SYSTEM*/
- return CreatePipe (read_hd, write_hd, sec_attr, size);
-#endif /*!HAVE_W32CE_SYSTEM*/
-}
-
-#endif /*!HAVE_W32_SYSTEM*/
-