whelk/registry.c
changeset 14 1a62417393a2
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/whelk/registry.c	Tue Feb 09 00:42:09 2010 +0000
     1.3 @@ -0,0 +1,175 @@
     1.4 +#include <stdlib.h>
     1.5 +#include <windows.h>
     1.6 +#include "_whelk.h"
     1.7 +
     1.8 +HRESULT whelk_reg_close_key(HKEY key)
     1.9 +{
    1.10 +    return RegCloseKey(key);
    1.11 +}
    1.12 +
    1.13 +HRESULT whelk_reg_open_key(HKEY key,const char *subkey,HKEY *out)
    1.14 +{
    1.15 +    int i;
    1.16 +    WCHAR *subkey2;
    1.17 +    HRESULT result;
    1.18 +    subkey2=whelk_utf8_to_utf16(subkey,-1);
    1.19 +    for(i=0;subkey2[i];i++)
    1.20 +	if (subkey2[i]=='/')
    1.21 +	    subkey2[i]='\\';
    1.22 +    result=RegOpenKeyExW(key,subkey2,0,KEY_READ|KEY_WRITE,out);
    1.23 +    free(subkey2);
    1.24 +    return result;
    1.25 +    
    1.26 +}
    1.27 +
    1.28 +HRESULT whelk_reg_create_key(HKEY key,const char *subkey,HKEY *out)
    1.29 +{
    1.30 +    int i;
    1.31 +    WCHAR *subkey2;
    1.32 +    HRESULT result;
    1.33 +    subkey2=whelk_utf8_to_utf16(subkey,-1);
    1.34 +    for(i=0;subkey2[i];i++)
    1.35 +	if (subkey2[i]=='/')
    1.36 +	    subkey2[i]='\\';
    1.37 +    result=RegCreateKeyExW(key,subkey2,0,NULL,REG_OPTION_NON_VOLATILE,
    1.38 +      KEY_READ|KEY_WRITE,NULL,out,NULL);
    1.39 +    free(subkey2);
    1.40 +    return result;
    1.41 +    
    1.42 +}
    1.43 +
    1.44 +HRESULT whelk_reg_get_value(HKEY key,const char *subkey,const char *value,
    1.45 +  DWORD *type,void **data,DWORD *nb)
    1.46 +{
    1.47 +    HRESULT result;
    1.48 +    WCHAR *value2,*str2;
    1.49 +    DWORD len;
    1.50 +    if (subkey && *subkey)
    1.51 +    {
    1.52 +	result=whelk_reg_open_key(key,subkey,&key);
    1.53 +	if (result!=ERROR_SUCCESS)
    1.54 +	    return result;
    1.55 +    }
    1.56 +    value2=whelk_utf8_to_utf16(value,-1);
    1.57 +    *nb=0;
    1.58 +    *data=NULL;
    1.59 +    result=RegQueryValueExW(key,value2,0,type,*data,nb);
    1.60 +    if (result==ERROR_MORE_DATA)
    1.61 +    {
    1.62 +	*data=malloc(*nb);
    1.63 +	result=RegQueryValueExW(key,value2,0,type,*data,nb);
    1.64 +    }
    1.65 +    free(value2);
    1.66 +    if (subkey && *subkey)
    1.67 +	(void)whelk_reg_close_key(key);
    1.68 +    if (result!=ERROR_SUCCESS)
    1.69 +    {
    1.70 +	free(*data);
    1.71 +	*data=NULL;
    1.72 +    }
    1.73 +    else if (*type==REG_SZ || *type==REG_EXPAND_SZ)
    1.74 +    {
    1.75 +	str2=*data;
    1.76 +	len=*nb/2;
    1.77 +	if (!str2[len-1])	/* Cope with unterminated strings */
    1.78 +	    len--;
    1.79 +	*data=whelk_utf16_to_utf8(str2,len);
    1.80 +	*nb=strlen(*data)+1;
    1.81 +	free(str2);
    1.82 +    }
    1.83 +    return result;
    1.84 +}
    1.85 +
    1.86 +/*
    1.87 + * To delete a value, set data to NULL.
    1.88 + */
    1.89 +
    1.90 +HRESULT whelk_reg_set_value(HKEY key,const char *subkey,const char *value,
    1.91 +  DWORD type,const void *data,int nb)
    1.92 +{
    1.93 +    HRESULT result;
    1.94 +    WCHAR *value2,*str2;
    1.95 +    if (subkey && *subkey)
    1.96 +    {
    1.97 +	if (data)
    1.98 +	    result=whelk_reg_create_key(key,subkey,&key);
    1.99 +	else
   1.100 +	{
   1.101 +	    result=whelk_reg_open_key(key,subkey,&key);
   1.102 +	    if (result==ERROR_FILE_NOT_FOUND || result==ERROR_PATH_NOT_FOUND)
   1.103 +		return ERROR_SUCCESS;
   1.104 +	}
   1.105 +	if (result!=ERROR_SUCCESS)
   1.106 +	    return result;
   1.107 +    }
   1.108 +    value2=whelk_utf8_to_utf16(value,-1);
   1.109 +    if (data)
   1.110 +    {
   1.111 +	/* FIXME: Support REG_MULTI_SZ */
   1.112 +	if (type==REG_SZ || type==REG_EXPAND_SZ)
   1.113 +	{
   1.114 +	    str2=whelk_utf8_to_utf16(data,nb);
   1.115 +	    nb=(lstrlenW(str2)+1)*sizeof(WCHAR);
   1.116 +	    data=str2;
   1.117 +	}
   1.118 +	result=RegSetValueExW(key,value2,0,type,data,nb);
   1.119 +	if (type==REG_SZ || type==REG_EXPAND_SZ)
   1.120 +	    free(str2);
   1.121 +    }
   1.122 +    else
   1.123 +	result=RegDeleteValueW(key,value2);
   1.124 +    free(value2);
   1.125 +    if (subkey && *subkey)
   1.126 +	(void)whelk_reg_close_key(key);
   1.127 +    return result;
   1.128 +}
   1.129 +
   1.130 +static HRESULT whelk_reg_delete_key_wide(HKEY key,WCHAR *subkey)
   1.131 +{
   1.132 +    HRESULT result,r;
   1.133 +    HKEY skey;
   1.134 +    int i;
   1.135 +    DWORD nsubkeys;
   1.136 +    DWORD name_len,max_name_len;	/* In WCHARs */
   1.137 +    WCHAR *name;
   1.138 +    result=RegOpenKeyExW(key,subkey,0,KEY_READ|KEY_WRITE,&skey);
   1.139 +    if (result==ERROR_FILE_NOT_FOUND || result==ERROR_PATH_NOT_FOUND)
   1.140 +	return ERROR_SUCCESS;
   1.141 +    else if (result!=ERROR_SUCCESS)
   1.142 +	return result;
   1.143 +    result=RegQueryInfoKeyW(skey,NULL,NULL,NULL,&nsubkeys,&max_name_len,NULL,
   1.144 +      NULL,NULL,NULL,NULL,NULL);
   1.145 +    if (result!=ERROR_SUCCESS)
   1.146 +    {
   1.147 +	RegCloseKey(skey);
   1.148 +	return result;
   1.149 +    }
   1.150 +    max_name_len++;			/* For terminator */
   1.151 +    name=malloc(max_name_len*sizeof(WCHAR));
   1.152 +    for(i=nsubkeys-1;i>=0;i--)
   1.153 +    {
   1.154 +	name_len=max_name_len;
   1.155 +	r=RegEnumKeyExW(skey,i,name,&name_len,NULL,NULL,NULL,NULL);
   1.156 +	if (r==ERROR_SUCCESS)
   1.157 +	    r=whelk_reg_delete_key_wide(skey,name);
   1.158 +	if (r!=ERROR_SUCCESS)
   1.159 +	    result=r;
   1.160 +    }
   1.161 +    free(name);
   1.162 +    RegCloseKey(skey);
   1.163 +    if (result==ERROR_SUCCESS)
   1.164 +	result=RegDeleteKeyW(key,subkey);
   1.165 +    return result;
   1.166 +}
   1.167 +
   1.168 +HRESULT whelk_reg_delete_key(HKEY key,const char *subkey)
   1.169 +{
   1.170 +    HRESULT result;
   1.171 +    WCHAR *subkey2;
   1.172 +    if (!subkey || !*subkey)
   1.173 +	return ERROR_INVALID_PARAMETER;
   1.174 +    subkey2=whelk_utf8_to_utf16(subkey,-1);
   1.175 +    result=whelk_reg_delete_key_wide(key,subkey2);
   1.176 +    free(subkey2);
   1.177 +    return result;
   1.178 +}