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