You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2009/09/15 09:30:03 UTC

svn commit: r815196 - in /commons/sandbox/runtime/trunk/src/main/native: include/arch/windows/acr_arch.h include/arch/windows/acr_arch_private.h include/arch/windows/acr_arch_registry.h os/win32/registry.c os/win32/signals.c os/win32/wutil.c

Author: mturk
Date: Tue Sep 15 07:30:02 2009
New Revision: 815196

URL: http://svn.apache.org/viewvc?rev=815196&view=rev
Log:
Add simple registry access API. The API is used for daemon like tools with UTF8 charset

Modified:
    commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h
    commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch_private.h
    commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch_registry.h
    commons/sandbox/runtime/trunk/src/main/native/os/win32/registry.c
    commons/sandbox/runtime/trunk/src/main/native/os/win32/signals.c
    commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c

Modified: commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h?rev=815196&r1=815195&r2=815196&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h Tue Sep 15 07:30:02 2009
@@ -347,6 +347,36 @@
     }
 }
 
+static ACR_INLINE char *x_strdup(const char *s)
+{
+    char *d = NULL;
+    if (s) {
+        size_t size = strlen(s);
+        d = x_malloc(size + 2);
+        if (d) {
+            memcpy(d, s, size);
+            d[size]   = '\0';
+            d[size+1] = '\0';
+        }
+    }
+    return d;
+}
+
+static ACR_INLINE wchar_t *x_wcsdup(const wchar_t *s)
+{
+    wchar_t *d = NULL;
+    if (s) {
+        size_t size = wcslen(s);
+        d = x_malloc((size + 2) * sizeof(wchar_t));
+        if (d) {
+            memcpy(d, s, size * sizeof(wchar_t));
+            d[size]   = L'\0';
+            d[size+1] = L'\0';
+        }
+    }
+    return d;
+}
+
 /**
  * Secure version of zero memory
  * It should force compiler to always set the

Modified: commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch_private.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch_private.h?rev=815196&r1=815195&r2=815196&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch_private.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch_private.h Tue Sep 15 07:30:02 2009
@@ -202,6 +202,8 @@
 wchar_t *x_wcsdup_utf8_path(const char *);
 wchar_t *x_wcsdup_utf8(const char *);
 char    *x_strdup_utf8(const wchar_t *);
+LPWSTR   MbsToWcs(DWORD, LPCSTR, LPWSTR, DWORD);
+LPSTR    WcsToMbs(DWORD, LPCWSTR, LPSTR, DWORD);
 
 /**
  * Wide char envvar functions from env.c

Modified: commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch_registry.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch_registry.h?rev=815196&r1=815195&r2=815196&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch_registry.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch_registry.h Tue Sep 15 07:30:02 2009
@@ -60,6 +60,22 @@
 #define ACR_REG_QWORD               5
 #define ACR_REG_SZ                  6
 
+#define SAFE_CLOSE_KEY(k) \
+    if ((k) != NULL && (k) != INVALID_HANDLE_VALUE) {   \
+        RegCloseKey((k));                               \
+        (k) = NULL;                                     \
+    } else (void)0
+
+/**
+ * Internal registry helper type
+ */
+typedef struct x_registry_t {
+    HKEY        key;
+    REGSAM      sam;
+    wchar_t    *name;
+} x_registry_t;
+
+
 #ifdef __cplusplus
 }
 #endif

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/registry.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/registry.c?rev=815196&r1=815195&r2=815196&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/registry.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/registry.c Tue Sep 15 07:30:02 2009
@@ -25,5 +25,326 @@
 #include "acr_tlsd.h"
 #include "acr_vm.h"
 
+#include <shlwapi.h>
 /* Windows Registry utility functions
  */
+
+static HKEY reg_rootnamed(const char *name)
+{
+    if (!strnicmp(name, "HKLM", 4))
+        return HKEY_LOCAL_MACHINE;
+    else if (!strnicmp(name, "HKCU", 4))
+        return HKEY_CURRENT_USER;
+    else if (!strnicmp(name, "HKCR", 4))
+        return HKEY_CLASSES_ROOT;
+    else if (!strnicmp(name, "HKCC", 4))
+        return HKEY_CURRENT_CONFIG;
+    else if (!strnicmp(name, "HKU", 3))
+        return HKEY_USERS;
+    else
+        return NULL;
+}
+
+static REGSAM reg_flags(const char *s)
+{
+    REGSAM sam = KEY_QUERY_VALUE;
+
+    if (strchr(s, 'x'))
+        sam |= KEY_ALL_ACCESS;
+    if (strchr(s, 'r'))
+        sam |= KEY_READ;
+    if (strchr(s, 'w'))
+        sam |= KEY_WRITE;
+    if (strstr(s, "32"))
+        sam |= KEY_WOW64_32KEY;
+    else if (strstr(s, "64"))
+        sam |= KEY_WOW64_64KEY;
+    return sam;
+}
+
+ACR_DECLARE(x_registry_t *) RegistryOpenA(const char *name, const char *sam)
+{
+    int   i;
+    HKEY  r;
+    char *p;
+    x_registry_t *k;
+
+    if (!(r = reg_rootnamed(name))) {
+        ACR_SET_OS_ERROR(ACR_EINVAL);
+        return NULL;
+    }
+
+    k = x_malloc(sizeof(x_registry_t));
+    if (!(p = strchr(name, '\\'))) {
+        x_free(k);
+        ACR_SET_OS_ERROR(ACR_EINVAL);
+        return NULL;
+    }
+    k->name = x_wcsdup_utf8(p + 1);
+    k->sam  = reg_flags(sam);
+
+    if ((i = RegOpenKeyExW(r, k->name, 0,
+                           k->sam, &k->key)) != ERROR_SUCCESS) {
+        x_free(k->name);
+        x_free(k);
+        ACR_SET_OS_ERROR(i);
+        return NULL;
+    }
+
+    return k;
+}
+
+ACR_DECLARE(void) RegistryClose(x_registry_t *key)
+{
+    if (key) {
+        SAFE_CLOSE_KEY(key->key);
+        x_free(key->name);
+        x_free(key);
+    }
+}
+
+ACR_DECLARE(int) RegistryDeleteA(const char *name, const char *sam, int all,
+                                 const char *value)
+{
+    int   i = ERROR_SUCCESS;
+    HKEY  r;
+    char *p;
+    x_registry_t k;
+    wchar_t *v;
+    wchar_t *s = NULL;
+
+    if (!(r = reg_rootnamed(name))) {
+        return ACR_EINVAL;
+    }
+
+    if (!(p = strchr(name, '\\'))) {
+        return ACR_EINVAL;
+    }
+    k.name = x_wcsdup_utf8(p + 1);
+    k.sam  = reg_flags(sam);
+
+    if ((s = wcsrchr(k.name, L'\\'))) {
+        *(s++) = L'\0';
+    }
+    else {
+        x_free(k.name);
+        return ACR_EINVAL;
+    }
+    if ((i = RegOpenKeyExW(r, k.name, 0,
+                           k.sam, &k.key)) != ERROR_SUCCESS) {
+        x_free(k.name);
+        return i;
+    }
+    if (value) {
+        v = x_wcsdup_utf8(value);
+        i = SHDeleteValueW(k.key, s, v);
+        x_free(v);
+    }
+    else {
+        if (all)
+            i = SHDeleteKeyW(k.key, s);
+        else
+            i = SHDeleteEmptyKeyW(k.key, s);
+    }
+    SAFE_CLOSE_KEY(k.key);
+    x_free(k.name);
+    return i;
+}
+
+ACR_DECLARE(x_registry_t *) RegistryCreateA(const char *name, const char *sam)
+{
+    DWORD c;
+    int   i;
+    HKEY  r;
+    char *p;
+    x_registry_t *k;
+
+    if (!(r = reg_rootnamed(name))) {
+        ACR_SET_OS_ERROR(ACR_EINVAL);
+        return NULL;
+    }
+
+    k = x_malloc(sizeof(x_registry_t));
+    if (!(p = strchr(name, '\\'))) {
+        x_free(k);
+        ACR_SET_OS_ERROR(ACR_EINVAL);
+        return NULL;
+    }
+    k->name = x_wcsdup_utf8(p + 1);
+    k->sam  = reg_flags(sam);
+
+    if ((i = RegCreateKeyExW(r, k->name, 0, NULL, 0,
+                k->sam, NULL, &k->key, &c)) != ERROR_SUCCESS) {
+        x_free(k->name);
+        x_free(k);
+        ACR_SET_OS_ERROR(i);
+        return NULL;
+    }
+
+    return k;
+}
+
+ACR_DECLARE(char *) RegistryGetA(x_registry_t *k, const char *name, int sc)
+{
+    int   rc = 0;
+    DWORD rt;
+    DWORD rl, dw;
+    INT64 qw;
+    wchar_t *wn;
+    char  tb[128];
+    unsigned char *buff  = NULL;
+    char          *value = NULL;
+    wchar_t *wp;
+    char    *cp;
+
+    if (k && IS_INVALID_HANDLE(k->key)) {
+        ACR_SET_OS_ERROR(ACR_EINVAL);
+        return NULL;
+    }
+    if (!(wn = x_wcsdup_utf8(name))) {
+        ACR_SET_OS_ERROR(ACR_ENOMEM);
+        return NULL;
+    }
+    if ((rc = (LONG)RegQueryValueExW(k->key, wn, NULL,
+                        &rt, NULL, &rl)) != ERROR_SUCCESS) {
+        goto cleanup;
+    }
+    buff = x_malloc((size_t)rl);
+    if ((rc = (int)RegQueryValueExW(k->key, wn, NULL,
+                        &rt, buff, &rl)) != ERROR_SUCCESS) {
+        goto cleanup;
+    }
+    switch (rt) {
+        case REG_SZ:
+            value = x_strdup_utf8((wchar_t *)buff);
+        break;
+        case REG_MULTI_SZ:
+            for (wp = (wchar_t *)buff; *wp; wp++) {
+                while (*wp)
+                    wp++;
+                if (*(wp + 1) != L'\0')
+                    *wp = sc;
+            }
+            value = x_strdup_utf8((wchar_t *)buff);
+        break;
+        case REG_EXPAND_SZ:
+            {
+                wchar_t *sb;
+                DWORD    sz;
+                sz = ExpandEnvironmentStringsW((wchar_t *)buff, NULL, 0);
+                if (sz) {
+                    sb = x_malloc(sz * sizeof(wchar_t));
+                    if (sb == NULL)
+                        break;
+                    sz = ExpandEnvironmentStringsW((wchar_t *)buff, sb, sz);
+                    if (!sz) {
+                        /* Shouldn't ever happen */
+                        int rc = GetLastError();
+                        x_free(sb);
+                        goto cleanup;
+                    }
+                    value =  x_strdup_utf8(sb);
+                    x_free(sb);
+                }
+            }
+        break;
+        case REG_DWORD:
+            memcpy(&rt, buff, 4);
+            value = x_strdup(itoa(rt, tb, 10));
+        break;
+        case REG_QWORD:
+            memcpy(&qw, buff, 8);
+            value = x_strdup(_i64toa(qw, tb, 10));
+        break;
+        case REG_BINARY:
+            value = x_malloc(rl * 4 + 1);
+            for (dw = 0, cp = value; dw < (rl - 1); dw++) {
+                sprintf(cp, "%02x, ", buff[dw]);
+                cp += 4;
+            }
+            sprintf(cp, "%02x", buff[dw]);
+        break;
+        default:
+            rc = ACR_EBADF;
+        break;
+    }
+
+cleanup:
+    x_free(wn);
+    x_free(buff);
+    ACR_SET_OS_ERROR(rc);
+    return value;
+}
+
+ACR_DECLARE(int) RegistrySetA(x_registry_t *k, const char *name,
+                              int type, const char *value, int sc)
+{
+    int   rc = 0;
+    DWORD rt, st = type;
+    DWORD rl, dw;
+    INT64 qw;
+    wchar_t *wn;
+    unsigned char *buff = NULL;
+    wchar_t *wp, *p;
+
+    if (k && IS_INVALID_HANDLE(k->key)) {
+        return ACR_EINVAL;
+    }
+    if (!(wn = x_wcsdup_utf8(name))) {
+        return ACR_ENOMEM;
+    }
+    if ((rc = (int)RegQueryValueExW(k->key, wn, NULL,
+                        &rt, NULL, &rl)) == ERROR_SUCCESS) {
+        if (st != REG_NONE && st != rt) {
+            rc = ACR_EINVAL;
+            goto cleanup;
+        }
+        st = rt;
+    }
+    if (st == REG_NONE)
+        st = REG_SZ;
+
+    switch (st) {
+        case REG_SZ:
+        case REG_EXPAND_SZ:
+            wp = x_wcsdup_utf8(value);
+            rc = RegSetValueExW(k->key, wn, 0, st,
+                                (const unsigned char *)wp,
+                                (wcslen(wp) + 1) * sizeof(wchar_t));
+            x_free(wp);
+        break;
+        case REG_MULTI_SZ:
+            wp = x_wcsdup_utf8(value);
+            rl = wcslen(wp);
+            for (p = wp; *p; p++) {
+                if (*p == sc)
+                    *p = L'\0';
+            }
+            rc = RegSetValueExW(k->key, wn, 0, st,
+                                (const unsigned char *)wp,
+                                (rl + 2) * sizeof(wchar_t));
+            x_free(wp);
+        break;
+        case REG_DWORD:
+            dw = (DWORD)atoi(value);
+            rc = RegSetValueExW(k->key, wn, 0, st,
+                                (const unsigned char *)&dw, 4);
+        break;
+        case REG_QWORD:
+            qw = _atoi64(value);
+            rc = RegSetValueExW(k->key, wn, 0, st,
+                                (const unsigned char *)&qw, 8);
+        break;
+        case REG_BINARY:
+            rc = ACR_ENOTIMPL;
+        break;
+        default:
+            rc = ACR_EBADF;
+        break;
+    }
+
+cleanup:
+    x_free(wn);
+    x_free(buff);
+    return rc;
+}

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/signals.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/signals.c?rev=815196&r1=815195&r2=815196&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/signals.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/signals.c Tue Sep 15 07:30:02 2009
@@ -578,8 +578,8 @@
         current_signal_queue |= sigmask(signum);
         /* Wake up the monitor thread.
          */
-        LeaveCriticalSection(&signal_lock);
         SetEvent(dll_auto_hevent);
+        LeaveCriticalSection(&signal_lock);
 
         return 0;
     }

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c?rev=815196&r1=815195&r2=815196&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c Tue Sep 15 07:30:02 2009
@@ -254,7 +254,7 @@
             ACR_SET_OS_ERROR(ACR_EILSEQ);
         return NULL;
     }
-    res = x_malloc(len * sizeof(wchar_t));
+    res = x_malloc((len + 1) * sizeof(wchar_t));
     if (!res)
         return NULL;
     if (!MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
@@ -270,6 +270,7 @@
         return NULL;
     }
     else {
+        res[len+1] = L'\0';
         return res;
     }
 }
@@ -327,7 +328,7 @@
             errno = EILSEQ;
         return NULL;
     }
-    if (!(res = x_malloc(len))) {
+    if (!(res = x_malloc(len + 1))) {
         /* Make sure GetLastError returns ENOMEM
          */
         ACR_SET_OS_ERROR(ACR_ENOMEM);
@@ -346,6 +347,44 @@
         return NULL;
     }
     else {
+        res[len+1] = '\0';
         return res;
     }
 }
+
+LPWSTR MbsToWcs(DWORD dwCp, LPCSTR szAnsi, LPWSTR szWide, DWORD dwLength)
+{
+
+    if (!szWide) {
+        dwLength = MultiByteToWideChar(dwCp, MB_ERR_INVALID_CHARS,
+                                       szAnsi, -1, NULL, 0);
+        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+            return NULL;
+        if (!(szWide = (LPWSTR)x_malloc(sizeof(WCHAR) * (dwLength + 1))))
+            return NULL;
+    }
+    if (MultiByteToWideChar(dwCp, MB_ERR_INVALID_CHARS,
+                            szAnsi, -1, szWide, dwLength))
+        return szWide;
+    else
+        return NULL;
+}
+
+LPSTR WcsToMbs(DWORD dwCp, LPCWSTR szWide, LPSTR szAnsi, DWORD dwLength)
+{
+    if (!szAnsi) {
+        dwLength = WideCharToMultiByte(dwCp, 0, szWide, -1,
+                                       NULL, 0, NULL, NULL);
+        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+            return NULL;
+        if (!(szAnsi = (LPSTR)x_malloc(dwLength + 1)))
+            return NULL;
+    }
+
+    if (WideCharToMultiByte(dwCp, 0, szWide, -1,
+                            szAnsi, dwLength, NULL, NULL))
+        return szAnsi;
+    else
+        return NULL;
+
+}