diff options
Diffstat (limited to 'src/sysutils.c')
-rw-r--r-- | src/sysutils.c | 84 |
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*/ + |