Added a first-cut version of MapVirtualKeyExW() that has the same
[wine] / dlls / shlwapi / reg.c
1 /*
2  * SHLWAPI registry functions
3  */
4
5 #include "windef.h"
6 #include "winerror.h"
7 #include "winreg.h"
8 #include "wine/undocshell.h"
9 #include "debugtools.h"
10
11 DEFAULT_DEBUG_CHANNEL(shell);
12
13 /*************************************************************************
14  * SHRegGetUSValueA     [SHLWAPI.@]
15  *
16  * Gets a user-specific registry value
17  */
18 LONG WINAPI SHRegGetUSValueA(
19         LPCSTR   pSubKey,
20         LPCSTR   pValue,
21         LPDWORD  pwType,
22         LPVOID   pvData,
23         LPDWORD  pbData,
24         BOOL     fIgnoreHKCU,
25         LPVOID   pDefaultData,
26         DWORD    wDefaultDataSize)
27 {
28         FIXME("(%p),stub!\n", pSubKey);
29         return ERROR_SUCCESS;  /* return success */
30 }
31
32 /*************************************************************************
33  * SHRegGetUSValueW     [SHLWAPI.@]
34  *
35  * Gets a user-specific registry value
36  */
37 LONG WINAPI SHRegGetUSValueW(
38         LPCWSTR  pSubKey,
39         LPCWSTR  pValue,
40         LPDWORD  pwType,
41         LPVOID   pvData,
42         LPDWORD  pbData,
43         BOOL     flagIgnoreHKCU,
44         LPVOID   pDefaultData,
45         DWORD    wDefaultDataSize)
46 {
47         FIXME("(%p),stub!\n", pSubKey);
48         return ERROR_SUCCESS;  /* return success */
49 }
50
51 /*************************************************************************
52  * SHRegGetBoolUSValueA   [SHLWAPI.@]
53  */
54 BOOL WINAPI SHRegGetBoolUSValueA(
55         LPCSTR pszSubKey,
56         LPCSTR pszValue,
57         BOOL fIgnoreHKCU,
58         BOOL fDefault)
59 {
60         FIXME("%s %s\n", pszSubKey,pszValue);
61         return fDefault;
62 }
63
64 /*************************************************************************
65  * SHRegGetBoolUSValueW   [SHLWAPI.@]
66  */
67 BOOL WINAPI SHRegGetBoolUSValueW(
68         LPCWSTR pszSubKey,
69         LPCWSTR pszValue,
70         BOOL fIgnoreHKCU,
71         BOOL fDefault)
72 {
73         FIXME("%s %s\n", debugstr_w(pszSubKey),debugstr_w(pszValue));
74         return fDefault;
75 }
76
77 /*************************************************************************
78  *      SHRegQueryUSValueA      [SHLWAPI]
79  */
80 LONG WINAPI SHRegQueryUSValueA(
81         HKEY hUSKey,             /* [in] FIXME: HUSKEY */
82         LPCSTR pszValue,
83         LPDWORD pdwType,
84         void *pvData,
85         LPDWORD pcbData,
86         BOOL fIgnoreHKCU,
87         void *pvDefaultData,
88         DWORD dwDefaultDataSize)
89 {
90         FIXME("%s stub\n",pszValue);
91         return 1;
92 }
93
94 /*************************************************************************
95  * SHRegGetPathA   [SHLWAPI.@]
96  */
97 DWORD WINAPI SHRegGetPathA(
98         HKEY hKey,
99         LPCSTR pcszSubKey,
100         LPCSTR pcszValue,
101         LPSTR pszPath,
102         DWORD dwFlags)
103 {
104         FIXME("%s %s\n", pcszSubKey, pcszValue);
105         return 0;
106 }
107
108 /*************************************************************************
109  * SHRegGetPathW   [SHLWAPI.@]
110  */
111 DWORD WINAPI SHRegGetPathW(
112         HKEY hKey,
113         LPCWSTR pcszSubKey,
114         LPCWSTR pcszValue,
115         LPWSTR pszPath,
116         DWORD dwFlags)
117 {
118         FIXME("%s %s\n", debugstr_w(pcszSubKey), debugstr_w(pcszValue));
119         return 0;
120 }
121
122 /*************************************************************************
123  * SHGetValueA   [SHLWAPI.@]
124  *
125  * Gets a value from the registry
126  */
127 DWORD WINAPI SHGetValueA(
128         HKEY     hkey,
129         LPCSTR   pSubKey,
130         LPCSTR   pValue,
131         LPDWORD  pwType,
132         LPVOID   pvData,
133         LPDWORD  pbData)
134 {
135         HKEY hSubKey;
136         DWORD res;
137         
138         TRACE("(%s %s)\n", pSubKey, pValue);
139         
140         if((res = RegOpenKeyA(hkey, pSubKey, &hSubKey))) return res;
141         res = RegQueryValueExA(hSubKey, pValue, 0, pwType, pvData, pbData);
142         RegCloseKey( hSubKey );
143         
144         return res;
145 }
146
147 /*************************************************************************
148  * SHGetValueW   [SHLWAPI.@]
149  *
150  * Gets a value from the registry
151  */
152 DWORD WINAPI SHGetValueW(
153         HKEY     hkey,
154         LPCWSTR  pSubKey,
155         LPCWSTR  pValue,
156         LPDWORD  pwType,
157         LPVOID   pvData,
158         LPDWORD  pbData)
159 {
160         HKEY hSubKey;
161         DWORD res;
162         
163         TRACE("(%s %s)\n", debugstr_w(pSubKey), debugstr_w(pValue));
164         
165         if((res = RegOpenKeyW(hkey, pSubKey, &hSubKey))) return res;
166         res = RegQueryValueExW(hSubKey, pValue, 0, pwType, pvData, pbData);
167         RegCloseKey( hSubKey );
168         
169         return res;
170 }
171
172 /*************************************************************************
173  *      SHSetValueA   [SHLWAPI.@]
174  */
175 HRESULT WINAPI SHSetValueA(
176         HKEY hkey,
177         LPCSTR pszSubKey,
178         LPCSTR pszValue,
179         DWORD dwType,
180         LPCVOID pvData,
181         DWORD cbData)
182 {
183     HKEY        subkey;
184     HRESULT     hres;
185
186     hres = RegCreateKeyA(hkey,pszSubKey,&subkey);
187     if (!hres)
188         return hres;
189     hres = RegSetValueExA(subkey,pszValue,0,dwType,pvData,cbData);
190     RegCloseKey(subkey);
191     return hres;
192 }
193
194 /*************************************************************************
195  *      SHSetValueW   [SHLWAPI.@]
196  */
197 HRESULT WINAPI SHSetValueW(
198         HKEY hkey,
199         LPCWSTR pszSubKey,
200         LPCWSTR pszValue,
201         DWORD dwType,
202         LPCVOID pvData,
203         DWORD cbData)
204 {
205     HKEY        subkey;
206     HRESULT     hres;
207
208     hres = RegCreateKeyW(hkey,pszSubKey,&subkey);
209     if (!hres)
210         return hres;
211     hres = RegSetValueExW(subkey,pszValue,0,dwType,pvData,cbData);
212     RegCloseKey(subkey);
213     return hres;
214 }
215
216 /*************************************************************************
217  * SHQueryValueExA              [SHLWAPI.@]
218  *
219  */
220 HRESULT WINAPI SHQueryValueExA(
221         HKEY hkey,
222         LPSTR lpValueName,
223         LPDWORD lpReserved,
224         LPDWORD lpType,
225         LPBYTE lpData,
226         LPDWORD lpcbData)
227 {
228         TRACE("0x%04x %s %p %p %p %p\n", hkey, lpValueName, lpReserved, lpType, lpData, lpcbData);
229         return RegQueryValueExA (hkey, lpValueName, lpReserved, lpType, lpData, lpcbData);
230 }
231
232
233 /*************************************************************************
234  * SHQueryValueExW   [SHLWAPI.@]
235  *
236  * FIXME 
237  *  if the datatype REG_EXPAND_SZ then expand the string and change
238  *  *pdwType to REG_SZ. 
239  */
240 HRESULT WINAPI SHQueryValueExW (
241         HKEY hkey,
242         LPWSTR pszValue,
243         LPDWORD pdwReserved,
244         LPDWORD pdwType,
245         LPVOID pvData,
246         LPDWORD pcbData)
247 {
248         WARN("0x%04x %s %p %p %p %p semi-stub\n",
249              hkey, debugstr_w(pszValue), pdwReserved, pdwType, pvData, pcbData);
250         return RegQueryValueExW ( hkey, pszValue, pdwReserved, pdwType, pvData, pcbData);
251 }
252
253 /*************************************************************************
254  * SHDeleteKeyA   [SHLWAPI.@]
255  *
256  * It appears this function is made available to account for the differences
257  * between the Win9x and WinNT/2k RegDeleteKeyA functions.
258  *
259  * According to docs, Win9x RegDeleteKeyA will delete all subkeys, whereas
260  * WinNt/2k will only delete the key if empty.
261  */
262 HRESULT WINAPI SHDeleteKeyA(
263         HKEY hKey,
264         LPCSTR lpszSubKey)
265 {
266     DWORD r, dwKeyCount, dwSize, i, dwMaxSubkeyLen;
267     HKEY hSubKey;
268     LPSTR lpszName;
269
270     TRACE("hkey=0x%08x, %s\n", hKey, debugstr_a(lpszSubKey));
271
272     hSubKey = 0;
273     r = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
274     if(r != ERROR_SUCCESS)
275         return r;
276
277     /* find how many subkeys there are */
278     dwKeyCount = 0;
279     dwMaxSubkeyLen = 0;
280     r = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, &dwKeyCount, 
281                     &dwMaxSubkeyLen, NULL, NULL, NULL, NULL, NULL, NULL);
282     if(r != ERROR_SUCCESS)
283     {
284         RegCloseKey(hSubKey);
285         return r;
286     }
287
288     /* alloc memory for the longest string terminating 0 */
289     dwMaxSubkeyLen++;
290     lpszName = HeapAlloc(GetProcessHeap(), 0, dwMaxSubkeyLen*sizeof(CHAR));
291     if(!lpszName)
292     {
293         RegCloseKey(hSubKey);
294         return ERROR_NOT_ENOUGH_MEMORY;
295     }
296
297     /* recursively delete all the subkeys */
298     for(i=0; i<dwKeyCount; i++)
299     {
300         dwSize = dwMaxSubkeyLen;
301         r = RegEnumKeyExA(hSubKey, i, lpszName, &dwSize, NULL, NULL, NULL, NULL);
302         if(r != ERROR_SUCCESS)
303             break;
304         r = SHDeleteKeyA(hSubKey, lpszName);
305         if(r != ERROR_SUCCESS)
306             break;
307     }
308
309     HeapFree(GetProcessHeap(), 0, lpszName);
310
311     RegCloseKey(hSubKey);
312
313     if(r == ERROR_SUCCESS)
314         r = RegDeleteKeyA(hKey, lpszSubKey);
315
316     return r;
317 }
318
319 /*************************************************************************
320  * SHDeleteKeyW   [SHLWAPI.@]
321  *
322  * It appears this function is made available to account for the differences
323  * between the Win9x and WinNT/2k RegDeleteKeyA functions.
324  *
325  * According to docs, Win9x RegDeleteKeyA will delete all subkeys, whereas
326  * WinNt/2k will only delete the key if empty.
327  */
328 HRESULT WINAPI SHDeleteKeyW(
329         HKEY hkey,
330         LPCWSTR pszSubKey)
331 {
332         FIXME("hkey=0x%08x, %s\n", hkey, debugstr_w(pszSubKey));
333         return 0;
334 }
335
336 /*************************************************************************
337  * SHDeleteValueA   [SHLWAPI.@]
338  *
339  * Function opens the key, get/set/delete the value, then close the key.
340  */
341 HRESULT WINAPI SHDeleteValueA(HKEY hkey, LPCSTR pszSubKey, LPCSTR pszValue) {
342     HKEY        subkey;
343     HRESULT     hres;
344
345     hres = RegOpenKeyA(hkey,pszSubKey,&subkey);
346     if (hres)
347         return hres;
348     hres = RegDeleteValueA(subkey,pszValue);
349     RegCloseKey(subkey);
350     return hres;
351 }
352
353 /*************************************************************************
354  * SHDeleteValueW   [SHLWAPI.@]
355  *
356  * Function opens the key, get/set/delete the value, then close the key.
357  */
358 HRESULT WINAPI SHDeleteValueW(HKEY hkey, LPCWSTR pszSubKey, LPCWSTR pszValue) {
359     HKEY        subkey;
360     HRESULT     hres;
361
362     hres = RegOpenKeyW(hkey,pszSubKey,&subkey);
363     if (hres)
364         return hres;
365     hres = RegDeleteValueW(subkey,pszValue);
366     RegCloseKey(subkey);
367     return hres;
368 }
369
370 /*************************************************************************
371  * SHDeleteEmptyKeyA   [SHLWAPI.@]
372  *
373  * It appears this function is made available to account for the differences
374  * between the Win9x and WinNT/2k RegDeleteKeyA functions.
375  *
376  * According to docs, Win9x RegDeleteKeyA will delete all subkeys, whereas
377  * WinNt/2k will only delete the key if empty.
378  */
379 DWORD WINAPI SHDeleteEmptyKeyA(HKEY hKey, LPCSTR lpszSubKey)
380 {
381     DWORD r, dwKeyCount;
382     HKEY hSubKey;
383
384     TRACE("hkey=0x%08x, %s\n", hKey, debugstr_a(lpszSubKey));
385
386     hSubKey = 0;
387     r = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
388     if(r != ERROR_SUCCESS)
389         return r;
390
391     dwKeyCount = 0;
392     r = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, &dwKeyCount, 
393                     NULL, NULL, NULL, NULL, NULL, NULL, NULL);
394     if(r != ERROR_SUCCESS)
395         return r;
396
397     RegCloseKey(hSubKey);
398
399     if(dwKeyCount)
400         return ERROR_KEY_HAS_CHILDREN;
401
402     r = RegDeleteKeyA(hKey, lpszSubKey);
403
404     return r;
405 }
406
407 /*************************************************************************
408  * SHDeleteEmptyKeyW   [SHLWAPI.@]
409  *
410  * It appears this function is made available to account for the differences
411  * between the Win9x and WinNT/2k RegDeleteKeyA functions.
412  *
413  * According to docs, Win9x RegDeleteKeyA will delete all subkeys, whereas
414  * WinNt/2k will only delete the key if empty.
415  */
416 DWORD WINAPI SHDeleteEmptyKeyW(HKEY hKey, LPCWSTR lpszSubKey)
417 {
418     FIXME("hkey=0x%08x, %s\n", hKey, debugstr_w(lpszSubKey));
419     return 0;
420 }
421