summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2022-08-31 14:18:24 +0900
committerNIIBE Yutaka <gniibe@fsij.org>2022-08-31 14:29:02 +0900
commite3b1e3857e00c6e8216e953b0b38f4dcda00cd53 (patch)
treeac7b2d6542c56903847d21b8e50367dd9a0beca4
parent6da6a3df3c98552c710616d40e245467c3fe675c (diff)
downloadlibassuan-e3b1e3857e00c6e8216e953b0b38f4dcda00cd53.tar.gz
Drop WindowsCE support.
* contrib/*: Remove. * Makefile.am (EXTRA_DIST): Don't include contrib/. * configure.ac (HAVE_W32CE_SYSTEM): Remove. * src/gpgcedev.c: Remove. * src/gpgcedev.def: Remove. * src/gpgcemgr.c: Remove. * src/system-w32ce.c: Remove. * src/w32ce-add.h: Remove. * src/w32ce-fd-t.inc.h: Remove. * src/Makefile.am (EXTRA_DIST, parts_of_assuan_h, common_sources): Fix. * src/assuan-buffer.c [HAVE_W32CE_SYSTEM]: No conditionalize. * src/setenv.c [HAVE_W32CE_SYSTEM]: Likewise. * src/assuan-defs.h [HAVE_W32CE_SYSTEM]: Remove dependent part. * src/assuan-error.c [HAVE_W32CE_SYSTEM]: Likewise. * src/assuan-handler.c [HAVE_W32CE_SYSTEM]: Likewise. * src/assuan-socket.c [HAVE_W32CE_SYSTEM]: Likewise. * src/system.c [HAVE_W32CE_SYSTEM]: Likewise. * src/sysutils.c [HAVE_W32CE_SYSTEM]: Likewise. * tests/Makefile.am (EXTRA_DIST): Fix. (w32cetools): Remove. * tests/common.h [HAVE_W32CE_SYSTEM]: Remove dependent part. * tests/pipeconnect.c [HAVE_W32CE_SYSTEM]: Likewise. * tests/ce-createpipe.c: Remove. * tests/ce-server.c: Remove. -- GnuPG-bug-id: 6170 Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
-rw-r--r--Makefile.am2
-rw-r--r--NEWS2
-rw-r--r--configure.ac21
-rw-r--r--contrib/ChangeLog-201129
-rwxr-xr-xcontrib/conf-w32ce-msc/build.mk169
-rw-r--r--contrib/conf-w32ce-msc/config.h188
-rwxr-xr-xcontrib/conf-w32ce-msc/stdint.h9
-rw-r--r--src/Makefile.am29
-rw-r--r--src/assuan-buffer.c2
-rw-r--r--src/assuan-defs.h9
-rw-r--r--src/assuan-error.c5
-rw-r--r--src/assuan-handler.c24
-rw-r--r--src/assuan-socket.c2
-rw-r--r--src/gpgcedev.c1640
-rw-r--r--src/gpgcedev.def34
-rw-r--r--src/gpgcemgr.c608
-rw-r--r--src/setenv.c4
-rw-r--r--src/system-w32ce.c706
-rw-r--r--src/system.c4
-rw-r--r--src/sysutils.c87
-rw-r--r--src/w32ce-add.h34
-rw-r--r--src/w32ce-fd-t.inc.h33
-rw-r--r--tests/Makefile.am6
-rw-r--r--tests/ce-createpipe.c179
-rw-r--r--tests/ce-server.c1418
-rw-r--r--tests/common.h5
-rw-r--r--tests/pipeconnect.c50
27 files changed, 11 insertions, 5288 deletions
diff --git a/Makefile.am b/Makefile.am
index 11e4696..0da00ea 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -27,7 +27,7 @@ GITLOG_TO_CHANGELOG=gitlog-to-changelog
EXTRA_DIST = autogen.sh autogen.rc README.GIT VERSION \
ChangeLog-2011 doc/ChangeLog-2011 src/ChangeLog-2011 \
- tests/ChangeLog-2011 contrib/ChangeLog-2011 \
+ tests/ChangeLog-2011 \
build-aux/git-log-footer build-aux/git-log-fix
if BUILD_DOC
diff --git a/NEWS b/NEWS
index 0ed6e87..dc04e8f 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,8 @@ Noteworthy changes in version 2.5.6 (unreleased) [C8/A8/R_]
* Use of ASSUAN_SYSTEM_NPTH is deprecated. Instead, please use
the gpgrt_set_syscall_clamp function from gpgrt library.
+ * No support for WindowsCE, any more.
+
Noteworthy changes in version 2.5.5 (2021-03-22) [C8/A8/R5]
------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 29c66dd..b5c2cc7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -156,9 +156,6 @@ AH_TOP([
#ifndef _ASSUAN_CONFIG_H_INCLUDED
#define _ASSUAN_CONFIG_H_INCLUDED
-/* Enable gpg-error's strerror macro under W32CE. */
-#define GPG_ERR_ENABLE_ERRNO_MACROS 1
-
/* Provide the es_ macro for estream. */
#define GPGRT_ENABLE_ES_MACROS 1
@@ -213,7 +210,6 @@ fi
have_dosish_system=no
have_w32_system=no
have_w64_system=no
-have_w32ce_system=no
case "${host}" in
*-linux*)
if test "$GCC" = yes; then
@@ -225,11 +221,6 @@ case "${host}" in
have_w32_system=yes
have_w64_system=yes
;;
- *-mingw32ce*)
- have_dosish_system=yes
- have_w32_system=yes
- have_w32ce_system=yes
- ;;
*-mingw32*)
have_dosish_system=yes
have_w32_system=yes
@@ -254,13 +245,9 @@ if test "$have_w32_system" = yes; then
AC_DEFINE(HAVE_W64_SYSTEM,1,
[Defined if we run on a 64 bit W32 API based system])
fi
- if test "$have_w32ce_system" = yes; then
- AC_DEFINE(HAVE_W32CE_SYSTEM,1,[Defined if we run on WindowsCE])
- fi
AC_CHECK_HEADERS([winsock2.h])
fi
AM_CONDITIONAL(HAVE_W32_SYSTEM, test "$have_w32_system" = yes)
-AM_CONDITIONAL(HAVE_W32CE_SYSTEM, test "$have_w32ce_system" = yes)
AM_CONDITIONAL(HAVE_W64_SYSTEM, test "$have_w64_system" = yes)
@@ -302,12 +289,8 @@ AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt,
AC_SUBST(NETLIBS)
if test "$have_w32_system" = yes; then
- if test "$have_w32ce_system" = yes; then
- NETLIBS="-lws2 $NETLIBS"
- else
- # FIXME: Check why we need to use ws2_32 and document that.
- NETLIBS="-lws2_32 $NETLIBS"
- fi
+ # FIXME: Check why we need to use ws2_32 and document that.
+ NETLIBS="-lws2_32 $NETLIBS"
fi
#
diff --git a/contrib/ChangeLog-2011 b/contrib/ChangeLog-2011
deleted file mode 100644
index 65306e3..0000000
--- a/contrib/ChangeLog-2011
+++ /dev/null
@@ -1,29 +0,0 @@
-2011-12-01 Werner Koch <wk@g10code.com>
-
- NB: ChangeLog files are no longer manually maintained. Starting
- on December 1st, 2011 we put change information only in the GIT
- commit log, and generate a top-level ChangeLog file from logs at
- "make dist". See doc/HACKING for details.
-
-2010-11-15 Marcus Brinkmann <mb@g10code.com>
-
- * conf-w32ce-msc/stdint.h: New file.
- * conf-w32ce-msc/build.mk (conf_sources): Add stdint.h.
- (copy-static-source): Revert last change.
-
-2010-11-15 Werner Koch <wk@g10code.com>
-
- * conf-w32ce-msc/config.h (strdup, strcasecmp): Add macros.
-
- * conf-w32ce-msc/build.mk (copy-static-source): Create stdint.h.
- (all): Add ws2.lib
- (clean): New.
-
-2010-11-02 Werner Koch <wk@g10code.com>
-
- * conf-w32ce-msc/build.mk: Change directory layout.
-
-2010-11-01 Werner Koch <wk@g10code.com>
-
- * conf-w32ce-msc/build.mk: New.
- * conf-w32ce-msc/config.h: New.
diff --git a/contrib/conf-w32ce-msc/build.mk b/contrib/conf-w32ce-msc/build.mk
deleted file mode 100755
index 70b9634..0000000
--- a/contrib/conf-w32ce-msc/build.mk
+++ /dev/null
@@ -1,169 +0,0 @@
-# build.mk - Makefile to build libgpg-error using Visual-C
-# Copyright 2010 g10 Code GmbH
-#
-# 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.
-
-# This is a helper make script to build libgpg-error for WindowsCE
-# using the Microsoft Visual C compiler.
-
-# The target build directory where we run the Visual C compiler/ This
-# needs to be an absolute directory name. Further we expect this
-# structure of the tree:
-#
-# TARGET/src - Source directories: One directory for each project
-# /bin - Installed DLLs
-# /lib - Installed import libs.
-# /include - Instaled header files.
-
-targetdir = /home/smb/xppro-gnu
-targetsrc = $(targetdir)/src
-
-# Install directories (relative)
-bindir = ../../../bin
-libdir = ../../../lib
-incdir = ../../../include
-
-help:
- @echo "Run "
- @echo " make -f ../contrib/conf-w32ce-msc/build.mk copy-source"
- @echo "on the POSIX system and then"
- @echo " nmake -f build.mk all"
- @echo " nmake -f build.mk install"
- @echo "on the Windows system"
-
-ce_defines = -DWINCE -D_WIN32_WCE=0x502 -DUNDER_CE \
- -DWIN32_PLATFORM_PSPC -D_UNICODE -DUNICODE \
- -D_CONSOLE -DARM -D_ARM_
-#-D_DEBUG -DDEBUG
-
-# See libgpg-error's build-mk for a list of compiler options.
-CFLAGS = -nologo -W3 -fp:fast -Os $(ce_defines) \
- -DHAVE_CONFIG_H -DDLL_EXPORT -D_CRT_SECURE_NO_WARNINGS \
- -I. -I$(incdir) -I$(incdir)/gpg-extra
-
-LDFLAGS =
-
-# Standard source files
-sources = \
- assuan.c \
- context.c \
- system.c \
- debug.c \
- conversion.c \
- sysutils.c \
- client.c \
- server.c \
- assuan-error.c \
- assuan-buffer.c \
- assuan-handler.c \
- assuan-inquire.c \
- assuan-listen.c \
- assuan-pipe-server.c \
- assuan-socket-server.c \
- assuan-pipe-connect.c \
- assuan-socket-connect.c \
- assuan-uds.c \
- assuan-logging.c \
- assuan-socket.c \
- system-w32ce.c \
- assuan-io.c \
- putc_unlocked.c \
- memrchr.c \
- stpcpy.c \
- setenv.c \
- vasprintf.c \
- assuan-defs.h \
- debug.h \
- libassuan.def
-
-# The object files we need to create from sources.
-objs = \
- assuan.obj \
- context.obj \
- system.obj \
- debug.obj \
- conversion.obj \
- sysutils.obj \
- client.obj \
- server.obj \
- assuan-error.obj \
- assuan-buffer.obj \
- assuan-handler.obj \
- assuan-inquire.obj \
- assuan-listen.obj \
- assuan-pipe-server.obj \
- assuan-socket-server.obj \
- assuan-pipe-connect.obj \
- assuan-socket-connect.obj \
- assuan-uds.obj \
- assuan-logging.obj \
- assuan-socket.obj \
- system-w32ce.obj \
- assuan-io.obj \
- putc_unlocked.obj \
- memrchr.obj \
- stpcpy.obj \
- setenv.obj \
- vasprintf.obj
-
-
-# Sources files in this directory inclduing this Makefile
-conf_sources = \
- build.mk \
- config.h \
- stdint.h
-
-# Source files built by running the standard build system.
-built_sources = \
- assuan.h
-
-
-copy-static-source:
- @if [ ! -f ./assuan-defs.h ]; then \
- echo "Please cd to the src/ directory first"; \
- exit 1; \
- fi
- cp -t $(targetsrc)/libassuan/src $(sources);
- cd ../contrib/conf-w32ce-msc ; \
- cp -t $(targetsrc)/libassuan/src $(conf_sources)
-
-
-copy-built-source:
- @if [ ! -f ./assuan.h ]; then \
- echo "Please build using ./autogen.sh --build-w32ce first"; \
- exit 1; \
- fi
- cp -t $(targetsrc)/libassuan/src $(built_sources)
-
-copy-source: copy-static-source copy-built-source
-
-
-.c.obj:
- $(CC) $(CFLAGS) -c $<
-
-all: $(sources) $(conf_sources) $(built_sources) $(objs)
- link /DLL /IMPLIB:libassuan-0-msc.lib \
- /OUT:libassuan-0-msc.dll \
- /DEF:libassuan.def /NOLOGO /MANIFEST:NO \
- /NODEFAULTLIB:"oldnames.lib" /DYNAMICBASE:NO \
- $(objs) $(libdir)/libgpg-error-0-msc.lib \
- coredll.lib corelibc.lib ole32.lib oleaut32.lib uuid.lib \
- commctrl.lib ws2.lib /subsystem:windowsce,5.02
-
-# Note that we don't need to create the install directories because
-# libgpg-error must have been build and installed prior to this
-# package.
-install: all
- copy /y libassuan-0-msc.dll $(bindir:/=\)
- copy /y libassuan-0-msc.lib $(libdir:/=\)
- copy /y assuan.h $(incdir:/=\)
-
-clean:
- del *.obj libassuan-0-msc.lib libassuan-0-msc.dll libassuan-0-msc.exp
-
diff --git a/contrib/conf-w32ce-msc/config.h b/contrib/conf-w32ce-msc/config.h
deleted file mode 100644
index c247377..0000000
--- a/contrib/conf-w32ce-msc/config.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/* config.h for building with Visual-C for WindowsCE.
- * Copyright 2010 g10 Code GmbH
- *
- * 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.
- */
-
-/* This file was originally created by running
- * ./autogen.sh --build-w32ce
- * on svn revision 389 (libassuan 2.0.2-svn389) and then adjusted to work
- * with Visual-C.
- */
-
-#ifndef _ASSUAN_CONFIG_H_INCLUDED
-#define _ASSUAN_CONFIG_H_INCLUDED
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "2.0.2-svn389-msc1"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "libassuan " PACKAGE_VERSION
-
-/* Name of this package */
-#define PACKAGE "libassuan"
-
-/* Bug report address */
-#define PACKAGE_BUGREPORT "bug-libassuan@gnupg.org"
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "libassuan"
-
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "libassuan"
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL ""
-
-/* Version of this package */
-#define VERSION PACKAGE_VERSION
-
-
-/* Enable gpg-error's strerror macro under W32CE. */
-#define GPG_ERR_ENABLE_ERRNO_MACROS 1
-
-
-/* Define to 1 if you have the declaration of `sys_siglist', and to 0 if you
- don't. */
-#define HAVE_DECL_SYS_SIGLIST 0
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-/* #undef HAVE_DLFCN_H */
-
-/* Defined if we run on some of the PCDOS like systems (DOS, Windoze. OS/2)
- with special properties like no file modes */
-#define HAVE_DOSISH_SYSTEM 1
-
-/* Define to 1 if you have the `flockfile' function. */
-/* #undef HAVE_FLOCKFILE */
-
-/* Define to 1 if you have the `fopencookie' function. */
-/* #undef HAVE_FOPENCOOKIE */
-
-/* Define to 1 if you have the `funlockfile' function. */
-/* #undef HAVE_FUNLOCKFILE */
-
-/* Define to 1 if you have the `funopen' function. */
-/* #undef HAVE_FUNOPEN */
-
-/* Define to 1 if you have the `inet_pton' function. */
-/* #undef HAVE_INET_PTON */
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-/* #undef HAVE_INTTYPES_H */
-
-/* Define to 1 if you have the `isascii' function. */
-#define HAVE_ISASCII 1
-
-/* Define to 1 if you have the <locale.h> header file. */
-/* #undef HAVE_LOCALE_H */
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the `memrchr' function. */
-/* #undef HAVE_MEMRCHR */
-
-/* Define to 1 if you have the `nanosleep' function in libc. */
-/* #undef HAVE_NANOSLEEP */
-
-/* Define to 1 if you have the `putc_unlocked' function. */
-/* #undef HAVE_PUTC_UNLOCKED */
-
-/* Define to 1 if you have the `setenv' function. */
-/* #undef HAVE_SETENV */
-
-/* Defined if SO_PEERCRED is supported (Linux specific) */
-/* #undef HAVE_SO_PEERCRED */
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the `stpcpy' function. */
-/* #undef HAVE_STPCPY */
-
-/* Define to 1 if you have the <strings.h> header file. */
-/* #undef HAVE_STRINGS_H */
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/socket.h> header file. */
-/* #undef HAVE_SYS_SOCKET_H */
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-/* #undef HAVE_SYS_STAT_H */
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-/* #undef HAVE_SYS_TYPES_H */
-
-/* Define to 1 if you have the <sys/uio.h> header file. */
-/* #undef HAVE_SYS_UIO_H */
-
-/* Define to 1 if the system has the type `uintptr_t'. */
-#define HAVE_UINTPTR_T 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-/* #undef HAVE_UNISTD_H */
-
-/* Define to 1 if you have the `vasprintf' function. */
-/* #undef HAVE_VASPRINTF */
-
-/* Defined if we run on WindowsCE */
-#define HAVE_W32CE_SYSTEM 1
-
-/* Defined if we run on a W32 API based system */
-#define HAVE_W32_SYSTEM 1
-
-/* Define to 1 if you have the <winsock2.h> header file. */
-#define HAVE_WINSOCK2_H 1
-
-/* Define to 1 if you have the <ws2tcpip.h> header file. */
-#define HAVE_WS2TCPIP_H 1
-
-/* Define to 1 if your C compiler doesn't accept -c and -o together. */
-/* #undef NO_MINUS_C_MINUS_O */
-
-/* Define as the return type of signal handlers (`int' or `void'). */
-#define RETSIGTYPE void
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Defined if descriptor passing is supported */
-/* #undef USE_DESCRIPTOR_PASSING */
-
-/* Enable extensions on AIX 3, Interix. */
-#ifndef _ALL_SOURCE
-# define _ALL_SOURCE 1
-#endif
-/* Enable GNU extensions on systems that have them. */
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE 1
-#endif
-/* Enable threading extensions on Solaris. */
-#ifndef _POSIX_PTHREAD_SEMANTICS
-# define _POSIX_PTHREAD_SEMANTICS 1
-#endif
-
-
-/* snprintf is not part of oldnames.lib thus we redefine it here. */
-#define snprintf _snprintf
-
-/* We also need to define these functions. */
-#define strdup _strdup
-#define strcasecmp _stricmp
-
-
-#endif /*_ASSUAN_CONFIG_H_INCLUDED*/
-
diff --git a/contrib/conf-w32ce-msc/stdint.h b/contrib/conf-w32ce-msc/stdint.h
deleted file mode 100755
index 0a821b7..0000000
--- a/contrib/conf-w32ce-msc/stdint.h
+++ /dev/null
@@ -1,9 +0,0 @@
-typedef unsigned long long uint64_t;
-typedef long long int64_t;
-typedef unsigned int uint32_t;
-typedef int int32_t;
-typedef unsigned short uint16_t;
-typedef short int16_t;
-typedef unsigned int uintptr_t;
-typedef int intptr_t;
-
diff --git a/src/Makefile.am b/src/Makefile.am
index 321aea3..f3a3aac 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -23,7 +23,7 @@ pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libassuan.pc
EXTRA_DIST = libassuan-config.in libassuan.m4 libassuan.vers \
- versioninfo.rc.in libassuan.def mkheader.c gpgcedev.def \
+ versioninfo.rc.in libassuan.def mkheader.c \
libassuan.pc.in
AM_CPPFLAGS = -I..
@@ -35,10 +35,6 @@ endif
m4datadir = $(datadir)/aclocal
m4data_DATA = libassuan.m4
lib_LTLIBRARIES = libassuan.la
-if HAVE_W32CE_SYSTEM
-lib_LTLIBRARIES += libgpgcedev.la
-bin_PROGRAMS = gpgcemgr
-endif
nodist_include_HEADERS = assuan.h
if HAVE_LD_VERSION_SCRIPT
@@ -52,11 +48,10 @@ CLEANFILES = mkheader assuan.h
BUILT_SOURCES = assuan.h
parts_of_assuan_h = \
- posix-includes.inc.h w32-includes.inc.h \
+ posix-includes.inc.h \
posix-types.inc.h w32-types.inc.h \
- posix-fd-t.inc.h w32-fd-t.inc.h w32ce-fd-t.inc.h \
- posix-sock-nonce.inc.h w32-sock-nonce.inc.h \
- w32ce-add.h
+ posix-fd-t.inc.h w32-fd-t.inc.h \
+ posix-sock-nonce.inc.h w32-sock-nonce.inc.h
common_sources = \
assuan.h.in $(parts_of_assuan_h) \
@@ -78,11 +73,7 @@ common_sources = \
assuan-socket.c
if HAVE_W32_SYSTEM
-if HAVE_W32CE_SYSTEM
-common_sources += system-w32ce.c
-else
common_sources += system-w32.c
-endif
else
common_sources += system-posix.c
endif
@@ -139,18 +130,6 @@ libassuan_la_DEPENDENCIES = @LTLIBOBJS@ \
$(srcdir)/libassuan.vers $(libassuan_deps)
libassuan_la_LIBADD = @LTLIBOBJS@ @NETLIBS@ @GPG_ERROR_LIBS@
-if HAVE_W32CE_SYSTEM
-libgpgcedev_la_SOURCES = gpgcedev.c
-libgpgcedev_la_CPPFLAGS = $(AM_CPPFLAGS)
-libgpgcedev_la_LDFLAGS = $(no_undefined) -export-symbols $(srcdir)/gpgcedev.def
-libgpgcedev_la_DEPENDENCIES = gpgcedev.def
-gpgcemgr_SOURCES = gpgcemgr.c
-gpgcemgr_CPPFLAGS = $(AM_CPPFLAGS)
-install-exec-hook:
- mv -f $(DESTDIR)$(bindir)/libgpgcedev-0.dll \
- $(DESTDIR)$(bindir)/gpgcedev.dll
-endif
-
mkheader$(EXEEXT_FOR_BUILD): mkheader.c Makefile
$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(CPPFLAGS_FOR_BUILD) \
$(LDFLAGS_FOR_BUILD) -I. -I$(srcdir) -o $@ $(srcdir)/mkheader.c
diff --git a/src/assuan-buffer.c b/src/assuan-buffer.c
index 7cb3032..895eb93 100644
--- a/src/assuan-buffer.c
+++ b/src/assuan-buffer.c
@@ -29,10 +29,8 @@
#endif
#include <assert.h>
#ifdef HAVE_W32_SYSTEM
-#ifndef HAVE_W32CE_SYSTEM
# include <process.h>
#endif
-#endif
#include "assuan-defs.h"
diff --git a/src/assuan-defs.h b/src/assuan-defs.h
index 37a50af..47ff4ef 100644
--- a/src/assuan-defs.h
+++ b/src/assuan-defs.h
@@ -375,15 +375,6 @@ FILE *_assuan_funopen(void *cookie,
/*-- sysutils.c --*/
const char *_assuan_sysutils_blurb (void);
-#ifdef HAVE_W32CE_SYSTEM
-
-#define getpid() GetCurrentProcessId ()
-char *_assuan_getenv (const char *name);
-#define getenv(a) _assuan_getenv ((a))
-
-#endif /*HAVE_W32CE_SYSTEM*/
-
-
/* Prototypes for replacement functions. */
#ifndef HAVE_MEMRCHR
void *memrchr (const void *block, int c, size_t size);
diff --git a/src/assuan-error.c b/src/assuan-error.c
index 8799203..57fb740 100644
--- a/src/assuan-error.c
+++ b/src/assuan-error.c
@@ -54,14 +54,9 @@ _assuan_w32_strerror (assuan_context_t ctx, int ec)
{
if (ec == -1)
ec = (int)GetLastError ();
-#ifdef HAVE_W32CE_SYSTEM
- snprintf (ctx->w32_strerror, sizeof (ctx->w32_strerror) - 1,
- "ec=%d", (int)GetLastError ());
-#else
FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, ec,
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
ctx->w32_strerror, sizeof (ctx->w32_strerror) - 1, NULL);
-#endif
return ctx->w32_strerror;
}
#endif
diff --git a/src/assuan-handler.c b/src/assuan-handler.c
index a572b62..126eccb 100644
--- a/src/assuan-handler.c
+++ b/src/assuan-handler.c
@@ -311,16 +311,6 @@ std_handler_input (assuan_context_t ctx, char *line)
if (rc)
return PROCESS_DONE (ctx, rc);
-#ifdef HAVE_W32CE_SYSTEM
- oldfd = fd;
- fd = _assuan_w32ce_finish_pipe ((int)fd, 0);
- if (fd == INVALID_HANDLE_VALUE)
- return PROCESS_DONE (ctx, set_error (ctx, GPG_ERR_ASS_PARAMETER,
- "rvid conversion failed"));
- TRACE2 (ctx, ASSUAN_LOG_SYSIO, "std_handler_input", ctx,
- "turned RVID 0x%x into handle 0x%x", oldfd, fd);
-#endif
-
if (ctx->input_notify_fnc)
{
oldfd = ctx->input_fd;
@@ -352,16 +342,6 @@ std_handler_output (assuan_context_t ctx, char *line)
if (rc)
return PROCESS_DONE (ctx, rc);
-#ifdef HAVE_W32CE_SYSTEM
- oldfd = fd;
- fd = _assuan_w32ce_finish_pipe ((int)fd, 1);
- if (fd == INVALID_HANDLE_VALUE)
- return PROCESS_DONE (ctx, set_error (ctx, gpg_err_code_from_syserror (),
- "rvid conversion failed"));
- TRACE2 (ctx, ASSUAN_LOG_SYSIO, "std_handler_output", ctx,
- "turned RVID 0x%x into handle 0x%x", oldfd, fd);
-#endif
-
if (ctx->output_notify_fnc)
{
oldfd = ctx->output_fd;
@@ -935,9 +915,7 @@ assuan_get_active_fds (assuan_context_t ctx, int what,
if (ctx->outbound.fd != ASSUAN_INVALID_FD)
fdarray[n++] = ctx->outbound.fd;
if (ctx->outbound.data.fp)
-#if defined(HAVE_W32CE_SYSTEM)
- fdarray[n++] = (void*)fileno (ctx->outbound.data.fp);
-#elif defined(HAVE_W32_SYSTEM)
+#if defined(HAVE_W32_SYSTEM)
fdarray[n++] = (void*)_get_osfhandle (fileno (ctx->outbound.data.fp));
#else
fdarray[n++] = fileno (ctx->outbound.data.fp);
diff --git a/src/assuan-socket.c b/src/assuan-socket.c
index 0588dc2..bb5ccfd 100644
--- a/src/assuan-socket.c
+++ b/src/assuan-socket.c
@@ -29,9 +29,7 @@
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# include <wincrypt.h>
-#ifndef HAVE_W32CE_SYSTEM
# include <io.h>
-#endif
#else
# include <sys/types.h>
# include <sys/socket.h>
diff --git a/src/gpgcedev.c b/src/gpgcedev.c
deleted file mode 100644
index c841ec2..0000000
--- a/src/gpgcedev.c
+++ /dev/null
@@ -1,1640 +0,0 @@
-/* gpgcedrv.c - WindowsCE device driver to implement pipe and syslog.
- * Copyright (C) 2010 Free Software Foundation, Inc.
- *
- * This file is part of Assuan.
- *
- * Assuan is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
- *
- * Assuan is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * 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/>.
- * SPDX-License-Identifier: LGPL-3.0+
- */
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <windows.h>
-#include <devload.h>
-#include <winioctl.h>
-
-/* FIXME Cancel not handled. */
-
-#define DBGFILENAME "\\gpgcedev.dbg"
-#define LOGFILENAME L"\\gpgcedev.log"
-#define GPGCEDEV_KEY_NAME L"Drivers\\GnuPG_Device"
-#define GPGCEDEV_KEY_NAME2 L"Drivers\\GnuPG_Log"
-
-
-/* Missing IOCTLs in the current mingw32ce. */
-#ifndef IOCTL_PSL_NOTIFY
-# define FILE_DEVICE_PSL 259
-# define IOCTL_PSL_NOTIFY \
- CTL_CODE (259, 255, METHOD_NEITHER, FILE_ANY_ACCESS)
-#endif /*IOCTL_PSL_NOTIFY*/
-
-
-/* The IOCTL to return the rendezvous id of the 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 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 the code: 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)
-
-/* The IOCTL used to unblock a blocking thread.
-
- The caller sends this IOCTL to the read or the write handle. No
- parameter is required. The effect is that a reader or writer
- blocked on the same handle is unblocked (and will return
- ERROR_BUSY). Note that the operation can be repeated, if so
- desired. The state of the pipe itself will not be affected in any
- way. */
-#define GPGCEDEV_IOCTL_UNBLOCK \
- CTL_CODE (FILE_DEVICE_STREAMS, 2050, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-/* The IOCTL to assign a rendezvous id to a process.
-
- The required inbuf parameters are the rendezvous ID to assign and
- the process ID of the process receiving the RVID. The handle on
- which this is called is not really used at all! */
-#define GPGCEDEV_IOCTL_ASSIGN_RVID \
- CTL_CODE (FILE_DEVICE_STREAMS, 2051, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-
-/* An object to describe a pipe. */
-struct pipeimpl_s
-{
- CRITICAL_SECTION critsect; /* Lock for all members. */
-
- int refcnt;
- char *buffer;
- size_t buffer_size;
- size_t buffer_len; /* The valid length of the bufer. */
- size_t buffer_pos; /* The actual read position. */
-
-#define PIPE_FLAG_NO_READER 1
-#define PIPE_FLAG_NO_WRITER 2
-#define PIPE_FLAG_UNBLOCK_READER 4
-#define PIPE_FLAG_UNBLOCK_WRITER 8
-#define PIPE_FLAG_HALT_MONITOR 16
- int flags;
-
- HANDLE space_available; /* Set if space is available. */
- HANDLE data_available; /* Set if data is available. */
-
- /* For the monitor thread started by ASSIGN_RVID. */
- HANDLE monitor_proc;
- int monitor_access;
- LONG monitor_rvid;
-};
-typedef struct pipeimpl_s *pipeimpl_t;
-
-
-/* An object to describe a logging context. We can't write directly
- to the log stream because we want to do line buffering and thus we
- need to store data until we see LF. */
-struct logimpl_s;
-typedef struct logimpl_s *logimpl_t;
-struct logimpl_s
-{
- unsigned long logid; /* An identifier for a log source. */
- unsigned long dsec; /* Tenth of a second since system start. */
- char *line; /* Malloced line buffer. */
- size_t linesize; /* Allocated size of LINE. */
- size_t linelen; /* Used length of the line. */
- int truncated; /* Indicates a truncated log line. */
-};
-
-
-
-/* An object to store information pertaining to an open-context. */
-struct opnctx_s;
-typedef struct opnctx_s *opnctx_t;
-struct opnctx_s
-{
- int inuse; /* True if this object has valid data. */
- int is_log; /* True if this describes a log device. */
- LONG rvid; /* The unique rendezvous identifier. */
- DWORD access_code;/* Value from OpenFile. */
- DWORD share_mode; /* Value from OpenFile. */
-
- /* The state shared by all pipe users. Only used if IS_LOG is false. */
- pipeimpl_t pipeimpl;
-
- /* The state used to implement a log stream. Only used if IS_LOG is true. */
- logimpl_t logimpl;
-};
-
-/* A malloced table of open-context and the number of allocated slots. */
-static opnctx_t opnctx_table;
-static size_t opnctx_table_size;
-/* The macros make sure that 0 is never a valid openctx_arg. */
-#define OPNCTX_TO_IDX(ctx_arg) (((ctx_arg) - opnctx_table) + 1)
-#define OPNCTX_FROM_IDX(idx) (&opnctx_table[(idx) - 1])
-#define OPNCTX_VALID_IDX_P(idx) ((idx) > 0 && (idx) <= opnctx_table_size)
-
-typedef struct monitor_s *monitor_t;
-struct monitor_s
-{
- int inuse; /* True if this object has valid data. */
- pipeimpl_t pipeimpl;
-};
-static monitor_t monitor_table;
-static size_t monitor_table_size;
-
-/* A criticial section object used to protect the OPNCTX_TABLE and
- MONITOR_TABLE. */
-static CRITICAL_SECTION opnctx_table_cs;
-
-
-
-/* A global object to control the logging. */
-struct {
- CRITICAL_SECTION lock; /* Lock for this structure. */
- HANDLE filehd; /* Handle of the log output file. */
- int references; /* Number of objects references this one. */
-} logcontrol;
-
-
-/* We don't need a device context for the pipe thus we use the address
- of the critical section object for it. */
-#define PIPECTX_VALUE ((DWORD)(&opnctx_table_cs))
-
-/* The device context for the log device is the address of our
- control structure. */
-#define LOGCTX_VALUE ((DWORD)(&logcontrol))
-
-
-/* True if we have enabled debugging. */
-static int enable_debug;
-
-/* True if logging has been enabled. */
-static int enable_logging;
-
-
-
-static void
-log_debug (const char *fmt, ...)
-{
- if (enable_debug)
- {
- va_list arg_ptr;
- FILE *fp;
-
- fp = fopen (DBGFILENAME, "a+");
- if (!fp)
- return;
- va_start (arg_ptr, fmt);
- vfprintf (fp, fmt, arg_ptr);
- va_end (arg_ptr);
- fclose (fp);
- }
-}
-
-
-/* Return a new rendezvous id. 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 log id. These log ids are used to identify log lines
- send to the same device; ie. for each CreateFile("GPG2:") a new log
- id is assigned. We will ever return a log id of 0. */
-static LONG
-create_log_id (void)
-{
- static LONG log_id;
- LONG lid;
-
- while (!(lid = InterlockedIncrement (&log_id)))
- ;
- return lid;
-}
-
-
-
-pipeimpl_t
-pipeimpl_new (void)
-{
- pipeimpl_t pimpl;
-
- pimpl = malloc (sizeof (*pimpl));
- if (!pimpl)
- return NULL;
-
- InitializeCriticalSection (&pimpl->critsect);
- pimpl->refcnt = 1;
- pimpl->buffer_size = 512;
- pimpl->buffer = malloc (pimpl->buffer_size);
- if (!pimpl->buffer)
- {
- DeleteCriticalSection (&pimpl->critsect);
- free (pimpl);
- return NULL;
- }
- pimpl->buffer_len = 0;
- pimpl->buffer_pos = 0;
- pimpl->flags = 0;
- pimpl->space_available = CreateEvent (NULL, FALSE, FALSE, NULL);
- if (!pimpl->space_available)
- {
- free (pimpl->buffer);
- DeleteCriticalSection (&pimpl->critsect);
- free (pimpl);
- return NULL;
- }
- pimpl->data_available = CreateEvent (NULL, FALSE, FALSE, NULL);
- if (!pimpl->data_available)
- {
- CloseHandle (pimpl->space_available);
- free (pimpl->buffer);
- DeleteCriticalSection (&pimpl->critsect);
- free (pimpl);
- return NULL;
- }
- pimpl->monitor_proc = INVALID_HANDLE_VALUE;
- pimpl->monitor_access = 0;
- pimpl->monitor_rvid = 0;
- return pimpl;
-}
-
-
-/* PIMPL must be locked. It is unlocked at exit. */
-void
-pipeimpl_unref (pipeimpl_t pimpl)
-{
- int release = 0;
-
- if (!pimpl)
- return;
-
- log_debug ("pipeimpl_unref (%p): dereference\n", pimpl);
-
- if (--pimpl->refcnt == 0)
- release = 1;
- LeaveCriticalSection (&pimpl->critsect);
-
- if (! release)
- return;
-
- log_debug ("pipeimpl_unref (%p): release\n", pimpl);
-
- DeleteCriticalSection (&pimpl->critsect);
- if (pimpl->buffer)
- {
- free (pimpl->buffer);
- pimpl->buffer = NULL;
- pimpl->buffer_size = 0;
- }
- if (pimpl->space_available != INVALID_HANDLE_VALUE)
- {
- CloseHandle (pimpl->space_available);
- pimpl->space_available = INVALID_HANDLE_VALUE;
- }
- if (pimpl->data_available != INVALID_HANDLE_VALUE)
- {
- CloseHandle (pimpl->data_available);
- pimpl->data_available = INVALID_HANDLE_VALUE;
- }
-}
-
-
-
-/* Allocate a new log structure. */
-logimpl_t
-logimpl_new (void)
-{
- logimpl_t limpl;
-
- limpl = calloc (1, sizeof *limpl);
- if (!limpl)
- return NULL;
- limpl->logid = create_log_id ();
- limpl->linesize = 256;
- limpl->line = malloc (limpl->linesize);
- if (!limpl->line)
- {
- free (limpl);
- return NULL;
- }
-
- return limpl;
-}
-
-
-/* There is no need to lock LIMPL, thus is a dummy function. */
-void
-logimpl_unref (logimpl_t limpl)
-{
- (void)limpl;
-}
-
-
-/* Flush a pending log line. */
-static void
-logimpl_flush (logimpl_t limpl)
-{
- if (!limpl->linelen || !enable_logging)
- return;
-
- EnterCriticalSection (&logcontrol.lock);
- if (logcontrol.filehd == INVALID_HANDLE_VALUE)
- logcontrol.filehd = CreateFile (LOGFILENAME, GENERIC_WRITE,
- FILE_SHARE_READ,
- NULL, OPEN_ALWAYS,
- FILE_ATTRIBUTE_NORMAL, NULL);
- if (!logcontrol.filehd)
- log_debug ("can't open log file: rc=%d\n", (int)GetLastError ());
- else
- {
- char buf[50];
- DWORD nwritten;
-
- snprintf (buf, sizeof buf,
- "%06lu/%lu//", limpl->dsec % 1000000, limpl->logid);
- if (!WriteFile (logcontrol.filehd, buf, strlen (buf), &nwritten, NULL))
- log_debug ("error writing log file: rc=%d\n", (int)GetLastError ());
- else if (!WriteFile (logcontrol.filehd,
- limpl->line, limpl->linelen, &nwritten, NULL))
- log_debug ("error writing log file: rc=%d\n", (int)GetLastError ());
-
- snprintf (buf, sizeof buf, "%s\n", limpl->truncated? "[...]":"");
- if (!WriteFile (logcontrol.filehd, buf, strlen (buf), &nwritten, NULL))
- log_debug ("error writing log file: rc=%d\n", (int)GetLastError ());
- }
-
- LeaveCriticalSection (&logcontrol.lock);
- limpl->linelen = 0;
- limpl->truncated = 0;
-}
-
-
-/* Return a new opnctx handle and mark it as used. Returns NULL and
- sets LastError on memory failure etc. opnctx_table_cs must be
- locked on entry and is locked on exit. Note that the returned
- pointer is only valid as long as opnctx_table_cs stays locked, as
- it is not stable under table reallocation. */
-static opnctx_t
-allocate_opnctx (int is_log)
-{
- opnctx_t opnctx = NULL;
- int idx;
-
- for (idx = 0; idx < opnctx_table_size; idx++)
- if (! opnctx_table[idx].inuse)
- break;
- if (idx == opnctx_table_size)
- {
- /* We need to increase the size of the table. The approach we
- take is straightforward to minimize the risk of bugs. */
- opnctx_t newtbl;
- size_t newsize = opnctx_table_size + 64;
-
- newtbl = calloc (newsize, sizeof *newtbl);
- if (!newtbl)
- goto leave;
- memcpy (newtbl, opnctx_table, opnctx_table_size * sizeof (*newtbl));
- free (opnctx_table);
- opnctx_table = newtbl;
- idx = opnctx_table_size;
- opnctx_table_size = newsize;
- }
- opnctx = &opnctx_table[idx];
- opnctx->inuse = 1;
- opnctx->is_log = is_log;
- opnctx->rvid = 0;
- opnctx->access_code = 0;
- opnctx->share_mode = 0;
- opnctx->pipeimpl = 0;
- opnctx->logimpl = 0;
-
- leave:
- return opnctx;
-}
-
-
-/* Verify context CTX, returns NULL if not valid and the pointer to
- the context if valid. opnctx_table_cs must be locked on entry and
- is locked on exit. Note that the returned pointer is only valid as
- long as opnctx_table_cs remains locked. */
-opnctx_t
-verify_opnctx (DWORD ctx_arg)
-{
- opnctx_t ctx;
-
- if (! OPNCTX_VALID_IDX_P (ctx_arg))
- {
- SetLastError (ERROR_INVALID_HANDLE);
- return NULL;
- }
- ctx = OPNCTX_FROM_IDX (ctx_arg);
-
- if (! ctx->inuse)
- {
- SetLastError (ERROR_INVALID_HANDLE);
- return NULL;
- }
- return ctx;
-}
-
-
-/* Return a new monitor handle and mark it as used. Returns NULL and
- sets LastError on memory failure etc. opnctx_table_cs must be
- locked on entry and is locked on exit. Note that the returned
- pointer is only valid as long as opnctx_table_cs stays locked, as
- it is not stable under table reallocation. */
-static monitor_t
-allocate_monitor (void)
-{
- monitor_t monitor = NULL;
- int idx;
-
- for (idx = 0; idx < monitor_table_size; idx++)
- if (! monitor_table[idx].inuse)
- break;
- if (idx == monitor_table_size)
- {
- /* We need to increase the size of the table. The approach we
- take is straightforward to minimize the risk of bugs. */
- monitor_t newtbl;
- size_t newsize = monitor_table_size + 16;
-
- newtbl = calloc (newsize, sizeof *newtbl);
- if (!newtbl)
- goto leave;
- memcpy (newtbl, monitor_table, monitor_table_size * sizeof (*newtbl));
- free (monitor_table);
- monitor_table = newtbl;
- idx = monitor_table_size;
- monitor_table_size = newsize;
- }
- monitor = &monitor_table[idx];
- monitor->inuse = 1;
- monitor->pipeimpl = 0;
-
- leave:
- return monitor;
-}
-
-
-static pipeimpl_t
-assert_pipeimpl (opnctx_t ctx)
-{
- DWORD ctx_arg = OPNCTX_TO_IDX (ctx);
-
- if (ctx->is_log)
- {
- log_debug (" assert_pipeimpl (ctx=%i): "
- "error: not valid for a log device\n", ctx_arg);
- return NULL;
- }
- if (! ctx->pipeimpl)
- {
- ctx->pipeimpl = pipeimpl_new ();
- if (! ctx->pipeimpl)
- {
- log_debug (" assert_pipeimpl (ctx=%i): error: can't create pipe\n",
- ctx_arg);
- return NULL;
- }
- log_debug (" assert_pipeimpl (ctx=%i): created pipe 0x%p\n",
- ctx_arg, ctx->pipeimpl);
- }
- return ctx->pipeimpl;
-}
-
-
-static logimpl_t
-assert_logimpl (opnctx_t ctx)
-{
- DWORD ctx_arg = OPNCTX_TO_IDX (ctx);
-
- if (!ctx->is_log)
- {
- log_debug (" assert_logimpl (ctx=%i): "
- "error: not valid for a pipe device\n", ctx_arg);
- return NULL;
- }
- if (!ctx->logimpl)
- {
- ctx->logimpl = logimpl_new ();
- if (!ctx->logimpl)
- {
- log_debug (" assert_logimpl (ctx=%i): error: can't create log\n",
- ctx_arg);
- return NULL;
- }
- log_debug (" assert_logimpl (ctx=%i): created log 0x%p\n",
- ctx_arg, ctx->logimpl);
- }
- return ctx->logimpl;
-}
-
-
-/* Verify access CODE for context CTX_ARG, returning a reference to
- the locked pipe or the locked log implementation. opnctx_table_cs
- must be unlocked on entry and is unlocked on exit. */
-int
-access_opnctx (DWORD ctx_arg, DWORD code, pipeimpl_t *r_pipe, logimpl_t *r_log)
-{
- opnctx_t ctx;
-
- *r_pipe = NULL;
- *r_log = NULL;
-
- EnterCriticalSection (&opnctx_table_cs);
- ctx = verify_opnctx (ctx_arg);
- if (! ctx)
- {
- /* Error is set by verify_opnctx. */
- LeaveCriticalSection (&opnctx_table_cs);
- return -1;
- }
-
- if (! (ctx->access_code & code))
- {
- SetLastError (ERROR_INVALID_ACCESS);
- LeaveCriticalSection (&opnctx_table_cs);
- return -1;
- }
-
- if (ctx->is_log)
- {
- logimpl_t limpl;
-
- limpl = assert_logimpl (ctx);
- if (!limpl)
- {
- LeaveCriticalSection (&opnctx_table_cs);
- return -1;
- }
- *r_log = limpl;
- }
- else
- {
- pipeimpl_t pimpl;
-
- pimpl = assert_pipeimpl (ctx);
- if (! pimpl)
- {
- LeaveCriticalSection (&opnctx_table_cs);
- return -1;
- }
- EnterCriticalSection (&pimpl->critsect);
- pimpl->refcnt++;
- *r_pipe = pimpl;
- }
-
- LeaveCriticalSection (&opnctx_table_cs);
- return 0;
-}
-
-
-
-static char *
-wchar_to_utf8 (const wchar_t *string)
-{
- int n;
- size_t length = wcslen (string);
- char *result;
-
- n = WideCharToMultiByte (CP_UTF8, 0, string, length, NULL, 0, NULL, NULL);
- if (n < 0 || (n+1) <= 0)
- abort ();
-
- result = malloc (n+1);
- if (!result)
- abort ();
- n = WideCharToMultiByte (CP_ACP, 0, string, length, result, n, NULL, NULL);
- if (n < 0)
- abort ();
-
- result[n] = 0;
- return result;
-}
-
-
-/* Initialize the device and return a device specific context. */
-DWORD
-GPG_Init (LPCTSTR active_key, DWORD bus_context)
-{
- static int firsttimedone;
- HKEY handle;
- wchar_t buffer[25];
- DWORD buflen;
- DWORD result;
-
- (void)bus_context;
-
- EnterCriticalSection (&logcontrol.lock);
- if (!firsttimedone)
- {
- firsttimedone++;
- if (!RegOpenKeyEx (HKEY_LOCAL_MACHINE, GPGCEDEV_KEY_NAME,
- 0, KEY_READ, &handle))
- {
- buflen = sizeof buffer;
- if (!RegQueryValueEx (handle, L"debugDriver", 0, NULL,
- (PBYTE)buffer, &buflen)
- && wcstol (buffer, NULL, 10) > 0)
- enable_debug = 1;
- RegCloseKey (handle);
- }
- if (!RegOpenKeyEx (HKEY_LOCAL_MACHINE, GPGCEDEV_KEY_NAME2,
- 0, KEY_READ, &handle))
- {
- buflen = sizeof buffer;
- if (!RegQueryValueEx (handle, L"enableLog", 0, NULL,
- (PBYTE)buffer, &buflen)
- && wcstol (buffer, NULL, 10) > 0)
- enable_logging = 1;
- RegCloseKey (handle);
- }
- }
- LeaveCriticalSection (&logcontrol.lock);
-
- if (enable_debug)
- {
- char *tmpbuf;
- tmpbuf = wchar_to_utf8 (active_key);
- log_debug ("GPG_Init (%s)\n", tmpbuf);
- free (tmpbuf);
- }
-
- if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, active_key, 0, KEY_READ, &handle))
- {
- log_debug ("GPG_Init: error reading registry: rc=%d\n",
- (int)GetLastError ());
- return 0;
- }
-
- buflen = sizeof buffer;
- if (RegQueryValueEx (handle, L"Name", 0, NULL, (PBYTE)buffer, &buflen))
- {
- log_debug ("GPG_Init: error reading registry value 'Name': rc=%d\n",
- (int)GetLastError ());
- result = 0;
- }
- else if (!wcscmp (buffer, L"GPG1:"))
- {
- /* This is the pipe device: We don't need any global data.
- However, we need to return something. */
- log_debug ("GPG_Init: created pipe device (devctx=%p)\n", PIPECTX_VALUE);
- result = PIPECTX_VALUE;
- }
- else if (!wcscmp (buffer, L"GPG2:"))
- {
- /* This is the log device. Clear the object and return something. */
- logcontrol.filehd = INVALID_HANDLE_VALUE;
- log_debug ("GPG_Init: created log device (devctx=%p)\n", 0);
- result = LOGCTX_VALUE;
- }
- else
- {
- if (enable_debug)
- {
- char *tmpbuf;
- tmpbuf = wchar_to_utf8 (buffer);
- log_debug ("GPG_Init: device '%s' is not supported\n", tmpbuf);
- free (tmpbuf);
- }
- SetLastError (ERROR_DEV_NOT_EXIST);
- result = 0;
- }
-
- RegCloseKey (handle);
- return result;
-}
-
-
-
-/* Deinitialize this device driver. */
-BOOL
-GPG_Deinit (DWORD devctx)
-{
- log_debug ("GPG_Deinit (devctx=0x%p)\n", (void*)devctx);
- if (devctx == PIPECTX_VALUE)
- {
- /* No need to release resources. */
- }
- else if (devctx == LOGCTX_VALUE)
- {
- EnterCriticalSection (&logcontrol.lock);
- if (logcontrol.filehd != INVALID_HANDLE_VALUE)
- {
- CloseHandle (logcontrol.filehd);
- logcontrol.filehd = INVALID_HANDLE_VALUE;
- }
- LeaveCriticalSection (&logcontrol.lock);
- }
- else
- {
- SetLastError (ERROR_INVALID_PARAMETER);
- return FALSE; /* Error. */
- }
-
- return TRUE; /* Success. */
-}
-
-
-
-/* Create a new open context. This function is called due to a
- CreateFile from the application. */
-DWORD
-GPG_Open (DWORD devctx, DWORD access_code, DWORD share_mode)
-{
- opnctx_t opnctx;
- DWORD ctx_arg = 0;
- int is_log;
-
- log_debug ("GPG_Open (devctx=%p)\n", (void*)devctx);
- if (devctx == PIPECTX_VALUE)
- is_log = 0;
- else if (devctx == LOGCTX_VALUE)
- is_log = 1;
- else
- {
- log_debug ("GPG_Open (devctx=%p): error: wrong devctx (expected 0x%p)\n",
- (void*) devctx);
- SetLastError (ERROR_INVALID_PARAMETER);
- return 0; /* Error. */
- }
-
- EnterCriticalSection (&opnctx_table_cs);
- opnctx = allocate_opnctx (is_log);
- if (!opnctx)
- {
- log_debug ("GPG_Open (devctx=%p): error: could not allocate context\n",
- (void*) devctx);
- goto leave;
- }
-
- opnctx->access_code = access_code;
- opnctx->share_mode = share_mode;
-
- ctx_arg = OPNCTX_TO_IDX (opnctx);
-
- log_debug ("GPG_Open (devctx=%p, is_log=%d): success: created context %i\n",
- (void*) devctx, is_log, ctx_arg);
- if (is_log)
- {
- EnterCriticalSection (&logcontrol.lock);
- logcontrol.references++;
- LeaveCriticalSection (&logcontrol.lock);
- }
-
- leave:
- LeaveCriticalSection (&opnctx_table_cs);
- return ctx_arg;
-}
-
-
-
-BOOL
-GPG_Close (DWORD opnctx_arg)
-{
- opnctx_t opnctx;
- BOOL result = FALSE;
-
- log_debug ("GPG_Close (ctx=%i)\n", opnctx_arg);
-
- EnterCriticalSection (&opnctx_table_cs);
- opnctx = verify_opnctx (opnctx_arg);
- if (!opnctx)
- {
- log_debug ("GPG_Close (ctx=%i): could not find context\n", opnctx_arg);
- goto leave;
- }
-
- if (opnctx->pipeimpl)
- {
- pipeimpl_t pimpl = opnctx->pipeimpl;
- EnterCriticalSection (&pimpl->critsect);
- /* This needs to be adjusted if there can be multiple
- reader/writers. */
- if (opnctx->access_code & GENERIC_READ)
- {
- pimpl->flags |= PIPE_FLAG_NO_READER;
- SetEvent (pimpl->space_available);
- }
- else if (opnctx->access_code & GENERIC_WRITE)
- {
- pimpl->flags |= PIPE_FLAG_NO_WRITER;
- SetEvent (pimpl->data_available);
- }
- pipeimpl_unref (pimpl);
- opnctx->pipeimpl = 0;
- }
- if (opnctx->logimpl)
- {
- logimpl_t limpl = opnctx->logimpl;
-
- logimpl_flush (limpl);
- logimpl_unref (limpl);
- free (limpl->line);
- free (limpl);
- opnctx->logimpl = 0;
- EnterCriticalSection (&logcontrol.lock);
- logcontrol.references--;
- if (!logcontrol.references && logcontrol.filehd)
- {
- CloseHandle (logcontrol.filehd);
- logcontrol.filehd = INVALID_HANDLE_VALUE;
- }
- LeaveCriticalSection (&logcontrol.lock);
- }
- opnctx->access_code = 0;
- opnctx->share_mode = 0;
- opnctx->rvid = 0;
- opnctx->inuse = 0;
- result = TRUE;
- log_debug ("GPG_Close (ctx=%i): success\n", opnctx_arg);
-
- leave:
- LeaveCriticalSection (&opnctx_table_cs);
- return result;
-}
-
-
-
-DWORD
-GPG_Read (DWORD opnctx_arg, void *buffer, DWORD count)
-{
- pipeimpl_t pimpl;
- logimpl_t limpl;
- const char *src;
- char *dst;
- int result = -1;
-
- log_debug ("GPG_Read (ctx=%i, buffer=0x%p, count=%d)\n",
- opnctx_arg, buffer, count);
-
- if (access_opnctx (opnctx_arg, GENERIC_READ, &pimpl, &limpl))
- {
- log_debug ("GPG_Read (ctx=%i): error: could not access context\n",
- opnctx_arg);
- return -1;
- }
-
- if (limpl)
- {
- /* Reading from a log stream does not make sense. Return EOF. */
- result = 0;
- goto leave;
- }
-
- retry:
- if (pimpl->buffer_pos == pimpl->buffer_len)
- {
- HANDLE data_available = pimpl->data_available;
-
- /* Check for end of file. */
- if (pimpl->flags & PIPE_FLAG_NO_WRITER)
- {
- log_debug ("GPG_Read (ctx=%i): success: EOF\n", opnctx_arg);
- result = 0;
- goto leave;
- }
-
- /* Check for request to unblock once. */
- if (pimpl->flags & PIPE_FLAG_UNBLOCK_READER)
- {
- log_debug ("GPG_Read (ctx=%i): success: EBUSY (due to unblock)\n",
- opnctx_arg);
- pimpl->flags &= ~PIPE_FLAG_UNBLOCK_READER;
- SetLastError (ERROR_BUSY);
- result = -1;
- goto leave;
- }
-
- LeaveCriticalSection (&pimpl->critsect);
- log_debug ("GPG_Read (ctx=%i): waiting: data_available\n", opnctx_arg);
- WaitForSingleObject (data_available, INFINITE);
- log_debug ("GPG_Read (ctx=%i): resuming: data_available\n", opnctx_arg);
- EnterCriticalSection (&pimpl->critsect);
- goto retry;
- }
-
- dst = buffer;
- src = pimpl->buffer + pimpl->buffer_pos;
- while (count > 0 && pimpl->buffer_pos < pimpl->buffer_len)
- {
- *dst++ = *src++;
- count--;
- pimpl->buffer_pos++;
- }
- result = (dst - (char*)buffer);
- if (pimpl->buffer_pos == pimpl->buffer_len)
- pimpl->buffer_pos = pimpl->buffer_len = 0;
-
- /* Now there should be some space available. Signal the write end.
- Even if COUNT was passed as NULL and no space is available,
- signaling must be done. */
- if (!SetEvent (pimpl->space_available))
- log_debug ("GPG_Read (ctx=%i): warning: SetEvent(space_available) "
- "failed: rc=%d\n", opnctx_arg, (int)GetLastError ());
-
- log_debug ("GPG_Read (ctx=%i): success: result=%d\n", opnctx_arg, result);
-
- leave:
- pipeimpl_unref (pimpl);
- logimpl_unref (limpl);
- return result;
-}
-
-
-
-DWORD
-GPG_Write (DWORD opnctx_arg, const void *buffer, DWORD count)
-{
- pipeimpl_t pimpl;
- logimpl_t limpl;
- int result = -1;
- const char *src;
- char *dst;
- size_t nwritten = 0;
-
- log_debug ("GPG_Write (ctx=%i, buffer=0x%p, count=%d)\n", opnctx_arg,
- buffer, count);
-
- if (access_opnctx (opnctx_arg, GENERIC_WRITE, &pimpl, &limpl))
- {
- log_debug ("GPG_Write (ctx=%i): error: could not access context\n",
- opnctx_arg);
- return -1;
- }
-
- if (!count)
- {
- log_debug ("GPG_Write (ctx=%i): success\n", opnctx_arg);
- result = 0;
- goto leave;
- }
-
- retry:
- if (limpl)
- {
- /* Store it in our buffer up to a LF and print complete lines. */
- result = count;
- if (!limpl->linelen)
- limpl->dsec = GetTickCount () / 100;
- dst = limpl->line + limpl->linelen;
- for (src = buffer; count; count--, src++)
- {
- if (*src == '\n')
- {
- logimpl_flush (limpl);
- dst = limpl->line + limpl->linelen;
- }
- else if (limpl->linelen >= limpl->linesize)
- limpl->truncated = 1;
- else
- {
- *dst++ = *src;
- limpl->linelen++;
- }
- }
- }
- else /* pimpl */
- {
- /* Check for broken pipe. */
- if (pimpl->flags & PIPE_FLAG_NO_READER)
- {
- log_debug ("GPG_Write (ctx=%i): error: broken pipe\n", opnctx_arg);
- SetLastError (ERROR_BROKEN_PIPE);
- goto leave;
- }
-
- /* Check for request to unblock once. */
- if (pimpl->flags & PIPE_FLAG_UNBLOCK_WRITER)
- {
- log_debug ("GPG_Write (ctx=%i): success: EBUSY (due to unblock)\n",
- opnctx_arg);
- pimpl->flags &= ~PIPE_FLAG_UNBLOCK_WRITER;
- SetLastError (ERROR_BUSY);
- result = -1;
- goto leave;
- }
-
- /* Write to our buffer. */
- if (pimpl->buffer_len == pimpl->buffer_size)
- {
- /* Buffer is full. */
- HANDLE space_available = pimpl->space_available;
- LeaveCriticalSection (&pimpl->critsect);
- log_debug ("GPG_Write (ctx=%i): waiting: space_available\n",
- opnctx_arg);
- WaitForSingleObject (space_available, INFINITE);
- log_debug ("GPG_Write (ctx=%i): resuming: space_available\n",
- opnctx_arg);
- EnterCriticalSection (&pimpl->critsect);
- goto retry;
- }
-
- src = buffer;
- dst = pimpl->buffer + pimpl->buffer_len;
- while (count > 0 && pimpl->buffer_len < pimpl->buffer_size)
- {
- *dst++ = *src++;
- count--;
- pimpl->buffer_len++;
- nwritten++;
- }
- result = nwritten;
-
- if (!SetEvent (pimpl->data_available))
- log_debug ("GPG_Write (ctx=%i): warning: SetEvent(data_available) "
- "failed: rc=%d\n", opnctx_arg, (int)GetLastError ());
- }
-
- log_debug ("GPG_Write (ctx=%i): success: result=%d\n", opnctx_arg, result);
-
- leave:
- pipeimpl_unref (pimpl);
- logimpl_unref (limpl);
- return result;
-}
-
-
-
-DWORD
-GPG_Seek (DWORD opnctx_arg, long amount, WORD type)
-{
- SetLastError (ERROR_SEEK_ON_DEVICE);
- return -1; /* Error. */
-}
-
-
-
-/* opnctx_table_s is locked on entering and on exit. */
-static BOOL
-make_pipe (opnctx_t ctx, LONG rvid)
-{
- DWORD ctx_arg = OPNCTX_TO_IDX (ctx);
- opnctx_t peerctx = NULL;
- int idx;
- pipeimpl_t pimpl;
-
- log_debug (" make_pipe (ctx=%i, rvid=%08lx)\n", ctx_arg, rvid);
-
- if (ctx->pipeimpl)
- {
- log_debug (" make_pipe (ctx=%i): error: already assigned\n", ctx_arg);
- SetLastError (ERROR_ALREADY_ASSIGNED);
- return FALSE;
- }
-
- /* GnuPG and other programs don't use the safe ASSIGN_RVID call
- because they guarantee that the context exists during the whole
- time the child process runs. GPGME is more asynchronous and
- relies on ASSIGN_RVID monitors. So, first check for open
- contexts, then check for monitors. */
-
- for (idx = 0; idx < opnctx_table_size; idx++)
- if (opnctx_table[idx].inuse && opnctx_table[idx].rvid == rvid)
- {
- peerctx = &opnctx_table[idx];
- break;
- }
- if (peerctx)
- {
- /* This is the GnuPG etc case, where the context is still open.
- It may also cover the GPGME case if GPGME is still using its
- own end of the pipe at the time of this call. */
- if (peerctx == ctx)
- {
- log_debug (" make_pipe (ctx=%i): error: target and source identical\n",
- ctx_arg);
- SetLastError (ERROR_INVALID_TARGET_HANDLE);
- return FALSE;
- }
-
- if ((ctx->access_code & GENERIC_READ))
- {
- /* Check that the peer is a write end. */
- if (!(peerctx->access_code & GENERIC_WRITE))
- {
- log_debug (" make_pipe (ctx=%i): error: peer is not writer\n",
- ctx_arg);
- SetLastError (ERROR_INVALID_ACCESS);
- return FALSE;
- }
- }
- else if ((ctx->access_code & GENERIC_WRITE))
- {
- /* Check that the peer is a read end. */
- if (!(peerctx->access_code & GENERIC_READ))
- {
- log_debug (" make_pipe (ctx=%i): error: peer is not reader\n",
- ctx_arg);
- SetLastError (ERROR_INVALID_ACCESS);
- return FALSE;
- }
- }
- else
- {
- log_debug (" make_pipe (ctx=%i): error: invalid access\n", ctx_arg);
- SetLastError (ERROR_INVALID_ACCESS);
- return FALSE;
- }
-
- /* Make sure the peer has a pipe implementation to be shared. If
- not yet, create one. */
- pimpl = assert_pipeimpl (peerctx);
- if (! pimpl)
- return FALSE;
- }
- else
- {
- /* This is the case where ASSIGN_RVID was called to create a
- monitor, and the pipe is already closed at the parent side.
- For example GPGME verify detached plain text, where GPG calls
- MAKE_PIPE very late. */
-
- for (idx = 0; idx < monitor_table_size; idx++)
- if (monitor_table[idx].inuse
- && monitor_table[idx].pipeimpl->monitor_rvid == rvid)
- {
- pimpl = monitor_table[idx].pipeimpl;
- break;
- }
- if (idx == monitor_table_size)
- {
- log_debug (" make_pipe (ctx=%i): error: not found\n", ctx_arg);
- SetLastError (ERROR_NOT_FOUND);
- return FALSE;
- }
-
- if (ctx->access_code & GENERIC_READ)
- {
- /* Check that the peer is a write end. */
- if (!(pimpl->monitor_access & GENERIC_READ))
- {
- log_debug (" make_pipe (ctx=%i): error: monitor is not reader\n",
- ctx_arg);
- SetLastError (ERROR_INVALID_ACCESS);
- return FALSE;
- }
- }
- else if ((ctx->access_code & GENERIC_WRITE))
- {
- /* Check that the peer is a read end. */
- if (!(pimpl->monitor_access & GENERIC_WRITE))
- {
- log_debug (" make_pipe (ctx=%i): error: monitor is not writer\n",
- ctx_arg);
- SetLastError (ERROR_INVALID_ACCESS);
- return FALSE;
- }
- }
- else
- {
- log_debug (" make_pipe (ctx=%i): error: invalid access\n", ctx_arg);
- SetLastError (ERROR_INVALID_ACCESS);
- return FALSE;
- }
- }
-
- EnterCriticalSection (&pimpl->critsect);
- pimpl->refcnt++;
- if (pimpl->monitor_proc != INVALID_HANDLE_VALUE)
- {
- /* If there is a monitor to the pipe, then it's now about time
- to ask it to go away. */
- log_debug (" make_pipe (ctx=%i): waking up monitor for pipe 0x%p\n",
- ctx_arg, pimpl);
- pimpl->flags |= PIPE_FLAG_HALT_MONITOR;
- if (pimpl->monitor_access & GENERIC_READ)
- SetEvent (pimpl->data_available);
- else
- SetEvent (pimpl->space_available);
- }
- LeaveCriticalSection (&pimpl->critsect);
-
- ctx->pipeimpl = pimpl;
-
- if (peerctx)
- {
- log_debug (" make_pipe (ctx=%i): success: combined with peer ctx=%i "
- "(pipe 0x%p)\n", ctx_arg, OPNCTX_TO_IDX (peerctx), pimpl);
- }
- else
- {
- log_debug (" make_pipe (ctx=%i): success: combined with "
- "pipe 0x%p\n", ctx_arg, OPNCTX_TO_IDX (peerctx), pimpl);
- }
-
- return TRUE;
-}
-
-
-/* opnctx_table_s is locked on entering and on exit. */
-static BOOL
-unblock_call (opnctx_t ctx)
-{
- /* If there is no pipe object, no thread can be blocked. */
- if (!ctx->pipeimpl)
- return TRUE;
-
- EnterCriticalSection (&ctx->pipeimpl->critsect);
- if (ctx->access_code & GENERIC_READ)
- {
- ctx->pipeimpl->flags |= PIPE_FLAG_UNBLOCK_READER;
- SetEvent (ctx->pipeimpl->data_available);
- }
- else if (ctx->access_code & GENERIC_WRITE)
- {
- ctx->pipeimpl->flags |= PIPE_FLAG_UNBLOCK_WRITER;
- SetEvent (ctx->pipeimpl->space_available);
- }
- LeaveCriticalSection (&ctx->pipeimpl->critsect);
-
- return TRUE;
-}
-
-
-static DWORD CALLBACK
-monitor_main (void *arg)
-{
- pipeimpl_t pimpl = (pipeimpl_t) arg;
- HANDLE handles[2];
- int idx;
-
- log_debug ("starting monitor (pimpl=0x%p)\n", pimpl);
-
- EnterCriticalSection (&pimpl->critsect);
- /* Putting proc first in the array is convenient, as this is a hard
- break-out condition (and thus takes precedence in WFMO). The
- reader/writer event is a soft condition, which also requires a
- flag to be set. */
- handles[0] = pimpl->monitor_proc;
- if (pimpl->monitor_access & GENERIC_READ)
- handles[1] = pimpl->data_available;
- else
- handles[1] = pimpl->space_available;
-
- retry:
- /* First check if the peer has not gone away. If it has, we are done. */
- if (pimpl->flags & PIPE_FLAG_HALT_MONITOR)
- {
- log_debug ("monitor (pimpl=0x%p): done: monitored process taking over\n",
- pimpl);
- }
- else
- {
- DWORD res;
-
- LeaveCriticalSection (&pimpl->critsect);
- log_debug ("monitor (pimpl=0x%p): waiting\n", pimpl);
- res = WaitForMultipleObjects (2, handles, FALSE, INFINITE);
- log_debug ("monitor (pimpl=0x%p): resuming\n", pimpl);
- EnterCriticalSection (&pimpl->critsect);
-
- if (res == WAIT_FAILED)
- {
- log_debug ("monitor (pimpl=0x%p): WFMO failed: %i\n",
- pimpl, GetLastError ());
- }
- else if (res == WAIT_OBJECT_0)
- {
- log_debug ("monitor (pimpl=0x%p): done: monitored process died\n",
- pimpl);
- }
- else if (res == WAIT_OBJECT_0 + 1)
- goto retry;
- else
- {
- log_debug ("monitor (pimpl=0x%p): unexpected result of WFMO: %i\n",
- pimpl, res);
- }
- }
-
- log_debug ("ending monitor (pimpl=0x%p)\n", pimpl);
-
- /* Remove the monitor from the monitor table. */
- LeaveCriticalSection (&pimpl->critsect);
- EnterCriticalSection (&opnctx_table_cs);
- for (idx = 0; idx < monitor_table_size; idx++)
- if (monitor_table[idx].inuse
- && monitor_table[idx].pipeimpl == pimpl)
- {
- monitor_table[idx].pipeimpl = NULL;
- monitor_table[idx].inuse = 0;
- break;
- }
- if (idx == monitor_table_size)
- log_debug ("can not find monitor in table (pimpl=0x%p)\n", pimpl);
- LeaveCriticalSection (&opnctx_table_cs);
- EnterCriticalSection (&pimpl->critsect);
-
- /* Now do the rest of the cleanup. */
- CloseHandle (pimpl->monitor_proc);
- pimpl->monitor_proc = INVALID_HANDLE_VALUE;
- pimpl->monitor_access = 0;
- pimpl->monitor_rvid = 0;
- pimpl->flags &= ~PIPE_FLAG_HALT_MONITOR;
- pipeimpl_unref (pimpl);
-
- return 0;
-}
-
-
-/* opnctx_table_s is locked on entering and on exit. */
-static BOOL
-assign_rvid (opnctx_t ctx, DWORD rvid, DWORD pid)
-{
- DWORD ctx_arg = OPNCTX_TO_IDX (ctx);
- int idx;
- opnctx_t peerctx;
- HANDLE monitor_hnd;
- HANDLE proc;
- pipeimpl_t pimpl;
- monitor_t monitor;
-
- log_debug (" assign_rvid (ctx=%i, rvid=%08lx, pid=%08lx)\n",
- ctx_arg, rvid, pid);
-
- for (idx = 0; idx < opnctx_table_size; idx++)
- if (opnctx_table[idx].inuse && opnctx_table[idx].rvid == rvid)
- {
- peerctx = &opnctx_table[idx];
- break;
- }
- if (! peerctx)
- {
- log_debug (" assign_rvid (ctx=%i): error: not found\n", ctx_arg);
- SetLastError (ERROR_NOT_FOUND);
- return FALSE;
- }
-
- if (peerctx->pipeimpl
- && peerctx->pipeimpl->monitor_proc != INVALID_HANDLE_VALUE)
- {
- log_debug (" assign_rvid (ctx=%i): error: rvid already assigned\n",
- ctx_arg);
- SetLastError (ERROR_ALREADY_ASSIGNED);
- return FALSE;
- }
-
- proc = OpenProcess (0, FALSE, pid);
- if (proc == NULL)
- {
- log_debug (" assign_rvid (ctx=%i): error: process not found\n",
- ctx_arg);
- return FALSE;
- }
-
- /* Acquire a reference to the pipe. We don't want accesss to be
- checked. */
- pimpl = assert_pipeimpl (peerctx);
- if (! pimpl)
- {
- CloseHandle (proc);
- return FALSE;
- }
-
- monitor = allocate_monitor ();
- if (!monitor)
- {
- log_debug (" assign_rvid (ctx=%i): error: could not allocate monitor\n",
- ctx_arg);
- CloseHandle (proc);
- return FALSE;
- }
- monitor->pipeimpl = pimpl;
-
- EnterCriticalSection (&pimpl->critsect);
- pimpl->refcnt++;
-
- /* The monitor shadows the peer, so it takes its access. Our access
- is the opposite of that of the peer. */
- pimpl->monitor_proc = proc;
- if (peerctx->access_code == GENERIC_READ)
- pimpl->monitor_access = GENERIC_WRITE;
- else
- pimpl->monitor_access = GENERIC_READ;
- pimpl->monitor_rvid = rvid;
-
- monitor_hnd = CreateThread (NULL, 0, monitor_main, pimpl, 0, NULL);
- if (monitor_hnd == INVALID_HANDLE_VALUE)
- {
- pimpl->monitor_access = 0;
- pimpl->monitor_proc = INVALID_HANDLE_VALUE;
- LeaveCriticalSection (&pimpl->critsect);
-
- monitor->pipeimpl = NULL;
- monitor->inuse = 0;
-
- CloseHandle (proc);
- log_debug (" assign_rvid (ctx=%i): error: can not create monitor\n",
- ctx_arg);
- return FALSE;
- }
- CloseHandle (monitor_hnd);
-
- /* Consume the pimpl reference. */
- LeaveCriticalSection (&pimpl->critsect);
-
- return TRUE;
-}
-
-
-BOOL
-GPG_IOControl (DWORD opnctx_arg, DWORD code, void *inbuf, DWORD inbuflen,
- void *outbuf, DWORD outbuflen, DWORD *actualoutlen)
-{
- opnctx_t opnctx;
- BOOL result = FALSE;
- LONG rvid;
- LONG pid;
-
- log_debug ("GPG_IOControl (ctx=%i, %08x)\n", opnctx_arg, code);
-
- EnterCriticalSection (&opnctx_table_cs);
- opnctx = verify_opnctx (opnctx_arg);
- if (!opnctx)
- {
- log_debug ("GPG_IOControl (ctx=%i): error: could not access context\n",
- opnctx_arg);
- goto leave;
- }
- if (opnctx->is_log)
- {
- log_debug ("GPG_IOControl (ctx=%i): error: invalid code %u"
- " for log device\n", opnctx_arg, (unsigned int)code);
- SetLastError (ERROR_INVALID_PARAMETER);
- goto leave;
- }
-
- switch (code)
- {
- case GPGCEDEV_IOCTL_GET_RVID:
- log_debug ("GPG_IOControl (ctx=%i): code: GET_RVID\n", opnctx_arg);
- if (inbuf || inbuflen || !outbuf || outbuflen < sizeof (LONG))
- {
- log_debug ("GPG_IOControl (ctx=%i): error: invalid parameter\n",
- opnctx_arg);
- SetLastError (ERROR_INVALID_PARAMETER);
- goto leave;
- }
-
- if (! opnctx->rvid)
- opnctx->rvid = create_rendezvous_id ();
- log_debug ("GPG_IOControl (ctx=%i): returning rvid: %08lx\n",
- opnctx_arg, opnctx->rvid);
-
- memcpy (outbuf, &opnctx->rvid, sizeof (LONG));
- if (actualoutlen)
- *actualoutlen = sizeof (LONG);
- result = TRUE;
- break;
-
- case GPGCEDEV_IOCTL_MAKE_PIPE:
- log_debug ("GPG_IOControl (ctx=%i): code: MAKE_PIPE\n", opnctx_arg);
- if (!inbuf || inbuflen < sizeof (LONG)
- || outbuf || outbuflen || actualoutlen)
- {
- log_debug ("GPG_IOControl (ctx=%i): error: invalid parameter\n",
- opnctx_arg);
- SetLastError (ERROR_INVALID_PARAMETER);
- goto leave;
- }
- memcpy (&rvid, inbuf, sizeof (LONG));
- log_debug ("GPG_IOControl (ctx=%i): make pipe for rvid: %08lx\n",
- opnctx_arg, rvid);
- if (make_pipe (opnctx, rvid))
- result = TRUE;
- break;
-
- case GPGCEDEV_IOCTL_UNBLOCK:
- log_debug ("GPG_IOControl (ctx=%i): code: UNBLOCK\n", opnctx_arg);
- if (inbuf || inbuflen || outbuf || outbuflen || actualoutlen)
- {
- log_debug ("GPG_IOControl (ctx=%i): error: invalid parameter\n",
- opnctx_arg);
- SetLastError (ERROR_INVALID_PARAMETER);
- goto leave;
- }
-
- if (unblock_call (opnctx))
- result = TRUE;
- break;
-
- case GPGCEDEV_IOCTL_ASSIGN_RVID:
- log_debug ("GPG_IOControl (ctx=%i): code: ASSIGN_RVID\n", opnctx_arg);
- if (!inbuf || inbuflen < 2 * sizeof (DWORD)
- || outbuf || outbuflen || actualoutlen)
- {
- log_debug ("GPG_IOControl (ctx=%i): error: invalid parameter\n",
- opnctx_arg);
- SetLastError (ERROR_INVALID_PARAMETER);
- goto leave;
- }
- memcpy (&rvid, inbuf, sizeof (DWORD));
- memcpy (&pid, ((char *) inbuf) + sizeof (DWORD), sizeof (DWORD));
- log_debug ("GPG_IOControl (ctx=%i): assign rvid %08lx to pid %08lx\n",
- opnctx_arg, rvid, pid);
- if (assign_rvid (opnctx, rvid, pid))
- result = TRUE;
- break;
-
- case IOCTL_PSL_NOTIFY:
- /* This notification is received if the application's main
- thread exits and the application has other threads running
- and the application has open handles for this device. What
- we do is to unblock them all simialr to an explicit unblock
- call. */
- log_debug ("GPG_IOControl (ctx=%i): code: NOTIFY\n", opnctx_arg);
-
- if (unblock_call (opnctx))
- result = TRUE;
- break;
-
- default:
- log_debug ("GPG_IOControl (ctx=%i): code: (unknown)\n", opnctx_arg);
- SetLastError (ERROR_INVALID_PARAMETER);
- break;
- }
-
- log_debug ("GPG_IOControl (ctx=%i): success: result=%d\n", opnctx_arg,
- result);
-
- leave:
- LeaveCriticalSection (&opnctx_table_cs);
- return result;
-}
-
-
-
-void
-GPG_PowerUp (DWORD devctx)
-{
- log_debug ("GPG_PowerUp (devctx=%i)\n", devctx);
-}
-
-
-
-void
-GPG_PowerDown (DWORD devctx)
-{
- log_debug ("GPG_PowerDown (devctx=%i)\n", devctx);
-}
-
-
-
-
-
-/* Entry point called by the DLL loader. */
-int WINAPI
-DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserved)
-{
- (void)reserved;
-
- switch (reason)
- {
- case DLL_PROCESS_ATTACH:
- InitializeCriticalSection (&opnctx_table_cs);
- InitializeCriticalSection (&logcontrol.lock);
- break;
-
- case DLL_THREAD_ATTACH:
- break;
-
- case DLL_THREAD_DETACH:
- break;
-
- case DLL_PROCESS_DETACH:
- DeleteCriticalSection (&opnctx_table_cs);
- break;
-
- default:
- break;
- }
-
- return TRUE;
-}
diff --git a/src/gpgcedev.def b/src/gpgcedev.def
deleted file mode 100644
index bc52d3a..0000000
--- a/src/gpgcedev.def
+++ /dev/null
@@ -1,34 +0,0 @@
-; gpgcedev.def - List of symbols to export for gpgcedev.
-; Copyright (C) 2010 Free Software Foundation, Inc.
-;
-; This file is part of Assuan.
-;
-; Assuan is free software; you can redistribute it and/or modify it
-; under the terms of the GNU Lesser General Public License as
-; published by the Free Software Foundation; either version 3 of
-; the License, or (at your option) any later version.
-;
-; Assuan is distributed in the hope that it will be useful, but
-; WITHOUT ANY WARRANTY; without even the implied warranty of
-; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-; Lesser General Public License for more details.
-;
-; 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/>.
-; SPDX-License-Identifier: LGPL-3.0+
-
-
-EXPORTS
- GPG_Init
- GPG_Deinit
- GPG_Open
- GPG_Close
- GPG_Read
- GPG_Write
- GPG_Seek
- GPG_IOControl
- GPG_PowerUp
- GPG_PowerDown
-
-; END
-
diff --git a/src/gpgcemgr.c b/src/gpgcemgr.c
deleted file mode 100644
index 5b4f56e..0000000
--- a/src/gpgcemgr.c
+++ /dev/null
@@ -1,608 +0,0 @@
-/* gpgcempr.c - Manager for GPG CE devices
- * Copyright (C) 2010 Free Software Foundation, Inc.
- *
- * This file is part of Assuan.
- *
- * Assuan is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or (at your option) any later version.
- *
- * Assuan is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * 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/>.
- * SPDX-License-Identifier: LGPL-3.0+
- */
-
-#define _WIN32_WCE 0x0500
-
-#include <stdio.h>
-#include <windows.h>
-
-#define PGM "gpgcemgr"
-
-#define GPGCEDEV_KEY_NAME L"Drivers\\GnuPG_Device"
-#define GPGCEDEV_KEY_NAME2 L"Drivers\\GnuPG_Log"
-#define GPGCEDEV_DLL_NAME L"gpgcedev.dll"
-#define GPGCEDEV_PREFIX L"GPG"
-
-
-static char *
-wchar_to_utf8 (const wchar_t *string)
-{
- int n;
- size_t length = wcslen (string);
- char *result;
-
- n = WideCharToMultiByte (CP_UTF8, 0, string, length, NULL, 0, NULL, NULL);
- if (n < 0 || (n+1) <= 0)
- abort ();
-
- result = malloc (n+1);
- if (!result)
- abort ();
- n = WideCharToMultiByte (CP_ACP, 0, string, length, result, n, NULL, NULL);
- if (n < 0)
- abort ();
-
- result[n] = 0;
- return result;
-}
-
-
-static wchar_t *
-utf8_to_wchar (const char *string)
-{
- int n;
- size_t nbytes;
- wchar_t *result;
-
- if (!string)
- abort ();
-
- n = MultiByteToWideChar (CP_UTF8, 0, string, -1, NULL, 0);
- if (n < 0)
- abort ();
- nbytes = (size_t)(n+1) * sizeof(*result);
- if (nbytes / sizeof(*result) != (n+1))
- abort ();
- result = malloc (nbytes);
- if (!result)
- abort ();
-
- n = MultiByteToWideChar (CP_UTF8, 0, string, -1, result, n);
- if (n < 0)
- abort ();
- return result;
-}
-
-
-static int
-install (void)
-{
- HKEY handle;
- DWORD disp, dw;
- int rc;
-
- if ((rc=RegCreateKeyEx (HKEY_LOCAL_MACHINE, GPGCEDEV_KEY_NAME, 0, NULL, 0,
- KEY_WRITE, NULL, &handle, &disp)))
- {
- fprintf (stderr, PGM": error creating registry key 1: rc=%d\n", rc);
- return 1;
- }
-
- RegSetValueEx (handle, L"dll", 0, REG_SZ,
- (void*)GPGCEDEV_DLL_NAME, sizeof (GPGCEDEV_DLL_NAME));
- RegSetValueEx (handle, L"prefix", 0, REG_SZ,
- (void*)GPGCEDEV_PREFIX, sizeof (GPGCEDEV_PREFIX));
-
- dw = 1;
- RegSetValueEx (handle, L"Index", 0, REG_DWORD, (void*)&dw, sizeof dw);
-
- RegCloseKey (handle);
-
- fprintf (stderr, PGM": registry key 1 created\n");
-
- if ((rc=RegCreateKeyEx (HKEY_LOCAL_MACHINE, GPGCEDEV_KEY_NAME2, 0, NULL, 0,
- KEY_WRITE, NULL, &handle, &disp)))
- {
- fprintf (stderr, PGM": error creating registry key 2: rc=%d\n", rc);
- return 1;
- }
-
- RegSetValueEx (handle, L"dll", 0, REG_SZ,
- (void*)GPGCEDEV_DLL_NAME, sizeof (GPGCEDEV_DLL_NAME));
- RegSetValueEx (handle, L"prefix", 0, REG_SZ,
- (void*)GPGCEDEV_PREFIX, sizeof (GPGCEDEV_PREFIX));
-
- dw = 2;
- RegSetValueEx (handle, L"Index", 0, REG_DWORD, (void*)&dw, sizeof dw);
-
- RegCloseKey (handle);
-
- fprintf (stderr, PGM": registry key 2 created\n");
-
-
- return 0;
-}
-
-
-static int
-deinstall (wchar_t *name)
-{
- int result = 0;
- HANDLE shd;
- DEVMGR_DEVICE_INFORMATION dinfo;
-
- memset (&dinfo, 0, sizeof dinfo);
- dinfo.dwSize = sizeof dinfo;
- shd = FindFirstDevice (DeviceSearchByLegacyName, name, &dinfo);
- if (shd == INVALID_HANDLE_VALUE)
- {
- if (GetLastError () == 18)
- fprintf (stderr, PGM": device not found\n");
- else
- {
- fprintf (stderr, PGM": FindFirstDevice failed: rc=%d\n",
- (int)GetLastError ());
- result = 1;
- }
- }
- else
- {
- fprintf (stderr, PGM": ActivateDevice handle is %p\n", dinfo.hDevice);
- if (dinfo.hDevice && dinfo.hDevice != INVALID_HANDLE_VALUE)
- {
- if (!DeactivateDevice (dinfo.hDevice))
- {
- fprintf (stderr, PGM": DeactivateDevice failed: rc=%d\n",
- (int)GetLastError ());
- result = 1;
- }
- else
- fprintf (stderr, PGM": DeactivateDevice succeeded\n");
- }
- FindClose (shd);
- }
-
- return result;
-}
-
-
-static int
-enable_debug (int yes)
-{
- HKEY handle;
- DWORD disp;
- int rc;
-
- if ((rc=RegCreateKeyEx (HKEY_LOCAL_MACHINE, GPGCEDEV_KEY_NAME, 0, NULL, 0,
- KEY_WRITE, NULL, &handle, &disp)))
- {
- fprintf (stderr, PGM": error creating debug registry key: rc=%d\n", rc);
- return 1;
- }
-
- RegSetValueEx (handle, L"debugDriver", 0, REG_SZ,
- (void*)(yes? L"1":L"0"), sizeof L"0");
- RegCloseKey (handle);
- return 0;
-}
-
-
-static int
-enable_log (int yes)
-{
- HKEY handle;
- DWORD disp;
- int rc;
-
- if ((rc=RegCreateKeyEx (HKEY_LOCAL_MACHINE, GPGCEDEV_KEY_NAME2, 0, NULL, 0,
- KEY_WRITE, NULL, &handle, &disp)))
- {
- fprintf (stderr, PGM": error creating debug registry key: rc=%d\n", rc);
- return 1;
- }
-
- RegSetValueEx (handle, L"enableLog", 0, REG_SZ,
- (void*)(yes? L"1":L"0"), sizeof L"0");
- RegCloseKey (handle);
- return 0;
-}
-
-
-
-/* Kudos to Scott Seligman <scott@scottandmichelle.net> for his work
- on the reverse engineering. */
-struct htc_sensor_s
-{
- SHORT tilt_x; // From -1000 to 1000 (about), 0 is flat
- SHORT tilt_y; // From -1000 to 1000 (about), 0 is flat
- SHORT tilt_z; // From -1000 to 1000 (about)
- DWORD angle_x; // 0 .. 359
- DWORD angle_y; // From 0 to 359
- DWORD orientation; // 0.. 5?
- DWORD unknown; // Handle?
-};
-typedef struct htc_sensor_s *htc_sensor_t;
-
-static HANDLE (WINAPI *HTCSensorOpen) (DWORD);
-static void (WINAPI *HTCSensorClose) (HANDLE);
-static DWORD (WINAPI *HTCSensorGetDataOutput) (HANDLE, htc_sensor_t);
-
-static int
-load_sensor_api (void)
-{
- static HMODULE dll_hd;
-
- if (dll_hd)
- return 0;
-
- dll_hd = LoadLibrary (L"HTCSensorSDK.dll");
- if (!dll_hd)
- {
- fprintf (stderr, PGM": error loading sensor DLL: rc=%d\n",
- (int)GetLastError ());
- return 1;
- }
-
- HTCSensorOpen = (void*)GetProcAddress (dll_hd, L"HTCSensorOpen");
- if (HTCSensorOpen)
- HTCSensorClose = (void*)GetProcAddress (dll_hd, L"HTCSensorClose");
- if (HTCSensorClose)
- HTCSensorGetDataOutput = (void*)
- GetProcAddress (dll_hd, L"HTCSensorGetDataOutput");
- if (!HTCSensorGetDataOutput)
- {
- fprintf (stderr, PGM": error loading function from sensor DLL: rc=%d\n",
- (int)GetLastError ());
- CloseHandle (dll_hd);
- return 1;
- }
- return 0;
-}
-
-
-static int
-gravity (void)
-{
- int rc;
- HANDLE sensor;
- struct htc_sensor_s lastdata;
- struct htc_sensor_s data;
-
- rc = load_sensor_api ();
- if (rc)
- return rc;
-
- sensor = HTCSensorOpen (1 /* tilt sensor */);
- if (!sensor || sensor == INVALID_HANDLE_VALUE)
- {
- fprintf (stderr, PGM": error opening gravity sensor: rc=%d\n",
- (int)GetLastError ());
- HTCSensorClose (sensor);
- return 1;
- }
-
- memset (&lastdata, 0, sizeof lastdata);
- while (HTCSensorGetDataOutput (sensor, &data))
- {
- if (lastdata.tilt_x/10 != data.tilt_x/10
- || lastdata.tilt_y/10 != data.tilt_y/10
- || lastdata.tilt_z/10 != data.tilt_z/10
- || lastdata.angle_x/5 != data.angle_x/5
- || lastdata.angle_y/5 != data.angle_y/5
- || lastdata.orientation != data.orientation)
- {
- lastdata = data;
- printf ("tilt: x=%-5d y=%-5d z=%-5d "
- "angle: x=%-3d y=%-3d "
- "ori: %d\n",
- (int)data.tilt_x, (int)data.tilt_y, (int)data.tilt_z,
- (int)data.angle_x, (int)data.angle_y,
- (int)data.orientation);
- }
- Sleep (200);
- }
- fprintf (stderr, PGM": reading sensor data failed: rc=%d\n",
- (int)GetLastError ());
- HTCSensorClose (sensor);
- return 0;
-}
-
-
-
-/* No GPD1 device on the HTC Touch Pro 2. */
-# if 0
-static int
-gps_raw (void)
-{
- HANDLE hd;
- char buffer[1000];
- unsigned long nread;
- int count;
-
- hd = CreateFile (L"GPD1:", GENERIC_READ, FILE_SHARE_READ,
- NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (hd == INVALID_HANDLE_VALUE)
- {
- fprintf (stderr, PGM": can't open `GPD1': rc=%d\n",
- (int)GetLastError ());
- return 1;
- }
- fprintf (stderr, PGM": GPS device successfully opened\n");
-
- for (count=0; count < 100; count++)
- {
- if (!ReadFile (hd, buffer, sizeof buffer-1, &nread, NULL))
- {
- fprintf (stderr, PGM": error reading `GPD1': rc=%d\n",
- (int)GetLastError ());
- CloseHandle (hd);
- return 1;
- }
- buffer[nread-1] = 0;
- fputs (buffer, stdout);
- }
-
- CloseHandle (hd);
- return 0;
-}
-#endif
-
-/* Untested samples for CE6. */
-#if 0
-static int
-gps (void)
-{
- HANDLE hd;
- GPS_POSITION pos;
-
- hd = GPSOpenDevice (NULL, NULL, NULL, 0);
- if (hd == INVALID_HANDLE_VALUE)
- {
- fprintf (stderr, PGM": GPSOpenDevice failed: rc=%d\n",
- (int)GetLastError ());
- return 1;
- }
- fprintf (stderr, PGM": GPS device successfully opened\n");
-
- if (GPSGetPosition (hd, &pos, 2000, 0))
- {
- fprintf (stderr, PGM": GPSGetPosition failed: rc=%d\n",
- (int)GetLastError ());
- GPSCloseDevice (hd);
- return 1;
- }
-
-
- GPSCloseDevice (hd);
- return 0;
-}
-#endif
-
-
-static void
-set_show_registry (const wchar_t *key, const wchar_t *name, const char *value)
-{
- HKEY handle;
- DWORD disp, nbytes, n1, type;
- int rc;
-
- if ((rc=RegCreateKeyEx (HKEY_LOCAL_MACHINE, key, 0, NULL, 0,
- KEY_WRITE, NULL, &handle, &disp)))
- {
- fprintf (stderr, PGM": error creating registry key: rc=%d\n", rc);
- return;
- }
-
- if (value && !stricmp (value, "none"))
- {
- if ((rc=RegDeleteValue (handle, name)))
- fprintf (stderr, PGM": error deleting registry value: rc=%d\n", rc);
- }
- else if (value)
- {
- wchar_t *tmp = utf8_to_wchar (value);
- if ((rc=RegSetValueEx (handle, name, 0, REG_SZ,
- (void*)tmp, wcslen (tmp)*sizeof(wchar_t))))
- fprintf (stderr, PGM": error setting registry value: rc=%d\n", rc);
- free (tmp);
- }
- else
- {
- nbytes = 2;
- if ((rc=RegQueryValueEx (handle, name, 0, NULL, NULL, &nbytes)))
- {
- if (rc == ERROR_FILE_NOT_FOUND)
- fprintf (stderr, PGM": registry value not set\n");
- else
- fprintf (stderr, PGM": error reading registry value: rc=%d\n", rc);
- }
- else
- {
- char *result = malloc ((n1=nbytes+2));
- if (!result)
- fprintf (stderr, PGM": malloc failed: rc=%d\n",
- (int)GetLastError ());
- else if ((rc=RegQueryValueEx (handle, name, 0, &type,
- (void*)result, &n1)))
- {
- fprintf (stderr, PGM": error reading registry value (2): "
- "rc=%d\n", rc);
- free (result);
- }
- else
- {
- result[nbytes] = 0; /* Make sure it is a string. */
- result[nbytes+1] = 0;
- if (type == REG_SZ)
- {
- wchar_t *tmp = (void*)result;
- result = wchar_to_utf8 (tmp);
- free (tmp);
- printf ("%s\n", result);
- }
- else
- fprintf (stderr, PGM": registry value is not a string\n");
- free (result);
- }
- }
- }
-
- RegCloseKey (handle);
-}
-
-
-
-int
-main (int argc, char **argv)
-{
- int result = 0;
-
- if (argc > 1 && !strcmp (argv[1], "--register"))
- result = install ();
- else if (argc > 1 && !strcmp (argv[1], "--deactivate"))
- {
- if (deinstall (L"GPG1:"))
- result = 1;
- if (deinstall (L"GPG2:"))
- result = 1;
- }
- else if (argc > 1 && !strcmp (argv[1], "--activate"))
- {
- HANDLE hd;
-
- /* This is mainly for testing. The activation is usually done
- right before the device is opened. */
- if (ActivateDevice (GPGCEDEV_KEY_NAME, 0) == INVALID_HANDLE_VALUE)
- {
- fprintf (stderr, PGM": ActivateDevice 1 failed: rc=%d\n",
- (int)GetLastError ());
- result = 1;
- }
- else if (ActivateDevice (GPGCEDEV_KEY_NAME2, 0) == INVALID_HANDLE_VALUE)
- {
- fprintf (stderr, PGM": ActivateDevice 2 failed: rc=%d\n",
- (int)GetLastError ());
- result = 1;
- }
- else
- {
- fprintf (stderr, PGM": devices activated\n");
- hd = CreateFile (L"GPG1:", GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (hd == INVALID_HANDLE_VALUE)
- {
- fprintf (stderr, PGM": opening `GPG1:' failed: rc=%d\n",
- (int)GetLastError ());
- result = 1;
- }
- else
- {
- fprintf (stderr, PGM": device `GPG1:' seems to work\n");
- CloseHandle (hd);
- }
-
- hd = CreateFile (L"GPG2:", GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (hd == INVALID_HANDLE_VALUE)
- {
- fprintf (stderr, PGM": opening `GPG2:' failed: rc=%d\n",
- (int)GetLastError ());
- result = 1;
- }
- else
- {
- fprintf (stderr, PGM": device `GPG2:' seems to work\n");
- CloseHandle (hd);
- }
-
- }
- }
- else if (argc > 1 && !strcmp (argv[1], "--gravity"))
- result = gravity ();
- /* else if (argc > 1 && !strcmp (argv[1], "--gps")) */
- /* result = gps (); */
- else if (argc > 1 && !strcmp (argv[1], "--log"))
- {
- HANDLE hd;
-
- hd = CreateFile (L"GPG2:", GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (hd == INVALID_HANDLE_VALUE)
- {
- fprintf (stderr, PGM": opening `GPG2:' failed: rc=%d\n",
- (int)GetLastError ());
- result = 1;
- }
- else
- {
- char marktwain[] = "I have never let my schooling interfere"
- " with my education.\n";
- DWORD nwritten;
- int i;
-
- for (i=0; i < 3; i++)
- {
- if (!WriteFile (hd, marktwain, strlen (marktwain),
- &nwritten, NULL))
- {
- fprintf (stderr, PGM": writing `GPG2:' failed: rc=%d\n",
- (int)GetLastError ());
- result = 1;
- }
- Sleep (200);
- }
- CloseHandle (hd);
- }
- }
- else if (argc > 1 && !strcmp (argv[1], "--enable-debug"))
- result = enable_debug (1);
- else if (argc > 1 && !strcmp (argv[1], "--disable-debug"))
- result = enable_debug (0);
- else if (argc > 1 && !strcmp (argv[1], "--enable-log"))
- result = enable_log (1);
- else if (argc > 1 && !strcmp (argv[1], "--disable-log"))
- result = enable_log (0);
- else if (argc > 1 && !strcmp (argv[1], "--gpgme-log"))
- set_show_registry (L"Software\\GNU\\gpgme", L"debug",
- argc > 2? argv[2] : NULL);
- else if (argc > 1 && !strcmp (argv[1], "--gnupg-log"))
- set_show_registry (L"Software\\GNU\\GnuPG", L"DefaultLogFile",
- argc > 2? argv[2] : NULL);
- else
- {
- fprintf (stderr,
- "usage: " PGM " COMMAND\n"
- "Commands are:\n"
- " --register Register the GPGCEDEV device\n"
- " --deactivate Deactivate the GPGCEDEV device\n"
- " --activate Activate the GPGCEDEV devive\n"
- " --enable-debug Enable debugging of GPGCEDEV device\n"
- " --disable-debug Disable debugging of GPGCEDEV device\n"
- " --gravity Show output of the gravity sensor\n"
- " --enable-log Enable logging via \"GPG2:\"\n"
- " --disable-log Disable logging via \"GPG2:\"\n"
- " --log Write a test string to \"GPG2:\"\n"
- " --gpgme-log [ARG] Show or set GPGME log output\n"
- " --gnupg-log [ARG] Show or set GnuPG default log file\n"
- " (No ARG shows, \"none\" disables)\n"
- );
- result = 1;
- }
-
- fflush (stdout);
- fflush (stderr);
- Sleep (1000);
- return result;
-}
-
-
diff --git a/src/setenv.c b/src/setenv.c
index 3410b30..487de4e 100644
--- a/src/setenv.c
+++ b/src/setenv.c
@@ -21,8 +21,6 @@
# include <config.h>
#endif
-#ifndef HAVE_W32CE_SYSTEM
-
#define setenv _assuan_setenv
#define unsetenv _assuan_unsetenv
#define clearenv _assuan_clearenv
@@ -354,5 +352,3 @@ weak_alias (__setenv, setenv)
weak_alias (__unsetenv, unsetenv)
weak_alias (__clearenv, clearenv)
#endif
-
-#endif /*!HAVE_W32CE_SYSTEM*/
diff --git a/src/system-w32ce.c b/src/system-w32ce.c
deleted file mode 100644
index da5dcf2..0000000
--- a/src/system-w32ce.c
+++ /dev/null
@@ -1,706 +0,0 @@
-/* system-w32ce.c - System support functions for WindowsCE.
- * Copyright (C) 2010 Free Software Foundation, Inc.
- *
- * This file is part of Assuan.
- *
- * Assuan is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Assuan is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * 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/>.
- * SPDX-License-Identifier: LGPL-2.1+
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <errno.h>
-#include <time.h>
-# ifdef HAVE_WINSOCK2_H
-# include <winsock2.h>
-# endif
-#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)
-
-
-
-
-static wchar_t *
-utf8_to_wchar (const char *string)
-{
- int n;
- size_t nbytes;
- wchar_t *result;
-
- if (!string)
- return NULL;
-
- n = MultiByteToWideChar (CP_UTF8, 0, string, -1, NULL, 0);
- if (n < 0)
- {
- 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 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;
-}
-
-
-
-/* Sleep for the given number of microseconds. Default
- implementation. */
-void
-__assuan_usleep (assuan_context_t ctx, unsigned int usec)
-{
- if (usec)
- Sleep (usec / 1000);
-}
-
-
-
-/* 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 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;
-}
-
-
-/* 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 (!rvid)
- {
- SetLastError (ERROR_INVALID_HANDLE);
- return INVALID_HANDLE_VALUE;
- }
-
- 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_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;
-}
-
-
-/* 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,
- "CreatePipe failed: %s", _assuan_w32_strerror (ctx, -1));
- gpg_err_set_errno (EIO);
- return -1;
- }
-
- if (inherit_idx)
- {
- fd[0] = hd;
- fd[1] = (void*)rvid;
- }
- else
- {
- fd[0] = (void*)rvid;
- fd[1] = hd;
- }
- return 0;
-}
-
-
-
-/* Close the given file descriptor, created with _assuan_pipe or one
- of the socket functions. Default implementation. */
-int
-__assuan_close (assuan_context_t ctx, assuan_fd_t fd)
-{
- int rc = closesocket (HANDLE2SOCKET(fd));
- int err = WSAGetLastError ();
-
- /* Note that gpg_err_set_errno on Windows CE overwrites
- WSAGetLastError() (via SetLastError()). */
- if (rc)
- gpg_err_set_errno (_assuan_sock_wsa2errno (err));
- if (rc && err == WSAENOTSOCK)
- {
- rc = CloseHandle (fd);
- if (rc)
- /* FIXME. */
- gpg_err_set_errno (EIO);
- }
- return rc;
-}
-
-
-
-ssize_t
-__assuan_read (assuan_context_t ctx, assuan_fd_t fd, void *buffer, size_t size)
-{
- /* Due to the peculiarities of the W32 API we can't use read for a
- network socket and thus we try to use recv first and fallback to
- 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);
-
-#ifdef HAVE_W32CE_SYSTEM
- /* This is a bit of a hack to support stdin over ssh. Note that
- fread buffers fully while getchar is line buffered. Weird, but
- that's the way it is. ASSUAN_STDIN and ASSUAN_STDOUT are
- special handle values that shouldn't occur in the wild. */
- if (fd == ASSUAN_STDIN)
- {
- int i = 0;
- int chr;
- while (i < size)
- {
- chr = getchar();
- if (chr == EOF)
- break;
- ((char*)buffer)[i++] = (char) chr;
- if (chr == '\n')
- break;
- }
- return TRACE_SYSRES (i);
- }
-#endif
-
- res = recv (HANDLE2SOCKET (fd), buffer, size, 0);
- if (res == -1)
- {
- TRACE_LOG1 ("recv failed: rc=%d", (int)WSAGetLastError ());
- switch (WSAGetLastError ())
- {
- case WSAENOTSOCK:
- {
- DWORD nread = 0;
-
- res = ReadFile (fd, buffer, size, &nread, NULL);
- if (! res)
- {
- TRACE_LOG1 ("ReadFile failed: rc=%d", (int)GetLastError ());
- switch (GetLastError ())
- {
- case ERROR_BROKEN_PIPE:
- gpg_err_set_errno (EPIPE);
- break;
-
- case ERROR_PIPE_NOT_CONNECTED:
- case ERROR_BUSY:
- gpg_err_set_errno (EAGAIN);
- break;
-
- default:
- gpg_err_set_errno (EIO);
- }
- res = -1;
- }
- else
- res = (int) nread;
- }
- break;
-
- case WSAEWOULDBLOCK:
- gpg_err_set_errno (EAGAIN);
- break;
-
- case ERROR_BROKEN_PIPE:
- gpg_err_set_errno (EPIPE);
- break;
-
- default:
- gpg_err_set_errno (EIO);
- break;
- }
- }
- return TRACE_SYSRES (res);
-}
-
-
-
-ssize_t
-__assuan_write (assuan_context_t ctx, assuan_fd_t fd, const void *buffer,
- size_t size)
-{
- /* Due to the peculiarities of the W32 API we can't use write for a
- network socket and thus we try to use send first and fallback to
- write if send detects that it is not a network socket. */
- int res;
-
- TRACE_BEG3 (ctx, ASSUAN_LOG_SYSIO, "__assuan_write", ctx,
- "fd=0x%x, buffer=%p, size=%i", fd, buffer, size);
-
-#ifdef HAVE_W32CE_SYSTEM
- /* This is a bit of a hack to support stdout over ssh. Note that
- fread buffers fully while getchar is line buffered. Weird, but
- that's the way it is. ASSUAN_STDIN and ASSUAN_STDOUT are
- special handle values that shouldn't occur in the wild. */
- if (fd == ASSUAN_STDOUT)
- {
- res = fwrite (buffer, 1, size, stdout);
- return TRACE_SYSRES (res);
- }
-#endif
-
- 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:
- case ERROR_NO_DATA:
- gpg_err_set_errno (EPIPE);
- break;
-
- case ERROR_PIPE_NOT_CONNECTED:
- case ERROR_BUSY:
- gpg_err_set_errno (EAGAIN);
- break;
-
- default:
- gpg_err_set_errno (EIO);
- break;
- }
- res = -1;
- }
- else
- res = (int) nwrite;
- }
- else if (res == -1)
- TRACE_LOG1 ("send call failed: rc=%d", (int)GetLastError ());
- return TRACE_SYSRES (res);
-}
-
-
-
-int
-__assuan_recvmsg (assuan_context_t ctx, assuan_fd_t fd, assuan_msghdr_t msg,
- int flags)
-{
- gpg_err_set_errno (ENOSYS);
- return -1;
-}
-
-
-
-
-int
-__assuan_sendmsg (assuan_context_t ctx, assuan_fd_t fd, assuan_msghdr_t msg,
- int flags)
-{
- gpg_err_set_errno (ENOSYS);
- return -1;
-}
-
-
-
-
-/* Build a command line for use with W32's CreateProcess. On success
- CMDLINE gets the address of a newly allocated string. */
-static int
-build_w32_commandline (assuan_context_t ctx, const char * const *argv,
- 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 = strlen (fdbuf);
- for (i=0; (s = argv[i]); i++)
- {
- 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. */
- }
- n++;
-
- buf = p = _assuan_malloc (ctx, n);
- if (! buf)
- return -1;
-
- p = stpcpy (p, fdbuf);
- for (i = 0; argv[i]; 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\""))
- {
- p = stpcpy (p, "\"");
- for (s = argv[i]; *s; s++)
- {
- *p++ = *s;
- if (*s == '\"')
- *p++ = *s;
- }
- *p++ = '\"';
- *p = 0;
- }
- else
- p = stpcpy (p, argv[i]);
- }
-
- *cmdline = buf;
- return 0;
-}
-
-
-int
-__assuan_spawn (assuan_context_t ctx, pid_t *r_pid, const char *name,
- const char **argv,
- assuan_fd_t fd_in, assuan_fd_t fd_out,
- assuan_fd_t *fd_child_list,
- void (*atfork) (void *opaque, int reserved),
- void *atforkvalue, unsigned int flags)
-{
- PROCESS_INFORMATION pi =
- {
- NULL, /* Returns process handle. */
- 0, /* Returns primary thread handle. */
- 0, /* Returns pid. */
- 0 /* Returns tid. */
- };
- assuan_fd_t fd;
- assuan_fd_t *fdp;
- assuan_fd_t fd_err;
- int fd_err_isnull = 0;
- char *cmdline;
-
- /* 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. */
-
- /* FIXME: As long as we can't decide whether a handle is a real
- handler or an rendezvous id we can't do anything with the
- FD_CHILD_LIST. We can't do much with stderr either, thus we
- better don't pass stderr to the child at all. If we would do so
- and it is not a rendezvous id the client would run into
- problems. */
- fd = assuan_fd_from_posix_fd (fileno (stderr));
- fdp = fd_child_list;
- if (fdp)
- {
- for (; *fdp != ASSUAN_INVALID_FD && *fdp != 0 && *fdp != fd; fdp++)
- ;
- }
- if (!fdp || *fdp == ASSUAN_INVALID_FD)
- fd_err_isnull = 1;
- fd_err = ASSUAN_INVALID_FD;
-
- if (build_w32_commandline (ctx, argv, fd_in, fd_out, fd_err, fd_err_isnull,
- &cmdline))
- {
- return -1;
- }
-
- 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;
-
- 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);
-
- 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;
- return 0;
-}
-
-
-
-
-pid_t
-__assuan_waitpid (assuan_context_t ctx, pid_t pid, int nowait,
- int *status, int options)
-{
- CloseHandle ((HANDLE) pid);
- return 0;
-}
-
-
-
-int
-__assuan_socketpair (assuan_context_t ctx, int namespace, int style,
- int protocol, assuan_fd_t filedes[2])
-{
- gpg_err_set_errno (ENOSYS);
- return -1;
-}
-
-
-int
-__assuan_socket (assuan_context_t ctx, int namespace, int style, int protocol)
-{
- int res;
-
- res = socket (namespace, style, protocol);
- if (res == -1)
- gpg_err_set_errno (_assuan_sock_wsa2errno (WSAGetLastError ()));
- return res;
-}
-
-
-int
-__assuan_connect (assuan_context_t ctx, int sock, struct sockaddr *addr,
- socklen_t length)
-{
- int res;
-
- res = connect (sock, addr, length);
- if (res < 0)
- gpg_err_set_errno (_assuan_sock_wsa2errno (WSAGetLastError ()));
- return res;
-}
-
-
-
-/* The default system hooks for assuan contexts. */
-struct assuan_system_hooks _assuan_system_hooks =
- {
- ASSUAN_SYSTEM_HOOKS_VERSION,
- __assuan_usleep,
- __assuan_pipe,
- __assuan_close,
- __assuan_read,
- __assuan_write,
- __assuan_recvmsg,
- __assuan_sendmsg,
- __assuan_spawn,
- __assuan_waitpid,
- __assuan_socketpair,
- __assuan_socket,
- __assuan_connect
- };
diff --git a/src/system.c b/src/system.c
index fa13987..e5104bb 100644
--- a/src/system.c
+++ b/src/system.c
@@ -203,9 +203,6 @@ _assuan_close_inheritable (assuan_context_t ctx, assuan_fd_t fd)
TRACE1 (ctx, ASSUAN_LOG_SYSIO, "_assuan_close_inheritable", ctx,
"fd=0x%x", fd);
-#ifdef HAVE_W32CE_SYSTEM
- return 0; /* Nothing to do because it is a rendezvous id. */
-#else
if (ctx->system.version)
return (ctx->system.close) (ctx, fd);
else
@@ -216,7 +213,6 @@ _assuan_close_inheritable (assuan_context_t ctx, assuan_fd_t fd)
_assuan_post_syscall ();
return res;
}
-#endif
}
diff --git a/src/sysutils.c b/src/sysutils.c
index 6c09e47..3778668 100644
--- a/src/sysutils.c
+++ b/src/sysutils.c
@@ -30,9 +30,6 @@
# include <winsock2.h>
# endif
# include <windows.h>
-# ifdef HAVE_W32CE_SYSTEM
-# include <winioctl.h>
-# endif /*HAVE_W32CE_SYSTEM*/
#endif /*HAVE_W32_SYSTEM*/
#include "assuan-defs.h"
@@ -54,87 +51,3 @@ _assuan_sysutils_blurb (void)
"\n\n";
return blurb;
}
-
-
-/* Return a string from the Win32 Registry or NULL in case of error.
- The returned string is allocated using a plain malloc and thus the
- caller needs to call the standard free(). The string is looked up
- under HKEY_LOCAL_MACHINE. */
-#ifdef HAVE_W32CE_SYSTEM
-static char *
-w32_read_registry (const wchar_t *dir, const wchar_t *name)
-{
- HKEY handle;
- DWORD n, nbytes;
- wchar_t *buffer = NULL;
- char *result = NULL;
-
- if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &handle))
- return NULL; /* No need for a RegClose, so return immediately. */
-
- nbytes = 1;
- if (RegQueryValueEx (handle, name, 0, NULL, NULL, &nbytes))
- goto out;
- buffer = malloc ((n=nbytes+2));
- if (!buffer)
- goto out;
- if (RegQueryValueEx (handle, name, 0, NULL, (PBYTE)buffer, &n))
- {
- free (buffer);
- buffer = NULL;
- goto out;
- }
-
- n = WideCharToMultiByte (CP_UTF8, 0, buffer, nbytes, NULL, 0, NULL, NULL);
- if (n < 0 || (n+1) <= 0)
- goto out;
- result = malloc (n+1);
- if (!result)
- goto out;
- n = WideCharToMultiByte (CP_UTF8, 0, buffer, nbytes, result, n, NULL, NULL);
- if (n < 0)
- {
- free (result);
- result = NULL;
- goto out;
- }
- result[n] = 0;
-
- out:
- free (buffer);
- RegCloseKey (handle);
- return result;
-}
-#endif /*HAVE_W32CE_SYSTEM*/
-
-
-
-#ifdef HAVE_W32CE_SYSTEM
-/* Replacement for getenv which takes care of the our use of getenv.
- The code is not thread safe but we expect it to work in all cases
- because it is called for the first time early enough. */
-char *
-_assuan_getenv (const char *name)
-{
- static int initialized;
- static char *val_debug;
- static char *val_full_logging;
-
- if (!initialized)
- {
- val_debug = w32_read_registry (L"\\Software\\GNU\\libassuan",
- L"debug");
- val_full_logging = w32_read_registry (L"\\Software\\GNU\\libassuan",
- L"full_logging");
- initialized = 1;
- }
-
-
- if (!strcmp (name, "ASSUAN_DEBUG"))
- return val_debug;
- else if (!strcmp (name, "ASSUAN_FULL_LOGGING"))
- return val_full_logging;
- else
- return NULL;
-}
-#endif /*HAVE_W32CE_SYSTEM*/
diff --git a/src/w32ce-add.h b/src/w32ce-add.h
deleted file mode 100644
index 1f7d7db..0000000
--- a/src/w32ce-add.h
+++ /dev/null
@@ -1,34 +0,0 @@
-## w32ce-add.h - Include fragment to build assuan.h.
-## Copyright (C) 2010 Free Software Foundation, Inc.
-##
-## This file is part of Assuan.
-##
-## Assuan is free software; you can redistribute it and/or modify it
-## under the terms of the GNU Lesser General Public License as
-## published by the Free Software Foundation; either version 2.1 of
-## the License, or (at your option) any later version.
-##
-## Assuan is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-## Lesser General Public License for more details.
-##
-## 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/>.
-## SPDX-License-Identifier: LGPL-2.1+
-##
-##
-## This file is included by the mkheader tool. Lines starting with
-## a double hash mark are not copied to the destination file.
-
-HANDLE _assuan_w32ce_prepare_pipe (int *r_rvid, int write_end);
-HANDLE _assuan_w32ce_finish_pipe (int rvid, int write_end);
-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))
-
-/* Magic handle values. Let's hope those never occur legitimately as
- handles or sockets. (Sockets are numbered sequentially from 0,
- while handles seem aligned to wordsize. */
-#define ASSUAN_STDIN (void*)0x7ffffffd
-#define ASSUAN_STDOUT (void*)0x7fffffff
diff --git a/src/w32ce-fd-t.inc.h b/src/w32ce-fd-t.inc.h
deleted file mode 100644
index 70c7997..0000000
--- a/src/w32ce-fd-t.inc.h
+++ /dev/null
@@ -1,33 +0,0 @@
-## w32ce-fd-t.inc.h - Include fragment to build assuan.h.
-## Copyright (C) 2010 Free Software Foundation, Inc.
-##
-## This file is part of Assuan.
-##
-## Assuan is free software; you can redistribute it and/or modify it
-## under the terms of the GNU Lesser General Public License as
-## published by the Free Software Foundation; either version 2.1 of
-## the License, or (at your option) any later version.
-##
-## Assuan is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-## Lesser General Public License for more details.
-##
-## 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/>.
-## SPDX-License-Identifier: LGPL-2.1+
-##
-##
-## This file is included by the mkheader tool. Lines starting with
-## a double hash mark are not copied to the destination file.
-
-typedef void *assuan_fd_t;
-#define ASSUAN_INVALID_FD ((void*)(-1))
-#define ASSUAN_INVALID_PID ((pid_t) -1)
-static GPG_ERR_INLINE assuan_fd_t
-assuan_fd_from_posix_fd (int fd)
-{
- return (assuan_fd_t)(fd);
-}
-
-##EOF##
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b547d37..f43c712 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -20,17 +20,13 @@
TESTS_ENVIRONMENT =
-EXTRA_DIST = motd ce-createpipe.c
+EXTRA_DIST = motd
BUILT_SOURCES =
CLEANFILES =
TESTS = version
-if HAVE_W32CE_SYSTEM
-w32cetools = ce-createpipe ce-server
-endif
-
if HAVE_W32_SYSTEM
testtools =
else
diff --git a/tests/ce-createpipe.c b/tests/ce-createpipe.c
deleted file mode 100644
index b44784c..0000000
--- a/tests/ce-createpipe.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/* ce-createpipe.c - Test the W32CE CreatePipe implementation.
- Copyright (C) 2010 Free Software Foundation, Inc.
-
- This file is part of Assuan.
-
- Assuan is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as
- published by the Free Software Foundation; either version 3 of
- the License, or (at your option) any later version.
-
- Assuan is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- 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/>.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <errno.h>
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
-#include "common.h"
-
-#include "../src/assuan.h" /* We need the CreatePipe prototype. */
-
-
-static DWORD
-reader_thread (void *arg)
-{
- HANDLE hd = arg;
- DWORD nread;
- char buffer[16];
-
- for (;;)
- {
- if (!ReadFile (hd, buffer, sizeof buffer, &nread, FALSE))
- {
- log_error ("reader: ReadFile failed: rc=%d\n", (int)GetLastError ());
- break;
- }
- log_info ("reader: read %d bytes\n", (int)nread);
- log_printhex ("got: ", buffer, nread);
- }
-
- log_info ("reader: finished\n");
- CloseHandle (hd);
- return 0;
-}
-
-
-static DWORD
-writer_thread (void *arg)
-{
- HANDLE hd = arg;
- DWORD nwritten;
- int i = 0;
- int j;
- char buffer[20];
- int count;
-
- for (count=0; count < 30; count++)
- {
- for (j=0; j < sizeof buffer; j++)
- buffer[j] = i++;
-
- if (!WriteFile (hd, buffer, sizeof buffer, &nwritten, NULL))
- {
- log_error ("writer: WriteFile failed: rc=%d\n", (int)GetLastError ());
- break;
- }
- if (nwritten != sizeof buffer)
- log_info ("writer: wrote only %d bytes\n", (int)nwritten);
- }
-
- log_info ("writer: finished\n");
- CloseHandle (hd);
- return 0;
-}
-
-
-
-static void
-run_test (void)
-{
- HANDLE hd[2];
- HANDLE threads[2];
-
- if (!CreatePipe (&hd[0], &hd[1], NULL, 0))
- {
- log_error ("CreatePipe failed: rc=%d\n", (int)GetLastError ());
- return;
- }
- log_info ("pipe created read=%p write=%p\n", hd[0], hd[1]);
-
- threads[0] = CreateThread (NULL, 0, reader_thread, hd[0], 0, NULL);
- if (!threads[0])
- log_fatal ("error creating reader thread: rc=%d\n", (int)GetLastError ());
- else
- log_info ("reader thread created\n");
- threads[1] = CreateThread (NULL, 0, writer_thread, hd[1], 0, NULL);
- if (!threads[0])
- log_fatal ("error creating writer thread: rc=%d\n", (int)GetLastError ());
- else
- log_info ("writer thread created\n");
-
- switch (WaitForMultipleObjects (2, threads, FALSE, INFINITE))
- {
- case WAIT_OBJECT_0:
- log_info ("reader thread finished first\n");
- break;
- case WAIT_OBJECT_0 + 1:
- log_info ("writer thread finished first\n");
- break;
- default:
- log_error ("WFMO failed: rc=%d\n", (int)GetLastError ());
- break;
- }
-
-
-
- CloseHandle (threads[0]);
- CloseHandle (threads[1]);
-}
-
-
-
-/*
- M A I N
- */
-int
-main (int argc, char **argv)
-{
- int last_argc = -1;
-
- if (argc)
- {
- log_set_prefix (*argv);
- argc--; argv++;
- }
- while (argc && last_argc != argc )
- {
- last_argc = argc;
- if (!strcmp (*argv, "--help"))
- {
- printf ("usage: %s [options]\n"
- "\n"
- "Options:\n"
- " --verbose Show what is going on\n",
- log_get_prefix ());
- exit (0);
- }
- if (!strcmp (*argv, "--verbose"))
- {
- verbose = 1;
- argc--; argv++;
- }
- else if (!strcmp (*argv, "--debug"))
- {
- verbose = debug = 1;
- argc--; argv++;
- }
- }
-
- run_test ();
-
- return errorcount ? 1 : 0;
-}
-
diff --git a/tests/ce-server.c b/tests/ce-server.c
deleted file mode 100644
index 0565aee..0000000
--- a/tests/ce-server.c
+++ /dev/null
@@ -1,1418 +0,0 @@
-/* ce-server.c - An Assuan testbed for W32CE; server code
- Copyright (C) 2010 Free Software Foundation, Inc.
-
- This file is part of Assuan.
-
- Assuan is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as
- published by the Free Software Foundation; either version 3 of
- the License, or (at your option) any later version.
-
- Assuan is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- 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/>.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#ifdef HAVE_W32_SYSTEM
-# define WIN32_LEAN_AND_MEAN
-# include <windows.h>
-#else
-# include <sys/types.h>
-# include <sys/socket.h>
-# include <netinet/in.h>
-# include <arpa/inet.h>
-# ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-# endif
-#endif
-#include <errno.h>
-
-#ifdef HAVE_W32CE_SYSTEM
-# ifndef FILE_ATTRIBUTE_ROMSTATICREF
-# define FILE_ATTRIBUTE_ROMSTATICREF FILE_ATTRIBUTE_OFFLINE
-# endif
-extern BOOL GetStdioPathW (int, wchar_t *, DWORD *);
-extern BOOL SetStdioPathW (int, const wchar_t *);
-#endif /*!HAVE_W32CE_SYSTEM*/
-
-#include "../src/assuan.h"
-
-#include "common.h"
-
-/* The port we are using by default. */
-static short server_port = 15898;
-
-/* Flag set to indicate a shutdown. */
-static int shutdown_pending;
-
-/* An object to keep track of file descriptors. */
-struct fdinfo_s
-{
- struct fdinfo_s *next;
- assuan_fd_t fd; /* The descriptor. */
-};
-typedef struct fdinfo_s *fdinfo_t;
-
-
-/* The local state of a connection. */
-struct state_s
-{
- /* The current working directory - access using get_cwd(). */
- char *cwd;
-
- /* If valid, a socket in listening state created by the dataport
- command. */
- assuan_fd_t dataport_listen_fd;
-
- /* If valid the socket accepted for the dataport. */
- assuan_fd_t dataport_accepted_fd;
-
- /* The error code from a dataport accept operation. */
- gpg_error_t dataport_accept_err;
-
- /* A list of all unused descriptors created by dataport commands. */
- fdinfo_t dataport_fds;
-
- /* The descriptor set by the DATAPORT command. */
- assuan_fd_t dataport_fd;
-};
-typedef struct state_s *state_t;
-
-
-
-/* Local prototypes. */
-static gpg_error_t cmd_newdataport_cont (void *opaque, gpg_error_t err,
- unsigned char *data, size_t datalen);
-
-
-
-/* A wrapper around read to make it work under Windows with HANDLES
- and socket descriptors. Takes care of EINTR on POSIX. */
-static int
-my_read (assuan_fd_t fd, void *buffer, size_t size)
-{
- int res;
-
-#ifdef HAVE_W32_SYSTEM
- res = recv (HANDLE2SOCKET (fd), buffer, size, 0);
- if (res == -1)
- {
- switch (WSAGetLastError ())
- {
- case WSAENOTSOCK:
- {
- DWORD nread = 0;
-
- res = ReadFile (fd, buffer, size, &nread, NULL);
- if (!res)
- {
- switch (GetLastError ())
- {
- case ERROR_BROKEN_PIPE:
- gpg_err_set_errno (EPIPE);
- break;
-
- default:
- gpg_err_set_errno (EIO);
- }
- res = -1;
- }
- else
- res = (int) nread;
- }
- break;
-
- case WSAEWOULDBLOCK:
- gpg_err_set_errno (EAGAIN);
- break;
-
- case ERROR_BROKEN_PIPE:
- gpg_err_set_errno (EPIPE);
- break;
-
- default:
- gpg_err_set_errno (EIO);
- break;
- }
- }
- return res;
-#else /*!HAVE_W32_SYSTEM*/
- do
- res = read (fd, buffer, size);
- while (res == -1 && errno == EINTR);
- return res;
-#endif /*!HAVE_W32_SYSTEM*/
-}
-
-
-/* Extended version of write(2) to guarantee that all bytes are
- written. Returns 0 on success or -1 and ERRNO on failure. NOTE:
- This function does not return the number of bytes written, so any
- error must be treated as fatal for this connection as the state of
- the receiver is unknown. This works best if blocking is allowed
- (so EAGAIN cannot occur). Under Windows this function handles
- socket descriptors and system handles. */
-static int
-my_writen (assuan_fd_t fd, const char *buffer, size_t length)
-{
- while (length)
- {
- int nwritten;
-#ifdef HAVE_W32_SYSTEM
- nwritten = send (HANDLE2SOCKET (fd), buffer, length, 0);
- if (nwritten == -1 && WSAGetLastError () == WSAENOTSOCK)
- {
- DWORD nwrite;
-
- nwritten = WriteFile (fd, buffer, length, &nwrite, NULL);
- if (!nwritten)
- {
- switch (GetLastError ())
- {
- case ERROR_BROKEN_PIPE:
- case ERROR_NO_DATA:
- gpg_err_set_errno (EPIPE);
- break;
-
- default:
- gpg_err_set_errno (EIO);
- break;
- }
- nwritten= -1;
- }
- else
- nwritten = (int)nwrite;
- }
-#else /*!HAVE_W32_SYSTEM*/
- nwritten = write (fd, buffer, length);
-#endif /*!HAVE_W32_SYSTEM*/
- if (nwritten < 0)
- {
- if (errno == EINTR)
- continue;
- return -1; /* write error */
- }
- length -= nwritten;
- buffer += nwritten;
- }
- return 0; /* okay */
-}
-
-
-
-static state_t
-new_state (void)
-{
- state_t state = xcalloc (1, sizeof *state);
- state->dataport_listen_fd = ASSUAN_INVALID_FD;
- state->dataport_accepted_fd = ASSUAN_INVALID_FD;
- state->dataport_fd = ASSUAN_INVALID_FD;
- return state;
-}
-
-static void
-release_state (state_t state)
-{
- fdinfo_t fi, fi2;
-
- if (!state)
- return;
-
- xfree (state->cwd);
-
- if (state->dataport_fd != ASSUAN_INVALID_FD)
- assuan_sock_close (state->dataport_fd);
- if (state->dataport_listen_fd != ASSUAN_INVALID_FD)
- assuan_sock_close (state->dataport_listen_fd);
- if (state->dataport_accepted_fd != ASSUAN_INVALID_FD)
- assuan_sock_close (state->dataport_accepted_fd);
-
- for (fi=state->dataport_fds; fi; fi = fi2)
- {
- fi2 = fi->next;
- if (fi->fd != ASSUAN_INVALID_FD)
- assuan_sock_close (fi->fd);
- }
-
- xfree (state);
-}
-
-
-/* Helper to print a message while leaving a command and to
- acknowledge the command. */
-static gpg_error_t
-leave_cmd (assuan_context_t ctx, gpg_error_t err)
-{
- if (err)
- {
- const char *name = assuan_get_command_name (ctx);
- if (!name)
- name = "?";
- if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT)
- log_error ("command '%s' failed: %s\n", name, gpg_strerror (err));
- else
- log_error ("command '%s' failed: %s <%s>\n", name,
- gpg_strerror (err), gpg_strsource (err));
- }
- return assuan_process_done (ctx, err);
-}
-
-
-#ifdef HAVE_W32CE_SYSTEM
-static char *
-wchar_to_utf8 (const wchar_t *string)
-{
- int n;
- size_t length = wcslen (string);
- char *result;
-
- n = WideCharToMultiByte (CP_UTF8, 0, string, length, NULL, 0, NULL, NULL);
- if (n < 0 || (n+1) <= 0)
- log_fatal ("WideCharToMultiByte failed\n");
-
- result = xmalloc (n+1);
- n = WideCharToMultiByte (CP_ACP, 0, string, length, result, n, NULL, NULL);
- if (n < 0)
- log_fatal ("WideCharToMultiByte failed\n");
-
- result[n] = 0;
- return result;
-}
-
-static wchar_t *
-utf8_to_wchar (const char *string)
-{
- int n;
- size_t length = strlen (string);
- wchar_t *result;
- size_t nbytes;
-
- n = MultiByteToWideChar (CP_UTF8, 0, string, length, NULL, 0);
- if (n < 0 || (n+1) <= 0)
- log_fatal ("MultiByteToWideChar failed\n");
-
- nbytes = (size_t)(n+1) * sizeof(*result);
- if (nbytes / sizeof(*result) != (n+1))
- log_fatal ("utf8_to_wchar: integer overflow\n");
- result = xmalloc (nbytes);
- n = MultiByteToWideChar (CP_UTF8, 0, string, length, result, n);
- if (n < 0)
- log_fatal ("MultiByteToWideChar failed\n");
- result[n] = 0;
-
- return result;
-}
-#endif /*HAVE_W32CE_SYSTEM*/
-
-#ifndef HAVE_W32CE_SYSTEM
-static char *
-gnu_getcwd (void)
-{
- size_t size = 100;
-
- while (1)
- {
- char *buffer = xmalloc (size);
- if (getcwd (buffer, size) == buffer)
- return buffer;
- xfree (buffer);
- if (errno != ERANGE)
- return 0;
- size *= 2;
- }
-}
-#endif /*!HAVE_W32CE_SYSTEM*/
-
-
-/* Return the current working directory. The returned string is valid
- as long as STATE->cwd is not changed. */
-static const char *
-get_cwd (state_t state)
-{
- if (!state->cwd)
- {
- /* No working directory yet. On WindowsCE make it the module
- directory of this process. */
-#ifdef HAVE_W32_SYSTEM
- char *p;
-#endif
-#ifdef HAVE_W32CE_SYSTEM
- wchar_t buf[MAX_PATH+1];
- size_t n;
-
- n = GetModuleFileName (NULL, buf, MAX_PATH);
- if (!n)
- state->cwd = xstrdup ("/");
- else
- {
- buf[n] = 0;
- state->cwd = wchar_to_utf8 (buf);
- p = strrchr (state->cwd, '\\');
- if (p)
- *p = 0;
- }
-#else
- state->cwd = gnu_getcwd ();
-#endif
-#ifdef HAVE_W32_SYSTEM
- for (p=state->cwd; *p; p++)
- if (*p == '\\')
- *p = '/';
-#endif /*HAVE_W32_SYSTEM*/
- }
-
- return state->cwd;
-}
-
-
-
-static gpg_error_t
-reset_notify (assuan_context_t ctx, char *line)
-{
- state_t state = assuan_get_pointer (ctx);
- fdinfo_t fi, fi2;
-
- /* Close all lingering dataport connections. */
- for (fi=state->dataport_fds; fi; fi = fi2)
- {
- fi2 = fi->next;
- if (fi->fd != ASSUAN_INVALID_FD)
- assuan_sock_close (fi->fd);
- }
- state->dataport_fds = NULL;
-
- return 0;
-}
-
-
-static gpg_error_t
-input_notify (assuan_context_t ctx, char *line)
-{
- state_t state = assuan_get_pointer (ctx);
- assuan_fd_t fd = assuan_get_input_fd (ctx);
- fdinfo_t fi;
-
- if (fd != ASSUAN_INVALID_FD)
- {
- /* The fd is now in use use - remove it from the unused list. */
- for (fi=state->dataport_fds; fi; fi = fi->next)
- if (fi->fd == fd)
- fi->fd = ASSUAN_INVALID_FD;
- }
-
- return 0;
-}
-
-
-static gpg_error_t
-output_notify (assuan_context_t ctx, char *line)
-{
- state_t state = assuan_get_pointer (ctx);
- assuan_fd_t fd = assuan_get_output_fd (ctx);
- fdinfo_t fi;
-
- if (fd != ASSUAN_INVALID_FD)
- {
- /* The fd is now in use - remove it from the unused list. */
- for (fi=state->dataport_fds; fi; fi = fi->next)
- if (fi->fd == fd)
- fi->fd = ASSUAN_INVALID_FD;
- }
-
- return 0;
-}
-
-
-
-static const char hlp_echo[] =
- "ECHO <line>\n"
- "\n"
- "Print LINE as data lines.\n";
-static gpg_error_t
-cmd_echo (assuan_context_t ctx, char *line)
-{
- gpg_error_t err;
-
- err = assuan_send_data (ctx, line, strlen (line));
-
- return leave_cmd (ctx, err);
-}
-
-
-
-static const char hlp_cat[] =
- "CAT [<filename>]\n"
- "\n"
- "Copy the content of FILENAME to the descriptor set by the OUTPUT\n"
- "command. If no OUTPUT command has been given, send the content\n"
- "using data lines. Without FILENAME take the content from the\n"
- "descriptor set by the INPUT command; if a DATAPORT has been set\n"
- "this descriptor is used for I/O and the INOPUT/OUTPUT descriptors\n"
- "are not touched.";
-static gpg_error_t
-cmd_cat (assuan_context_t ctx, char *line)
-{
- state_t state = assuan_get_pointer (ctx);
- gpg_error_t err = 0;
- assuan_fd_t fd_in = ASSUAN_INVALID_FD;
- assuan_fd_t fd_out = ASSUAN_INVALID_FD;
- FILE *fp_in = NULL;
- char buf[256];
- size_t nread;
- int use_dataport = 0;
-
- if (*line)
- {
- fp_in = fopen (line, "rb");
- if (!fp_in)
- err = gpg_error_from_syserror ();
- else
- fd_out = assuan_get_output_fd (ctx);
- }
- else if (state->dataport_fd != ASSUAN_INVALID_FD)
- {
- use_dataport = 1;
- fd_in = state->dataport_fd;
- fd_out = state->dataport_fd;
- }
- else if ((fd_in = assuan_get_input_fd (ctx)) != ASSUAN_INVALID_FD)
- {
- /* This FD is actually a socket descriptor. We can't fdopen it
- because under Windows we ust use recv(2) instead of read(2).
- Note that on POSIX systems there is no difference between
- libc file descriptors and socket descriptors. */
-
- fd_out = assuan_get_output_fd (ctx);
- }
- else
- err = gpg_error (GPG_ERR_ASS_NO_INPUT);
- if (err)
- goto leave;
-
- do
- {
- if (fp_in)
- {
- nread = fread (buf, 1, sizeof buf, fp_in);
- if (nread < sizeof buf)
- {
- if (ferror (fp_in))
- err = gpg_error_from_syserror ();
- else if (feof (fp_in))
- err = gpg_error (GPG_ERR_EOF);
- }
- }
- else
- {
- int n;
-
- nread = 0;
- n = my_read (fd_in, buf, sizeof buf);
- if (n < 0)
- err = gpg_error_from_syserror ();
- else if (!n)
- err = gpg_error (GPG_ERR_EOF);
- else
- nread = n;
- }
-
-
- if (fd_out != ASSUAN_INVALID_FD)
- {
- if (nread && my_writen (fd_out, buf, nread))
- err = gpg_error_from_syserror ();
- }
- else if (nread)
- err = assuan_send_data (ctx, buf, nread);
- }
- while (!err);
- if (gpg_err_code (err) == GPG_ERR_EOF)
- err = 0;
-
-leave:
- if (fp_in)
- fclose (fp_in);
- if (use_dataport)
- {
- if (state->dataport_fd != ASSUAN_INVALID_FD)
- {
- assuan_sock_close (state->dataport_fd);
- state->dataport_fd = ASSUAN_INVALID_FD;
- }
- }
- else
- {
- assuan_close_input_fd (ctx);
- assuan_close_output_fd (ctx);
- }
- return leave_cmd (ctx, err);
-}
-
-
-static const char hlp_pwd[] =
- "PWD\n"
- "\n"
- "Print the curent working directory of this session.\n";
-static gpg_error_t
-cmd_pwd (assuan_context_t ctx, char *line)
-{
- state_t state = assuan_get_pointer (ctx);
- gpg_error_t err;
- const char *string;
-
- string = get_cwd (state);
- err = assuan_send_data (ctx, string, strlen (string));
-
- return leave_cmd (ctx, err);
-}
-
-
-static const char hlp_cd[] =
- "CD [dir]\n"
- "\n"
- "Change the curretn directory of the session.\n";
-static gpg_error_t
-cmd_cd (assuan_context_t ctx, char *line)
-{
- state_t state = assuan_get_pointer (ctx);
- gpg_error_t err = 0;
- char *newdir, *p;
-
- for (p=line; *p; p++)
- if (*p == '\\')
- *p = '/';
-
- if (!*line)
- {
- xfree (state->cwd);
- state->cwd = NULL;
- get_cwd (state);
- }
- else
- {
- if (*line == '/')
- newdir = xstrdup (line);
- else
- newdir = xstrconcat (get_cwd (state), "/", line, NULL);
-
- while (strlen(newdir) > 1 && line[strlen(newdir)-1] == '/')
- line[strlen(newdir)-1] = 0;
- xfree (state->cwd);
- state->cwd = newdir;
- }
-
- return leave_cmd (ctx, err);
-}
-
-
-
-
-
-#ifdef HAVE_W32CE_SYSTEM
-static const char hlp_ls[] =
- "LS [<pattern>]\n"
- "\n"
- "List the files described by PATTERN.\n";
-static gpg_error_t
-cmd_ls (assuan_context_t ctx, char *line)
-{
- state_t state = assuan_get_pointer (ctx);
- gpg_error_t err;
- WIN32_FIND_DATA fi;
- char buf[500];
- HANDLE hd;
- char *p, *fname;
- wchar_t *wfname;
-
- if (!*line)
- fname = xstrconcat (get_cwd (state), "/*", NULL);
- else if (*line == '/' || *line == '\\')
- fname = xstrdup (line);
- else
- fname = xstrconcat (get_cwd (state), "/", line, NULL);
- for (p=fname; *p; p++)
- if (*p == '/')
- *p = '\\';
- assuan_write_status (ctx, "PATTERN", fname);
- wfname = utf8_to_wchar (fname);
- xfree (fname);
- hd = FindFirstFile (wfname, &fi);
- free (wfname);
- if (hd == INVALID_HANDLE_VALUE)
- {
- log_info ("FindFirstFile returned %d\n", GetLastError ());
- err = gpg_error_from_syserror (); /* Works for W32CE. */
- goto leave;
- }
-
- do
- {
- DWORD attr = fi.dwFileAttributes;
-
- fname = wchar_to_utf8 (fi.cFileName);
- snprintf (buf, sizeof buf,
- "%c%c%c%c%c%c%c%c%c%c%c%c%c %7lu%c %s\n",
- (attr & FILE_ATTRIBUTE_DIRECTORY)
- ? ((attr & FILE_ATTRIBUTE_DEVICE)? 'c':'d'):'-',
- (attr & FILE_ATTRIBUTE_READONLY)? 'r':'-',
- (attr & FILE_ATTRIBUTE_HIDDEN)? 'h':'-',
- (attr & FILE_ATTRIBUTE_SYSTEM)? 's':'-',
- (attr & FILE_ATTRIBUTE_ARCHIVE)? 'a':'-',
- (attr & FILE_ATTRIBUTE_COMPRESSED)? 'c':'-',
- (attr & FILE_ATTRIBUTE_ENCRYPTED)? 'e':'-',
- (attr & FILE_ATTRIBUTE_INROM)? 'R':'-',
- (attr & FILE_ATTRIBUTE_REPARSE_POINT)? 'P':'-',
- (attr & FILE_ATTRIBUTE_ROMMODULE)? 'M':'-',
- (attr & FILE_ATTRIBUTE_ROMSTATICREF)? 'R':'-',
- (attr & FILE_ATTRIBUTE_SPARSE_FILE)? 'S':'-',
- (attr & FILE_ATTRIBUTE_TEMPORARY)? 't':'-',
- (unsigned long)fi.nFileSizeLow,
- fi.nFileSizeHigh? 'X':' ',
- fname);
- free (fname);
- err = assuan_send_data (ctx, buf, strlen (buf));
- if (!err)
- err = assuan_send_data (ctx, NULL, 0);
- }
- while (!err && FindNextFile (hd, &fi));
- if (err)
- ;
- else if (GetLastError () == ERROR_NO_MORE_FILES)
- err = 0;
- else
- {
- log_info ("FindNextFile returned %d\n", GetLastError ());
- err = gpg_error_from_syserror ();
- }
- FindClose (hd);
-
- leave:
- return leave_cmd (ctx, err);
-}
-#endif /*HAVE_W32CE_SYSTEM*/
-
-
-#ifdef HAVE_W32CE_SYSTEM
-static const char hlp_run[] =
- "RUN <filename> [<args>]\n"
- "\n"
- "Run the program in FILENAME with the arguments ARGS.\n"
- "This creates a new process and waits for it to finish.\n"
- "FIXME: The process' stdin is connected to the file set by the\n"
- "INPUT command; stdout and stderr to the one set by OUTPUT.\n";
-static gpg_error_t
-cmd_run (assuan_context_t ctx, char *line)
-{
- /* state_t state = assuan_get_pointer (ctx); */
- gpg_error_t err;
- BOOL w32ret;
- PROCESS_INFORMATION pi = { NULL, 0, 0, 0 };
- char *p;
- wchar_t *pgmname = NULL;
- wchar_t *cmdline = NULL;
- int code;
- DWORD exc;
- int idx;
- struct {
- HANDLE hd[2];
- int oldname_valid;
- wchar_t oldname[MAX_PATH];
- } pipes[3];
-
- for (idx=0; idx < 3; idx++)
- {
- pipes[idx].hd[0] = pipes[idx].hd[1] = INVALID_HANDLE_VALUE;
- pipes[idx].oldname_valid = 0;
- }
-
- p = strchr (line, ' ');
- if (p)
- {
- *p = 0;
- pgmname = utf8_to_wchar (line);
- for (p++; *p && *p == ' '; p++)
- ;
- cmdline = utf8_to_wchar (p);
- }
- else
- pgmname = utf8_to_wchar (line);
- {
- char *tmp1 = wchar_to_utf8 (pgmname);
- char *tmp2 = wchar_to_utf8 (cmdline);
- log_info ("CreateProcess, path=`%s' cmdline=`%s'\n", tmp1, tmp2);
- xfree (tmp2);
- xfree (tmp1);
- }
-
- /* Redirect the standard handles. */
- /* Create pipes. */
- for (idx=0; idx < 3; idx++)
- {
- if (!_assuan_w32ce_create_pipe (&pipes[idx].hd[0], &pipes[idx].hd[1],
- NULL, 0))
- {
- err = gpg_error_from_syserror ();
- log_error ("CreatePipe failed: %d\n", GetLastError ());
- pipes[idx].hd[0] = pipes[idx].hd[1] = INVALID_HANDLE_VALUE;
- goto leave;
- }
- }
-
- /* Save currently assigned devices. */
- for (idx=0; idx < 3; idx++)
- {
- DWORD dwlen = MAX_PATH;
- if (!GetStdioPathW (idx, pipes[idx].oldname, &dwlen))
- {
- err = gpg_error_from_syserror ();
- log_error ("GetStdioPath failed: %d\n", GetLastError ());
- goto leave;
- }
- pipes[idx].oldname_valid = 1;
- }
-
- /* Connect the pipes. */
- {
- if (!SetStdioPathW (1, L"\\mystdout.log"))
- {
- err = gpg_error_from_syserror ();
- log_error ("SetStdioPathW(%d) failed: %d\n", idx, GetLastError ());
- goto leave;
- }
- if (!SetStdioPathW (2, L"\\mystderr.log"))
- {
- err = gpg_error_from_syserror ();
- log_error ("SetStdioPathW(%d) failed: %d\n", idx, GetLastError ());
- goto leave;
- }
- }
-
- /* Create the process, restore the devices and check the error. */
- w32ret = CreateProcess (pgmname, /* Program to start. */
- cmdline, /* Command line arguments. */
- NULL, /* Process security. Not used. */
- NULL, /* Thread security. Not used. */
- FALSE, /* Inherit handles. Not used. */
- CREATE_SUSPENDED, /* Creation flags. */
- NULL, /* Environment. Not used. */
- NULL, /* Use current dir. Not used. */
- NULL, /* Startup information. Not used. */
- &pi /* Returns process information. */
- );
- for (idx=0; idx < 3; idx++)
- {
- if (pipes[idx].oldname_valid)
- {
- if (!SetStdioPathW (idx, pipes[idx].oldname))
- log_error ("SetStdioPath(%d) failed during restore: %d\n",
- idx, GetLastError ());
- else
- pipes[idx].oldname_valid = 0;
- }
- }
- if (!w32ret)
- {
- /* Error checking after restore so that the messages are visible. */
- log_error ("CreateProcess failed: %d\n", GetLastError ());
- err = gpg_error_from_syserror ();
- goto leave;
- }
-
- log_info ("CreateProcess ready: hProcess=%p hThread=%p"
- " dwProcessID=%d dwThreadId=%d\n",
- pi.hProcess, pi.hThread,
- (int) pi.dwProcessId, (int) pi.dwThreadId);
-
- ResumeThread (pi.hThread);
- CloseHandle (pi.hThread);
-
- code = WaitForSingleObject (pi.hProcess, INFINITE);
- switch (code)
- {
- case WAIT_FAILED:
- err = gpg_error_from_syserror ();;
- log_error ("waiting for process %d to terminate failed: %d\n",
- (int)pi.dwProcessId, GetLastError ());
- break;
-
- case WAIT_OBJECT_0:
- if (!GetExitCodeProcess (pi.hProcess, &exc))
- {
- err = gpg_error_from_syserror ();;
- log_error ("error getting exit code of process %d: %s\n",
- (int)pi.dwProcessId, GetLastError () );
- }
- else if (exc)
- {
- log_info ("error running process: exit status %d\n", (int)exc);
- err = gpg_error (GPG_ERR_GENERAL);
- }
- else
- {
- err = 0;
- }
- break;
-
- default:
- err = gpg_error_from_syserror ();;
- log_error ("WaitForSingleObject returned unexpected "
- "code %d for pid %d\n", code, (int)pi.dwProcessId);
- break;
- }
- CloseHandle (pi.hProcess);
-
- leave:
- for (idx=0; idx < 3; idx++)
- {
- if (pipes[idx].oldname_valid)
- {
- if (!SetStdioPathW (idx, pipes[idx].oldname))
- log_error ("SetStdioPath(%d) failed during restore: %d\n",
- idx, GetLastError ());
- else
- pipes[idx].oldname_valid = 0;
- }
- }
- for (idx=0; idx < 3; idx++)
- {
- if (pipes[idx].hd[0] != INVALID_HANDLE_VALUE)
- CloseHandle (pipes[idx].hd[0]);
- if (pipes[idx].hd[1] != INVALID_HANDLE_VALUE)
- CloseHandle (pipes[idx].hd[1]);
- }
- xfree (cmdline);
- xfree (pgmname);
- return leave_cmd (ctx, err);
-}
-#endif /*HAVE_W32CE_SYSTEM*/
-
-
-
-
-
-static const char hlp_newdataport[] =
- "NEWDATAPORT\n"
- "\n"
- "Create a new dataport. The server creates a listening socket and\n"
- "issues the inquiry:\n"
- " INQUIRE CONNECT-TO <port>\n"
- "The client is expected to connect to PORT of the server and confirm\n"
- "this by sending just an \"END\". In turn the server sends:\n"
- " S FDINFO <n>\n"
- "With N being the local descriptor for the accepted connection. This\n"
- "descriptor may now be used with INPUT or OUTPUT commands.";
-struct cmd_dataport_locals
-{
- assuan_context_t ctx;
- int passthru;
- int port;
-};
-static gpg_error_t
-cmd_newdataport (assuan_context_t ctx, char *line)
-{
- state_t state = assuan_get_pointer (ctx);
- gpg_error_t err = 0;
- struct sockaddr_in addr;
- socklen_t addrlen;
- struct cmd_dataport_locals *cont;
- char inqline[100];
-
- cont = xmalloc (sizeof *cont);
- cont->ctx = ctx;
- cont->passthru = 0;
- cont->port = 0;
-
- if (state->dataport_listen_fd != ASSUAN_INVALID_FD)
- {
- log_error ("Oops, still listening on a dataport socket\n");
- state->dataport_listen_fd = ASSUAN_INVALID_FD;
- }
- if (state->dataport_accepted_fd != ASSUAN_INVALID_FD)
- {
- log_error ("Oops, still holding an accepted dataport socket\n");
- state->dataport_accepted_fd = ASSUAN_INVALID_FD;
- }
- state->dataport_accept_err = 0;
-
- state->dataport_listen_fd = assuan_sock_new (PF_INET, SOCK_STREAM, 0);
- if (state->dataport_listen_fd == ASSUAN_INVALID_FD)
- {
- err = gpg_error_from_syserror ();
- log_error ("socket() failed: %s\n", strerror (errno));
- goto leave;
- }
-
- addr.sin_family = AF_INET;
- addr.sin_port = 0;
- addr.sin_addr.s_addr = htonl (INADDR_ANY);
- if (assuan_sock_bind (state->dataport_listen_fd,
- (struct sockaddr *)&addr, sizeof addr))
- {
- err = gpg_error_from_syserror ();
- log_error ("listen() failed: %s\n", strerror (errno));
- goto leave;
- }
-
- if (listen (HANDLE2SOCKET (state->dataport_listen_fd), 1))
- {
- err = gpg_error_from_syserror ();
- log_error ("listen() failed: %s\n", strerror (errno));
- goto leave;
- }
-
- addrlen = sizeof addr;
- if (getsockname (HANDLE2SOCKET (state->dataport_listen_fd),
- (struct sockaddr *)&addr, &addrlen))
- {
- err = gpg_error_from_syserror ();
- log_error ("getsockname() failed: %s\n", strerror (errno));
- goto leave;
- }
- cont->port = ntohs (addr.sin_port);
-
- if (verbose)
- log_info ("server now also listening on port %d\n", cont->port);
- snprintf (inqline, sizeof inqline, "CONNECT-TO %d", cont->port);
- err = assuan_inquire_ext (ctx, inqline, 0, cmd_newdataport_cont, cont);
- if (!err)
- return 0; /* Transfer to continuation. */
-
- leave:
- cont->passthru = 1;
- return cmd_newdataport_cont (cont, err, NULL, 0);
-}
-
-/* Continuation used by cmd_newdataport. */
-static gpg_error_t
-cmd_newdataport_cont (void *opaque, gpg_error_t err,
- unsigned char *data, size_t datalen)
-{
- struct cmd_dataport_locals *cont = opaque;
- assuan_context_t ctx = cont->ctx;
- state_t state = assuan_get_pointer (ctx);
- char numbuf[35];
- fdinfo_t fi;
-
- if (cont->passthru || err)
- goto leave;
-
- err = state->dataport_accept_err;
- if (err)
- goto leave;
- if (state->dataport_listen_fd != ASSUAN_INVALID_FD
- || state->dataport_accepted_fd == ASSUAN_INVALID_FD)
- {
- err = gpg_error (GPG_ERR_MISSING_ACTION);
- goto leave;
- }
-
- for (fi = state->dataport_fds; fi; fi = fi->next)
- if (fi->fd == ASSUAN_INVALID_FD)
- break;
- if (!fi)
- {
- fi = xcalloc (1, sizeof *fi);
- fi->next = state->dataport_fds;
- state->dataport_fds = fi;
- }
- fi->fd = state->dataport_accepted_fd;
- state->dataport_accepted_fd = ASSUAN_INVALID_FD;
-
- /* Note that under Windows the FD is the socket descriptor. Socket
- descriptors are neither handles nor libc file descriptors. */
- snprintf (numbuf, sizeof numbuf, "%d", HANDLE2SOCKET (fi->fd));
- err = assuan_write_status (ctx, "FDINFO", numbuf);
-
- leave:
- if (state->dataport_listen_fd != ASSUAN_INVALID_FD)
- {
- assuan_sock_close (state->dataport_listen_fd);
- state->dataport_listen_fd = ASSUAN_INVALID_FD;
- }
- if (state->dataport_accepted_fd != ASSUAN_INVALID_FD)
- {
- assuan_sock_close (state->dataport_accepted_fd);
- state->dataport_accepted_fd = ASSUAN_INVALID_FD;
- }
- xfree (cont);
- return leave_cmd (ctx, err);
-}
-
-
-
-static const char hlp_dataport[] =
- "DATAPORT FD[=<n>]\n"
- "\n"
- "Set the file descriptor to read and write data via port.\n"
- "This is similar to the \"INPUT\" and \"OUTPUT\" commands\n"
- "but useful for socketpairs.";
-static gpg_error_t
-cmd_dataport (assuan_context_t ctx, char *line)
-{
- state_t state = assuan_get_pointer (ctx);
- gpg_error_t err;
- assuan_fd_t fd;
-
- if (state->dataport_fd != ASSUAN_INVALID_FD)
- {
- assuan_sock_close (state->dataport_fd);
- state->dataport_fd = ASSUAN_INVALID_FD;
- }
-
- err = assuan_command_parse_fd (ctx, line, &fd);
- if (!err && fd != ASSUAN_INVALID_FD)
- {
- fdinfo_t fi;
-
- state->dataport_fd = fd;
-
- /* The fd is now in use use - remove it from the unused list. */
- for (fi=state->dataport_fds; fi; fi = fi->next)
- if (fi->fd == fd)
- fi->fd = ASSUAN_INVALID_FD;
- }
-
- return leave_cmd (ctx, err);
-}
-
-
-
-static const char hlp_getinfo[] =
- "GETINFO <what>\n"
- "\n"
- "Multipurpose function to return a variety of information.\n"
- "Supported values for WHAT are:\n"
- "\n"
- " version - Return the version of the program.\n"
- " pid - Return the process id of the server.\n"
- " dataports - Return a list of usused dataports.";
-static gpg_error_t
-cmd_getinfo (assuan_context_t ctx, char *line)
-{
- state_t state = assuan_get_pointer (ctx);
- gpg_error_t err = 0;
- char numbuf[50];
-
- if (!strcmp (line, "version"))
- {
- const char *s = VERSION;
- err = assuan_send_data (ctx, s, strlen (s));
- }
- else if (!strcmp (line, "pid"))
- {
- snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
- err = assuan_send_data (ctx, numbuf, strlen (numbuf));
- }
- else if (!strcmp (line, "dataports"))
- {
- fdinfo_t fi;
- int any = 0;
-
- for (fi=state->dataport_fds; !err && fi; fi = fi->next)
- {
- if (fi->fd != ASSUAN_INVALID_FD)
- {
- snprintf (numbuf, sizeof numbuf, "%s%d",
- any? " ":"", HANDLE2SOCKET (fi->fd));
- any = 1;
- err = assuan_send_data (ctx, numbuf, strlen (numbuf));
- }
- }
- }
- else
- err = gpg_error (GPG_ERR_ASS_PARAMETER);
-
- return leave_cmd (ctx, err);
-}
-
-
-
-static const char hlp_shutdown[] =
- "SHUTDOWN\n"
- "\n"
- "Shutdown the server process\n";
-static gpg_error_t
-cmd_shutdown (assuan_context_t ctx, char *line)
-{
- (void)line;
- shutdown_pending = 1;
- return leave_cmd (ctx, 0);;
-}
-
-
-static gpg_error_t
-register_commands (assuan_context_t ctx)
-{
- static struct
- {
- const char *name;
- gpg_error_t (*handler) (assuan_context_t, char *line);
- const char * const help;
- } table[] =
- {
-#ifdef HAVE_W32CE_SYSTEM
- { "LS", cmd_ls, hlp_ls },
- { "RUN", cmd_run, hlp_run },
-#endif
- { "PWD", cmd_pwd, hlp_pwd },
- { "CD", cmd_cd, hlp_cd },
- { "ECHO", cmd_echo, hlp_echo },
- { "CAT", cmd_cat, hlp_cat },
- { "NEWDATAPORT", cmd_newdataport, hlp_newdataport },
- { "DATAPORT", cmd_dataport, hlp_dataport },
- { "INPUT", NULL },
- { "OUTPUT", NULL },
- { "GETINFO", cmd_getinfo, hlp_getinfo },
- { "SHUTDOWN", cmd_shutdown, hlp_shutdown },
- { NULL, NULL }
- };
- int i;
- gpg_error_t rc;
-
- for (i=0; table[i].name; i++)
- {
- rc = assuan_register_command (ctx, table[i].name,
- table[i].handler, table[i].help);
- if (rc)
- return rc;
- }
- return 0;
-}
-
-
-
-static assuan_fd_t
-get_connection_fd (assuan_context_t ctx)
-{
- assuan_fd_t fds[5];
-
- if (assuan_get_active_fds (ctx, 0, fds, DIM (fds)) < 1)
- log_fatal ("assuan_get_active_fds failed\n");
- if (fds[0] == ASSUAN_INVALID_FD)
- log_fatal ("assuan_get_active_fds returned invalid conenction fd\n");
- return fds[0];
-}
-
-
-/* Startup the server. */
-static void
-server (void)
-{
- gpg_error_t err;
- assuan_fd_t server_fd;
- assuan_sock_nonce_t server_nonce;
- int one = 1;
- struct sockaddr_in name;
- assuan_context_t ctx;
- state_t state = NULL;
-
- err = assuan_new (&ctx);
- if (err)
- log_fatal ("assuan_new failed: %s\n", gpg_strerror (err));
-
- server_fd = assuan_sock_new (PF_INET, SOCK_STREAM, 0);
- if (server_fd == ASSUAN_INVALID_FD)
- log_fatal ("socket() failed: %s\n", strerror (errno));
-
- if (setsockopt (HANDLE2SOCKET (server_fd),
- SOL_SOCKET, SO_REUSEADDR, (void*)&one, sizeof one))
- log_error ("setsockopt(SO_REUSEADDR) failed: %s\n", strerror (errno));
-
- name.sin_family = AF_INET;
- name.sin_port = htons (server_port);
- name.sin_addr.s_addr = htonl (INADDR_ANY);
- if (assuan_sock_bind (server_fd, (struct sockaddr *) &name, sizeof name))
- log_fatal ("bind() failed: %s\n", strerror (errno));
- if (assuan_sock_get_nonce ((struct sockaddr*)&name, sizeof name,
- &server_nonce))
- log_fatal ("assuan_sock_get_nonce failed: %s\n", strerror (errno));
-
- /* Register the nonce with the context so that assuan_accept knows
- about it. We can't do that directly in assuan_sock_bind because
- we want these socket wrappers to be context neutral and drop in
- replacement for the standard socket functions. */
- assuan_set_sock_nonce (ctx, &server_nonce);
-
- if (listen (HANDLE2SOCKET (server_fd), 5))
- log_fatal ("listen() failed: %s\n", strerror (errno));
-
- log_info ("server listening on port %hd\n", server_port);
-
- err = assuan_init_socket_server (ctx, server_fd, 0);
- if (err)
- log_fatal ("assuan_init_socket_server failed: %s\n", gpg_strerror (err));
-
- err = register_commands (ctx);
- if (err)
- log_fatal ("register_commands failed: %s\n", gpg_strerror(err));
-
- if (debug)
- assuan_set_log_stream (ctx, stderr);
-
- assuan_register_reset_notify (ctx, reset_notify);
- assuan_register_input_notify (ctx, input_notify);
- assuan_register_output_notify (ctx, output_notify);
-
-
- state = new_state ();
-
- assuan_set_pointer (ctx, state);
-
- while (!shutdown_pending)
- {
- int done;
-
- err = assuan_accept (ctx);
- if (err)
- {
- if (gpg_err_code (err) == GPG_ERR_EOF || err == -1)
- log_error ("assuan_accept failed: %s\n", gpg_strerror (err));
- break;
- }
-
- log_info ("client connected. Client's pid is %ld\n",
- (long)assuan_get_pid (ctx));
- do
- {
- /* We need to use select here so that we can accept
- supplemental connections from the client as requested by
- the DATAPORT command. */
- fd_set rfds;
- int connfd, datafd, max_fd;
-
- connfd = HANDLE2SOCKET (get_connection_fd (ctx));
- FD_ZERO (&rfds);
- FD_SET (connfd, &rfds);
- max_fd = connfd;
-
- if (state->dataport_listen_fd != ASSUAN_INVALID_FD)
- {
- datafd = HANDLE2SOCKET (state->dataport_listen_fd);
- FD_SET (datafd, &rfds);
- if (datafd > max_fd)
- max_fd = datafd;
- }
- else
- datafd = -1;
-
- if (select (max_fd + 1, &rfds, NULL, NULL, NULL) > 0)
- {
- if (datafd != -1 && FD_ISSET (datafd, &rfds))
- {
- struct sockaddr_in clnt_addr;
- socklen_t len = sizeof clnt_addr;
- int fd;
-
- fd = accept (datafd, (struct sockaddr*)&clnt_addr, &len);
- if (fd == -1)
- {
- err = gpg_err_code_from_syserror ();
- assuan_sock_close (state->dataport_listen_fd);
- state->dataport_listen_fd = ASSUAN_INVALID_FD;
- log_error ("accepting on dataport failed: %s\n",
- gpg_strerror (err));
- state->dataport_accept_err = err;
- err = 0;
- }
- else
- {
- /* No more need for the listening socket. */
- assuan_sock_close (state->dataport_listen_fd);
- state->dataport_listen_fd = ASSUAN_INVALID_FD;
- /* Record the accepted fd. */
- state->dataport_accept_err = 0;
- state->dataport_accepted_fd = SOCKET2HANDLE (fd);
- }
- }
-
- if (FD_ISSET (connfd, &rfds))
- {
- err = assuan_process_next (ctx, &done);
- }
- }
- }
- while (!err && !done && !shutdown_pending);
- if (err)
- log_error ("assuan_process failed: %s\n", gpg_strerror (err));
- }
-
- assuan_sock_close (server_fd);
- assuan_release (ctx);
- release_state (state);
-}
-
-
-
-
-
-/*
-
- M A I N
-
-*/
-int
-main (int argc, char **argv)
-{
- gpg_error_t err;
- int last_argc = -1;
-
- if (argc)
- {
- log_set_prefix (*argv);
- argc--; argv++;
- }
- while (argc && last_argc != argc )
- {
- last_argc = argc;
- if (!strcmp (*argv, "--help"))
- {
- printf (
- "usage: %s [options]\n"
- "\n"
- "Options:\n"
- " --verbose Show what is going on\n",
- log_get_prefix ());
- exit (0);
- }
- if (!strcmp (*argv, "--verbose"))
- {
- verbose = 1;
- argc--; argv++;
- }
- else if (!strcmp (*argv, "--debug"))
- {
- verbose = debug = 1;
- argc--; argv++;
- }
- }
-
- assuan_set_assuan_log_prefix (log_prefix);
- if (debug)
- assuan_set_assuan_log_stream (stderr);
-
- err = assuan_sock_init ();
- if (err)
- log_fatal ("assuan_sock_init failed: %s\n", gpg_strerror (err));
-
- log_info ("server starting...\n");
- server ();
- log_info ("server finished\n");
-
- assuan_sock_deinit ();
-
- return errorcount ? 1 : 0;
-}
diff --git a/tests/common.h b/tests/common.h
index c5ce811..dc3c073 100644
--- a/tests/common.h
+++ b/tests/common.h
@@ -26,11 +26,6 @@
#endif
-#ifdef HAVE_W32CE_SYSTEM
-#define getpid() GetCurrentProcessId ()
-#define getenv(a) (NULL)
-#endif
-
#if HAVE_W32_SYSTEM
#define SOCKET2HANDLE(s) ((void *)(s))
#define HANDLE2SOCKET(h) ((unsigned int)(h))
diff --git a/tests/pipeconnect.c b/tests/pipeconnect.c
index ddb4a06..b477af1 100644
--- a/tests/pipeconnect.c
+++ b/tests/pipeconnect.c
@@ -247,61 +247,11 @@ run_client (const char *servername)
static void
parse_std_file_handles (int *argcp, char ***argvp)
{
-#ifdef HAVE_W32CE_SYSTEM
- int argc = *argcp;
- char **argv = *argvp;
- const char *s;
- assuan_fd_t fd;
- int i;
- int fixup = 0;
-
- if (!argc)
- return;
-
- for (argc--, argv++; argc; argc--, argv++)
- {
- s = *argv;
- if (*s == '-' && s[1] == '&' && s[2] == 'S'
- && (s[3] == '0' || s[3] == '1' || s[3] == '2')
- && s[4] == '='
- && (strchr ("-01234567890", s[5]) || !strcmp (s+5, "null")))
- {
- if (s[5] == 'n')
- fd = ASSUAN_INVALID_FD;
- else
- fd = _assuan_w32ce_finish_pipe (atoi (s+5), s[3] != '0');
- switch (s[3] - '0')
- {
- case 0: my_stdin = fd; break;
- case 1: my_stdout = fd; break;
- case 2: my_stderr = fd; break;
- }
-
- fixup++;
- }
- else
- break;
- }
-
- if (fixup)
- {
- argc = *argcp;
- argc -= fixup;
- *argcp = argc;
-
- argv = *argvp;
- for (i=1; i < argc; i++)
- argv[i] = argv[i + fixup];
- for (; i < argc + fixup; i++)
- argv[i] = NULL;
- }
-#else
(void)argcp;
(void)argvp;
my_stdin = 0;
my_stdout = 1;
my_stderr = 2;
-#endif
}