Optimized {,p}MoveTo{,Ex}{,16}.
[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*/ 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 DWORD WINAPI SHSetValueA(
176         HKEY hkey,
177         LPCSTR pszSubKey,
178         LPCSTR pszValue,
179         DWORD dwType,
180         LPCVOID pvData,
181         DWORD cbData)
182 {
183         FIXME("(%s %s)stub\n",pszSubKey, pszValue);
184         return 1;
185 }
186
187 /*************************************************************************
188  * SHQueryValueExA              [SHLWAPI.@]
189  *
190  */
191 HRESULT WINAPI SHQueryValueExA(
192         HKEY hkey,
193         LPSTR lpValueName,
194         LPDWORD lpReserved,
195         LPDWORD lpType,
196         LPBYTE lpData,
197         LPDWORD lpcbData)
198 {
199         TRACE("0x%04x %s %p %p %p %p\n", hkey, lpValueName, lpReserved, lpType, lpData, lpcbData);
200         return RegQueryValueExA (hkey, lpValueName, lpReserved, lpType, lpData, lpcbData);
201 }
202
203
204 /*************************************************************************
205  * SHQueryValueExW   [SHLWAPI.@]
206  *
207  * FIXME 
208  *  if the datatype REG_EXPAND_SZ then expand the string and change
209  *  *pdwType to REG_SZ. 
210  */
211 HRESULT WINAPI SHQueryValueExW (
212         HKEY hkey,
213         LPWSTR pszValue,
214         LPDWORD pdwReserved,
215         LPDWORD pdwType,
216         LPVOID pvData,
217         LPDWORD pcbData)
218 {
219         WARN("0x%04x %s %p %p %p %p semi-stub\n",
220              hkey, debugstr_w(pszValue), pdwReserved, pdwType, pvData, pcbData);
221         return RegQueryValueExW ( hkey, pszValue, pdwReserved, pdwType, pvData, pcbData);
222 }
223
224 /*************************************************************************
225  * SHDeleteKeyA   [SHLWAPI.@]
226  *
227  * It appears this function is made available to account for the differences
228  * between the Win9x and WinNT/2k RegDeleteKeyA functions.
229  *
230  * According to docs, Win9x RegDeleteKeyA will delete all subkeys, whereas
231  * WinNt/2k will only delete the key if empty.
232  */
233 HRESULT WINAPI SHDeleteKeyA(
234         HKEY hKey,
235         LPCSTR lpszSubKey)
236 {
237     DWORD r, dwKeyCount, dwSize, i, dwMaxSubkeyLen;
238     HKEY hSubKey;
239     LPSTR lpszName;
240
241     TRACE("hkey=0x%08x, %s\n", hKey, debugstr_a(lpszSubKey));
242
243     hSubKey = 0;
244     r = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
245     if(r != ERROR_SUCCESS)
246         return r;
247
248     /* find how many subkeys there are */
249     dwKeyCount = 0;
250     dwMaxSubkeyLen = 0;
251     r = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, &dwKeyCount, 
252                     &dwMaxSubkeyLen, NULL, NULL, NULL, NULL, NULL, NULL);
253     if(r != ERROR_SUCCESS)
254     {
255         RegCloseKey(hSubKey);
256         return r;
257     }
258
259     /* alloc memory for the longest string terminating 0 */
260     dwMaxSubkeyLen++;
261     lpszName = HeapAlloc(GetProcessHeap(), 0, dwMaxSubkeyLen*sizeof(CHAR));
262     if(!lpszName)
263     {
264         RegCloseKey(hSubKey);
265         return ERROR_NOT_ENOUGH_MEMORY;
266     }
267
268     /* recursively delete all the subkeys */
269     for(i=0; i<dwKeyCount; i++)
270     {
271         dwSize = dwMaxSubkeyLen;
272         r = RegEnumKeyExA(hSubKey, i, lpszName, &dwSize, NULL, NULL, NULL, NULL);
273         if(r != ERROR_SUCCESS)
274             break;
275         r = SHDeleteKeyA(hSubKey, lpszName);
276         if(r != ERROR_SUCCESS)
277             break;
278     }
279
280     HeapFree(GetProcessHeap(), 0, lpszName);
281
282     RegCloseKey(hSubKey);
283
284     if(r == ERROR_SUCCESS)
285         r = RegDeleteKeyA(hKey, lpszSubKey);
286
287     return r;
288 }
289
290 /*************************************************************************
291  * SHDeleteKeyW   [SHLWAPI.@]
292  *
293  * It appears this function is made available to account for the differences
294  * between the Win9x and WinNT/2k RegDeleteKeyA functions.
295  *
296  * According to docs, Win9x RegDeleteKeyA will delete all subkeys, whereas
297  * WinNt/2k will only delete the key if empty.
298  */
299 HRESULT WINAPI SHDeleteKeyW(
300         HKEY hkey,
301         LPCWSTR pszSubKey)
302 {
303         FIXME("hkey=0x%08x, %s\n", hkey, debugstr_w(pszSubKey));
304         return 0;
305 }
306
307 /*************************************************************************
308  * SHDeleteEmptyKeyA   [SHLWAPI.@]
309  *
310  * It appears this function is made available to account for the differences
311  * between the Win9x and WinNT/2k RegDeleteKeyA functions.
312  *
313  * According to docs, Win9x RegDeleteKeyA will delete all subkeys, whereas
314  * WinNt/2k will only delete the key if empty.
315  */
316 DWORD WINAPI SHDeleteEmptyKeyA(HKEY hKey, LPCSTR lpszSubKey)
317 {
318     DWORD r, dwKeyCount;
319     HKEY hSubKey;
320
321     TRACE("hkey=0x%08x, %s\n", hKey, debugstr_a(lpszSubKey));
322
323     hSubKey = 0;
324     r = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
325     if(r != ERROR_SUCCESS)
326         return r;
327
328     dwKeyCount = 0;
329     r = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, &dwKeyCount, 
330                     NULL, NULL, NULL, NULL, NULL, NULL, NULL);
331     if(r != ERROR_SUCCESS)
332         return r;
333
334     RegCloseKey(hSubKey);
335
336     if(dwKeyCount)
337         return ERROR_KEY_HAS_CHILDREN;
338
339     r = RegDeleteKeyA(hKey, lpszSubKey);
340
341     return r;
342 }
343
344 /*************************************************************************
345  * SHDeleteEmptyKeyW   [SHLWAPI.@]
346  *
347  * It appears this function is made available to account for the differences
348  * between the Win9x and WinNT/2k RegDeleteKeyA functions.
349  *
350  * According to docs, Win9x RegDeleteKeyA will delete all subkeys, whereas
351  * WinNt/2k will only delete the key if empty.
352  */
353 DWORD WINAPI SHDeleteEmptyKeyW(HKEY hKey, LPCWSTR lpszSubKey)
354 {
355     FIXME("hkey=0x%08x, %s\n", hKey, debugstr_w(lpszSubKey));
356     return 0;
357 }
358