diff --git a/jnlib/ChangeLog b/jnlib/ChangeLog index 5a9e7072d..53ceedf27 100644 --- a/jnlib/ChangeLog +++ b/jnlib/ChangeLog @@ -1,3 +1,10 @@ +2010-03-01 Werner Koch + + * t-w32-reg.c: New. + + * w32-reg.c (read_w32_registry_string) + (write_w32_registry_string): Support W32CE. + 2010-02-26 Werner Koch * t-timestuff.c: New. diff --git a/jnlib/Makefile.am b/jnlib/Makefile.am index a0da872aa..232aef980 100644 --- a/jnlib/Makefile.am +++ b/jnlib/Makefile.am @@ -61,6 +61,9 @@ endif # so that there is no dependency on libgcrypt. # module_tests = t-stringhelp t-timestuff +if HAVE_W32_SYSTEM +module_tests += t-w32-reg +endif t_jnlib_src = t-support.c t-support.h t_jnlib_ldadd = libjnlib.a $(LIBINTL) $(LIBICONV) @@ -75,4 +78,8 @@ t_stringhelp_LDADD = $(t_jnlib_ldadd) t_timestuff_SOURCES = t-timestuff.c $(t_jnlib_src) t_timestuff_LDADD = $(t_jnlib_ldadd) +if HAVE_W32_SYSTEM +t_w32_reg_SOURCES = t-w32-reg.c $(t_jnlib_src) +t_w32_reg_LDADD = $(t_jnlib_ldadd) +endif diff --git a/jnlib/t-w32-reg.c b/jnlib/t-w32-reg.c new file mode 100644 index 000000000..f4848cbaa --- /dev/null +++ b/jnlib/t-w32-reg.c @@ -0,0 +1,70 @@ +/* t-w32-reg.c - Regression tests for W32 registry functions + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * This file is part of JNLIB. + * + * JNLIB 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. + * + * JNLIB 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 . + */ + +#include +#include +#include +#include +#include +#include + +#include "mischelp.h" + +#include "t-support.h" +#include "w32help.h" + + +static void +test_read_registry (void) +{ + char *string; + +#ifdef HAVE_W32CE_SYSTEM + string = read_w32_registry_string ("HKEY_CLASSES_ROOT", + "BOOTSTRAP\\CLSID", NULL); + if (!string) + fail (0); + fprintf (stderr, "Bootstrap clsid: %s\n", string); + xfree (string); +#endif + + string = read_w32_registry_string + ("HKEY_CURRENT_USER", + "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", + "User Agent"); + if (!string) + fail (0); + fprintf (stderr, "User agent: %s\n", string); + xfree (string); +} + + + + +int +main (int argc, char **argv) +{ + (void)argc; + (void)argv; + + test_read_registry (); + + return 0; +} + diff --git a/jnlib/w32-afunix.h b/jnlib/w32-afunix.h index 6b8f3f954..23681ddeb 100644 --- a/jnlib/w32-afunix.h +++ b/jnlib/w32-afunix.h @@ -26,6 +26,9 @@ #include #include +/* We can easiliy replace this code by the socket wrappers from libassuan. */ +#warning Please do not use this module anymore + #define DIRSEP_C '\\' #define AF_LOCAL AF_UNIX diff --git a/jnlib/w32-reg.c b/jnlib/w32-reg.c index e6bd911c5..5809c32bb 100644 --- a/jnlib/w32-reg.c +++ b/jnlib/w32-reg.c @@ -28,8 +28,10 @@ #include #include "libjnlib-config.h" +#include "utf8conv.h" #include "w32help.h" + static HKEY get_root_key(const char *root) { @@ -62,6 +64,70 @@ get_root_key(const char *root) char * read_w32_registry_string (const char *root, const char *dir, const char *name) { +#ifdef HAVE_W32CE_SYSTEM + HKEY root_key, key_handle; + DWORD n1, nbytes, type; + char *result = NULL; + wchar_t *wdir, *wname; + + if ( !(root_key = get_root_key(root) ) ) + return NULL; + + wdir = utf8_to_wchar (dir); + if (!wdir) + return NULL; + + if (RegOpenKeyEx (root_key, wdir, 0, KEY_READ, &key_handle) ) + { + if (root) + { + jnlib_free (wdir); + return NULL; /* No need for a RegClose, so return immediately. */ + } + /* It seems to be common practise to fall back to HKLM. */ + if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, wdir, 0, KEY_READ, &key_handle) ) + { + jnlib_free (wdir); + return NULL; /* Still no need for a RegClose. */ + } + } + jnlib_free (wdir); + + if (name) + { + wname = utf8_to_wchar (name); + if (!wname) + goto leave; + } + else + wname = NULL; + + nbytes = 2; + if (RegQueryValueEx (key_handle, wname, 0, NULL, NULL, &nbytes)) + goto leave; + result = jnlib_malloc ((n1=nbytes+2)); + if (!result) + goto leave; + if (RegQueryValueEx (key_handle, wname, 0, &type, result, &n1)) + { + jnlib_free (result); + result = NULL; + goto leave; + } + result[nbytes] = 0; /* Make sure it is a string. */ + result[nbytes+1] = 0; + if (type == REG_SZ || type == REG_EXPAND_SZ) + { + wchar_t *tmp = (void*)result; + result = wchar_to_utf8 (tmp); + jnlib_free (tmp); + } + + leave: + jnlib_free (wname); + RegCloseKey (key_handle); + return result; +#else /*!HAVE_W32CE_SYSTEM*/ HKEY root_key, key_handle; DWORD n1, nbytes, type; char *result = NULL; @@ -69,7 +135,7 @@ read_w32_registry_string (const char *root, const char *dir, const char *name) if ( !(root_key = get_root_key(root) ) ) return NULL; - if ( RegOpenKeyEx( root_key, dir, 0, KEY_READ, &key_handle ) ) + if (RegOpenKeyEx (root_key, dir, 0, KEY_READ, &key_handle) ) { if (root) return NULL; /* No need for a RegClose, so return immediately. */ @@ -142,15 +208,79 @@ read_w32_registry_string (const char *root, const char *dir, const char *name) leave: RegCloseKey (key_handle); return result; +#endif /*!HAVE_W32CE_SYSTEM*/ } +/* Note: This code is not well tested. However, it is not used in + GnuPG. */ int write_w32_registry_string (const char *root, const char *dir, const char *name, const char *value) { HKEY root_key, reg_key; +#ifdef HAVE_W32CE_SYSTEM + wchar_t *wdir, *wname, *wvalue; + DWORD disp; + + if ( !(root_key = get_root_key(root) ) ) + return -1; + + wdir = utf8_to_wchar (dir); + if (!wdir) + return -1; + + if (RegOpenKeyEx (root_key, wdir, 0, 0, ®_key)) + { + jnlib_free (wdir); + return -1; + } + jnlib_free (wdir); + if (name) + { + wname = utf8_to_wchar (name); + if (!wname) + return -1; + } + else + wname = NULL; + + wvalue = utf8_to_wchar (value); + if (wvalue) + { + jnlib_free (wname); + return -1; + } + + if (RegSetValueEx (reg_key, wname, 0, REG_SZ, + (BYTE *)wvalue, wcslen (wvalue)) != ERROR_SUCCESS ) + { + + if (RegCreateKeyEx (root_key, wname, 0, NULL, 0, 0, NULL, + ®_key, &disp) != ERROR_SUCCESS) + { + RegCloseKey(reg_key); + jnlib_free (wname); + jnlib_free (wvalue); + return -1; + } + if (RegSetValueEx (reg_key, wname, 0, REG_SZ, + (BYTE *)wvalue, wcslen (wvalue)) != ERROR_SUCCESS ) + { + RegCloseKey(reg_key); + jnlib_free (wname); + jnlib_free (wvalue); + return -1; + } + } + + jnlib_free (wname); + jnlib_free (wvalue); + RegCloseKey (reg_key); + return 0; +#else /*!HAVE_W32CE_SYSTEM*/ + if ( !(root_key = get_root_key(root) ) ) return -1; @@ -175,8 +305,8 @@ write_w32_registry_string (const char *root, const char *dir, } RegCloseKey (reg_key); - return 0; +#endif /*!HAVE_W32CE_SYSTEM*/ } #endif /*HAVE_W32_SYSTEM*/