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.