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;
+
+}