You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by wr...@apache.org on 2002/07/02 21:02:00 UTC
cvs commit: httpd-2.0/os/win32 ap_regkey.c ap_regkey.h
wrowe 2002/07/02 12:02:00
Modified: os/win32 ap_regkey.c ap_regkey.h
Log:
Introduce a _raw_set/_raw_get for regkey values. Takes care of all the
oddballs, and lets us simplify _array_set/_array_get.
Revision Changes Path
1.3 +138 -69 httpd-2.0/os/win32/ap_regkey.c
Index: ap_regkey.c
===================================================================
RCS file: /home/cvs/httpd-2.0/os/win32/ap_regkey.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ap_regkey.c 24 Jun 2002 07:50:36 -0000 1.2
+++ ap_regkey.c 2 Jul 2002 19:02:00 -0000 1.3
@@ -324,6 +324,7 @@
AP_DECLARE(apr_status_t) ap_regkey_value_set(ap_regkey_t *key,
const char *valuename,
const char *value,
+ apr_int32_t flags,
apr_pool_t *pool)
{
/* Retrieve a registry string value, and explode any envvars
@@ -331,6 +332,7 @@
*/
LONG rc;
DWORD size = strlen(value) + 1;
+ DWORD type = (flags & AP_REGKEY_EXPAND) ? REG_EXPAND_SZ : REG_SZ;
#if APR_HAS_UNICODE_FS
IF_WIN_OS_IS_UNICODE
@@ -359,7 +361,7 @@
* converted to bytes; the trailing L'\0' continues to be counted.
*/
size = (alloclen - wvallen) * 2;
- rc = RegSetValueExW(key->hkey, wvalname, 0, REG_SZ,
+ rc = RegSetValueExW(key->hkey, wvalname, 0, type,
(LPBYTE)wvalue, size);
if (rc != ERROR_SUCCESS)
return APR_FROM_OS_ERROR(rc);
@@ -368,7 +370,7 @@
#if APR_HAS_ANSI_FS
ELSE_WIN_OS_IS_ANSI
{
- rc = RegSetValueEx(key->hkey, valuename, 0, REG_SZ, value, size);
+ rc = RegSetValueEx(key->hkey, valuename, 0, type, value, size);
if (rc != ERROR_SUCCESS)
return APR_FROM_OS_ERROR(rc);
}
@@ -377,28 +379,24 @@
}
-AP_DECLARE(apr_status_t) ap_regkey_value_array_get(apr_array_header_t **result,
- ap_regkey_t *key,
- const char *valuename,
- apr_pool_t *pool)
+AP_DECLARE(apr_status_t) ap_regkey_value_raw_get(void **result,
+ apr_size_t *resultsize,
+ apr_int32_t *resulttype,
+ ap_regkey_t *key,
+ const char *valuename,
+ apr_pool_t *pool)
{
/* Retrieve a registry string value, and explode any envvars
* that the system has configured (e.g. %SystemRoot%/someapp.exe)
*/
LONG rc;
- char *buf;
- char *tmp;
- DWORD type;
- DWORD size = 0;
#if APR_HAS_UNICODE_FS
IF_WIN_OS_IS_UNICODE
{
- apr_size_t alloclen;
apr_size_t valuelen = strlen(valuename) + 1;
apr_size_t wvallen = 256;
apr_wchar_t wvalname[256];
- apr_wchar_t *wvalue;
apr_status_t rv;
rv = apr_conv_utf8_to_ucs2(valuename, &valuelen, wvalname, &wvallen);
if (rv != APR_SUCCESS)
@@ -406,21 +404,113 @@
else if (valuelen)
return APR_ENAMETOOLONG;
/* Read to NULL buffer to determine value size */
- rc = RegQueryValueExW(key->hkey, wvalname, 0, &type, NULL, &size);
+ rc = RegQueryValueExW(key->hkey, wvalname, 0, resulttype,
+ NULL, resultsize);
if (rc != ERROR_SUCCESS) {
return APR_FROM_OS_ERROR(rc);
}
- if ((size < 2) || (type != REG_MULTI_SZ)) {
- return APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER);
- }
- wvalue = apr_palloc(pool, size);
/* Read value based on size query above */
- rc = RegQueryValueExW(key->hkey, wvalname, 0, &type,
- (LPBYTE)wvalue, &size);
- if (rc != ERROR_SUCCESS) {
+ *result = apr_palloc(pool, *resultsize);
+ rc = RegQueryValueExW(key->hkey, wvalname, 0, resulttype,
+ (LPBYTE)*result, resultsize);
+ }
+#endif /* APR_HAS_UNICODE_FS */
+#if APR_HAS_ANSI_FS
+ ELSE_WIN_OS_IS_ANSI
+ {
+ /* Read to NULL buffer to determine value size */
+ rc = RegQueryValueEx(key->hkey, valuename, 0, resulttype,
+ NULL, resultsize);
+ if (rc != ERROR_SUCCESS)
return APR_FROM_OS_ERROR(rc);
- }
+
+ /* Read value based on size query above */
+ *result = apr_palloc(pool, *resultsize);
+ rc = RegQueryValueEx(key->hkey, valuename, 0, resulttype,
+ (LPBYTE)*result, resultsize);
+ if (rc != ERROR_SUCCESS)
+ return APR_FROM_OS_ERROR(rc);
+ }
+#endif
+ if (rc != ERROR_SUCCESS) {
+ return APR_FROM_OS_ERROR(rc);
+ }
+
+ return APR_SUCCESS;
+}
+
+
+AP_DECLARE(apr_status_t) ap_regkey_value_raw_set(ap_regkey_t *key,
+ const char *valuename,
+ void *value,
+ apr_size_t valuesize,
+ apr_int32_t valuetype,
+ apr_pool_t *pool)
+{
+ LONG rc;
+
+#if APR_HAS_UNICODE_FS
+ IF_WIN_OS_IS_UNICODE
+ {
+ apr_size_t valuelen = strlen(valuename) + 1;
+ apr_size_t wvallen = 256;
+ apr_wchar_t wvalname[256];
+ apr_status_t rv;
+ rv = apr_conv_utf8_to_ucs2(valuename, &valuelen, wvalname, &wvallen);
+ if (rv != APR_SUCCESS)
+ return rv;
+ else if (valuelen)
+ return APR_ENAMETOOLONG;
+
+ rc = RegSetValueExW(key->hkey, wvalname, 0, valuetype,
+ (LPBYTE)value, valuesize);
+ }
+#endif /* APR_HAS_UNICODE_FS */
+#if APR_HAS_ANSI_FS
+ ELSE_WIN_OS_IS_ANSI
+ {
+ rc = RegSetValueEx(key->hkey, valuename, 0, valuetype,
+ (LPBYTE)value, valuesize);
+ }
+#endif
+ if (rc != ERROR_SUCCESS) {
+ return APR_FROM_OS_ERROR(rc);
+ }
+ return APR_SUCCESS;
+}
+
+
+AP_DECLARE(apr_status_t) ap_regkey_value_array_get(apr_array_header_t **result,
+ ap_regkey_t *key,
+ const char *valuename,
+ apr_pool_t *pool)
+{
+ /* Retrieve a registry string value, and explode any envvars
+ * that the system has configured (e.g. %SystemRoot%/someapp.exe)
+ */
+ apr_status_t rv;
+ void *value;
+ char *buf;
+ char *tmp;
+ DWORD type;
+ DWORD size = 0;
+
+ rv = ap_regkey_value_raw_get(&value, &size, &type, key, valuename, pool);
+ if (rv != APR_SUCCESS) {
+ return rv;
+ }
+ else if (type != REG_MULTI_SZ) {
+ return APR_EINVAL;
+ }
+
+#if APR_HAS_UNICODE_FS
+ IF_WIN_OS_IS_UNICODE
+ {
+ apr_size_t alloclen;
+ apr_size_t valuelen = strlen(valuename) + 1;
+ apr_size_t wvallen = 256;
+ apr_wchar_t *wvalue = (apr_wchar_t *)value;
/* ###: deliberately overallocate plus two extra nulls.
* We could precalculate the exact buffer here instead, the question
@@ -429,10 +519,10 @@
size /= 2;
alloclen = valuelen = size * 3 + 2;
buf = apr_palloc(pool, valuelen);
- rv = apr_conv_ucs2_to_utf8(wvalue, &size, buf, &valuelen);
+ rv = apr_conv_ucs2_to_utf8(value, &size, buf, &valuelen);
if (rv != APR_SUCCESS)
return rv;
- else if (size || (valuelen < 2))
+ else if (size)
return APR_ENAMETOOLONG;
buf[(alloclen - valuelen)] = '\0';
buf[(alloclen - valuelen) + 1] = '\0';
@@ -441,26 +531,16 @@
#if APR_HAS_ANSI_FS
ELSE_WIN_OS_IS_ANSI
{
- /* Read to NULL buffer to determine value size */
- rc = RegQueryValueEx(key->hkey, valuename, 0, &type, NULL, &size);
- if (rc != ERROR_SUCCESS)
- return APR_FROM_OS_ERROR(rc);
-
- if ((size < 1) || (type != REG_MULTI_SZ)) {
- return APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER);
- }
-
/* Small possiblity the array is either unterminated
* or single NULL terminated. Avert.
*/
- buf = apr_palloc(pool, size + 2);
- buf[size + 1] = '\0';
- buf[size] = '\0';
-
- /* Read value based on size query above */
- rc = RegQueryValueEx(key->hkey, valuename, 0, &type, buf, &size);
- if (rc != ERROR_SUCCESS)
- return APR_FROM_OS_ERROR(rc);
+ buf = (char *)value;
+ if (size < 2 || buf[size - 1] != '\0' || buf[size - 1] != '\0') {
+ buf = apr_palloc(pool, size + 2);
+ memcpy(buf, value, size);
+ buf[size + 1] = '\0';
+ buf[size] = '\0';
+ }
}
#endif
@@ -494,26 +574,17 @@
/* Retrieve a registry string value, and explode any envvars
* that the system has configured (e.g. %SystemRoot%/someapp.exe)
*/
- LONG rc;
+ int i;
+ const void *value;
+ apr_size_t bufsize;
#if APR_HAS_UNICODE_FS
IF_WIN_OS_IS_UNICODE
{
- int i;
- DWORD size;
+ apr_status_t rv;
apr_wchar_t *buf;
apr_wchar_t *tmp;
apr_size_t bufrem;
- apr_size_t bufsize;
- apr_size_t valuelen = strlen(valuename) + 1;
- apr_size_t wvallen = 256;
- apr_wchar_t wvalname[256];
- apr_status_t rv;
- rv = apr_conv_utf8_to_ucs2(valuename, &valuelen, wvalname, &wvallen);
- if (rv != APR_SUCCESS)
- return rv;
- else if (valuelen)
- return APR_ENAMETOOLONG;
bufsize = 1; /* For trailing second null */
for (i = 0; i < nelts; ++i) {
@@ -528,7 +599,7 @@
tmp = buf;
for (i = 0; i < nelts; ++i) {
apr_size_t eltsize = strlen(elts[i]) + 1;
- size = eltsize;
+ apr_size_t size = eltsize;
rv = apr_conv_utf8_to_ucs2(elts[i], &size, tmp, &bufrem);
if (rv != APR_SUCCESS)
return rv;
@@ -537,22 +608,22 @@
tmp += eltsize;
}
if (!nelts) {
+ --bufrem;
(*tmp++) = L'\0';
}
+ --bufrem;
*tmp = L'\0'; /* Trailing second null */
- size = (bufsize - bufrem) * 2;
- rc = RegSetValueExW(key->hkey, wvalname, 0, REG_MULTI_SZ,
- (LPBYTE)buf, size);
- if (rc != ERROR_SUCCESS)
- return APR_FROM_OS_ERROR(rc);
+ bufsize = (bufsize - bufrem) * 2;
+ value = (void*)buf;
}
#endif /* APR_HAS_UNICODE_FS */
#if APR_HAS_ANSI_FS
ELSE_WIN_OS_IS_ANSI
{
- int bufsize, i;
- char *buf, *tmp;
+ char *buf;
+ char *tmp;
+
bufsize = 1; /* For trailing second null */
for (i = 0; i < nelts; ++i) {
bufsize += strlen(elts[i]) + 1;
@@ -563,21 +634,19 @@
buf = apr_palloc(pool, bufsize);
tmp = buf;
for (i = 0; i < nelts; ++i) {
- strcpy(tmp, elts[i]);
- tmp += strlen(elts[i]) + 1;
+ apr_size_t len = strlen(elts[i]) + 1;
+ memcpy(tmp, elts[i], len);
+ tmp += len;
}
if (!nelts) {
(*tmp++) = '\0';
}
*tmp = '\0'; /* Trailing second null */
-
- rc = RegSetValueEx(key->hkey, valuename, 0, REG_MULTI_SZ,
- buf, bufsize);
- if (rc != ERROR_SUCCESS)
- return APR_FROM_OS_ERROR(rc);
+ value = buf;
}
#endif
- return APR_SUCCESS;
+ return ap_regkey_value_raw_set(key, valuename, value,
+ bufsize, REG_MULTI_SZ, pool);
}
1.3 +43 -0 httpd-2.0/os/win32/ap_regkey.h
Index: ap_regkey.h
===================================================================
RCS file: /home/cvs/httpd-2.0/os/win32/ap_regkey.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ap_regkey.h 27 Jun 2002 03:54:50 -0000 1.2
+++ ap_regkey.h 2 Jul 2002 19:02:00 -0000 1.3
@@ -92,6 +92,11 @@
#define AP_REGKEY_DYN_DATA ap_regkey_const(6)
/**
+ * Win32 Only: Flags for ap_regkey_value_set()
+ */
+#define AP_REGKEY_EXPAND 0x0001
+
+/**
* Win32 Only: Open the specified registry key.
* @param newkey The opened registry key
* @param parentkey The open registry key of the parent, or one of
@@ -158,6 +163,9 @@
* @param key The registry key to retrieve the value from
* @param valuename The named value to retrieve (pass "" for the default)
* @param pool The pool used to store the result
+ * @remark There is no toggle to prevent environment variable expansion
+ * if the registry value is set with AP_REG_EXPAND (REG_EXPAND_SZ), such
+ * expansions are always performed.
*/
AP_DECLARE(apr_status_t) ap_regkey_value_get(char **result,
ap_regkey_t *key,
@@ -169,12 +177,47 @@
* @param key The registry key to store the value into
* @param valuename The named value to store (pass "" for the default)
* @param value The string to store for the named value
+ * @param flags The option AP_REGKEY_EXPAND or 0, where AP_REGKEY_EXPAND
+ * values will find all %foo% variables expanded from the environment.
* @param pool The pool used for temp allocations
*/
AP_DECLARE(apr_status_t) ap_regkey_value_set(ap_regkey_t *key,
const char *valuename,
const char *value,
+ apr_int32_t flags,
apr_pool_t *pool);
+
+/**
+ * Win32 Only: Retrieve a raw byte value from an open key.
+ * @param result The raw bytes value retrieved
+ * @param resultsize Pointer to a variable to store the number raw bytes retrieved
+ * @param key The registry key to retrieve the value from
+ * @param valuename The named value to retrieve (pass "" for the default)
+ * @param pool The pool used to store the result
+ */
+AP_DECLARE(apr_status_t) ap_regkey_value_raw_get(void **result,
+ apr_size_t *resultsize,
+ apr_int32_t *resulttype,
+ ap_regkey_t *key,
+ const char *valuename,
+ apr_pool_t *pool);
+
+/**
+ * Win32 Only: Store a raw bytes value into an open key.
+ * @param key The registry key to store the value into
+ * @param valuename The named value to store (pass "" for the default)
+ * @param value The bytes to store for the named value
+ * @param valuesize The number of bytes for value
+ * @param valuetype The
+ * values will find all %foo% variables expanded from the environment.
+ * @param pool The pool used for temp allocations
+ */
+AP_DECLARE(apr_status_t) ap_regkey_value_raw_set(ap_regkey_t *key,
+ const char *valuename,
+ const void *value,
+ apr_size_t valuesize,
+ apr_int32_t valuetype,
+ apr_pool_t *pool);
/**
* Win32 Only: Retrieve a registry value string from an open key.