2 * SHLWAPI registry functions
12 #include "debugtools.h"
14 #include "wine/unicode.h"
16 DEFAULT_DEBUG_CHANNEL(shell);
18 static const char *lpszContentTypeA = "Content Type";
19 static const WCHAR lpszContentTypeW[] = { 'C','o','n','t','e','n','t',' ','T','y','p','e','\0'};
21 /*************************************************************************
22 * SHRegGetUSValueA [SHLWAPI.@]
24 * Gets a user-specific registry value
26 LONG WINAPI SHRegGetUSValueA(
34 DWORD wDefaultDataSize)
36 FIXME("(%p),stub!\n", pSubKey);
37 return ERROR_SUCCESS; /* return success */
40 /*************************************************************************
41 * SHRegGetUSValueW [SHLWAPI.@]
43 * Gets a user-specific registry value
45 LONG WINAPI SHRegGetUSValueW(
53 DWORD wDefaultDataSize)
55 FIXME("(%p),stub!\n", pSubKey);
56 return ERROR_SUCCESS; /* return success */
59 /*************************************************************************
60 * SHRegOpenUSKeyA [SHLWAPI.@]
62 * Opens a user-specific registry key
64 LONG WINAPI SHRegOpenUSKeyA(
72 return ERROR_SUCCESS; /* return success */
75 /*************************************************************************
76 * SHRegOpenUSKeyW [SHLWAPI.@]
78 * Openss a user-specific registry key
80 LONG WINAPI SHRegOpenUSKeyW(
88 return ERROR_SUCCESS; /* return success */
91 /*************************************************************************
92 * SHRegGetBoolUSValueA [SHLWAPI.@]
94 BOOL WINAPI SHRegGetBoolUSValueA(
100 FIXME("%s %s\n", pszSubKey,pszValue);
104 /*************************************************************************
105 * SHRegGetBoolUSValueW [SHLWAPI.@]
107 BOOL WINAPI SHRegGetBoolUSValueW(
113 FIXME("%s %s\n", debugstr_w(pszSubKey),debugstr_w(pszValue));
117 /*************************************************************************
118 * SHRegQueryUSValueA [SHLWAPI.@]
120 LONG WINAPI SHRegQueryUSValueA(
121 HKEY hUSKey, /* [in] FIXME: HUSKEY */
128 DWORD dwDefaultDataSize)
130 FIXME("%s stub\n",pszValue);
134 /*************************************************************************
135 * SHRegQueryUSValueW [SHLWAPI.@]
137 LONG WINAPI SHRegQueryUSValueW(
138 HKEY hUSKey, /* [in] FIXME: HUSKEY */
145 DWORD dwDefaultDataSize)
147 FIXME("%s stub\n",pszValue);
151 /*************************************************************************
152 * SHRegEnumUSKeyA [SHLWAPI.@]
154 LONG WINAPI SHRegEnumUSKeyA(
155 HKEY hUSKey, /* [in] FIXME: HUSKEY */
158 LPDWORD pcchValueNameLen,
159 DWORD enumRegFlags) /* [in] FIXME: SHREGENUM_FLAGS */
161 FIXME("%s stub\n",debugstr_a(pszName));
162 return ERROR_NO_MORE_ITEMS;
165 /*************************************************************************
166 * SHRegEnumUSKeyW [SHLWAPI.@]
168 LONG WINAPI SHRegEnumUSKeyW(
169 HKEY hUSKey, /* [in] FIXME: HUSKEY */
172 LPDWORD pcchValueNameLen,
173 DWORD enumRegFlags) /* [in] FIXME: SHREGENUM_FLAGS */
175 FIXME("%s stub\n",debugstr_w(pszName));
176 return ERROR_NO_MORE_ITEMS;
179 /*************************************************************************
180 * SHRegGetPathA [SHLWAPI.@]
182 DWORD WINAPI SHRegGetPathA(
189 FIXME("%s %s\n", pcszSubKey, pcszValue);
193 /*************************************************************************
194 * SHRegGetPathW [SHLWAPI.@]
196 DWORD WINAPI SHRegGetPathW(
203 FIXME("%s %s\n", debugstr_w(pcszSubKey), debugstr_w(pcszValue));
207 /*************************************************************************
208 * SHGetValueA [SHLWAPI.@]
210 * Gets a value from the registry
212 DWORD WINAPI SHGetValueA(
223 TRACE("(%s %s)\n", pSubKey, pValue);
225 if((res = RegOpenKeyA(hkey, pSubKey, &hSubKey))) return res;
226 res = RegQueryValueExA(hSubKey, pValue, 0, pwType, pvData, pbData);
227 RegCloseKey( hSubKey );
232 /*************************************************************************
233 * SHGetValueW [SHLWAPI.@]
235 * Gets a value from the registry
237 DWORD WINAPI SHGetValueW(
248 TRACE("(%s %s)\n", debugstr_w(pSubKey), debugstr_w(pValue));
250 if((res = RegOpenKeyW(hkey, pSubKey, &hSubKey))) return res;
251 res = RegQueryValueExW(hSubKey, pValue, 0, pwType, pvData, pbData);
252 RegCloseKey( hSubKey );
257 /*************************************************************************
258 * SHSetValueA [SHLWAPI.@]
260 HRESULT WINAPI SHSetValueA(
271 hres = RegCreateKeyA(hkey,pszSubKey,&subkey);
274 hres = RegSetValueExA(subkey,pszValue,0,dwType,pvData,cbData);
279 /*************************************************************************
280 * SHSetValueW [SHLWAPI.@]
282 HRESULT WINAPI SHSetValueW(
293 hres = RegCreateKeyW(hkey,pszSubKey,&subkey);
296 hres = RegSetValueExW(subkey,pszValue,0,dwType,pvData,cbData);
301 /*************************************************************************
302 * SHQueryValueExA [SHLWAPI.@]
305 HRESULT WINAPI SHQueryValueExA(
313 TRACE("0x%04x %s %p %p %p %p\n", hkey, lpValueName, lpReserved, lpType, lpData, lpcbData);
314 return RegQueryValueExA (hkey, lpValueName, lpReserved, lpType, lpData, lpcbData);
318 /*************************************************************************
319 * SHQueryValueExW [SHLWAPI.@]
322 * if the datatype REG_EXPAND_SZ then expand the string and change
323 * *pdwType to REG_SZ.
325 HRESULT WINAPI SHQueryValueExW (
333 WARN("0x%04x %s %p %p %p %p semi-stub\n",
334 hkey, debugstr_w(pszValue), pdwReserved, pdwType, pvData, pcbData);
335 return RegQueryValueExW ( hkey, pszValue, pdwReserved, pdwType, pvData, pcbData);
338 /*************************************************************************
339 * SHDeleteKeyA [SHLWAPI.@]
341 * It appears this function is made available to account for the differences
342 * between the Win9x and WinNT/2k RegDeleteKeyA functions.
344 * According to docs, Win9x RegDeleteKeyA will delete all subkeys, whereas
345 * WinNt/2k will only delete the key if empty.
347 HRESULT WINAPI SHDeleteKeyA(
351 DWORD r, dwKeyCount, dwSize, i, dwMaxSubkeyLen;
355 TRACE("hkey=0x%08x, %s\n", hKey, debugstr_a(lpszSubKey));
358 r = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
359 if(r != ERROR_SUCCESS)
362 /* find how many subkeys there are */
365 r = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, &dwKeyCount,
366 &dwMaxSubkeyLen, NULL, NULL, NULL, NULL, NULL, NULL);
367 if(r != ERROR_SUCCESS)
369 RegCloseKey(hSubKey);
373 /* alloc memory for the longest string terminating 0 */
375 lpszName = HeapAlloc(GetProcessHeap(), 0, dwMaxSubkeyLen*sizeof(CHAR));
378 RegCloseKey(hSubKey);
379 return ERROR_NOT_ENOUGH_MEMORY;
382 /* recursively delete all the subkeys */
383 for(i=0; i<dwKeyCount; i++)
385 dwSize = dwMaxSubkeyLen;
386 r = RegEnumKeyExA(hSubKey, i, lpszName, &dwSize, NULL, NULL, NULL, NULL);
387 if(r != ERROR_SUCCESS)
389 r = SHDeleteKeyA(hSubKey, lpszName);
390 if(r != ERROR_SUCCESS)
394 HeapFree(GetProcessHeap(), 0, lpszName);
396 RegCloseKey(hSubKey);
398 if(r == ERROR_SUCCESS)
399 r = RegDeleteKeyA(hKey, lpszSubKey);
404 /*************************************************************************
405 * SHDeleteKeyW [SHLWAPI.@]
407 * It appears this function is made available to account for the differences
408 * between the Win9x and WinNT/2k RegDeleteKeyA functions.
410 * According to docs, Win9x RegDeleteKeyA will delete all subkeys, whereas
411 * WinNt/2k will only delete the key if empty.
413 HRESULT WINAPI SHDeleteKeyW(
417 FIXME("hkey=0x%08x, %s\n", hkey, debugstr_w(pszSubKey));
421 /*************************************************************************
422 * SHDeleteValueA [SHLWAPI.@]
424 * Function opens the key, get/set/delete the value, then close the key.
426 HRESULT WINAPI SHDeleteValueA(HKEY hkey, LPCSTR pszSubKey, LPCSTR pszValue) {
430 hres = RegOpenKeyA(hkey,pszSubKey,&subkey);
433 hres = RegDeleteValueA(subkey,pszValue);
438 /*************************************************************************
439 * SHDeleteValueW [SHLWAPI.@]
441 * Function opens the key, get/set/delete the value, then close the key.
443 HRESULT WINAPI SHDeleteValueW(HKEY hkey, LPCWSTR pszSubKey, LPCWSTR pszValue) {
447 hres = RegOpenKeyW(hkey,pszSubKey,&subkey);
450 hres = RegDeleteValueW(subkey,pszValue);
455 /*************************************************************************
456 * SHDeleteEmptyKeyA [SHLWAPI.@]
458 * It appears this function is made available to account for the differences
459 * between the Win9x and WinNT/2k RegDeleteKeyA functions.
461 * According to docs, Win9x RegDeleteKeyA will delete all subkeys, whereas
462 * WinNt/2k will only delete the key if empty.
464 DWORD WINAPI SHDeleteEmptyKeyA(HKEY hKey, LPCSTR lpszSubKey)
469 TRACE("hkey=0x%08x, %s\n", hKey, debugstr_a(lpszSubKey));
472 r = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
473 if(r != ERROR_SUCCESS)
477 r = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, &dwKeyCount,
478 NULL, NULL, NULL, NULL, NULL, NULL, NULL);
479 if(r != ERROR_SUCCESS)
482 RegCloseKey(hSubKey);
485 return ERROR_KEY_HAS_CHILDREN;
487 r = RegDeleteKeyA(hKey, lpszSubKey);
492 /*************************************************************************
493 * SHDeleteEmptyKeyW [SHLWAPI.@]
495 * It appears this function is made available to account for the differences
496 * between the Win9x and WinNT/2k RegDeleteKeyA functions.
498 * According to docs, Win9x RegDeleteKeyA will delete all subkeys, whereas
499 * WinNt/2k will only delete the key if empty.
501 DWORD WINAPI SHDeleteEmptyKeyW(HKEY hKey, LPCWSTR lpszSubKey)
503 FIXME("hkey=0x%08x, %s\n", hKey, debugstr_w(lpszSubKey));
507 /*************************************************************************
510 * Wrapper for SHGetValueA in case machine is in safe mode.
512 DWORD WINAPI SHLWAPI_205(HKEY hkey, LPCSTR pSubKey, LPCSTR pValue,
513 LPDWORD pwType, LPVOID pvData, LPDWORD pbData)
515 if (GetSystemMetrics(SM_CLEANBOOT))
516 return ERROR_INVALID_FUNCTION;
517 return SHGetValueA(hkey, pSubKey, pValue, pwType, pvData, pbData);
520 /*************************************************************************
523 * Unicode version of SHLWAPI_205.
525 DWORD WINAPI SHLWAPI_206(HKEY hkey, LPCWSTR pSubKey, LPCWSTR pValue,
526 LPDWORD pwType, LPVOID pvData, LPDWORD pbData)
528 if (GetSystemMetrics(SM_CLEANBOOT))
529 return ERROR_INVALID_FUNCTION;
530 return SHGetValueW(hkey, pSubKey, pValue, pwType, pvData, pbData);
533 /*************************************************************************
537 BOOL WINAPI SHLWAPI_320(LPCSTR lpszSubKey, LPCSTR lpszValue)
539 DWORD dwLen = strlen(lpszValue);
540 HRESULT ret = SHSetValueA(HKEY_CLASSES_ROOT, lpszSubKey, lpszContentTypeA,
541 REG_SZ, lpszValue, dwLen);
542 return ret ? FALSE : TRUE;
545 /*************************************************************************
548 * Unicode version of SHLWAPI_320.
550 BOOL WINAPI SHLWAPI_321(LPCWSTR lpszSubKey, LPCWSTR lpszValue)
552 DWORD dwLen = strlenW(lpszValue);
553 HRESULT ret = SHSetValueW(HKEY_CLASSES_ROOT, lpszSubKey, lpszContentTypeW,
554 REG_SZ, lpszValue, dwLen);
555 return ret ? FALSE : TRUE;
558 /*************************************************************************
562 BOOL WINAPI SHLWAPI_322(LPCSTR lpszSubKey)
564 HRESULT ret = SHDeleteValueA(HKEY_CLASSES_ROOT, lpszSubKey, lpszContentTypeA);
565 return ret ? FALSE : TRUE;
568 /*************************************************************************
571 * Unicode version of SHLWAPI_322.
573 BOOL WINAPI SHLWAPI_323(LPCWSTR lpszSubKey)
575 HRESULT ret = SHDeleteValueW(HKEY_CLASSES_ROOT, lpszSubKey, lpszContentTypeW);
576 return ret ? FALSE : TRUE;