2 * SHLWAPI registry functions
11 #include "debugtools.h"
13 #include "wine/unicode.h"
15 DEFAULT_DEBUG_CHANNEL(shell);
17 static const char *lpszContentTypeA = "Content Type";
18 static const WCHAR lpszContentTypeW[] = { 'C','o','n','t','e','n','t',' ','T','y','p','e','\0'};
20 /*************************************************************************
21 * SHRegGetUSValueA [SHLWAPI.@]
23 * Gets a user-specific registry value
25 LONG WINAPI SHRegGetUSValueA(
33 DWORD wDefaultDataSize)
35 FIXME("(%p),stub!\n", pSubKey);
36 return ERROR_SUCCESS; /* return success */
39 /*************************************************************************
40 * SHRegGetUSValueW [SHLWAPI.@]
42 * Gets a user-specific registry value
44 LONG WINAPI SHRegGetUSValueW(
52 DWORD wDefaultDataSize)
54 FIXME("(%p),stub!\n", pSubKey);
55 return ERROR_SUCCESS; /* return success */
58 /*************************************************************************
59 * SHRegGetBoolUSValueA [SHLWAPI.@]
61 BOOL WINAPI SHRegGetBoolUSValueA(
67 FIXME("%s %s\n", pszSubKey,pszValue);
71 /*************************************************************************
72 * SHRegGetBoolUSValueW [SHLWAPI.@]
74 BOOL WINAPI SHRegGetBoolUSValueW(
80 FIXME("%s %s\n", debugstr_w(pszSubKey),debugstr_w(pszValue));
84 /*************************************************************************
85 * SHRegQueryUSValueA [SHLWAPI]
87 LONG WINAPI SHRegQueryUSValueA(
88 HKEY hUSKey, /* [in] FIXME: HUSKEY */
95 DWORD dwDefaultDataSize)
97 FIXME("%s stub\n",pszValue);
101 /*************************************************************************
102 * SHRegGetPathA [SHLWAPI.@]
104 DWORD WINAPI SHRegGetPathA(
111 FIXME("%s %s\n", pcszSubKey, pcszValue);
115 /*************************************************************************
116 * SHRegGetPathW [SHLWAPI.@]
118 DWORD WINAPI SHRegGetPathW(
125 FIXME("%s %s\n", debugstr_w(pcszSubKey), debugstr_w(pcszValue));
129 /*************************************************************************
130 * SHGetValueA [SHLWAPI.@]
132 * Gets a value from the registry
134 DWORD WINAPI SHGetValueA(
145 TRACE("(%s %s)\n", pSubKey, pValue);
147 if((res = RegOpenKeyA(hkey, pSubKey, &hSubKey))) return res;
148 res = RegQueryValueExA(hSubKey, pValue, 0, pwType, pvData, pbData);
149 RegCloseKey( hSubKey );
154 /*************************************************************************
155 * SHGetValueW [SHLWAPI.@]
157 * Gets a value from the registry
159 DWORD WINAPI SHGetValueW(
170 TRACE("(%s %s)\n", debugstr_w(pSubKey), debugstr_w(pValue));
172 if((res = RegOpenKeyW(hkey, pSubKey, &hSubKey))) return res;
173 res = RegQueryValueExW(hSubKey, pValue, 0, pwType, pvData, pbData);
174 RegCloseKey( hSubKey );
179 /*************************************************************************
180 * SHSetValueA [SHLWAPI.@]
182 HRESULT WINAPI SHSetValueA(
193 hres = RegCreateKeyA(hkey,pszSubKey,&subkey);
196 hres = RegSetValueExA(subkey,pszValue,0,dwType,pvData,cbData);
201 /*************************************************************************
202 * SHSetValueW [SHLWAPI.@]
204 HRESULT WINAPI SHSetValueW(
215 hres = RegCreateKeyW(hkey,pszSubKey,&subkey);
218 hres = RegSetValueExW(subkey,pszValue,0,dwType,pvData,cbData);
223 /*************************************************************************
224 * SHQueryValueExA [SHLWAPI.@]
227 HRESULT WINAPI SHQueryValueExA(
235 TRACE("0x%04x %s %p %p %p %p\n", hkey, lpValueName, lpReserved, lpType, lpData, lpcbData);
236 return RegQueryValueExA (hkey, lpValueName, lpReserved, lpType, lpData, lpcbData);
240 /*************************************************************************
241 * SHQueryValueExW [SHLWAPI.@]
244 * if the datatype REG_EXPAND_SZ then expand the string and change
245 * *pdwType to REG_SZ.
247 HRESULT WINAPI SHQueryValueExW (
255 WARN("0x%04x %s %p %p %p %p semi-stub\n",
256 hkey, debugstr_w(pszValue), pdwReserved, pdwType, pvData, pcbData);
257 return RegQueryValueExW ( hkey, pszValue, pdwReserved, pdwType, pvData, pcbData);
260 /*************************************************************************
261 * SHDeleteKeyA [SHLWAPI.@]
263 * It appears this function is made available to account for the differences
264 * between the Win9x and WinNT/2k RegDeleteKeyA functions.
266 * According to docs, Win9x RegDeleteKeyA will delete all subkeys, whereas
267 * WinNt/2k will only delete the key if empty.
269 HRESULT WINAPI SHDeleteKeyA(
273 DWORD r, dwKeyCount, dwSize, i, dwMaxSubkeyLen;
277 TRACE("hkey=0x%08x, %s\n", hKey, debugstr_a(lpszSubKey));
280 r = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
281 if(r != ERROR_SUCCESS)
284 /* find how many subkeys there are */
287 r = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, &dwKeyCount,
288 &dwMaxSubkeyLen, NULL, NULL, NULL, NULL, NULL, NULL);
289 if(r != ERROR_SUCCESS)
291 RegCloseKey(hSubKey);
295 /* alloc memory for the longest string terminating 0 */
297 lpszName = HeapAlloc(GetProcessHeap(), 0, dwMaxSubkeyLen*sizeof(CHAR));
300 RegCloseKey(hSubKey);
301 return ERROR_NOT_ENOUGH_MEMORY;
304 /* recursively delete all the subkeys */
305 for(i=0; i<dwKeyCount; i++)
307 dwSize = dwMaxSubkeyLen;
308 r = RegEnumKeyExA(hSubKey, i, lpszName, &dwSize, NULL, NULL, NULL, NULL);
309 if(r != ERROR_SUCCESS)
311 r = SHDeleteKeyA(hSubKey, lpszName);
312 if(r != ERROR_SUCCESS)
316 HeapFree(GetProcessHeap(), 0, lpszName);
318 RegCloseKey(hSubKey);
320 if(r == ERROR_SUCCESS)
321 r = RegDeleteKeyA(hKey, lpszSubKey);
326 /*************************************************************************
327 * SHDeleteKeyW [SHLWAPI.@]
329 * It appears this function is made available to account for the differences
330 * between the Win9x and WinNT/2k RegDeleteKeyA functions.
332 * According to docs, Win9x RegDeleteKeyA will delete all subkeys, whereas
333 * WinNt/2k will only delete the key if empty.
335 HRESULT WINAPI SHDeleteKeyW(
339 FIXME("hkey=0x%08x, %s\n", hkey, debugstr_w(pszSubKey));
343 /*************************************************************************
344 * SHDeleteValueA [SHLWAPI.@]
346 * Function opens the key, get/set/delete the value, then close the key.
348 HRESULT WINAPI SHDeleteValueA(HKEY hkey, LPCSTR pszSubKey, LPCSTR pszValue) {
352 hres = RegOpenKeyA(hkey,pszSubKey,&subkey);
355 hres = RegDeleteValueA(subkey,pszValue);
360 /*************************************************************************
361 * SHDeleteValueW [SHLWAPI.@]
363 * Function opens the key, get/set/delete the value, then close the key.
365 HRESULT WINAPI SHDeleteValueW(HKEY hkey, LPCWSTR pszSubKey, LPCWSTR pszValue) {
369 hres = RegOpenKeyW(hkey,pszSubKey,&subkey);
372 hres = RegDeleteValueW(subkey,pszValue);
377 /*************************************************************************
378 * SHDeleteEmptyKeyA [SHLWAPI.@]
380 * It appears this function is made available to account for the differences
381 * between the Win9x and WinNT/2k RegDeleteKeyA functions.
383 * According to docs, Win9x RegDeleteKeyA will delete all subkeys, whereas
384 * WinNt/2k will only delete the key if empty.
386 DWORD WINAPI SHDeleteEmptyKeyA(HKEY hKey, LPCSTR lpszSubKey)
391 TRACE("hkey=0x%08x, %s\n", hKey, debugstr_a(lpszSubKey));
394 r = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
395 if(r != ERROR_SUCCESS)
399 r = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, &dwKeyCount,
400 NULL, NULL, NULL, NULL, NULL, NULL, NULL);
401 if(r != ERROR_SUCCESS)
404 RegCloseKey(hSubKey);
407 return ERROR_KEY_HAS_CHILDREN;
409 r = RegDeleteKeyA(hKey, lpszSubKey);
414 /*************************************************************************
415 * SHDeleteEmptyKeyW [SHLWAPI.@]
417 * It appears this function is made available to account for the differences
418 * between the Win9x and WinNT/2k RegDeleteKeyA functions.
420 * According to docs, Win9x RegDeleteKeyA will delete all subkeys, whereas
421 * WinNt/2k will only delete the key if empty.
423 DWORD WINAPI SHDeleteEmptyKeyW(HKEY hKey, LPCWSTR lpszSubKey)
425 FIXME("hkey=0x%08x, %s\n", hKey, debugstr_w(lpszSubKey));
429 /*************************************************************************
430 * SHLWAPI_205 [SHLWAPI.205]
432 * Wrapper for SHGetValueA in case machine is in safe mode.
434 DWORD WINAPI SHLWAPI_205(HKEY hkey, LPCSTR pSubKey, LPCSTR pValue,
435 LPDWORD pwType, LPVOID pvData, LPDWORD pbData)
437 if (GetSystemMetrics(SM_CLEANBOOT))
438 return ERROR_INVALID_FUNCTION;
439 return SHGetValueA(hkey, pSubKey, pValue, pwType, pvData, pbData);
442 /*************************************************************************
443 * SHLWAPI_206 [SHLWAPI.206]
445 * Unicode version of SHLWAPI_205.
447 DWORD WINAPI SHLWAPI_206(HKEY hkey, LPCWSTR pSubKey, LPCWSTR pValue,
448 LPDWORD pwType, LPVOID pvData, LPDWORD pbData)
450 if (GetSystemMetrics(SM_CLEANBOOT))
451 return ERROR_INVALID_FUNCTION;
452 return SHGetValueW(hkey, pSubKey, pValue, pwType, pvData, pbData);
455 /*************************************************************************
456 * SHLWAPI_320 [SHLWAPI.320]
459 BOOL WINAPI SHLWAPI_320(LPCSTR lpszSubKey, LPCSTR lpszValue)
461 DWORD dwLen = strlen(lpszValue);
462 HRESULT ret = SHSetValueA(HKEY_CLASSES_ROOT, lpszSubKey, lpszContentTypeA,
463 REG_SZ, lpszValue, dwLen);
464 return ret ? FALSE : TRUE;
467 /*************************************************************************
468 * SHLWAPI_321 [SHLWAPI.321]
470 * Unicode version of SHLWAPI_320.
472 BOOL WINAPI SHLWAPI_321(LPCWSTR lpszSubKey, LPCWSTR lpszValue)
474 DWORD dwLen = strlenW(lpszValue);
475 HRESULT ret = SHSetValueW(HKEY_CLASSES_ROOT, lpszSubKey, lpszContentTypeW,
476 REG_SZ, lpszValue, dwLen);
477 return ret ? FALSE : TRUE;
480 /*************************************************************************
481 * SHLWAPI_322 [SHLWAPI.322]
484 BOOL WINAPI SHLWAPI_322(LPCSTR lpszSubKey)
486 HRESULT ret = SHDeleteValueA(HKEY_CLASSES_ROOT, lpszSubKey, lpszContentTypeA);
487 return ret ? FALSE : TRUE;
490 /*************************************************************************
491 * SHLWAPI_323 [SHLWAPI.323]
493 * Unicode version of SHLWAPI_322.
495 BOOL WINAPI SHLWAPI_323(LPCWSTR lpszSubKey)
497 HRESULT ret = SHDeleteValueW(HKEY_CLASSES_ROOT, lpszSubKey, lpszContentTypeW);
498 return ret ? FALSE : TRUE;