aboutsummaryrefslogtreecommitdiffstats
path: root/util
diff options
context:
space:
mode:
Diffstat (limited to 'util')
-rw-r--r--util/ChangeLog69
-rw-r--r--util/Makefile.am8
-rw-r--r--util/argparse.c2
-rw-r--r--util/dotlock.c41
-rw-r--r--util/errors.c1
-rw-r--r--util/http.c40
-rw-r--r--util/iobuf.c38
-rw-r--r--util/logger.c6
-rw-r--r--util/miscutil.c2
-rw-r--r--util/secmem.c20
-rw-r--r--util/simple-gettext.c29
-rw-r--r--util/strgutil.c12
-rw-r--r--util/ttyio.c40
-rw-r--r--util/w32reg.c88
14 files changed, 338 insertions, 58 deletions
diff --git a/util/ChangeLog b/util/ChangeLog
index d5b661095..c6d64aa6a 100644
--- a/util/ChangeLog
+++ b/util/ChangeLog
@@ -1,3 +1,70 @@
+Tue May 30 16:37:55 CEST 2000 Werner Koch <[email protected]>
+
+ * iobuf.c (iobuf_cancel): Fix for MSDOS.
+
+Fri Apr 14 19:37:08 CEST 2000 Werner Koch <[email protected]>
+
+ * dotlock.c (disable_dotlock): New. Implmented this in the module.
+
+2000-03-09 14:04:22 Werner Koch ([email protected])
+
+ * argparse.c (default_strusage): Changed year of default copyright.
+
+Tue Mar 7 18:45:31 CET 2000 Werner Koch <[email protected]>
+
+ * secmem.c (lock_pool): No more warning for QNX. By Sam Roberts.
+
+2000-03-02 15:51:04 Werner Koch ([email protected])
+
+ * ttyio.c (tty_print_utf8_string): Oops.
+
+Thu Mar 2 15:37:46 CET 2000 Werner Koch <[email protected]>
+
+ * ttyio.c (tty_print_utf8_string2): New to allow a max output size.
+
+Wed Feb 23 10:07:57 CET 2000 Werner Koch <[email protected]>
+
+ * miscutil.c (asctimestamp): Fix for possible buffer overflow by
+ large system returned date format string.
+
+Fri Dec 31 14:08:15 CET 1999 Werner Koch <[email protected]>
+
+ * logger.c (log_inc_errorcount): New.
+
+Sat Dec 4 12:30:28 CET 1999 Werner Koch <[email protected]>
+
+ * iobuf.c (iobuf_cancel): Broadcast the new Cancel mesaage to all
+ filters.
+
+Mon Nov 22 11:14:53 CET 1999 Werner Koch <[email protected]>
+
+ * strgutil.c (strcasecmp): New.
+
+ * secmem.c (pool_is_mmapped): Made volatile.
+
+Sat Oct 9 20:34:41 CEST 1999 Werner Koch <[email protected]>
+
+ * Makefile.am: Removed libtool.
+
+Fri Oct 8 20:32:01 CEST 1999 Werner Koch <[email protected]>
+
+ * w32reg.c: New.
+ * simple-gettext.c: Use the Registry to locate the mo file.
+
+ * http.c (send_request): Add support for proxys; suggested by
+ Walter Hofmann.
+ (http_open_document): Pass flags to http_open.
+
+Fri Sep 17 12:56:42 CEST 1999 Werner Koch <[email protected]>
+
+
+ * secmem.c (lock_pool): Check for ENOSYS return my mlock() on
+ old SCOs.
+
+ * ttyio.c (do_get): Replaced #if __MINGW32__ by #ifdef becuase
+ gcc 2.95.1 assigns a floating point value (0.2) to this macro,
+ which in turn can't be used in an expression.
+
Wed Sep 15 16:22:17 CEST 1999 Werner Koch <[email protected]>
@@ -71,7 +138,7 @@ Sat Jun 26 12:15:59 CEST 1999 Werner Koch <[email protected]>
Fri Jun 18 00:18:02 CEST 1999 Michael Roth <[email protected]>
* iobuf.c: file_filter() Detection of EOF on terminals
- improved/fixed (see Bug #21).
+ improved/fixed (see Bug #21).
Mon Jun 14 21:18:54 CEST 1999 Michael Roth <[email protected]>
diff --git a/util/Makefile.am b/util/Makefile.am
index 95096c7e7..5870fb6a9 100644
--- a/util/Makefile.am
+++ b/util/Makefile.am
@@ -2,13 +2,13 @@
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl
-noinst_LTLIBRARIES = libutil.la
+noinst_LIBRARIES = libutil.a
-libutil_la_LDFLAGS =
-libutil_la_SOURCES = g10u.c logger.c fileutil.c miscutil.c strgutil.c \
+#libutil_a_LDFLAGS =
+libutil_a_SOURCES = g10u.c logger.c fileutil.c miscutil.c strgutil.c \
ttyio.c argparse.c memory.c secmem.c errors.c iobuf.c \
- dotlock.c http.c simple-gettext.c
+ dotlock.c http.c simple-gettext.c w32reg.c
http-test: http.c
diff --git a/util/argparse.c b/util/argparse.c
index c6f405f62..929d62a79 100644
--- a/util/argparse.c
+++ b/util/argparse.c
@@ -892,7 +892,7 @@ default_strusage( int level )
switch( level ) {
case 11: p = "foo"; break;
case 13: p = "0.0"; break;
- case 14: p = "Copyright (C) 1999 Free Software Foundation, Inc."; break;
+ case 14: p = "Copyright (C) 2000 Free Software Foundation, Inc."; break;
case 15: p =
"This program comes with ABSOLUTELY NO WARRANTY.\n"
"This is free software, and you are welcome to redistribute it\n"
diff --git a/util/dotlock.c b/util/dotlock.c
index 369a3d42a..fc8ddae36 100644
--- a/util/dotlock.c
+++ b/util/dotlock.c
@@ -1,5 +1,5 @@
/* dotlock.c - dotfile locking
- * Copyright (C) 1998 Free Software Foundation, Inc.
+ * Copyright (C) 1998,2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -42,14 +42,22 @@ struct dotlock_handle {
char *tname; /* name of lockfile template */
char *lockname; /* name of the real lockfile */
int locked; /* lock status */
+ int disable; /* locking */
};
static DOTLOCK all_lockfiles;
+static int never_lock;
static int read_lockfile( const char *name );
static void remove_lockfiles(void);
+void
+disable_dotlock(void)
+{
+ never_lock = 1;
+}
+
/****************
* Create a lockfile with the given name and return an object of
* type DOTLOCK which may be used later to actually do the lock.
@@ -88,6 +96,17 @@ create_dotlock( const char *file_to_lock )
return NULL;
h = m_alloc_clear( sizeof *h );
+ if( never_lock ) {
+ h->disable = 1;
+ #ifdef _REENTRANT
+ /* fixme: aquire mutex on all_lockfiles */
+ #endif
+ h->next = all_lockfiles;
+ all_lockfiles = h;
+ return h;
+ }
+
+
#ifndef HAVE_DOSISH_SYSTEM
sprintf( pidstr, "%10d\n", (int)getpid() );
/* fixme: add the hostname to the second line (FQDN or IP addr?) */
@@ -191,6 +210,10 @@ make_dotlock( DOTLOCK h, long timeout )
const char *maybe_dead="";
int backoff=0;
+ if( h->disable ) {
+ return 0;
+ }
+
if( h->locked ) {
log_debug("oops, `%s' is already locked\n", h->lockname );
return 0;
@@ -259,6 +282,10 @@ release_dotlock( DOTLOCK h )
#else
int pid;
+ if( h->disable ) {
+ return 0;
+ }
+
if( !h->locked ) {
log_debug("oops, `%s' is not locked\n", h->lockname );
return 0;
@@ -333,11 +360,13 @@ remove_lockfiles()
while( h ) {
h2 = h->next;
- if( h->locked )
- unlink( h->lockname );
- unlink(h->tname);
- m_free(h->tname);
- m_free(h->lockname);
+ if( !h->disable ) {
+ if( h->locked )
+ unlink( h->lockname );
+ unlink(h->tname);
+ m_free(h->tname);
+ m_free(h->lockname);
+ }
m_free(h);
h = h2;
}
diff --git a/util/errors.c b/util/errors.c
index 0590f8ed8..e1551d03d 100644
--- a/util/errors.c
+++ b/util/errors.c
@@ -100,6 +100,7 @@ g10_errstr( int err )
X(NETWORK ,N_("network error"))
X(SELFTEST_FAILED,"selftest failed")
X(NOT_ENCRYPTED ,N_("not encrypted"))
+ X(NOT_PROCESSED ,N_("not processed"))
default: p = buf; sprintf(buf, "g10err=%d", err); break;
}
#undef X
diff --git a/util/http.c b/util/http.c
index 4bac8d845..d3bc44fe3 100644
--- a/util/http.c
+++ b/util/http.c
@@ -74,7 +74,7 @@ http_open( HTTP_HD hd, HTTP_REQ_TYPE reqtype, const char *url,
{
int rc;
- if( flags || !(reqtype == HTTP_REQ_GET || reqtype == HTTP_REQ_POST) )
+ if( !(reqtype == HTTP_REQ_GET || reqtype == HTTP_REQ_POST) )
return G10ERR_INV_ARG;
/* initialize the handle */
@@ -82,6 +82,7 @@ http_open( HTTP_HD hd, HTTP_REQ_TYPE reqtype, const char *url,
hd->sock = -1;
hd->initialized = 1;
hd->req_type = reqtype;
+ hd->flags = flags;
rc = parse_uri( &hd->uri, url );
if( !rc ) {
@@ -148,10 +149,7 @@ http_open_document( HTTP_HD hd, const char *document, unsigned int flags )
{
int rc;
- if( flags )
- return G10ERR_INV_ARG;
-
- rc = http_open( hd, HTTP_REQ_GET, document, 0 );
+ rc = http_open( hd, HTTP_REQ_GET, document, flags );
if( rc )
return rc;
@@ -427,21 +425,47 @@ send_request( HTTP_HD hd )
byte *request, *p;
ushort port;
int rc;
+ const char *http_proxy = NULL;
server = *hd->uri->host? hd->uri->host : "localhost";
port = hd->uri->port? hd->uri->port : 80;
- hd->sock = connect_server( server, port );
+ if( (hd->flags & HTTP_FLAG_TRY_PROXY)
+ && (http_proxy = getenv( "http_proxy" )) ) {
+ PARSED_URI uri;
+
+ rc = parse_uri( &uri, http_proxy );
+ if (rc) {
+ log_error("invalid $http_proxy: %s\n", g10_errstr(rc));
+ release_parsed_uri( uri );
+ return G10ERR_NETWORK;
+ }
+ hd->sock = connect_server( *uri->host? uri->host : "localhost",
+ uri->port? uri->port : 80 );
+ release_parsed_uri( uri );
+ }
+ else
+ hd->sock = connect_server( server, port );
+
if( hd->sock == -1 )
return G10ERR_NETWORK;
p = build_rel_path( hd->uri );
- request = m_alloc( strlen(p) + 20 );
- sprintf( request, "%s %s%s HTTP/1.0\r\n",
+ request = m_alloc( strlen(server) + strlen(p) + 50 );
+ if( http_proxy ) {
+ sprintf( request, "%s http://%s:%hu%s%s HTTP/1.0\r\n",
+ hd->req_type == HTTP_REQ_GET ? "GET" :
+ hd->req_type == HTTP_REQ_HEAD? "HEAD":
+ hd->req_type == HTTP_REQ_POST? "POST": "OOPS",
+ server, port, *p == '/'? "":"/", p );
+ }
+ else {
+ sprintf( request, "%s %s%s HTTP/1.0\r\n",
hd->req_type == HTTP_REQ_GET ? "GET" :
hd->req_type == HTTP_REQ_HEAD? "HEAD":
hd->req_type == HTTP_REQ_POST? "POST": "OOPS",
*p == '/'? "":"/", p );
+ }
m_free(p);
rc = write_server( hd->sock, request, strlen(request) );
diff --git a/util/iobuf.c b/util/iobuf.c
index 83c1e475d..0254ca78c 100644
--- a/util/iobuf.c
+++ b/util/iobuf.c
@@ -80,6 +80,8 @@ static int underflow(IOBUF a);
* IOBUFCTRL_FLUSH: called by iobuf_flush() to write out the collected stuff.
* *RET_LAN is the number of bytes in BUF.
*
+ * IOBUFCTRL_CANCEL: send to all filters on behalf of iobuf_cancel. The
+ * filter may take appropriate action on this message.
*/
static int
file_filter(void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len)
@@ -497,13 +499,41 @@ int
iobuf_cancel( IOBUF a )
{
const char *s;
+ IOBUF a2;
+ int rc;
+ #ifdef HAVE_DOSISH_SYSTEM
+ char *remove_name = NULL;
+ #endif
if( a && a->use == 2 ) {
s = iobuf_get_real_fname(a);
- if( s && *s )
- remove(s); /* remove the file. Fixme: this will fail for MSDOZE*/
- } /* because the file is still open */
- return iobuf_close(a);
+ if( s && *s ) {
+ #ifdef HAVE_DOSISH_SYSTEM
+ remove_name = m_strdup ( s );
+ #else
+ remove(s);
+ #endif
+ }
+ }
+
+ /* send a cancel message to all filters */
+ for( a2 = a; a2 ; a2 = a2->chain ) {
+ size_t dummy;
+ if( a2->filter )
+ a2->filter( a2->filter_ov, IOBUFCTRL_CANCEL, a2->chain,
+ NULL, &dummy );
+ }
+
+ rc = iobuf_close(a);
+ #ifdef HAVE_DOSISH_SYSTEM
+ if ( remove_name ) {
+ /* Argg, MSDOS does not allow to remove open files. So
+ * we have to do it here */
+ remove ( remove_name );
+ m_free ( remove_name );
+ }
+ #endif
+ return rc;
}
diff --git a/util/logger.c b/util/logger.c
index a1fb1f3d7..d9e908aec 100644
--- a/util/logger.c
+++ b/util/logger.c
@@ -101,6 +101,12 @@ log_get_errorcount( int clear)
return n;
}
+void
+log_inc_errorcount()
+{
+ errorcount++;
+}
+
void
g10_log_print_prefix(const char *text)
diff --git a/util/miscutil.c b/util/miscutil.c
index eb72415bb..0b87f1b84 100644
--- a/util/miscutil.c
+++ b/util/miscutil.c
@@ -147,7 +147,7 @@ asctimestamp( u32 stamp )
tp = localtime( &atime );
#ifdef HAVE_STRFTIME
#if defined(HAVE_NL_LANGINFO)
- mem2str( fmt, nl_langinfo(D_T_FMT), DIM(fmt) );
+ mem2str( fmt, nl_langinfo(D_T_FMT), DIM(fmt)-3 );
if( strstr( fmt, "%Z" ) == NULL )
strcat( fmt, " %Z");
strftime( buffer, DIM(buffer)-1, fmt, tp );
diff --git a/util/secmem.c b/util/secmem.c
index 3f253d6db..54836cbcf 100644
--- a/util/secmem.c
+++ b/util/secmem.c
@@ -58,7 +58,7 @@ struct memblock_struct {
static void *pool;
static volatile int pool_okay; /* may be checked in an atexit function */
-static int pool_is_mmapped;
+static volatile int pool_is_mmapped;
static size_t poolsize; /* allocated length */
static size_t poollen; /* used length */
static MEMBLOCK *unused_blocks;
@@ -97,8 +97,11 @@ lock_pool( void *p, size_t n )
#ifdef EAGAIN /* OpenBSD returns this */
&& errno != EAGAIN
#endif
+ #ifdef ENOSYS /* Some SCOs return this (function not implemented) */
+ && errno != ENOSYS
+ #endif
)
- log_error("can�t lock memory: %s\n", strerror(err));
+ log_error("can't lock memory: %s\n", strerror(err));
show_warning = 1;
}
@@ -134,11 +137,20 @@ lock_pool( void *p, size_t n )
#ifdef EAGAIN /* OpenBSD returns this */
&& errno != EAGAIN
#endif
+ #ifdef ENOSYS /* Some SCOs return this (function not implemented) */
+ && errno != ENOSYS
+ #endif
)
- log_error("can�t lock memory: %s\n", strerror(err));
+ log_error("can't lock memory: %s\n", strerror(err));
show_warning = 1;
}
+ #elif defined ( __QNX__ )
+ /* QNX does not page at all, so the whole secure memory stuff does
+ * not make much sense. However it is still of use because it
+ * wipes out the memory on a free().
+ * Therefore it is sufficient to suppress the warning
+ */
#else
log_info("Please note that you don't have secure memory on this system\n");
#endif
@@ -374,7 +386,7 @@ m_is_secure( const void *p )
/****************
* Warning: This code might be called by an interrupt handler
- * and frankly, thre should really be such a handler,
+ * and frankly, there should really be such a handler,
* to make sure that the memory is wiped out.
* We hope that the OS wipes out mlocked memory after
* receiving a SIGKILL - it really should do so, otherwise
diff --git a/util/simple-gettext.c b/util/simple-gettext.c
index bf25e8b18..a45ecb2b2 100644
--- a/util/simple-gettext.c
+++ b/util/simple-gettext.c
@@ -242,19 +242,21 @@ set_gettext_file( const char *filename )
#endif
) {
/* absolute path - use it as is */
- log_info("trying `%s'\n", filename );
domain = load_domain( filename );
}
- else { /* relative path - append ".mo" and get DIR from env */
+ else { /* relative path - append ".mo" and get dir from the environment */
char *buf = NULL;
- const char *s;
+ char *dir;
- s = getenv("MINGW32_NLS_DIR");
- if( s && (buf=malloc(strlen(s)+strlen(filename)+1+3+1)) ) {
- strcpy(stpcpy(stpcpy(stpcpy( buf, s),"/"), filename),".mo");
+ dir = read_w32_registry_string( NULL,
+ "Control Panel\\Mingw32\\NLS",
+ "MODir" );
+ if( dir && (buf=malloc(strlen(dir)+strlen(filename)+1+3+1)) ) {
+ strcpy(stpcpy(stpcpy(stpcpy( buf, dir),"/"), filename),".mo");
domain = load_domain( buf );
free(buf);
}
+ free(dir);
}
if( !domain )
return -1;
@@ -464,5 +466,20 @@ gettext( const char *msgid )
return msgid;
}
+#if 0
+ unsigned int cp1, cp2;
+
+ cp1 = GetConsoleCP();
+ cp2 = GetConsoleOutputCP();
+
+ log_info("InputCP=%u OutputCP=%u\n", cp1, cp2 );
+
+ if( !SetConsoleOutputCP( 1252 ) )
+ log_info("SetConsoleOutputCP failed: %d\n", (int)GetLastError() );
+
+ cp1 = GetConsoleCP();
+ cp2 = GetConsoleOutputCP();
+ log_info("InputCP=%u OutputCP=%u after switch1\n", cp1, cp2 );
+#endif
#endif /* USE_SIMPLE_GETTEXT */
diff --git a/util/strgutil.c b/util/strgutil.c
index 9ab63a047..861bf0d6b 100644
--- a/util/strgutil.c
+++ b/util/strgutil.c
@@ -559,6 +559,18 @@ strlwr(char *s)
}
#endif
+#ifndef HAVE_STRCASECMP
+int
+strcasecmp( const char *a, const char *b )
+{
+ for( ; *a && *b; a++, b++ ) {
+ if( *a != *b && toupper(*a) != toupper(*b) )
+ break;
+ }
+ return *(const byte*)a - *(const byte*)b;
+}
+#endif
+
/****************
* mingw32/cpd has a memicmp()
*/
diff --git a/util/ttyio.c b/util/ttyio.c
index 6c1a5059a..8d0824aad 100644
--- a/util/ttyio.c
+++ b/util/ttyio.c
@@ -107,23 +107,6 @@ init_ttyfp(void)
SetConsoleMode(con.in, DEF_INPMODE );
SetConsoleMode(con.out, DEF_OUTMODE );
-#warning DEBUG CODE
- {
- unsigned int cp1, cp2;
-
- cp1 = GetConsoleCP();
- cp2 = GetConsoleOutputCP();
-
- log_info("InputCP=%u OutputCP=%u\n", cp1, cp2 );
-
- if( !SetConsoleOutputCP( 1252 ) )
- log_info("SetConsoleOutputCP failed: %d\n", (int)GetLastError() );
-
- cp1 = GetConsoleCP();
- cp2 = GetConsoleOutputCP();
- log_info("InputCP=%u OutputCP=%u after switch1\n", cp1, cp2 );
-
- }
#elif defined(__EMX__)
ttyfp = stdout; /* Fixme: replace by the real functions: see wklib */
#else
@@ -253,7 +236,7 @@ tty_print_string( byte *p, size_t n )
}
void
-tty_print_utf8_string( byte *p, size_t n )
+tty_print_utf8_string2( byte *p, size_t n, size_t max_n )
{
size_t i;
char *buf;
@@ -268,15 +251,26 @@ tty_print_utf8_string( byte *p, size_t n )
}
if( i < n ) {
buf = utf8_to_native( p, n );
+ if( strlen( buf ) > max_n ) {
+ buf[max_n] = 0;
+ }
+ /*(utf8 conversion already does the control character quoting)*/
tty_printf("%s", buf );
m_free( buf );
}
- else
+ else {
+ if( n > max_n ) {
+ n = max_n;
+ }
tty_print_string( p, n );
+ }
}
-
-
+void
+tty_print_utf8_string( byte *p, size_t n )
+{
+ tty_print_utf8_string2( p, n, n );
+}
static char *
@@ -304,7 +298,7 @@ do_get( const char *prompt, int hidden )
buf = m_alloc(n=50);
i = 0;
- #if __MINGW32__ /* windoze version */
+ #ifdef __MINGW32__ /* windoze version */
if( hidden )
SetConsoleMode(con.in, HID_INPMODE );
@@ -419,7 +413,7 @@ tty_kill_prompt()
last_prompt_len = 0;
if( !last_prompt_len )
return;
- #if __MINGW32__
+ #ifdef __MINGW32__
tty_printf("\r%*s\r", last_prompt_len, "");
#else
{
diff --git a/util/w32reg.c b/util/w32reg.c
new file mode 100644
index 000000000..0cf38090f
--- /dev/null
+++ b/util/w32reg.c
@@ -0,0 +1,88 @@
+/* w32reg.c - MS-Windows Registry access
+ * Copyright (C) 1999 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#ifdef __MINGW32__ /* This module is only used in this environment */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <windows.h>
+#include "util.h"
+#include "memory.h"
+
+
+/****************
+ * Return a string from the Win32 Registry or NULL in case of
+ * error. Caller must release the return value. A NUKK for root
+ * is an alias fro HKEY_CURRENT_USER
+ * NOTE: The value is allocated with a plain malloc() - use free() and not
+ * the usual m_free()!!!
+ */
+char *
+read_w32_registry_string( const char *root, const char *dir, const char *name )
+{
+ HKEY root_key, key_handle;
+ DWORD n1, nbytes;
+ char *result = NULL;
+
+ if( !root )
+ root_key = HKEY_CURRENT_USER;
+ else if( !strcmp( root, "HKEY_CLASSES_ROOT" ) )
+ root_key = HKEY_CLASSES_ROOT;
+ else if( !strcmp( root, "HKEY_CURRENT_USER" ) )
+ root_key = HKEY_CURRENT_USER;
+ else if( !strcmp( root, "HKEY_LOCAL_MACHINE" ) )
+ root_key = HKEY_LOCAL_MACHINE;
+ else if( !strcmp( root, "HKEY_USERS" ) )
+ root_key = HKEY_USERS;
+ else if( !strcmp( root, "HKEY_PERFORMANCE_DATA" ) )
+ root_key = HKEY_PERFORMANCE_DATA;
+ else if( !strcmp( root, "HKEY_CURRENT_CONFIG" ) )
+ root_key = HKEY_CURRENT_CONFIG;
+ else
+ return NULL;
+
+ if( RegOpenKeyEx( root_key, dir, 0, KEY_READ, &key_handle ) )
+ return NULL; /* no need for a RegClose, so return direct */
+
+ nbytes = 1;
+ if( RegQueryValueEx( key_handle, name, 0, NULL, NULL, &nbytes ) )
+ goto leave;
+ result = malloc( (n1=nbytes+1) );
+ if( !result )
+ goto leave;
+ if( RegQueryValueEx( key_handle, name, 0, NULL, result, &n1 ) ) {
+ free(result); result = NULL;
+ goto leave;
+ }
+ result[nbytes] = 0; /* make sure it is really a string */
+
+ leave:
+ RegCloseKey( key_handle );
+ return result;
+}
+
+
+
+
+
+#endif /* __MINGW32__ */