]> granicus.if.org Git - apache/commitdiff
Introduce a _raw_set/_raw_get for regkey values. Takes care of all the
authorWilliam A. Rowe Jr <wrowe@apache.org>
Tue, 2 Jul 2002 19:02:00 +0000 (19:02 +0000)
committerWilliam A. Rowe Jr <wrowe@apache.org>
Tue, 2 Jul 2002 19:02:00 +0000 (19:02 +0000)
  oddballs, and lets us simplify _array_set/_array_get.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@95936 13f79535-47bb-0310-9956-ffa450edef68

os/win32/ap_regkey.c
os/win32/ap_regkey.h

index f7240f6f1bf51f4ef4d05da5f3595e8e779f9be5..c313a4490623e2f747b2872e9d70684f1f82ef0b 100644 (file)
@@ -324,6 +324,7 @@ AP_DECLARE(apr_status_t) ap_regkey_value_get(char **result,
 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 @@ AP_DECLARE(apr_status_t) ap_regkey_value_set(ap_regkey_t *key,
      */
     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 @@ AP_DECLARE(apr_status_t) ap_regkey_value_set(ap_regkey_t *key,
          * 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 @@ AP_DECLARE(apr_status_t) ap_regkey_value_set(ap_regkey_t *key,
 #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_set(ap_regkey_t *key,
 }
 
 
-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 @@ AP_DECLARE(apr_status_t) ap_regkey_value_array_get(apr_array_header_t **result,
         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 @@ AP_DECLARE(apr_status_t) ap_regkey_value_array_get(apr_array_header_t **result,
         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 @@ AP_DECLARE(apr_status_t) ap_regkey_value_array_get(apr_array_header_t **result,
 #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 @@ AP_DECLARE(apr_status_t) ap_regkey_value_array_set(ap_regkey_t *key,
     /* 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 @@ AP_DECLARE(apr_status_t) ap_regkey_value_array_set(ap_regkey_t *key,
         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 @@ AP_DECLARE(apr_status_t) ap_regkey_value_array_set(ap_regkey_t *key,
             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 @@ AP_DECLARE(apr_status_t) ap_regkey_value_array_set(ap_regkey_t *key,
         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);
 }
 
 
index 489467587922a5fdcefb717b18709a110fd25f5b..8f47e3f471259e017eace68803d99e63c62e9b09 100644 (file)
@@ -91,6 +91,11 @@ AP_DECLARE(const ap_regkey_t *) ap_regkey_const(int i);
 #define AP_REGKEY_PERFORMANCE_DATA     ap_regkey_const(5)
 #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
@@ -158,6 +163,9 @@ AP_DECLARE(apr_status_t) ap_regkey_remove(const ap_regkey_t *parent,
  * @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,13 +177,48 @@ AP_DECLARE(apr_status_t) ap_regkey_value_get(char **result,
  * @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.
  * @param result The string elements retrieved from a REG_MULTI_SZ string array