aboutsummaryrefslogtreecommitdiffstats
path: root/src/sysutils.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sysutils.c')
-rw-r--r--src/sysutils.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/sysutils.c b/src/sysutils.c
index 448f803..c7e20a8 100644
--- a/src/sysutils.c
+++ b/src/sysutils.c
@@ -26,10 +26,22 @@
#include <stdarg.h>
#ifdef HAVE_W32_SYSTEM
#include <windows.h>
+# ifdef HAVE_W32CE_SYSTEM
+# include <winioctl.h>
+# include <devload.h>
+# endif /*HAVE_W32CE_SYSTEM*/
#endif /*HAVE_W32_SYSTEM*/
#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. */
@@ -128,3 +140,75 @@ _assuan_getenv (const char *name)
return NULL;
}
#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*/
+