Author: mturk
Date: Mon Jan 11 15:20:50 2010
New Revision: 897899

URL: http://svn.apache.org/viewvc?rev=897899&view=rev
Log:
Add unicode registry helpers

Modified:
    
commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h
    commons/sandbox/runtime/trunk/src/main/native/os/win32/registry.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=897899&r1=897898&r2=897899&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 
Mon Jan 11 15:20:50 2010
@@ -297,6 +297,38 @@
 #define ACR_IOH_FLAGS(H)    acr_ioh_tab[(H) & acr_ioh_mask].flags
 #define ACR_IOH_FDATA(H)    acr_ioh_tab[(H) & acr_ioh_mask].h
 
+static ACR_INLINE void FS2BSW(wchar_t *s)
+{
+    for (; *s; s++) {
+        if (*s == L'/')
+            *s = L'\\';
+    }
+}
+
+static ACR_INLINE void BS2FSW(wchar_t *s)
+{
+    for (; *s; s++) {
+        if (*s == L'\\')
+            *s = L'/';
+    }
+}
+
+static ACR_INLINE void FS2BSA(char *s)
+{
+    for (; *s; s++) {
+        if (*s == '/')
+            *s = '\\';
+    }
+}
+
+static ACR_INLINE void BS2FSA(char *s)
+{
+    for (; *s; s++) {
+        if (*s == '\\')
+            *s = '/';
+    }
+}
+
 static ACR_INLINE void FileTimeToUsecTime(acr_time_t *result, LPFILETIME input)
 {
     /* Convert FILETIME one 64 bit number so we can work with it. */

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=897899&r1=897898&r2=897899&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 Mon Jan 
11 15:20:50 2010
@@ -45,6 +45,22 @@
         return NULL;
 }
 
+static HKEY wcs_rootnamed(const wchar_t *name)
+{
+    if (!wcsnicmp(name, L"HKLM", 4))
+        return HKEY_LOCAL_MACHINE;
+    else if (!wcsnicmp(name, L"HKCU", 4))
+        return HKEY_CURRENT_USER;
+    else if (!wcsnicmp(name, L"HKCR", 4))
+        return HKEY_CLASSES_ROOT;
+    else if (!wcsnicmp(name, L"HKCC", 4))
+        return HKEY_CURRENT_CONFIG;
+    else if (!wcsnicmp(name, L"HKU", 3))
+        return HKEY_USERS;
+    else
+        return NULL;
+}
+
 static REGSAM reg_flags(const char *s)
 {
     REGSAM sam = KEY_QUERY_VALUE;
@@ -57,7 +73,24 @@
         sam |= KEY_WRITE;
     if (strchr(s, '3'))
         sam |= KEY_WOW64_32KEY;
-    else if (strchr(s, '6'))
+    else if (strstr(s, "64"))
+        sam |= KEY_WOW64_64KEY;
+    return sam;
+}
+
+static REGSAM wcs_flags(const wchar_t *s)
+{
+    REGSAM sam = KEY_QUERY_VALUE;
+
+    if (wcschr(s, L'x'))
+        sam |= KEY_ALL_ACCESS;
+    if (wcschr(s, L'r'))
+        sam |= KEY_READ;
+    if (wcschr(s, L'w'))
+        sam |= KEY_WRITE;
+    if (wcschr(s, L'3'))
+        sam |= KEY_WOW64_32KEY;
+    else if (wcsstr(s, L"64"))
         sam |= KEY_WOW64_64KEY;
     return sam;
 }
@@ -94,6 +127,38 @@
     return k;
 }
 
+ACR_DECLARE(x_registry_t *) RegistryOpenW(const wchar_t *name, const wchar_t 
*sam)
+{
+    int   i;
+    HKEY  r;
+    wchar_t *p;
+    x_registry_t *k;
+
+    if (!(r = wcs_rootnamed(name))) {
+        ACR_SET_OS_ERROR(ACR_EINVAL);
+        return NULL;
+    }
+
+    k = x_malloc(sizeof(x_registry_t));
+    if (!(p = wcschr(name, L'\\'))) {
+        x_free(k);
+        ACR_SET_OS_ERROR(ACR_EINVAL);
+        return NULL;
+    }
+    k->name = x_wcsdup(p + 1);
+    k->sam  = wcs_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) {
@@ -151,6 +216,51 @@
     return i;
 }
 
+ACR_DECLARE(int) RegistryDeleteW(const wchar_t *name, const wchar_t *sam, int 
all,
+                                 const wchar_t *value)
+{
+    int   i = ERROR_SUCCESS;
+    HKEY  r;
+    wchar_t *p;
+    x_registry_t k;
+    wchar_t *s = NULL;
+
+    if (!(r = wcs_rootnamed(name))) {
+        return ACR_EINVAL;
+    }
+
+    if (!(p = wcschr(name, L'\\'))) {
+        return ACR_EINVAL;
+    }
+    k.name = x_wcsdup(p + 1);
+    k.sam  = wcs_flags(sam);
+
+    if ((s = wcschr(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) {
+        i = SHDeleteValueW(k.key, s, value);
+    }
+    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;
@@ -184,6 +294,39 @@
     return k;
 }
 
+ACR_DECLARE(x_registry_t *) RegistryCreateW(const wchar_t *name, const wchar_t 
*sam)
+{
+    DWORD c;
+    int   i;
+    HKEY  r;
+    wchar_t *p;
+    x_registry_t *k;
+
+    if (!(r = wcs_rootnamed(name))) {
+        ACR_SET_OS_ERROR(ACR_EINVAL);
+        return NULL;
+    }
+
+    k = x_malloc(sizeof(x_registry_t));
+    if (!(p = wcschr(name, '\\'))) {
+        x_free(k);
+        ACR_SET_OS_ERROR(ACR_EINVAL);
+        return NULL;
+    }
+    k->name = x_wcsdup(p + 1);
+    k->sam  = wcs_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;
@@ -278,6 +421,96 @@
     return value;
 }
 
+ACR_DECLARE(wchar_t *) RegistryGetW(x_registry_t *k, const wchar_t *name, int 
sc)
+{
+    int   rc = 0;
+    DWORD rt;
+    DWORD rl, dw;
+    INT64 qw;
+    wchar_t *wn = NULL;
+    wchar_t  tb[128];
+    unsigned char *bb  = NULL;
+    wchar_t     *value = NULL;
+    wchar_t *wp;
+    wchar_t *wb;
+    wchar_t *cp;
+
+    if (k && IS_INVALID_HANDLE(k->key)) {
+        ACR_SET_OS_ERROR(ACR_EINVAL);
+        return NULL;
+    }
+    if ((rc = (LONG)RegQueryValueExW(k->key, name, NULL,
+                        &rt, NULL, &rl)) != ERROR_SUCCESS) {
+        goto cleanup;
+    }
+    bb = x_malloc((size_t)rl);
+    if ((rc = (int)RegQueryValueExW(k->key, name, NULL,
+                        &rt, bb, &rl)) != ERROR_SUCCESS) {
+        goto cleanup;
+    }
+    wb = (wchar_t *)bb;
+    switch (rt) {
+        case REG_SZ:
+            value = wb;
+            bb = NULL;
+        break;
+        case REG_MULTI_SZ:
+            for (wp = wb; *wp; wp++) {
+                while (*wp)
+                    wp++;
+                if (*(wp + 1) != L'\0')
+                    *wp = sc;
+            }
+            value = wb;
+            bb = NULL;
+        break;
+        case REG_EXPAND_SZ:
+            {
+                wchar_t *sb;
+                DWORD    sz;
+                sz = ExpandEnvironmentStringsW(wb, NULL, 0);
+                if (sz) {
+                    sb = s_malloc(wchar_t, sz);
+                    if (sb == NULL)
+                        break;
+                    sz = ExpandEnvironmentStringsW(wb, sb, sz);
+                    if (!sz) {
+                        /* Shouldn't ever happen */
+                        int rc = GetLastError();
+                        x_free(sb);
+                        goto cleanup;
+                    }
+                    value = sb;
+                }
+            }
+        break;
+        case REG_DWORD:
+            memcpy(&rt, bb, 4);
+            value = x_wcsdup(_itow(rt, tb, 10));
+        break;
+        case REG_QWORD:
+            memcpy(&qw, bb, 8);
+            value = x_wcsdup(_i64tow(qw, tb, 10));
+        break;
+        case REG_BINARY:
+            value = s_malloc(wchar_t, rl * 4 + 1);
+            for (dw = 0, cp = value; dw < (rl - 1); dw++) {
+                _snwprintf(cp, 4, L"%02x, ", bb[dw]);
+                cp += 4;
+            }
+            _snwprintf(cp, 4, L"%02x", bb[dw]);
+        break;
+        default:
+            rc = ACR_EBADF;
+        break;
+    }
+
+cleanup:
+    x_free(bb);
+    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)
 {
@@ -355,6 +588,7 @@
                         pp++;
                 }
                 rc = RegSetValueExW(k->key, wn, 0, st, bb, i);
+                x_free(bb);
             }
         break;
         default:
@@ -367,6 +601,89 @@
     return rc;
 }
 
+ACR_DECLARE(int) RegistrySetW(x_registry_t *k, const wchar_t *name,
+                              int type, const wchar_t *value, int sc)
+{
+    int   rc = 0;
+    DWORD rt, st = type;
+    DWORD rl, dw;
+    INT64 qw;
+    wchar_t *wp, *p;
+
+    if (k && IS_INVALID_HANDLE(k->key)) {
+        return ACR_EINVAL;
+    }
+    if ((rc = (int)RegQueryValueExW(k->key, name, 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:
+            rc = RegSetValueExW(k->key, name, 0, st,
+                                (const unsigned char *)value,
+                                (DWORD)((wcslen(value) + 1) * 
sizeof(wchar_t)));
+        break;
+        case REG_MULTI_SZ:
+            wp = x_wcsdup(value);
+            rl = (DWORD)wcslen(wp);
+            for (p = wp; *p; p++) {
+                if (*p == sc)
+                    *p = L'\0';
+            }
+            rc = RegSetValueExW(k->key, name, 0, st,
+                                (const unsigned char *)wp,
+                                (DWORD)((rl + 2) * sizeof(wchar_t)));
+            x_free(wp);
+        break;
+        case REG_DWORD:
+            dw = (DWORD)_wtoi(value);
+            rc = RegSetValueExW(k->key, name, 0, st,
+                                (const unsigned char *)&dw, 4);
+        break;
+        case REG_QWORD:
+            qw = _wtoi64(value);
+            rc = RegSetValueExW(k->key, name, 0, st,
+                                (const unsigned char *)&qw, 8);
+        break;
+        case REG_BINARY:
+            {
+                DWORD i = 0;
+                const wchar_t *pp;
+                unsigned char *bb = x_malloc(wcslen(value) / 2);
+                if (!bb) {
+                    rc = ACR_ENOMEM;
+                    break;
+                }
+                for (pp = value; *pp; ) {
+                    wchar_t *ep;
+                    unsigned long v = wcstoul(pp, &ep, 16);
+
+                    bb[i++] = (unsigned char)v;
+                    pp = ep;
+                    while (*pp && !iswxdigit(*pp))
+                        pp++;
+                }
+                rc = RegSetValueExW(k->key, name, 0, st, bb, i);
+                x_free(bb);
+            }
+        break;
+        default:
+            rc = ACR_EBADF;
+        break;
+    }
+
+cleanup:
+    return rc;
+}
+
 ACR_DECLARE(int) RegistryHasA(const char *name)
 {
     int   i;
@@ -399,6 +716,38 @@
     return i;
 }
 
+ACR_DECLARE(int) RegistryHasW(const wchar_t *name)
+{
+    int   i;
+    HKEY  r;
+    wchar_t *p;
+    x_registry_t k;
+    wchar_t *s = NULL;
+
+    if (!(r = wcs_rootnamed(name))) {
+        return ACR_EINVAL;
+    }
+
+    if (!(p = wcschr(name, '\\'))) {
+        return ACR_EINVAL;
+    }
+    k.name = x_wcsdup(p + 1);
+    k.sam  = KEY_READ;
+    k.key  = 0;
+    if ((s = wcsrchr(k.name, L'\\'))) {
+        *(s++) = L'\0';
+    }
+    else {
+        x_free(k.name);
+        return ACR_EINVAL;
+    }
+    i = RegOpenKeyExW(r, k.name, 0, k.sam, &k.key);
+
+    SAFE_CLOSE_KEY(k.key);
+    x_free(k.name);
+    return i;
+}
+
 static REGSAM _regsam_translate(int nsam)
 {
     REGSAM rsam = 0;
@@ -429,14 +778,6 @@
     return rsam;
 }
 
-static __inline void FS2BS(wchar_t *s)
-{
-    for (; *s; s++) {
-        if (*s == L'/')
-            *s = L'\\';
-    }
-}
-
 ACR_JNI_PLATFORM_DECLARE(jint, RegistryKey, close0)(ACR_JNISTDARGS,
                                                     jlong key)
 {
@@ -474,7 +815,7 @@
     REGSAM rsam = _regsam_translate(sam);
 
     WITH_WSTR(name) {
-        FS2BS(J2W(name));
+        FS2BSW(J2W(name));
         rc = RegOpenKeyExW(hkey,
                            J2W(name),
                            0,
@@ -500,7 +841,7 @@
     REGSAM rsam = _regsam_translate(sam);
 
     WITH_WSTR(name) {
-        FS2BS(J2W(name));
+        FS2BSW(J2W(name));
         rc = RegCreateKeyExW(hkey,
                              J2W(name),
                              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=897899&r1=897898&r2=897899&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 Mon Jan 11 
15:20:50 2010
@@ -234,10 +234,7 @@
      * On Win32 for utf8 paths we always use the forwrd slashes.
      * They are converted to backward on translatio from utf8
      */
-    for (; *retstr; retstr++) {
-        if (*retstr == '\\')
-            *retstr = '/';
-    }
+    BS2FSA(retstr);
     return 0;
 }
 
@@ -273,14 +270,11 @@
      * On Win32 for utf8 paths we always use the forward slashes.
      * They are converted to backward on translation from acr.
      */
-    for (; *retstr; retstr++) {
-        if (*retstr == '\\')
-            *retstr = '/';
-    }
+    BS2FSW(retstr);
     return 0;
 }
 
-int acr_to_unicode_path(wchar_t* retstr, size_t retlen,
+int acr_to_unicode_path(wchar_t *retstr, size_t retlen,
                         const wchar_t* srcstr)
 {
     /* TODO: The computations could preconvert the string to determine


Reply via email to