Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenreg.c
Go to the documentation of this file.
00001 /* 00002 * SHLWAPI registry functions 00003 * 00004 * Copyright 1998 Juergen Schmied 00005 * Copyright 2001 Guy Albertelli 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00020 */ 00021 00022 #include <stdarg.h> 00023 #include <string.h> 00024 #include "windef.h" 00025 #include "winbase.h" 00026 #include "winuser.h" 00027 #include "winreg.h" 00028 #include "wine/debug.h" 00029 #define NO_SHLWAPI_STREAM 00030 #include "shlwapi.h" 00031 #include "wine/unicode.h" 00032 00033 WINE_DEFAULT_DEBUG_CHANNEL(shell); 00034 00035 /* Key/Value names for MIME content types */ 00036 static const char lpszContentTypeA[] = "Content Type"; 00037 static const WCHAR lpszContentTypeW[] = { 'C','o','n','t','e','n','t',' ','T','y','p','e','\0'}; 00038 00039 static const char szMimeDbContentA[] = "MIME\\Database\\Content Type\\"; 00040 static const WCHAR szMimeDbContentW[] = { 'M', 'I', 'M','E','\\', 00041 'D','a','t','a','b','a','s','e','\\','C','o','n','t','e','n','t', 00042 ' ','T','y','p','e','\\', 0 }; 00043 static const DWORD dwLenMimeDbContent = 27; /* strlen of szMimeDbContentA/W */ 00044 00045 static const char szExtensionA[] = "Extension"; 00046 static const WCHAR szExtensionW[] = { 'E', 'x', 't','e','n','s','i','o','n','\0' }; 00047 00048 /* internal structure of what the HUSKEY points to */ 00049 typedef struct { 00050 HKEY HKCUstart; /* Start key in CU hive */ 00051 HKEY HKCUkey; /* Opened key in CU hive */ 00052 HKEY HKLMstart; /* Start key in LM hive */ 00053 HKEY HKLMkey; /* Opened key in LM hive */ 00054 WCHAR lpszPath[MAX_PATH]; 00055 } SHUSKEY, *LPSHUSKEY; 00056 00057 INT WINAPI SHStringFromGUIDW(REFGUID,LPWSTR,INT); 00058 HRESULT WINAPI SHRegGetCLSIDKeyW(REFGUID,LPCWSTR,BOOL,BOOL,PHKEY); 00059 00060 00061 #define REG_HKCU TRUE 00062 #define REG_HKLM FALSE 00063 /************************************************************************* 00064 * REG_GetHKEYFromHUSKEY 00065 * 00066 * Function: Return the proper registry key from the HUSKEY structure 00067 * also allow special predefined values. 00068 */ 00069 static HKEY REG_GetHKEYFromHUSKEY(HUSKEY hUSKey, BOOL which) 00070 { 00071 HKEY test = hUSKey; 00072 LPSHUSKEY mihk = hUSKey; 00073 00074 if ((test == HKEY_CLASSES_ROOT) || 00075 (test == HKEY_CURRENT_CONFIG) || 00076 (test == HKEY_CURRENT_USER) || 00077 (test == HKEY_DYN_DATA) || 00078 (test == HKEY_LOCAL_MACHINE) || 00079 (test == HKEY_PERFORMANCE_DATA) || 00080 /* FIXME: need to define for Win2k, ME, XP 00081 * (test == HKEY_PERFORMANCE_TEXT) || 00082 * (test == HKEY_PERFORMANCE_NLSTEXT) || 00083 */ 00084 (test == HKEY_USERS)) return test; 00085 if (which == REG_HKCU) return mihk->HKCUkey; 00086 return mihk->HKLMkey; 00087 } 00088 00089 00090 /************************************************************************* 00091 * SHRegOpenUSKeyA [SHLWAPI.@] 00092 * 00093 * Open a user-specific registry key. 00094 * 00095 * PARAMS 00096 * Path [I] Key name to open 00097 * AccessType [I] Access type 00098 * hRelativeUSKey [I] Relative user key 00099 * phNewUSKey [O] Destination for created key 00100 * fIgnoreHKCU [I] TRUE=Don't check HKEY_CURRENT_USER 00101 * 00102 * RETURNS 00103 * Success: ERROR_SUCCESS 00104 * Failure: An error code from RegOpenKeyExA(). 00105 */ 00106 LONG WINAPI SHRegOpenUSKeyA(LPCSTR Path, REGSAM AccessType, HUSKEY hRelativeUSKey, 00107 PHUSKEY phNewUSKey, BOOL fIgnoreHKCU) 00108 { 00109 WCHAR szPath[MAX_PATH]; 00110 00111 if (Path) 00112 MultiByteToWideChar(CP_ACP, 0, Path, -1, szPath, MAX_PATH); 00113 00114 return SHRegOpenUSKeyW(Path ? szPath : NULL, AccessType, hRelativeUSKey, 00115 phNewUSKey, fIgnoreHKCU); 00116 } 00117 00118 /************************************************************************* 00119 * SHRegOpenUSKeyW [SHLWAPI.@] 00120 * 00121 * See SHRegOpenUSKeyA. 00122 */ 00123 LONG WINAPI SHRegOpenUSKeyW(LPCWSTR Path, REGSAM AccessType, HUSKEY hRelativeUSKey, 00124 PHUSKEY phNewUSKey, BOOL fIgnoreHKCU) 00125 { 00126 LONG ret2, ret1 = ~ERROR_SUCCESS; 00127 LPSHUSKEY hKey; 00128 00129 TRACE("(%s,0x%x,%p,%p,%d)\n", debugstr_w(Path),(LONG)AccessType, 00130 hRelativeUSKey, phNewUSKey, fIgnoreHKCU); 00131 00132 if (phNewUSKey) 00133 *phNewUSKey = NULL; 00134 00135 /* Create internal HUSKEY */ 00136 hKey = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*hKey)); 00137 lstrcpynW(hKey->lpszPath, Path, sizeof(hKey->lpszPath)/sizeof(WCHAR)); 00138 00139 if (hRelativeUSKey) 00140 { 00141 hKey->HKCUstart = SHRegDuplicateHKey(REG_GetHKEYFromHUSKEY(hRelativeUSKey, REG_HKCU)); 00142 hKey->HKLMstart = SHRegDuplicateHKey(REG_GetHKEYFromHUSKEY(hRelativeUSKey, REG_HKLM)); 00143 00144 /* FIXME: if either of these keys is NULL, create the start key from 00145 * the relative keys start+path 00146 */ 00147 } 00148 else 00149 { 00150 hKey->HKCUstart = HKEY_CURRENT_USER; 00151 hKey->HKLMstart = HKEY_LOCAL_MACHINE; 00152 } 00153 00154 if (!fIgnoreHKCU) 00155 { 00156 ret1 = RegOpenKeyExW(hKey->HKCUstart, hKey->lpszPath, 0, AccessType, &hKey->HKCUkey); 00157 if (ret1) 00158 hKey->HKCUkey = 0; 00159 } 00160 00161 ret2 = RegOpenKeyExW(hKey->HKLMstart, hKey->lpszPath, 0, AccessType, &hKey->HKLMkey); 00162 if (ret2) 00163 hKey->HKLMkey = 0; 00164 00165 if (ret1 || ret2) 00166 TRACE("one or more opens failed: HKCU=%d HKLM=%d\n", ret1, ret2); 00167 00168 if (ret1 && ret2) 00169 { 00170 /* Neither open succeeded: fail */ 00171 SHRegCloseUSKey(hKey); 00172 return ret2; 00173 } 00174 00175 TRACE("HUSKEY=%p\n", hKey); 00176 if (phNewUSKey) 00177 *phNewUSKey = hKey; 00178 return ERROR_SUCCESS; 00179 } 00180 00181 /************************************************************************* 00182 * SHRegCloseUSKey [SHLWAPI.@] 00183 * 00184 * Close a user-specific registry key 00185 * 00186 * RETURNS 00187 * Success: ERROR_SUCCESS 00188 * Failure: An error code from RegCloseKey(). 00189 */ 00190 LONG WINAPI SHRegCloseUSKey( 00191 HUSKEY hUSKey) /* [I] Key to close */ 00192 { 00193 LPSHUSKEY hKey = hUSKey; 00194 LONG ret = ERROR_SUCCESS; 00195 00196 if (hKey->HKCUkey) 00197 ret = RegCloseKey(hKey->HKCUkey); 00198 if (hKey->HKCUstart && hKey->HKCUstart != HKEY_CURRENT_USER) 00199 ret = RegCloseKey(hKey->HKCUstart); 00200 if (hKey->HKLMkey) 00201 ret = RegCloseKey(hKey->HKLMkey); 00202 if (hKey->HKLMstart && hKey->HKLMstart != HKEY_LOCAL_MACHINE) 00203 ret = RegCloseKey(hKey->HKLMstart); 00204 00205 HeapFree(GetProcessHeap(), 0, hKey); 00206 return ret; 00207 } 00208 00209 /************************************************************************* 00210 * SHRegCreateUSKeyA [SHLWAPI.@] 00211 * 00212 * Create or open a user-specific registry key. 00213 * 00214 * PARAMS 00215 * pszPath [I] Key name to create or open. 00216 * samDesired [I] Wanted security access. 00217 * hRelativeUSKey [I] Base path if pszPath is relative. NULL otherwise. 00218 * phNewUSKey [O] Receives a handle to the new or opened key. 00219 * dwFlags [I] Base key under which the key should be opened. 00220 * 00221 * RETURNS 00222 * Success: ERROR_SUCCESS 00223 * Failure: Nonzero error code from winerror.h 00224 */ 00225 LONG WINAPI SHRegCreateUSKeyA(LPCSTR pszPath, REGSAM samDesired, HUSKEY hRelativeUSKey, 00226 PHUSKEY phNewUSKey, DWORD dwFlags) 00227 { 00228 FIXME("(%s, 0x%08x, %p, %p, 0x%08x) stub\n", debugstr_a(pszPath), samDesired, 00229 hRelativeUSKey, phNewUSKey, dwFlags); 00230 return ERROR_SUCCESS; 00231 } 00232 00233 /************************************************************************* 00234 * SHRegCreateUSKeyW [SHLWAPI.@] 00235 * 00236 * See SHRegCreateUSKeyA. 00237 */ 00238 LONG WINAPI SHRegCreateUSKeyW(LPCWSTR pszPath, REGSAM samDesired, HUSKEY hRelativeUSKey, 00239 PHUSKEY phNewUSKey, DWORD dwFlags) 00240 { 00241 FIXME("(%s, 0x%08x, %p, %p, 0x%08x) stub\n", debugstr_w(pszPath), samDesired, 00242 hRelativeUSKey, phNewUSKey, dwFlags); 00243 return ERROR_SUCCESS; 00244 } 00245 00246 /************************************************************************* 00247 * SHRegDeleteEmptyUSKeyA [SHLWAPI.@] 00248 * 00249 * Delete an empty user-specific registry key. 00250 * 00251 * PARAMS 00252 * hUSKey [I] Handle to an open registry key. 00253 * pszValue [I] Empty key name. 00254 * delRegFlags [I] Flag that specifies the base from which to delete 00255 * the key. 00256 * 00257 * RETURNS 00258 * Success: ERROR_SUCCESS 00259 * Failure: Nonzero error code from winerror.h 00260 */ 00261 LONG WINAPI SHRegDeleteEmptyUSKeyA(HUSKEY hUSKey, LPCSTR pszValue, SHREGDEL_FLAGS delRegFlags) 00262 { 00263 FIXME("(%p, %s, 0x%08x) stub\n", hUSKey, debugstr_a(pszValue), delRegFlags); 00264 return ERROR_SUCCESS; 00265 } 00266 00267 /************************************************************************* 00268 * SHRegDeleteEmptyUSKeyW [SHLWAPI.@] 00269 * 00270 * See SHRegDeleteEmptyUSKeyA. 00271 */ 00272 LONG WINAPI SHRegDeleteEmptyUSKeyW(HUSKEY hUSKey, LPCWSTR pszValue, SHREGDEL_FLAGS delRegFlags) 00273 { 00274 FIXME("(%p, %s, 0x%08x) stub\n", hUSKey, debugstr_w(pszValue), delRegFlags); 00275 return ERROR_SUCCESS; 00276 } 00277 00278 /************************************************************************* 00279 * SHRegDeleteUSValueA [SHLWAPI.@] 00280 * 00281 * Delete a user-specific registry value. 00282 * 00283 * PARAMS 00284 * hUSKey [I] Handle to an open registry key. 00285 * pszValue [I] Specifies the value to delete. 00286 * delRegFlags [I] Flag that specifies the base of the key from which to 00287 * delete the value. 00288 * 00289 * RETURNS 00290 * Success: ERROR_SUCCESS 00291 * Failure: Nonzero error code from winerror.h 00292 */ 00293 LONG WINAPI SHRegDeleteUSValueA(HUSKEY hUSKey, LPCSTR pszValue, SHREGDEL_FLAGS delRegFlags) 00294 { 00295 FIXME("(%p, %s, 0x%08x) stub\n", hUSKey, debugstr_a(pszValue), delRegFlags); 00296 return ERROR_SUCCESS; 00297 } 00298 00299 /************************************************************************* 00300 * SHRegDeleteUSValueW [SHLWAPI.@] 00301 * 00302 * See SHRegDeleteUSValueA. 00303 */ 00304 LONG WINAPI SHRegDeleteUSValueW(HUSKEY hUSKey, LPCWSTR pszValue, SHREGDEL_FLAGS delRegFlags) 00305 { 00306 FIXME("(%p, %s, 0x%08x) stub\n", hUSKey, debugstr_w(pszValue), delRegFlags); 00307 return ERROR_SUCCESS; 00308 } 00309 00310 /************************************************************************* 00311 * SHRegEnumUSValueA [SHLWAPI.@] 00312 * 00313 * Enumerate values of a specified registry key. 00314 * 00315 * PARAMS 00316 * hUSKey [I] Handle to an open registry key. 00317 * dwIndex [I] Index of the value to be retrieved. 00318 * pszValueName [O] Buffer to receive the value name. 00319 * pcchValueNameLen [I] Size of pszValueName in characters. 00320 * pdwType [O] Receives data type of the value. 00321 * pvData [O] Receives value data. May be NULL. 00322 * pcbData [I/O] Size of pvData in bytes. 00323 * enumRegFlags [I] Flag that specifies the base key under which to 00324 * enumerate values. 00325 * 00326 * RETURNS 00327 * Success: ERROR_SUCCESS 00328 * Failure: Nonzero error code from winerror.h 00329 */ 00330 LONG WINAPI SHRegEnumUSValueA(HUSKEY hUSKey, DWORD dwIndex, LPSTR pszValueName, 00331 LPDWORD pcchValueNameLen, LPDWORD pdwType, LPVOID pvData, 00332 LPDWORD pcbData, SHREGENUM_FLAGS enumRegFlags) 00333 { 00334 HKEY dokey; 00335 00336 TRACE("(%p, 0x%08x, %p, %p, %p, %p, %p, 0x%08x)\n", hUSKey, dwIndex, 00337 pszValueName, pcchValueNameLen, pdwType, pvData, pcbData, enumRegFlags); 00338 00339 if (((enumRegFlags == SHREGENUM_HKCU) || 00340 (enumRegFlags == SHREGENUM_DEFAULT)) && 00341 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) { 00342 return RegEnumValueA(dokey, dwIndex, pszValueName, pcchValueNameLen, 00343 NULL, pdwType, pvData, pcbData); 00344 } 00345 00346 if (((enumRegFlags == SHREGENUM_HKLM) || 00347 (enumRegFlags == SHREGENUM_DEFAULT)) && 00348 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) { 00349 return RegEnumValueA(dokey, dwIndex, pszValueName, pcchValueNameLen, 00350 NULL, pdwType, pvData, pcbData); 00351 } 00352 FIXME("no support for SHREGENUM_BOTH\n"); 00353 return ERROR_INVALID_FUNCTION; 00354 } 00355 00356 /************************************************************************* 00357 * SHRegEnumUSValueW [SHLWAPI.@] 00358 * 00359 * See SHRegEnumUSValueA. 00360 */ 00361 LONG WINAPI SHRegEnumUSValueW(HUSKEY hUSKey, DWORD dwIndex, LPWSTR pszValueName, 00362 LPDWORD pcchValueNameLen, LPDWORD pdwType, LPVOID pvData, 00363 LPDWORD pcbData, SHREGENUM_FLAGS enumRegFlags) 00364 { 00365 HKEY dokey; 00366 00367 TRACE("(%p, 0x%08x, %p, %p, %p, %p, %p, 0x%08x)\n", hUSKey, dwIndex, 00368 pszValueName, pcchValueNameLen, pdwType, pvData, pcbData, enumRegFlags); 00369 00370 if (((enumRegFlags == SHREGENUM_HKCU) || 00371 (enumRegFlags == SHREGENUM_DEFAULT)) && 00372 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) { 00373 return RegEnumValueW(dokey, dwIndex, pszValueName, pcchValueNameLen, 00374 NULL, pdwType, pvData, pcbData); 00375 } 00376 00377 if (((enumRegFlags == SHREGENUM_HKLM) || 00378 (enumRegFlags == SHREGENUM_DEFAULT)) && 00379 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) { 00380 return RegEnumValueW(dokey, dwIndex, pszValueName, pcchValueNameLen, 00381 NULL, pdwType, pvData, pcbData); 00382 } 00383 FIXME("no support for SHREGENUM_BOTH\n"); 00384 return ERROR_INVALID_FUNCTION; 00385 } 00386 00387 /************************************************************************* 00388 * SHRegQueryUSValueA [SHLWAPI.@] 00389 * 00390 * Query a user-specific registry value. 00391 * 00392 * RETURNS 00393 * Success: ERROR_SUCCESS 00394 * Failure: An error code from RegQueryValueExA(). 00395 */ 00396 LONG WINAPI SHRegQueryUSValueA( 00397 HUSKEY hUSKey, /* [I] Key to query */ 00398 LPCSTR pszValue, /* [I] Value name under hUSKey */ 00399 LPDWORD pdwType, /* [O] Destination for value type */ 00400 LPVOID pvData, /* [O] Destination for value data */ 00401 LPDWORD pcbData, /* [O] Destination for value length */ 00402 BOOL fIgnoreHKCU, /* [I] TRUE=Don't check HKEY_CURRENT_USER */ 00403 LPVOID pvDefaultData, /* [I] Default data if pszValue does not exist */ 00404 DWORD dwDefaultDataSize) /* [I] Length of pvDefaultData */ 00405 { 00406 LONG ret = ~ERROR_SUCCESS; 00407 LONG i, maxmove; 00408 HKEY dokey; 00409 CHAR *src, *dst; 00410 00411 /* if user wants HKCU, and it exists, then try it */ 00412 if (!fIgnoreHKCU && (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) { 00413 ret = RegQueryValueExA(dokey, 00414 pszValue, 0, pdwType, pvData, pcbData); 00415 TRACE("HKCU RegQueryValue returned %08x\n", ret); 00416 } 00417 00418 /* if HKCU did not work and HKLM exists, then try it */ 00419 if ((ret != ERROR_SUCCESS) && 00420 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) { 00421 ret = RegQueryValueExA(dokey, 00422 pszValue, 0, pdwType, pvData, pcbData); 00423 TRACE("HKLM RegQueryValue returned %08x\n", ret); 00424 } 00425 00426 /* if neither worked, and default data exists, then use it */ 00427 if (ret != ERROR_SUCCESS) { 00428 if (pvDefaultData && (dwDefaultDataSize != 0)) { 00429 maxmove = (dwDefaultDataSize >= *pcbData) ? *pcbData : dwDefaultDataSize; 00430 src = pvDefaultData; 00431 dst = pvData; 00432 for(i=0; i<maxmove; i++) *dst++ = *src++; 00433 *pcbData = maxmove; 00434 TRACE("setting default data\n"); 00435 ret = ERROR_SUCCESS; 00436 } 00437 } 00438 return ret; 00439 } 00440 00441 00442 /************************************************************************* 00443 * SHRegQueryUSValueW [SHLWAPI.@] 00444 * 00445 * See SHRegQueryUSValueA. 00446 */ 00447 LONG WINAPI SHRegQueryUSValueW( 00448 HUSKEY hUSKey, 00449 LPCWSTR pszValue, 00450 LPDWORD pdwType, 00451 LPVOID pvData, 00452 LPDWORD pcbData, 00453 BOOL fIgnoreHKCU, 00454 LPVOID pvDefaultData, 00455 DWORD dwDefaultDataSize) 00456 { 00457 LONG ret = ~ERROR_SUCCESS; 00458 LONG i, maxmove; 00459 HKEY dokey; 00460 CHAR *src, *dst; 00461 00462 /* if user wants HKCU, and it exists, then try it */ 00463 if (!fIgnoreHKCU && (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) { 00464 ret = RegQueryValueExW(dokey, 00465 pszValue, 0, pdwType, pvData, pcbData); 00466 TRACE("HKCU RegQueryValue returned %08x\n", ret); 00467 } 00468 00469 /* if HKCU did not work and HKLM exists, then try it */ 00470 if ((ret != ERROR_SUCCESS) && 00471 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) { 00472 ret = RegQueryValueExW(dokey, 00473 pszValue, 0, pdwType, pvData, pcbData); 00474 TRACE("HKLM RegQueryValue returned %08x\n", ret); 00475 } 00476 00477 /* if neither worked, and default data exists, then use it */ 00478 if (ret != ERROR_SUCCESS) { 00479 if (pvDefaultData && (dwDefaultDataSize != 0)) { 00480 maxmove = (dwDefaultDataSize >= *pcbData) ? *pcbData : dwDefaultDataSize; 00481 src = pvDefaultData; 00482 dst = pvData; 00483 for(i=0; i<maxmove; i++) *dst++ = *src++; 00484 *pcbData = maxmove; 00485 TRACE("setting default data\n"); 00486 ret = ERROR_SUCCESS; 00487 } 00488 } 00489 return ret; 00490 } 00491 00492 /************************************************************************* 00493 * SHRegGetUSValueA [SHLWAPI.@] 00494 * 00495 * Get a user-specific registry value. 00496 * 00497 * RETURNS 00498 * Success: ERROR_SUCCESS 00499 * Failure: An error code from SHRegOpenUSKeyA() or SHRegQueryUSValueA(). 00500 * 00501 * NOTES 00502 * This function opens pSubKey, queries the value, and then closes the key. 00503 */ 00504 LONG WINAPI SHRegGetUSValueA( 00505 LPCSTR pSubKey, /* [I] Key name to open */ 00506 LPCSTR pValue, /* [I] Value name to open */ 00507 LPDWORD pwType, /* [O] Destination for the type of the value */ 00508 LPVOID pvData, /* [O] Destination for the value */ 00509 LPDWORD pcbData, /* [I] Destination for the length of the value **/ 00510 BOOL flagIgnoreHKCU, /* [I] TRUE=Don't check HKEY_CURRENT_USER */ 00511 LPVOID pDefaultData, /* [I] Default value if it doesn't exist */ 00512 DWORD wDefaultDataSize) /* [I] Length of pDefaultData */ 00513 { 00514 HUSKEY myhuskey; 00515 LONG ret; 00516 00517 if (!pvData || !pcbData) return ERROR_INVALID_FUNCTION; /* FIXME:wrong*/ 00518 TRACE("key '%s', value '%s', datalen %d, %s\n", 00519 debugstr_a(pSubKey), debugstr_a(pValue), *pcbData, 00520 (flagIgnoreHKCU) ? "Ignoring HKCU" : "Tries HKCU then HKLM"); 00521 00522 ret = SHRegOpenUSKeyA(pSubKey, 0x1, 0, &myhuskey, flagIgnoreHKCU); 00523 if (ret == ERROR_SUCCESS) { 00524 ret = SHRegQueryUSValueA(myhuskey, pValue, pwType, pvData, 00525 pcbData, flagIgnoreHKCU, pDefaultData, 00526 wDefaultDataSize); 00527 SHRegCloseUSKey(myhuskey); 00528 } 00529 return ret; 00530 } 00531 00532 /************************************************************************* 00533 * SHRegGetUSValueW [SHLWAPI.@] 00534 * 00535 * See SHRegGetUSValueA. 00536 */ 00537 LONG WINAPI SHRegGetUSValueW( 00538 LPCWSTR pSubKey, 00539 LPCWSTR pValue, 00540 LPDWORD pwType, 00541 LPVOID pvData, 00542 LPDWORD pcbData, 00543 BOOL flagIgnoreHKCU, 00544 LPVOID pDefaultData, 00545 DWORD wDefaultDataSize) 00546 { 00547 HUSKEY myhuskey; 00548 LONG ret; 00549 00550 if (!pvData || !pcbData) return ERROR_INVALID_FUNCTION; /* FIXME:wrong*/ 00551 TRACE("key '%s', value '%s', datalen %d, %s\n", 00552 debugstr_w(pSubKey), debugstr_w(pValue), *pcbData, 00553 (flagIgnoreHKCU) ? "Ignoring HKCU" : "Tries HKCU then HKLM"); 00554 00555 ret = SHRegOpenUSKeyW(pSubKey, 0x1, 0, &myhuskey, flagIgnoreHKCU); 00556 if (ret == ERROR_SUCCESS) { 00557 ret = SHRegQueryUSValueW(myhuskey, pValue, pwType, pvData, 00558 pcbData, flagIgnoreHKCU, pDefaultData, 00559 wDefaultDataSize); 00560 SHRegCloseUSKey(myhuskey); 00561 } 00562 return ret; 00563 } 00564 00565 /************************************************************************* 00566 * SHRegSetUSValueA [SHLWAPI.@] 00567 * 00568 * Set a user-specific registry value. 00569 * 00570 * PARAMS 00571 * pszSubKey [I] Name of key to set the value in 00572 * pszValue [I] Name of value under pszSubKey to set the value in 00573 * dwType [I] Type of the value 00574 * pvData [I] Data to set as the value 00575 * cbData [I] length of pvData 00576 * dwFlags [I] SHREGSET_ flags from "shlwapi.h" 00577 * 00578 * RETURNS 00579 * Success: ERROR_SUCCESS 00580 * Failure: An error code from SHRegOpenUSKeyA() or SHRegWriteUSValueA(), or 00581 * ERROR_INVALID_FUNCTION if pvData is NULL. 00582 * 00583 * NOTES 00584 * This function opens pszSubKey, sets the value, and then closes the key. 00585 */ 00586 LONG WINAPI SHRegSetUSValueA(LPCSTR pszSubKey, LPCSTR pszValue, DWORD dwType, 00587 LPVOID pvData, DWORD cbData, DWORD dwFlags) 00588 { 00589 BOOL ignoreHKCU = TRUE; 00590 HUSKEY hkey; 00591 LONG ret; 00592 00593 TRACE("(%s,%s,%d,%p,%d,0x%08x\n", debugstr_a(pszSubKey), debugstr_a(pszValue), 00594 dwType, pvData, cbData, dwFlags); 00595 00596 if (!pvData) 00597 return ERROR_INVALID_FUNCTION; 00598 00599 if (dwFlags & SHREGSET_HKCU || dwFlags & SHREGSET_FORCE_HKCU) 00600 ignoreHKCU = FALSE; 00601 00602 ret = SHRegOpenUSKeyA(pszSubKey, KEY_ALL_ACCESS, 0, &hkey, ignoreHKCU); 00603 if (ret == ERROR_SUCCESS) 00604 { 00605 ret = SHRegWriteUSValueA(hkey, pszValue, dwType, pvData, cbData, dwFlags); 00606 SHRegCloseUSKey(hkey); 00607 } 00608 return ret; 00609 } 00610 00611 /************************************************************************* 00612 * SHRegSetUSValueW [SHLWAPI.@] 00613 * 00614 * See SHRegSetUSValueA. 00615 */ 00616 LONG WINAPI SHRegSetUSValueW(LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwType, 00617 LPVOID pvData, DWORD cbData, DWORD dwFlags) 00618 { 00619 BOOL ignoreHKCU = TRUE; 00620 HUSKEY hkey; 00621 LONG ret; 00622 00623 TRACE("(%s,%s,%d,%p,%d,0x%08x\n", debugstr_w(pszSubKey), debugstr_w(pszValue), 00624 dwType, pvData, cbData, dwFlags); 00625 00626 if (!pvData) 00627 return ERROR_INVALID_FUNCTION; 00628 00629 if (dwFlags & SHREGSET_HKCU || dwFlags & SHREGSET_FORCE_HKCU) 00630 ignoreHKCU = FALSE; 00631 00632 ret = SHRegOpenUSKeyW(pszSubKey, KEY_ALL_ACCESS, 0, &hkey, ignoreHKCU); 00633 if (ret == ERROR_SUCCESS) 00634 { 00635 ret = SHRegWriteUSValueW(hkey, pszValue, dwType, pvData, cbData, dwFlags); 00636 SHRegCloseUSKey(hkey); 00637 } 00638 return ret; 00639 } 00640 00641 /************************************************************************* 00642 * SHRegGetBoolUSValueA [SHLWAPI.@] 00643 * 00644 * Get a user-specific registry boolean value. 00645 * 00646 * RETURNS 00647 * Success: ERROR_SUCCESS 00648 * Failure: An error code from SHRegOpenUSKeyA() or SHRegQueryUSValueA(). 00649 * 00650 * NOTES 00651 * This function opens pszSubKey, queries the value, and then closes the key. 00652 * 00653 * Boolean values are one of the following: 00654 * True: YES,TRUE,non-zero 00655 * False: NO,FALSE,0 00656 */ 00657 BOOL WINAPI SHRegGetBoolUSValueA( 00658 LPCSTR pszSubKey, /* [I] Key name to open */ 00659 LPCSTR pszValue, /* [I] Value name to open */ 00660 BOOL fIgnoreHKCU, /* [I] TRUE=Don't check HKEY_CURRENT_USER */ 00661 BOOL fDefault) /* [I] Default value to use if pszValue is not present */ 00662 { 00663 DWORD type, datalen, work; 00664 BOOL ret = fDefault; 00665 CHAR data[10]; 00666 00667 TRACE("key '%s', value '%s', %s\n", 00668 debugstr_a(pszSubKey), debugstr_a(pszValue), 00669 (fIgnoreHKCU) ? "Ignoring HKCU" : "Tries HKCU then HKLM"); 00670 00671 datalen = sizeof(data)-1; 00672 if (!SHRegGetUSValueA( pszSubKey, pszValue, &type, 00673 data, &datalen, 00674 fIgnoreHKCU, 0, 0)) { 00675 /* process returned data via type into bool */ 00676 switch (type) { 00677 case REG_SZ: 00678 data[9] = '\0'; /* set end of string */ 00679 if (lstrcmpiA(data, "YES") == 0) ret = TRUE; 00680 if (lstrcmpiA(data, "TRUE") == 0) ret = TRUE; 00681 if (lstrcmpiA(data, "NO") == 0) ret = FALSE; 00682 if (lstrcmpiA(data, "FALSE") == 0) ret = FALSE; 00683 break; 00684 case REG_DWORD: 00685 work = *(LPDWORD)data; 00686 ret = (work != 0); 00687 break; 00688 case REG_BINARY: 00689 if (datalen == 1) { 00690 ret = (data[0] != '\0'); 00691 break; 00692 } 00693 default: 00694 FIXME("Unsupported registry data type %d\n", type); 00695 ret = FALSE; 00696 } 00697 TRACE("got value (type=%d), returning <%s>\n", type, 00698 (ret) ? "TRUE" : "FALSE"); 00699 } 00700 else { 00701 ret = fDefault; 00702 TRACE("returning default data <%s>\n", 00703 (ret) ? "TRUE" : "FALSE"); 00704 } 00705 return ret; 00706 } 00707 00708 /************************************************************************* 00709 * SHRegGetBoolUSValueW [SHLWAPI.@] 00710 * 00711 * See SHRegGetBoolUSValueA. 00712 */ 00713 BOOL WINAPI SHRegGetBoolUSValueW( 00714 LPCWSTR pszSubKey, 00715 LPCWSTR pszValue, 00716 BOOL fIgnoreHKCU, 00717 BOOL fDefault) 00718 { 00719 static const WCHAR wYES[]= {'Y','E','S','\0'}; 00720 static const WCHAR wTRUE[]= {'T','R','U','E','\0'}; 00721 static const WCHAR wNO[]= {'N','O','\0'}; 00722 static const WCHAR wFALSE[]={'F','A','L','S','E','\0'}; 00723 DWORD type, datalen, work; 00724 BOOL ret = fDefault; 00725 WCHAR data[10]; 00726 00727 TRACE("key '%s', value '%s', %s\n", 00728 debugstr_w(pszSubKey), debugstr_w(pszValue), 00729 (fIgnoreHKCU) ? "Ignoring HKCU" : "Tries HKCU then HKLM"); 00730 00731 datalen = (sizeof(data)-1) * sizeof(WCHAR); 00732 if (!SHRegGetUSValueW( pszSubKey, pszValue, &type, 00733 data, &datalen, 00734 fIgnoreHKCU, 0, 0)) { 00735 /* process returned data via type into bool */ 00736 switch (type) { 00737 case REG_SZ: 00738 data[9] = '\0'; /* set end of string */ 00739 if (lstrcmpiW(data, wYES)==0 || lstrcmpiW(data, wTRUE)==0) 00740 ret = TRUE; 00741 else if (lstrcmpiW(data, wNO)==0 || lstrcmpiW(data, wFALSE)==0) 00742 ret = FALSE; 00743 break; 00744 case REG_DWORD: 00745 work = *(LPDWORD)data; 00746 ret = (work != 0); 00747 break; 00748 case REG_BINARY: 00749 if (datalen == 1) { 00750 ret = (data[0] != '\0'); 00751 break; 00752 } 00753 default: 00754 FIXME("Unsupported registry data type %d\n", type); 00755 ret = FALSE; 00756 } 00757 TRACE("got value (type=%d), returning <%s>\n", type, 00758 (ret) ? "TRUE" : "FALSE"); 00759 } 00760 else { 00761 ret = fDefault; 00762 TRACE("returning default data <%s>\n", 00763 (ret) ? "TRUE" : "FALSE"); 00764 } 00765 return ret; 00766 } 00767 00768 /************************************************************************* 00769 * SHRegQueryInfoUSKeyA [SHLWAPI.@] 00770 * 00771 * Get information about a user-specific registry key. 00772 * 00773 * RETURNS 00774 * Success: ERROR_SUCCESS 00775 * Failure: An error code from RegQueryInfoKeyA(). 00776 */ 00777 LONG WINAPI SHRegQueryInfoUSKeyA( 00778 HUSKEY hUSKey, /* [I] Key to query */ 00779 LPDWORD pcSubKeys, /* [O] Destination for number of sub keys */ 00780 LPDWORD pcchMaxSubKeyLen, /* [O] Destination for the length of the biggest sub key name */ 00781 LPDWORD pcValues, /* [O] Destination for number of values */ 00782 LPDWORD pcchMaxValueNameLen,/* [O] Destination for the length of the biggest value */ 00783 SHREGENUM_FLAGS enumRegFlags) /* [in] SHREGENUM_ flags from "shlwapi.h" */ 00784 { 00785 HKEY dokey; 00786 LONG ret; 00787 00788 TRACE("(%p,%p,%p,%p,%p,%d)\n", 00789 hUSKey,pcSubKeys,pcchMaxSubKeyLen,pcValues, 00790 pcchMaxValueNameLen,enumRegFlags); 00791 00792 /* if user wants HKCU, and it exists, then try it */ 00793 if (((enumRegFlags == SHREGENUM_HKCU) || 00794 (enumRegFlags == SHREGENUM_DEFAULT)) && 00795 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) { 00796 ret = RegQueryInfoKeyA(dokey, 0, 0, 0, 00797 pcSubKeys, pcchMaxSubKeyLen, 0, 00798 pcValues, pcchMaxValueNameLen, 0, 0, 0); 00799 if ((ret == ERROR_SUCCESS) || 00800 (enumRegFlags == SHREGENUM_HKCU)) 00801 return ret; 00802 } 00803 if (((enumRegFlags == SHREGENUM_HKLM) || 00804 (enumRegFlags == SHREGENUM_DEFAULT)) && 00805 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) { 00806 return RegQueryInfoKeyA(dokey, 0, 0, 0, 00807 pcSubKeys, pcchMaxSubKeyLen, 0, 00808 pcValues, pcchMaxValueNameLen, 0, 0, 0); 00809 } 00810 return ERROR_INVALID_FUNCTION; 00811 } 00812 00813 /************************************************************************* 00814 * SHRegQueryInfoUSKeyW [SHLWAPI.@] 00815 * 00816 * See SHRegQueryInfoUSKeyA. 00817 */ 00818 LONG WINAPI SHRegQueryInfoUSKeyW( 00819 HUSKEY hUSKey, 00820 LPDWORD pcSubKeys, 00821 LPDWORD pcchMaxSubKeyLen, 00822 LPDWORD pcValues, 00823 LPDWORD pcchMaxValueNameLen, 00824 SHREGENUM_FLAGS enumRegFlags) 00825 { 00826 HKEY dokey; 00827 LONG ret; 00828 00829 TRACE("(%p,%p,%p,%p,%p,%d)\n", 00830 hUSKey,pcSubKeys,pcchMaxSubKeyLen,pcValues, 00831 pcchMaxValueNameLen,enumRegFlags); 00832 00833 /* if user wants HKCU, and it exists, then try it */ 00834 if (((enumRegFlags == SHREGENUM_HKCU) || 00835 (enumRegFlags == SHREGENUM_DEFAULT)) && 00836 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) { 00837 ret = RegQueryInfoKeyW(dokey, 0, 0, 0, 00838 pcSubKeys, pcchMaxSubKeyLen, 0, 00839 pcValues, pcchMaxValueNameLen, 0, 0, 0); 00840 if ((ret == ERROR_SUCCESS) || 00841 (enumRegFlags == SHREGENUM_HKCU)) 00842 return ret; 00843 } 00844 if (((enumRegFlags == SHREGENUM_HKLM) || 00845 (enumRegFlags == SHREGENUM_DEFAULT)) && 00846 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) { 00847 return RegQueryInfoKeyW(dokey, 0, 0, 0, 00848 pcSubKeys, pcchMaxSubKeyLen, 0, 00849 pcValues, pcchMaxValueNameLen, 0, 0, 0); 00850 } 00851 return ERROR_INVALID_FUNCTION; 00852 } 00853 00854 /************************************************************************* 00855 * SHRegEnumUSKeyA [SHLWAPI.@] 00856 * 00857 * Enumerate a user-specific registry key. 00858 * 00859 * RETURNS 00860 * Success: ERROR_SUCCESS 00861 * Failure: An error code from RegEnumKeyExA(). 00862 */ 00863 LONG WINAPI SHRegEnumUSKeyA( 00864 HUSKEY hUSKey, /* [in] Key to enumerate */ 00865 DWORD dwIndex, /* [in] Index within hUSKey */ 00866 LPSTR pszName, /* [out] Name of the enumerated value */ 00867 LPDWORD pcchValueNameLen, /* [in/out] Length of pszName */ 00868 SHREGENUM_FLAGS enumRegFlags) /* [in] SHREGENUM_ flags from "shlwapi.h" */ 00869 { 00870 HKEY dokey; 00871 00872 TRACE("(%p,%d,%p,%p(%d),%d)\n", 00873 hUSKey, dwIndex, pszName, pcchValueNameLen, 00874 *pcchValueNameLen, enumRegFlags); 00875 00876 if (((enumRegFlags == SHREGENUM_HKCU) || 00877 (enumRegFlags == SHREGENUM_DEFAULT)) && 00878 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) { 00879 return RegEnumKeyExA(dokey, dwIndex, pszName, pcchValueNameLen, 00880 0, 0, 0, 0); 00881 } 00882 00883 if (((enumRegFlags == SHREGENUM_HKLM) || 00884 (enumRegFlags == SHREGENUM_DEFAULT)) && 00885 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) { 00886 return RegEnumKeyExA(dokey, dwIndex, pszName, pcchValueNameLen, 00887 0, 0, 0, 0); 00888 } 00889 FIXME("no support for SHREGENUM_BOTH\n"); 00890 return ERROR_INVALID_FUNCTION; 00891 } 00892 00893 /************************************************************************* 00894 * SHRegEnumUSKeyW [SHLWAPI.@] 00895 * 00896 * See SHRegEnumUSKeyA. 00897 */ 00898 LONG WINAPI SHRegEnumUSKeyW( 00899 HUSKEY hUSKey, 00900 DWORD dwIndex, 00901 LPWSTR pszName, 00902 LPDWORD pcchValueNameLen, 00903 SHREGENUM_FLAGS enumRegFlags) 00904 { 00905 HKEY dokey; 00906 00907 TRACE("(%p,%d,%p,%p(%d),%d)\n", 00908 hUSKey, dwIndex, pszName, pcchValueNameLen, 00909 *pcchValueNameLen, enumRegFlags); 00910 00911 if (((enumRegFlags == SHREGENUM_HKCU) || 00912 (enumRegFlags == SHREGENUM_DEFAULT)) && 00913 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) { 00914 return RegEnumKeyExW(dokey, dwIndex, pszName, pcchValueNameLen, 00915 0, 0, 0, 0); 00916 } 00917 00918 if (((enumRegFlags == SHREGENUM_HKLM) || 00919 (enumRegFlags == SHREGENUM_DEFAULT)) && 00920 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) { 00921 return RegEnumKeyExW(dokey, dwIndex, pszName, pcchValueNameLen, 00922 0, 0, 0, 0); 00923 } 00924 FIXME("no support for SHREGENUM_BOTH\n"); 00925 return ERROR_INVALID_FUNCTION; 00926 } 00927 00928 00929 /************************************************************************* 00930 * SHRegWriteUSValueA [SHLWAPI.@] 00931 * 00932 * Write a user-specific registry value. 00933 * 00934 * PARAMS 00935 * hUSKey [I] Key to write the value to 00936 * pszValue [I] Name of value under hUSKey to write the value as 00937 * dwType [I] Type of the value 00938 * pvData [I] Data to set as the value 00939 * cbData [I] length of pvData 00940 * dwFlags [I] SHREGSET_ flags from "shlwapi.h" 00941 * 00942 * RETURNS 00943 * Success: ERROR_SUCCESS. 00944 * Failure: ERROR_INVALID_PARAMETER, if any parameter is invalid, otherwise 00945 * an error code from RegSetValueExA(). 00946 * 00947 * NOTES 00948 * dwFlags must have at least SHREGSET_FORCE_HKCU or SHREGSET_FORCE_HKLM set. 00949 */ 00950 LONG WINAPI SHRegWriteUSValueA(HUSKEY hUSKey, LPCSTR pszValue, DWORD dwType, 00951 LPVOID pvData, DWORD cbData, DWORD dwFlags) 00952 { 00953 WCHAR szValue[MAX_PATH]; 00954 00955 if (pszValue) 00956 MultiByteToWideChar(CP_ACP, 0, pszValue, -1, szValue, MAX_PATH); 00957 00958 return SHRegWriteUSValueW(hUSKey, pszValue ? szValue : NULL, dwType, 00959 pvData, cbData, dwFlags); 00960 } 00961 00962 /************************************************************************* 00963 * SHRegWriteUSValueW [SHLWAPI.@] 00964 * 00965 * See SHRegWriteUSValueA. 00966 */ 00967 LONG WINAPI SHRegWriteUSValueW(HUSKEY hUSKey, LPCWSTR pszValue, DWORD dwType, 00968 LPVOID pvData, DWORD cbData, DWORD dwFlags) 00969 { 00970 DWORD dummy; 00971 LPSHUSKEY hKey = hUSKey; 00972 LONG ret = ERROR_SUCCESS; 00973 00974 TRACE("(%p,%s,%d,%p,%d,%d)\n", hUSKey, debugstr_w(pszValue), 00975 dwType, pvData, cbData, dwFlags); 00976 00977 if (!hUSKey || IsBadWritePtr(hUSKey, sizeof(SHUSKEY)) || 00978 !(dwFlags & (SHREGSET_FORCE_HKCU|SHREGSET_FORCE_HKLM))) 00979 return ERROR_INVALID_PARAMETER; 00980 00981 if (dwFlags & (SHREGSET_FORCE_HKCU|SHREGSET_HKCU)) 00982 { 00983 if (!hKey->HKCUkey) 00984 { 00985 /* Create the key */ 00986 ret = RegCreateKeyW(hKey->HKCUstart, hKey->lpszPath, &hKey->HKCUkey); 00987 TRACE("Creating HKCU key, ret = %d\n", ret); 00988 if (ret && (dwFlags & (SHREGSET_FORCE_HKCU))) 00989 { 00990 hKey->HKCUkey = 0; 00991 return ret; 00992 } 00993 } 00994 00995 if (!ret) 00996 { 00997 if ((dwFlags & SHREGSET_FORCE_HKCU) || 00998 RegQueryValueExW(hKey->HKCUkey, pszValue, NULL, NULL, NULL, &dummy)) 00999 { 01000 /* Doesn't exist or we are forcing: Write value */ 01001 ret = RegSetValueExW(hKey->HKCUkey, pszValue, 0, dwType, pvData, cbData); 01002 TRACE("Writing HKCU value, ret = %d\n", ret); 01003 } 01004 } 01005 } 01006 01007 if (dwFlags & (SHREGSET_FORCE_HKLM|SHREGSET_HKLM)) 01008 { 01009 if (!hKey->HKLMkey) 01010 { 01011 /* Create the key */ 01012 ret = RegCreateKeyW(hKey->HKLMstart, hKey->lpszPath, &hKey->HKLMkey); 01013 TRACE("Creating HKLM key, ret = %d\n", ret); 01014 if (ret && (dwFlags & (SHREGSET_FORCE_HKLM))) 01015 { 01016 hKey->HKLMkey = 0; 01017 return ret; 01018 } 01019 } 01020 01021 if (!ret) 01022 { 01023 if ((dwFlags & SHREGSET_FORCE_HKLM) || 01024 RegQueryValueExW(hKey->HKLMkey, pszValue, NULL, NULL, NULL, &dummy)) 01025 { 01026 /* Doesn't exist or we are forcing: Write value */ 01027 ret = RegSetValueExW(hKey->HKLMkey, pszValue, 0, dwType, pvData, cbData); 01028 TRACE("Writing HKLM value, ret = %d\n", ret); 01029 } 01030 } 01031 } 01032 01033 return ret; 01034 } 01035 01036 /************************************************************************* 01037 * SHRegGetPathA [SHLWAPI.@] 01038 * 01039 * Get a path from the registry. 01040 * 01041 * PARAMS 01042 * hKey [I] Handle to registry key 01043 * lpszSubKey [I] Name of sub key containing path to get 01044 * lpszValue [I] Name of value containing path to get 01045 * lpszPath [O] Buffer for returned path 01046 * dwFlags [I] Reserved 01047 * 01048 * RETURNS 01049 * Success: ERROR_SUCCESS. lpszPath contains the path. 01050 * Failure: An error code from RegOpenKeyExA() or SHQueryValueExA(). 01051 */ 01052 DWORD WINAPI SHRegGetPathA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue, 01053 LPSTR lpszPath, DWORD dwFlags) 01054 { 01055 DWORD dwSize = MAX_PATH; 01056 01057 TRACE("(hkey=%p,%s,%s,%p,%d)\n", hKey, debugstr_a(lpszSubKey), 01058 debugstr_a(lpszValue), lpszPath, dwFlags); 01059 01060 return SHGetValueA(hKey, lpszSubKey, lpszValue, 0, lpszPath, &dwSize); 01061 } 01062 01063 /************************************************************************* 01064 * SHRegGetPathW [SHLWAPI.@] 01065 * 01066 * See SHRegGetPathA. 01067 */ 01068 DWORD WINAPI SHRegGetPathW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue, 01069 LPWSTR lpszPath, DWORD dwFlags) 01070 { 01071 DWORD dwSize = MAX_PATH; 01072 01073 TRACE("(hkey=%p,%s,%s,%p,%d)\n", hKey, debugstr_w(lpszSubKey), 01074 debugstr_w(lpszValue), lpszPath, dwFlags); 01075 01076 return SHGetValueW(hKey, lpszSubKey, lpszValue, 0, lpszPath, &dwSize); 01077 } 01078 01079 01080 /************************************************************************* 01081 * SHRegSetPathA [SHLWAPI.@] 01082 * 01083 * Write a path to the registry. 01084 * 01085 * PARAMS 01086 * hKey [I] Handle to registry key 01087 * lpszSubKey [I] Name of sub key containing path to set 01088 * lpszValue [I] Name of value containing path to set 01089 * lpszPath [O] Path to write 01090 * dwFlags [I] Reserved, must be 0. 01091 * 01092 * RETURNS 01093 * Success: ERROR_SUCCESS. 01094 * Failure: An error code from SHSetValueA(). 01095 */ 01096 DWORD WINAPI SHRegSetPathA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue, 01097 LPCSTR lpszPath, DWORD dwFlags) 01098 { 01099 char szBuff[MAX_PATH]; 01100 01101 FIXME("(hkey=%p,%s,%s,%p,%d) - semi-stub\n",hKey, debugstr_a(lpszSubKey), 01102 debugstr_a(lpszValue), lpszPath, dwFlags); 01103 01104 lstrcpyA(szBuff, lpszPath); 01105 01106 /* FIXME: PathUnExpandEnvStringsA(szBuff); */ 01107 01108 return SHSetValueA(hKey,lpszSubKey, lpszValue, REG_SZ, szBuff, 01109 lstrlenA(szBuff)); 01110 } 01111 01112 /************************************************************************* 01113 * SHRegSetPathW [SHLWAPI.@] 01114 * 01115 * See SHRegSetPathA. 01116 */ 01117 DWORD WINAPI SHRegSetPathW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue, 01118 LPCWSTR lpszPath, DWORD dwFlags) 01119 { 01120 WCHAR szBuff[MAX_PATH]; 01121 01122 FIXME("(hkey=%p,%s,%s,%p,%d) - semi-stub\n",hKey, debugstr_w(lpszSubKey), 01123 debugstr_w(lpszValue), lpszPath, dwFlags); 01124 01125 lstrcpyW(szBuff, lpszPath); 01126 01127 /* FIXME: PathUnExpandEnvStringsW(szBuff); */ 01128 01129 return SHSetValueW(hKey,lpszSubKey, lpszValue, REG_SZ, szBuff, 01130 lstrlenW(szBuff)); 01131 } 01132 01133 /************************************************************************* 01134 * SHGetValueA [SHLWAPI.@] 01135 * 01136 * Get a value from the registry. 01137 * 01138 * PARAMS 01139 * hKey [I] Handle to registry key 01140 * lpszSubKey [I] Name of sub key containing value to get 01141 * lpszValue [I] Name of value to get 01142 * pwType [O] Pointer to the values type 01143 * pvData [O] Pointer to the values data 01144 * pcbData [O] Pointer to the values size 01145 * 01146 * RETURNS 01147 * Success: ERROR_SUCCESS. Output parameters contain the details read. 01148 * Failure: An error code from RegOpenKeyExA() or SHQueryValueExA(). 01149 */ 01150 DWORD WINAPI SHGetValueA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue, 01151 LPDWORD pwType, LPVOID pvData, LPDWORD pcbData) 01152 { 01153 DWORD dwRet = 0; 01154 HKEY hSubKey = 0; 01155 01156 TRACE("(hkey=%p,%s,%s,%p,%p,%p)\n", hKey, debugstr_a(lpszSubKey), 01157 debugstr_a(lpszValue), pwType, pvData, pcbData); 01158 01159 /* lpszSubKey can be 0. In this case the value is taken from the 01160 * current key. 01161 */ 01162 if(lpszSubKey) 01163 dwRet = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_QUERY_VALUE, &hSubKey); 01164 01165 if (! dwRet) 01166 { 01167 /* SHQueryValueEx expands Environment strings */ 01168 dwRet = SHQueryValueExA(hSubKey ? hSubKey : hKey, lpszValue, 0, pwType, pvData, pcbData); 01169 if (hSubKey) RegCloseKey(hSubKey); 01170 } 01171 return dwRet; 01172 } 01173 01174 /************************************************************************* 01175 * SHGetValueW [SHLWAPI.@] 01176 * 01177 * See SHGetValueA. 01178 */ 01179 DWORD WINAPI SHGetValueW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue, 01180 LPDWORD pwType, LPVOID pvData, LPDWORD pcbData) 01181 { 01182 DWORD dwRet = 0; 01183 HKEY hSubKey = 0; 01184 01185 TRACE("(hkey=%p,%s,%s,%p,%p,%p)\n", hKey, debugstr_w(lpszSubKey), 01186 debugstr_w(lpszValue), pwType, pvData, pcbData); 01187 01188 if(lpszSubKey) 01189 dwRet = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_QUERY_VALUE, &hSubKey); 01190 01191 if (! dwRet) 01192 { 01193 dwRet = SHQueryValueExW(hSubKey ? hSubKey : hKey, lpszValue, 0, pwType, pvData, pcbData); 01194 if (hSubKey) RegCloseKey(hSubKey); 01195 } 01196 return dwRet; 01197 } 01198 01199 /************************************************************************* 01200 * SHSetValueA [SHLWAPI.@] 01201 * 01202 * Set a value in the registry. 01203 * 01204 * PARAMS 01205 * hKey [I] Handle to registry key 01206 * lpszSubKey [I] Name of sub key under hKey 01207 * lpszValue [I] Name of value to set 01208 * dwType [I] Type of the value 01209 * pvData [I] Data of the value 01210 * cbData [I] Size of the value 01211 * 01212 * RETURNS 01213 * Success: ERROR_SUCCESS. The value is set with the data given. 01214 * Failure: An error code from RegCreateKeyExA() or RegSetValueExA() 01215 * 01216 * NOTES 01217 * If lpszSubKey does not exist, it is created before the value is set. If 01218 * lpszSubKey is NULL or an empty string, then the value is added directly 01219 * to hKey instead. 01220 */ 01221 DWORD WINAPI SHSetValueA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue, 01222 DWORD dwType, LPCVOID pvData, DWORD cbData) 01223 { 01224 DWORD dwRet = ERROR_SUCCESS, dwDummy; 01225 HKEY hSubKey; 01226 01227 TRACE("(hkey=%p,%s,%s,%d,%p,%d)\n", hKey, debugstr_a(lpszSubKey), 01228 debugstr_a(lpszValue), dwType, pvData, cbData); 01229 01230 if (lpszSubKey && *lpszSubKey) 01231 dwRet = RegCreateKeyExA(hKey, lpszSubKey, 0, NULL, 01232 0, KEY_SET_VALUE, NULL, &hSubKey, &dwDummy); 01233 else 01234 hSubKey = hKey; 01235 if (!dwRet) 01236 { 01237 dwRet = RegSetValueExA(hSubKey, lpszValue, 0, dwType, pvData, cbData); 01238 if (hSubKey != hKey) 01239 RegCloseKey(hSubKey); 01240 } 01241 return dwRet; 01242 } 01243 01244 /************************************************************************* 01245 * SHSetValueW [SHLWAPI.@] 01246 * 01247 * See SHSetValueA. 01248 */ 01249 DWORD WINAPI SHSetValueW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue, 01250 DWORD dwType, LPCVOID pvData, DWORD cbData) 01251 { 01252 DWORD dwRet = ERROR_SUCCESS, dwDummy; 01253 HKEY hSubKey; 01254 01255 TRACE("(hkey=%p,%s,%s,%d,%p,%d)\n", hKey, debugstr_w(lpszSubKey), 01256 debugstr_w(lpszValue), dwType, pvData, cbData); 01257 01258 if (lpszSubKey && *lpszSubKey) 01259 dwRet = RegCreateKeyExW(hKey, lpszSubKey, 0, NULL, 01260 0, KEY_SET_VALUE, NULL, &hSubKey, &dwDummy); 01261 else 01262 hSubKey = hKey; 01263 if (!dwRet) 01264 { 01265 dwRet = RegSetValueExW(hSubKey, lpszValue, 0, dwType, pvData, cbData); 01266 if (hSubKey != hKey) 01267 RegCloseKey(hSubKey); 01268 } 01269 return dwRet; 01270 } 01271 01272 /************************************************************************* 01273 * SHQueryInfoKeyA [SHLWAPI.@] 01274 * 01275 * Get information about a registry key. See RegQueryInfoKeyA(). 01276 * 01277 * RETURNS 01278 * The result of calling RegQueryInfoKeyA(). 01279 */ 01280 LONG WINAPI SHQueryInfoKeyA(HKEY hKey, LPDWORD pwSubKeys, LPDWORD pwSubKeyMax, 01281 LPDWORD pwValues, LPDWORD pwValueMax) 01282 { 01283 TRACE("(hkey=%p,%p,%p,%p,%p)\n", hKey, pwSubKeys, pwSubKeyMax, 01284 pwValues, pwValueMax); 01285 return RegQueryInfoKeyA(hKey, NULL, NULL, NULL, pwSubKeys, pwSubKeyMax, 01286 NULL, pwValues, pwValueMax, NULL, NULL, NULL); 01287 } 01288 01289 /************************************************************************* 01290 * SHQueryInfoKeyW [SHLWAPI.@] 01291 * 01292 * See SHQueryInfoKeyA. 01293 */ 01294 LONG WINAPI SHQueryInfoKeyW(HKEY hKey, LPDWORD pwSubKeys, LPDWORD pwSubKeyMax, 01295 LPDWORD pwValues, LPDWORD pwValueMax) 01296 { 01297 TRACE("(hkey=%p,%p,%p,%p,%p)\n", hKey, pwSubKeys, pwSubKeyMax, 01298 pwValues, pwValueMax); 01299 return RegQueryInfoKeyW(hKey, NULL, NULL, NULL, pwSubKeys, pwSubKeyMax, 01300 NULL, pwValues, pwValueMax, NULL, NULL, NULL); 01301 } 01302 01303 /************************************************************************* 01304 * SHQueryValueExA [SHLWAPI.@] 01305 * 01306 * Get a value from the registry, expanding environment variable strings. 01307 * 01308 * PARAMS 01309 * hKey [I] Handle to registry key 01310 * lpszValue [I] Name of value to query 01311 * lpReserved [O] Reserved for future use; must be NULL 01312 * pwType [O] Optional pointer updated with the values type 01313 * pvData [O] Optional pointer updated with the values data 01314 * pcbData [O] Optional pointer updated with the values size 01315 * 01316 * RETURNS 01317 * Success: ERROR_SUCCESS. Any non NULL output parameters are updated with 01318 * information about the value. 01319 * Failure: ERROR_OUTOFMEMORY if memory allocation fails, or the type of the 01320 * data is REG_EXPAND_SZ and pcbData is NULL. Otherwise an error 01321 * code from RegQueryValueExA() or ExpandEnvironmentStringsA(). 01322 * 01323 * NOTES 01324 * Either pwType, pvData or pcbData may be NULL if the caller doesn't want 01325 * the type, data or size information for the value. 01326 * 01327 * If the type of the data is REG_EXPAND_SZ, it is expanded to REG_SZ. The 01328 * value returned will be truncated if it is of type REG_SZ and bigger than 01329 * the buffer given to store it. 01330 * 01331 * REG_EXPAND_SZ: 01332 * case-1: the unexpanded string is smaller than the expanded one 01333 * subcase-1: the buffer is too small to hold the unexpanded string: 01334 * function fails and returns the size of the unexpanded string. 01335 * 01336 * subcase-2: buffer is too small to hold the expanded string: 01337 * the function return success (!!) and the result is truncated 01338 * *** This is clearly an error in the native implementation. *** 01339 * 01340 * case-2: the unexpanded string is bigger than the expanded one 01341 * The buffer must have enough space to hold the unexpanded 01342 * string even if the result is smaller. 01343 * 01344 */ 01345 DWORD WINAPI SHQueryValueExA( HKEY hKey, LPCSTR lpszValue, 01346 LPDWORD lpReserved, LPDWORD pwType, 01347 LPVOID pvData, LPDWORD pcbData) 01348 { 01349 DWORD dwRet, dwType, dwUnExpDataLen = 0, dwExpDataLen; 01350 01351 TRACE("(hkey=%p,%s,%p,%p,%p,%p=%d)\n", hKey, debugstr_a(lpszValue), 01352 lpReserved, pwType, pvData, pcbData, pcbData ? *pcbData : 0); 01353 01354 if (pcbData) dwUnExpDataLen = *pcbData; 01355 01356 dwRet = RegQueryValueExA(hKey, lpszValue, lpReserved, &dwType, pvData, &dwUnExpDataLen); 01357 01358 if (pcbData && (dwType == REG_EXPAND_SZ)) 01359 { 01360 DWORD nBytesToAlloc; 01361 01362 /* Expand type REG_EXPAND_SZ into REG_SZ */ 01363 LPSTR szData; 01364 01365 /* If the caller didn't supply a buffer or the buffer is too small we have 01366 * to allocate our own 01367 */ 01368 if ((!pvData) || (dwRet == ERROR_MORE_DATA) ) 01369 { 01370 char cNull = '\0'; 01371 nBytesToAlloc = dwUnExpDataLen; 01372 01373 szData = LocalAlloc(LMEM_ZEROINIT, nBytesToAlloc); 01374 RegQueryValueExA (hKey, lpszValue, lpReserved, NULL, (LPBYTE)szData, &nBytesToAlloc); 01375 dwExpDataLen = ExpandEnvironmentStringsA(szData, &cNull, 1); 01376 dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen); 01377 LocalFree(szData); 01378 } 01379 else 01380 { 01381 nBytesToAlloc = (lstrlenA(pvData)+1) * sizeof (CHAR); 01382 szData = LocalAlloc(LMEM_ZEROINIT, nBytesToAlloc); 01383 lstrcpyA(szData, pvData); 01384 dwExpDataLen = ExpandEnvironmentStringsA(szData, pvData, *pcbData / sizeof(CHAR)); 01385 if (dwExpDataLen > *pcbData) dwRet = ERROR_MORE_DATA; 01386 dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen); 01387 LocalFree(szData); 01388 } 01389 } 01390 01391 /* Update the type and data size if the caller wanted them */ 01392 if ( dwType == REG_EXPAND_SZ ) dwType = REG_SZ; 01393 if ( pwType ) *pwType = dwType; 01394 if ( pcbData ) *pcbData = dwUnExpDataLen; 01395 return dwRet; 01396 } 01397 01398 01399 /************************************************************************* 01400 * SHQueryValueExW [SHLWAPI.@] 01401 * 01402 * See SHQueryValueExA. 01403 */ 01404 DWORD WINAPI SHQueryValueExW(HKEY hKey, LPCWSTR lpszValue, 01405 LPDWORD lpReserved, LPDWORD pwType, 01406 LPVOID pvData, LPDWORD pcbData) 01407 { 01408 DWORD dwRet, dwType, dwUnExpDataLen = 0, dwExpDataLen; 01409 01410 TRACE("(hkey=%p,%s,%p,%p,%p,%p=%d)\n", hKey, debugstr_w(lpszValue), 01411 lpReserved, pwType, pvData, pcbData, pcbData ? *pcbData : 0); 01412 01413 if (pcbData) dwUnExpDataLen = *pcbData; 01414 01415 dwRet = RegQueryValueExW(hKey, lpszValue, lpReserved, &dwType, pvData, &dwUnExpDataLen); 01416 if (dwRet!=ERROR_SUCCESS && dwRet!=ERROR_MORE_DATA) 01417 return dwRet; 01418 01419 if (pcbData && (dwType == REG_EXPAND_SZ)) 01420 { 01421 DWORD nBytesToAlloc; 01422 01423 /* Expand type REG_EXPAND_SZ into REG_SZ */ 01424 LPWSTR szData; 01425 01426 /* If the caller didn't supply a buffer or the buffer is too small we have 01427 * to allocate our own 01428 */ 01429 if ((!pvData) || (dwRet == ERROR_MORE_DATA) ) 01430 { 01431 WCHAR cNull = '\0'; 01432 nBytesToAlloc = dwUnExpDataLen; 01433 01434 szData = LocalAlloc(LMEM_ZEROINIT, nBytesToAlloc); 01435 RegQueryValueExW (hKey, lpszValue, lpReserved, NULL, (LPBYTE)szData, &nBytesToAlloc); 01436 dwExpDataLen = ExpandEnvironmentStringsW(szData, &cNull, 1); 01437 dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen); 01438 LocalFree(szData); 01439 } 01440 else 01441 { 01442 nBytesToAlloc = (lstrlenW(pvData) + 1) * sizeof(WCHAR); 01443 szData = LocalAlloc(LMEM_ZEROINIT, nBytesToAlloc); 01444 lstrcpyW(szData, pvData); 01445 dwExpDataLen = ExpandEnvironmentStringsW(szData, pvData, *pcbData/sizeof(WCHAR) ); 01446 if (dwExpDataLen > *pcbData) dwRet = ERROR_MORE_DATA; 01447 dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen); 01448 LocalFree(szData); 01449 } 01450 } 01451 01452 /* Update the type and data size if the caller wanted them */ 01453 if ( dwType == REG_EXPAND_SZ ) dwType = REG_SZ; 01454 if ( pwType ) *pwType = dwType; 01455 if ( pcbData ) *pcbData = dwUnExpDataLen; 01456 return dwRet; 01457 } 01458 01459 /************************************************************************* 01460 * SHDeleteKeyA [SHLWAPI.@] 01461 * 01462 * Delete a registry key and any sub keys/values present 01463 * 01464 * This function forwards to the unicode version directly, to avoid 01465 * handling subkeys that are not representable in ASCII. 01466 * 01467 * PARAMS 01468 * hKey [I] Handle to registry key 01469 * lpszSubKey [I] Name of sub key to delete 01470 * 01471 * RETURNS 01472 * Success: ERROR_SUCCESS. The key is deleted. 01473 * Failure: An error code from RegOpenKeyExA(), RegQueryInfoKeyA(), 01474 * RegEnumKeyExA() or RegDeleteKeyA(). 01475 */ 01476 DWORD WINAPI SHDeleteKeyA(HKEY hKey, LPCSTR lpszSubKey) 01477 { 01478 WCHAR subkeyW[MAX_PATH]; 01479 01480 MultiByteToWideChar (CP_ACP, 0, lpszSubKey, -1, subkeyW, sizeof(subkeyW)/sizeof(WCHAR)); 01481 return SHDeleteKeyW(hKey, subkeyW); 01482 } 01483 01484 /************************************************************************* 01485 * SHDeleteKeyW [SHLWAPI.@] 01486 * 01487 * See SHDeleteKeyA. 01488 */ 01489 DWORD WINAPI SHDeleteKeyW(HKEY hKey, LPCWSTR lpszSubKey) 01490 { 01491 DWORD dwRet, dwMaxSubkeyLen = 0, dwSize; 01492 WCHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf; 01493 HKEY hSubKey = 0; 01494 01495 TRACE("(hkey=%p,%s)\n", hKey, debugstr_w(lpszSubKey)); 01496 01497 dwRet = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_READ, &hSubKey); 01498 if(!dwRet) 01499 { 01500 /* Find the maximum subkey length so that we can allocate a buffer */ 01501 dwRet = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL, 01502 &dwMaxSubkeyLen, NULL, NULL, NULL, NULL, NULL, NULL); 01503 if(!dwRet) 01504 { 01505 dwMaxSubkeyLen++; 01506 if (dwMaxSubkeyLen > sizeof(szNameBuf)/sizeof(WCHAR)) 01507 /* Name too big: alloc a buffer for it */ 01508 lpszName = HeapAlloc(GetProcessHeap(), 0, dwMaxSubkeyLen*sizeof(WCHAR)); 01509 01510 if(!lpszName) 01511 dwRet = ERROR_NOT_ENOUGH_MEMORY; 01512 else 01513 { 01514 while (dwRet == ERROR_SUCCESS) 01515 { 01516 dwSize = dwMaxSubkeyLen; 01517 dwRet = RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL, NULL, NULL, NULL); 01518 if (dwRet == ERROR_SUCCESS || dwRet == ERROR_MORE_DATA) 01519 dwRet = SHDeleteKeyW(hSubKey, lpszName); 01520 } 01521 if (dwRet == ERROR_NO_MORE_ITEMS) 01522 dwRet = ERROR_SUCCESS; 01523 01524 if (lpszName != szNameBuf) 01525 HeapFree(GetProcessHeap(), 0, lpszName); /* Free buffer if allocated */ 01526 } 01527 } 01528 01529 RegCloseKey(hSubKey); 01530 if(!dwRet) 01531 dwRet = RegDeleteKeyW(hKey, lpszSubKey); 01532 } 01533 return dwRet; 01534 } 01535 01536 /************************************************************************* 01537 * SHDeleteEmptyKeyA [SHLWAPI.@] 01538 * 01539 * Delete a registry key with no sub keys. 01540 * 01541 * PARAMS 01542 * hKey [I] Handle to registry key 01543 * lpszSubKey [I] Name of sub key to delete 01544 * 01545 * RETURNS 01546 * Success: ERROR_SUCCESS. The key is deleted. 01547 * Failure: If the key is not empty, returns ERROR_KEY_HAS_CHILDREN. Otherwise 01548 * returns an error code from RegOpenKeyExA(), RegQueryInfoKeyA() or 01549 * RegDeleteKeyA(). 01550 */ 01551 DWORD WINAPI SHDeleteEmptyKeyA(HKEY hKey, LPCSTR lpszSubKey) 01552 { 01553 DWORD dwRet, dwKeyCount = 0; 01554 HKEY hSubKey = 0; 01555 01556 TRACE("(hkey=%p,%s)\n", hKey, debugstr_a(lpszSubKey)); 01557 01558 dwRet = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_READ, &hSubKey); 01559 if(!dwRet) 01560 { 01561 dwRet = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, &dwKeyCount, 01562 NULL, NULL, NULL, NULL, NULL, NULL, NULL); 01563 RegCloseKey(hSubKey); 01564 if(!dwRet) 01565 { 01566 if (!dwKeyCount) 01567 dwRet = RegDeleteKeyA(hKey, lpszSubKey); 01568 else 01569 dwRet = ERROR_KEY_HAS_CHILDREN; 01570 } 01571 } 01572 return dwRet; 01573 } 01574 01575 /************************************************************************* 01576 * SHDeleteEmptyKeyW [SHLWAPI.@] 01577 * 01578 * See SHDeleteEmptyKeyA. 01579 */ 01580 DWORD WINAPI SHDeleteEmptyKeyW(HKEY hKey, LPCWSTR lpszSubKey) 01581 { 01582 DWORD dwRet, dwKeyCount = 0; 01583 HKEY hSubKey = 0; 01584 01585 TRACE("(hkey=%p, %s)\n", hKey, debugstr_w(lpszSubKey)); 01586 01587 dwRet = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_READ, &hSubKey); 01588 if(!dwRet) 01589 { 01590 dwRet = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, &dwKeyCount, 01591 NULL, NULL, NULL, NULL, NULL, NULL, NULL); 01592 RegCloseKey(hSubKey); 01593 if(!dwRet) 01594 { 01595 if (!dwKeyCount) 01596 dwRet = RegDeleteKeyW(hKey, lpszSubKey); 01597 else 01598 dwRet = ERROR_KEY_HAS_CHILDREN; 01599 } 01600 } 01601 return dwRet; 01602 } 01603 01604 /************************************************************************* 01605 * SHDeleteOrphanKeyA [SHLWAPI.@] 01606 * 01607 * Delete a registry key with no sub keys or values. 01608 * 01609 * PARAMS 01610 * hKey [I] Handle to registry key 01611 * lpszSubKey [I] Name of sub key to possibly delete 01612 * 01613 * RETURNS 01614 * Success: ERROR_SUCCESS. The key has been deleted if it was an orphan. 01615 * Failure: An error from RegOpenKeyExA(), RegQueryValueExA(), or RegDeleteKeyA(). 01616 */ 01617 DWORD WINAPI SHDeleteOrphanKeyA(HKEY hKey, LPCSTR lpszSubKey) 01618 { 01619 HKEY hSubKey; 01620 DWORD dwKeyCount = 0, dwValueCount = 0, dwRet; 01621 01622 TRACE("(hkey=%p,%s)\n", hKey, debugstr_a(lpszSubKey)); 01623 01624 dwRet = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_READ, &hSubKey); 01625 01626 if(!dwRet) 01627 { 01628 /* Get subkey and value count */ 01629 dwRet = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, &dwKeyCount, 01630 NULL, NULL, &dwValueCount, NULL, NULL, NULL, NULL); 01631 01632 if(!dwRet && !dwKeyCount && !dwValueCount) 01633 { 01634 dwRet = RegDeleteKeyA(hKey, lpszSubKey); 01635 } 01636 RegCloseKey(hSubKey); 01637 } 01638 return dwRet; 01639 } 01640 01641 /************************************************************************* 01642 * SHDeleteOrphanKeyW [SHLWAPI.@] 01643 * 01644 * See SHDeleteOrphanKeyA. 01645 */ 01646 DWORD WINAPI SHDeleteOrphanKeyW(HKEY hKey, LPCWSTR lpszSubKey) 01647 { 01648 HKEY hSubKey; 01649 DWORD dwKeyCount = 0, dwValueCount = 0, dwRet; 01650 01651 TRACE("(hkey=%p,%s)\n", hKey, debugstr_w(lpszSubKey)); 01652 01653 dwRet = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_READ, &hSubKey); 01654 01655 if(!dwRet) 01656 { 01657 /* Get subkey and value count */ 01658 dwRet = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, &dwKeyCount, 01659 NULL, NULL, &dwValueCount, NULL, NULL, NULL, NULL); 01660 01661 if(!dwRet && !dwKeyCount && !dwValueCount) 01662 { 01663 dwRet = RegDeleteKeyW(hKey, lpszSubKey); 01664 } 01665 RegCloseKey(hSubKey); 01666 } 01667 return dwRet; 01668 } 01669 01670 /************************************************************************* 01671 * SHDeleteValueA [SHLWAPI.@] 01672 * 01673 * Delete a value from the registry. 01674 * 01675 * PARAMS 01676 * hKey [I] Handle to registry key 01677 * lpszSubKey [I] Name of sub key containing value to delete 01678 * lpszValue [I] Name of value to delete 01679 * 01680 * RETURNS 01681 * Success: ERROR_SUCCESS. The value is deleted. 01682 * Failure: An error code from RegOpenKeyExA() or RegDeleteValueA(). 01683 */ 01684 DWORD WINAPI SHDeleteValueA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue) 01685 { 01686 DWORD dwRet; 01687 HKEY hSubKey; 01688 01689 TRACE("(hkey=%p,%s,%s)\n", hKey, debugstr_a(lpszSubKey), debugstr_a(lpszValue)); 01690 01691 dwRet = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_SET_VALUE, &hSubKey); 01692 if (!dwRet) 01693 { 01694 dwRet = RegDeleteValueA(hSubKey, lpszValue); 01695 RegCloseKey(hSubKey); 01696 } 01697 return dwRet; 01698 } 01699 01700 /************************************************************************* 01701 * SHDeleteValueW [SHLWAPI.@] 01702 * 01703 * See SHDeleteValueA. 01704 */ 01705 DWORD WINAPI SHDeleteValueW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue) 01706 { 01707 DWORD dwRet; 01708 HKEY hSubKey; 01709 01710 TRACE("(hkey=%p,%s,%s)\n", hKey, debugstr_w(lpszSubKey), debugstr_w(lpszValue)); 01711 01712 dwRet = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_SET_VALUE, &hSubKey); 01713 if (!dwRet) 01714 { 01715 dwRet = RegDeleteValueW(hSubKey, lpszValue); 01716 RegCloseKey(hSubKey); 01717 } 01718 return dwRet; 01719 } 01720 01721 /************************************************************************* 01722 * SHEnumKeyExA [SHLWAPI.@] 01723 * 01724 * Enumerate sub keys in a registry key. 01725 * 01726 * PARAMS 01727 * hKey [I] Handle to registry key 01728 * dwIndex [I] Index of key to enumerate 01729 * lpszSubKey [O] Pointer updated with the subkey name 01730 * pwLen [O] Pointer updated with the subkey length 01731 * 01732 * RETURNS 01733 * Success: ERROR_SUCCESS. lpszSubKey and pwLen are updated. 01734 * Failure: An error code from RegEnumKeyExA(). 01735 */ 01736 LONG WINAPI SHEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpszSubKey, 01737 LPDWORD pwLen) 01738 { 01739 TRACE("(hkey=%p,%d,%s,%p)\n", hKey, dwIndex, debugstr_a(lpszSubKey), pwLen); 01740 01741 return RegEnumKeyExA(hKey, dwIndex, lpszSubKey, pwLen, NULL, NULL, NULL, NULL); 01742 } 01743 01744 /************************************************************************* 01745 * SHEnumKeyExW [SHLWAPI.@] 01746 * 01747 * See SHEnumKeyExA. 01748 */ 01749 LONG WINAPI SHEnumKeyExW(HKEY hKey, DWORD dwIndex, LPWSTR lpszSubKey, 01750 LPDWORD pwLen) 01751 { 01752 TRACE("(hkey=%p,%d,%s,%p)\n", hKey, dwIndex, debugstr_w(lpszSubKey), pwLen); 01753 01754 return RegEnumKeyExW(hKey, dwIndex, lpszSubKey, pwLen, NULL, NULL, NULL, NULL); 01755 } 01756 01757 /************************************************************************* 01758 * SHEnumValueA [SHLWAPI.@] 01759 * 01760 * Enumerate values in a registry key. 01761 * 01762 * PARAMS 01763 * hKey [I] Handle to registry key 01764 * dwIndex [I] Index of key to enumerate 01765 * lpszValue [O] Pointer updated with the values name 01766 * pwLen [O] Pointer updated with the values length 01767 * pwType [O] Pointer updated with the values type 01768 * pvData [O] Pointer updated with the values data 01769 * pcbData [O] Pointer updated with the values size 01770 * 01771 * RETURNS 01772 * Success: ERROR_SUCCESS. Output parameters are updated. 01773 * Failure: An error code from RegEnumValueA(). 01774 */ 01775 LONG WINAPI SHEnumValueA(HKEY hKey, DWORD dwIndex, LPSTR lpszValue, 01776 LPDWORD pwLen, LPDWORD pwType, 01777 LPVOID pvData, LPDWORD pcbData) 01778 { 01779 TRACE("(hkey=%p,%d,%s,%p,%p,%p,%p)\n", hKey, dwIndex, 01780 debugstr_a(lpszValue), pwLen, pwType, pvData, pcbData); 01781 01782 return RegEnumValueA(hKey, dwIndex, lpszValue, pwLen, NULL, 01783 pwType, pvData, pcbData); 01784 } 01785 01786 /************************************************************************* 01787 * SHEnumValueW [SHLWAPI.@] 01788 * 01789 * See SHEnumValueA. 01790 */ 01791 LONG WINAPI SHEnumValueW(HKEY hKey, DWORD dwIndex, LPWSTR lpszValue, 01792 LPDWORD pwLen, LPDWORD pwType, 01793 LPVOID pvData, LPDWORD pcbData) 01794 { 01795 TRACE("(hkey=%p,%d,%s,%p,%p,%p,%p)\n", hKey, dwIndex, 01796 debugstr_w(lpszValue), pwLen, pwType, pvData, pcbData); 01797 01798 return RegEnumValueW(hKey, dwIndex, lpszValue, pwLen, NULL, 01799 pwType, pvData, pcbData); 01800 } 01801 01802 /************************************************************************* 01803 * @ [SHLWAPI.205] 01804 * 01805 * Get a value from the registry. 01806 * 01807 * PARAMS 01808 * hKey [I] Handle to registry key 01809 * pSubKey [I] Name of sub key containing value to get 01810 * pValue [I] Name of value to get 01811 * pwType [O] Destination for the values type 01812 * pvData [O] Destination for the values data 01813 * pbData [O] Destination for the values size 01814 * 01815 * RETURNS 01816 * Success: ERROR_SUCCESS. Output parameters contain the details read. 01817 * Failure: An error code from RegOpenKeyExA() or SHQueryValueExA(), 01818 * or ERROR_INVALID_FUNCTION in the machine is in safe mode. 01819 */ 01820 DWORD WINAPI SHGetValueGoodBootA(HKEY hkey, LPCSTR pSubKey, LPCSTR pValue, 01821 LPDWORD pwType, LPVOID pvData, LPDWORD pbData) 01822 { 01823 if (GetSystemMetrics(SM_CLEANBOOT)) 01824 return ERROR_INVALID_FUNCTION; 01825 return SHGetValueA(hkey, pSubKey, pValue, pwType, pvData, pbData); 01826 } 01827 01828 /************************************************************************* 01829 * @ [SHLWAPI.206] 01830 * 01831 * Unicode version of SHGetValueGoodBootW. 01832 */ 01833 DWORD WINAPI SHGetValueGoodBootW(HKEY hkey, LPCWSTR pSubKey, LPCWSTR pValue, 01834 LPDWORD pwType, LPVOID pvData, LPDWORD pbData) 01835 { 01836 if (GetSystemMetrics(SM_CLEANBOOT)) 01837 return ERROR_INVALID_FUNCTION; 01838 return SHGetValueW(hkey, pSubKey, pValue, pwType, pvData, pbData); 01839 } 01840 01841 /************************************************************************* 01842 * @ [SHLWAPI.320] 01843 * 01844 * Set a MIME content type in the registry. 01845 * 01846 * PARAMS 01847 * lpszSubKey [I] Name of key under HKEY_CLASSES_ROOT. 01848 * lpszValue [I] Value to set 01849 * 01850 * RETURNS 01851 * Success: TRUE 01852 * Failure: FALSE 01853 */ 01854 BOOL WINAPI RegisterMIMETypeForExtensionA(LPCSTR lpszSubKey, LPCSTR lpszValue) 01855 { 01856 DWORD dwRet; 01857 01858 if (!lpszValue) 01859 { 01860 WARN("Invalid lpszValue would crash under Win32!\n"); 01861 return FALSE; 01862 } 01863 01864 dwRet = SHSetValueA(HKEY_CLASSES_ROOT, lpszSubKey, lpszContentTypeA, 01865 REG_SZ, lpszValue, strlen(lpszValue)); 01866 return dwRet ? FALSE : TRUE; 01867 } 01868 01869 /************************************************************************* 01870 * @ [SHLWAPI.321] 01871 * 01872 * Unicode version of RegisterMIMETypeForExtensionA. 01873 */ 01874 BOOL WINAPI RegisterMIMETypeForExtensionW(LPCWSTR lpszSubKey, LPCWSTR lpszValue) 01875 { 01876 DWORD dwRet; 01877 01878 if (!lpszValue) 01879 { 01880 WARN("Invalid lpszValue would crash under Win32!\n"); 01881 return FALSE; 01882 } 01883 01884 dwRet = SHSetValueW(HKEY_CLASSES_ROOT, lpszSubKey, lpszContentTypeW, 01885 REG_SZ, lpszValue, strlenW(lpszValue)); 01886 return dwRet ? FALSE : TRUE; 01887 } 01888 01889 /************************************************************************* 01890 * @ [SHLWAPI.322] 01891 * 01892 * Delete a MIME content type from the registry. 01893 * 01894 * PARAMS 01895 * lpszSubKey [I] Name of sub key 01896 * 01897 * RETURNS 01898 * Success: TRUE 01899 * Failure: FALSE 01900 */ 01901 BOOL WINAPI UnregisterMIMETypeForExtensionA(LPCSTR lpszSubKey) 01902 { 01903 HRESULT ret = SHDeleteValueA(HKEY_CLASSES_ROOT, lpszSubKey, lpszContentTypeA); 01904 return ret ? FALSE : TRUE; 01905 } 01906 01907 /************************************************************************* 01908 * @ [SHLWAPI.323] 01909 * 01910 * Unicode version of UnregisterMIMETypeForExtensionA. 01911 */ 01912 BOOL WINAPI UnregisterMIMETypeForExtensionW(LPCWSTR lpszSubKey) 01913 { 01914 HRESULT ret = SHDeleteValueW(HKEY_CLASSES_ROOT, lpszSubKey, lpszContentTypeW); 01915 return ret ? FALSE : TRUE; 01916 } 01917 01918 /************************************************************************* 01919 * @ [SHLWAPI.328] 01920 * 01921 * Get the registry path to a MIME content key. 01922 * 01923 * PARAMS 01924 * lpszType [I] Content type to get the path for 01925 * lpszBuffer [O] Destination for path 01926 * dwLen [I] Length of lpszBuffer 01927 * 01928 * RETURNS 01929 * Success: TRUE. lpszBuffer contains the full path. 01930 * Failure: FALSE. 01931 * 01932 * NOTES 01933 * The base path for the key is "MIME\Database\Content Type\" 01934 */ 01935 BOOL WINAPI GetMIMETypeSubKeyA(LPCSTR lpszType, LPSTR lpszBuffer, DWORD dwLen) 01936 { 01937 TRACE("(%s,%p,%d)\n", debugstr_a(lpszType), lpszBuffer, dwLen); 01938 01939 if (dwLen > dwLenMimeDbContent && lpszType && lpszBuffer) 01940 { 01941 size_t dwStrLen = strlen(lpszType); 01942 01943 if (dwStrLen < dwLen - dwLenMimeDbContent) 01944 { 01945 memcpy(lpszBuffer, szMimeDbContentA, dwLenMimeDbContent); 01946 memcpy(lpszBuffer + dwLenMimeDbContent, lpszType, dwStrLen + 1); 01947 return TRUE; 01948 } 01949 } 01950 return FALSE; 01951 } 01952 01953 /************************************************************************* 01954 * @ [SHLWAPI.329] 01955 * 01956 * Unicode version of GetMIMETypeSubKeyA. 01957 */ 01958 BOOL WINAPI GetMIMETypeSubKeyW(LPCWSTR lpszType, LPWSTR lpszBuffer, DWORD dwLen) 01959 { 01960 TRACE("(%s,%p,%d)\n", debugstr_w(lpszType), lpszBuffer, dwLen); 01961 01962 if (dwLen > dwLenMimeDbContent && lpszType && lpszBuffer) 01963 { 01964 DWORD dwStrLen = strlenW(lpszType); 01965 01966 if (dwStrLen < dwLen - dwLenMimeDbContent) 01967 { 01968 memcpy(lpszBuffer, szMimeDbContentW, dwLenMimeDbContent * sizeof(WCHAR)); 01969 memcpy(lpszBuffer + dwLenMimeDbContent, lpszType, (dwStrLen + 1) * sizeof(WCHAR)); 01970 return TRUE; 01971 } 01972 } 01973 return FALSE; 01974 } 01975 01976 /************************************************************************* 01977 * @ [SHLWAPI.330] 01978 * 01979 * Get the file extension for a given Mime type. 01980 * 01981 * PARAMS 01982 * lpszType [I] Mime type to get the file extension for 01983 * lpExt [O] Destination for the resulting extension 01984 * iLen [I] Length of lpExt in characters 01985 * 01986 * RETURNS 01987 * Success: TRUE. lpExt contains the file extension. 01988 * Failure: FALSE, if any parameter is invalid or the extension cannot be 01989 * retrieved. If iLen > 0, lpExt is set to an empty string. 01990 * 01991 * NOTES 01992 * - The extension returned in lpExt always has a leading '.' character, even 01993 * if the registry Mime database entry does not. 01994 * - iLen must be long enough for the file extension for this function to succeed. 01995 */ 01996 BOOL WINAPI MIME_GetExtensionA(LPCSTR lpszType, LPSTR lpExt, INT iLen) 01997 { 01998 char szSubKey[MAX_PATH]; 01999 DWORD dwlen = iLen - 1, dwType; 02000 BOOL bRet = FALSE; 02001 02002 if (iLen > 0 && lpExt) 02003 *lpExt = '\0'; 02004 02005 if (lpszType && lpExt && iLen > 2 && 02006 GetMIMETypeSubKeyA(lpszType, szSubKey, MAX_PATH) && 02007 !SHGetValueA(HKEY_CLASSES_ROOT, szSubKey, szExtensionA, &dwType, lpExt + 1, &dwlen) && 02008 lpExt[1]) 02009 { 02010 if (lpExt[1] == '.') 02011 memmove(lpExt, lpExt + 1, strlen(lpExt + 1) + 1); 02012 else 02013 *lpExt = '.'; /* Supply a '.' */ 02014 bRet = TRUE; 02015 } 02016 return bRet; 02017 } 02018 02019 /************************************************************************* 02020 * @ [SHLWAPI.331] 02021 * 02022 * Unicode version of MIME_GetExtensionA. 02023 */ 02024 BOOL WINAPI MIME_GetExtensionW(LPCWSTR lpszType, LPWSTR lpExt, INT iLen) 02025 { 02026 WCHAR szSubKey[MAX_PATH]; 02027 DWORD dwlen = iLen - 1, dwType; 02028 BOOL bRet = FALSE; 02029 02030 if (iLen > 0 && lpExt) 02031 *lpExt = '\0'; 02032 02033 if (lpszType && lpExt && iLen > 2 && 02034 GetMIMETypeSubKeyW(lpszType, szSubKey, MAX_PATH) && 02035 !SHGetValueW(HKEY_CLASSES_ROOT, szSubKey, szExtensionW, &dwType, lpExt + 1, &dwlen) && 02036 lpExt[1]) 02037 { 02038 if (lpExt[1] == '.') 02039 memmove(lpExt, lpExt + 1, (strlenW(lpExt + 1) + 1) * sizeof(WCHAR)); 02040 else 02041 *lpExt = '.'; /* Supply a '.' */ 02042 bRet = TRUE; 02043 } 02044 return bRet; 02045 } 02046 02047 /************************************************************************* 02048 * @ [SHLWAPI.324] 02049 * 02050 * Set the file extension for a MIME content key. 02051 * 02052 * PARAMS 02053 * lpszExt [I] File extension to set 02054 * lpszType [I] Content type to set the extension for 02055 * 02056 * RETURNS 02057 * Success: TRUE. The file extension is set in the registry. 02058 * Failure: FALSE. 02059 */ 02060 BOOL WINAPI RegisterExtensionForMIMETypeA(LPCSTR lpszExt, LPCSTR lpszType) 02061 { 02062 DWORD dwLen; 02063 char szKey[MAX_PATH]; 02064 02065 TRACE("(%s,%s)\n", debugstr_a(lpszExt), debugstr_a(lpszType)); 02066 02067 if (!GetMIMETypeSubKeyA(lpszType, szKey, MAX_PATH)) /* Get full path to the key */ 02068 return FALSE; 02069 02070 dwLen = strlen(lpszExt) + 1; 02071 02072 if (SHSetValueA(HKEY_CLASSES_ROOT, szKey, szExtensionA, REG_SZ, lpszExt, dwLen)) 02073 return FALSE; 02074 return TRUE; 02075 } 02076 02077 /************************************************************************* 02078 * @ [SHLWAPI.325] 02079 * 02080 * Unicode version of RegisterExtensionForMIMETypeA. 02081 */ 02082 BOOL WINAPI RegisterExtensionForMIMETypeW(LPCWSTR lpszExt, LPCWSTR lpszType) 02083 { 02084 DWORD dwLen; 02085 WCHAR szKey[MAX_PATH]; 02086 02087 TRACE("(%s,%s)\n", debugstr_w(lpszExt), debugstr_w(lpszType)); 02088 02089 /* Get the full path to the key */ 02090 if (!GetMIMETypeSubKeyW(lpszType, szKey, MAX_PATH)) /* Get full path to the key */ 02091 return FALSE; 02092 02093 dwLen = (lstrlenW(lpszExt) + 1) * sizeof(WCHAR); 02094 02095 if (SHSetValueW(HKEY_CLASSES_ROOT, szKey, szExtensionW, REG_SZ, lpszExt, dwLen)) 02096 return FALSE; 02097 return TRUE; 02098 } 02099 02100 /************************************************************************* 02101 * @ [SHLWAPI.326] 02102 * 02103 * Delete a file extension from a MIME content type. 02104 * 02105 * PARAMS 02106 * lpszType [I] Content type to delete the extension for 02107 * 02108 * RETURNS 02109 * Success: TRUE. The file extension is deleted from the registry. 02110 * Failure: FALSE. The extension may have been removed but the key remains. 02111 * 02112 * NOTES 02113 * If deleting the extension leaves an orphan key, the key is removed also. 02114 */ 02115 BOOL WINAPI UnregisterExtensionForMIMETypeA(LPCSTR lpszType) 02116 { 02117 char szKey[MAX_PATH]; 02118 02119 TRACE("(%s)\n", debugstr_a(lpszType)); 02120 02121 if (!GetMIMETypeSubKeyA(lpszType, szKey, MAX_PATH)) /* Get full path to the key */ 02122 return FALSE; 02123 02124 if (!SHDeleteValueA(HKEY_CLASSES_ROOT, szKey, szExtensionA)) 02125 return FALSE; 02126 02127 if (!SHDeleteOrphanKeyA(HKEY_CLASSES_ROOT, szKey)) 02128 return FALSE; 02129 return TRUE; 02130 } 02131 02132 /************************************************************************* 02133 * @ [SHLWAPI.327] 02134 * 02135 * Unicode version of UnregisterExtensionForMIMETypeA. 02136 */ 02137 BOOL WINAPI UnregisterExtensionForMIMETypeW(LPCWSTR lpszType) 02138 { 02139 WCHAR szKey[MAX_PATH]; 02140 02141 TRACE("(%s)\n", debugstr_w(lpszType)); 02142 02143 if (!GetMIMETypeSubKeyW(lpszType, szKey, MAX_PATH)) /* Get full path to the key */ 02144 return FALSE; 02145 02146 if (!SHDeleteValueW(HKEY_CLASSES_ROOT, szKey, szExtensionW)) 02147 return FALSE; 02148 02149 if (!SHDeleteOrphanKeyW(HKEY_CLASSES_ROOT, szKey)) 02150 return FALSE; 02151 return TRUE; 02152 } 02153 02154 /************************************************************************* 02155 * SHRegDuplicateHKey [SHLWAPI.@] 02156 * 02157 * Create a duplicate of a registry handle. 02158 * 02159 * PARAMS 02160 * hKey [I] key to duplicate. 02161 * 02162 * RETURNS 02163 * A new handle pointing to the same key as hKey. 02164 */ 02165 HKEY WINAPI SHRegDuplicateHKey(HKEY hKey) 02166 { 02167 HKEY newKey = 0; 02168 02169 RegOpenKeyExA(hKey, 0, 0, MAXIMUM_ALLOWED, &newKey); 02170 TRACE("new key is %p\n", newKey); 02171 return newKey; 02172 } 02173 02174 02175 /************************************************************************* 02176 * SHCopyKeyA [SHLWAPI.@] 02177 * 02178 * Copy a key and its values/sub keys to another location. 02179 * 02180 * PARAMS 02181 * hKeySrc [I] Source key to copy from 02182 * lpszSrcSubKey [I] Sub key under hKeySrc, or NULL to use hKeySrc directly 02183 * hKeyDst [I] Destination key 02184 * dwReserved [I] Reserved, must be 0 02185 * 02186 * RETURNS 02187 * Success: ERROR_SUCCESS. The key is copied to the destination key. 02188 * Failure: A standard windows error code. 02189 * 02190 * NOTES 02191 * If hKeyDst is a key under hKeySrc, this function will misbehave 02192 * (It will loop until out of stack, or the registry is full). This 02193 * bug is present in Win32 also. 02194 */ 02195 DWORD WINAPI SHCopyKeyA(HKEY hKeySrc, LPCSTR lpszSrcSubKey, HKEY hKeyDst, DWORD dwReserved) 02196 { 02197 WCHAR szSubKeyW[MAX_PATH]; 02198 02199 TRACE("(hkey=%p,%s,%p08x,%d)\n", hKeySrc, debugstr_a(lpszSrcSubKey), hKeyDst, dwReserved); 02200 02201 if (lpszSrcSubKey) 02202 MultiByteToWideChar(0, 0, lpszSrcSubKey, -1, szSubKeyW, MAX_PATH); 02203 02204 return SHCopyKeyW(hKeySrc, lpszSrcSubKey ? szSubKeyW : NULL, hKeyDst, dwReserved); 02205 } 02206 02207 /************************************************************************* 02208 * SHCopyKeyW [SHLWAPI.@] 02209 * 02210 * See SHCopyKeyA. 02211 */ 02212 DWORD WINAPI SHCopyKeyW(HKEY hKeySrc, LPCWSTR lpszSrcSubKey, HKEY hKeyDst, DWORD dwReserved) 02213 { 02214 DWORD dwKeyCount = 0, dwValueCount = 0, dwMaxKeyLen = 0; 02215 DWORD dwMaxValueLen = 0, dwMaxDataLen = 0, i; 02216 BYTE buff[1024]; 02217 LPVOID lpBuff = buff; 02218 WCHAR szName[MAX_PATH], *lpszName = szName; 02219 DWORD dwRet = S_OK; 02220 02221 TRACE("hkey=%p,%s,%p08x,%d)\n", hKeySrc, debugstr_w(lpszSrcSubKey), hKeyDst, dwReserved); 02222 02223 if(!hKeyDst || !hKeySrc) 02224 dwRet = ERROR_INVALID_PARAMETER; 02225 else 02226 { 02227 /* Open source key */ 02228 if(lpszSrcSubKey) 02229 dwRet = RegOpenKeyExW(hKeySrc, lpszSrcSubKey, 0, KEY_ALL_ACCESS, &hKeySrc); 02230 02231 if(dwRet) 02232 hKeyDst = NULL; /* Don't close this key since we didn't open it */ 02233 else 02234 { 02235 /* Get details about sub keys and values */ 02236 dwRet = RegQueryInfoKeyW(hKeySrc, NULL, NULL, NULL, &dwKeyCount, &dwMaxKeyLen, 02237 NULL, &dwValueCount, &dwMaxValueLen, &dwMaxDataLen, 02238 NULL, NULL); 02239 if(!dwRet) 02240 { 02241 if (dwMaxValueLen > dwMaxKeyLen) 02242 dwMaxKeyLen = dwMaxValueLen; /* Get max size for key/value names */ 02243 02244 if (dwMaxKeyLen++ > MAX_PATH - 1) 02245 lpszName = HeapAlloc(GetProcessHeap(), 0, dwMaxKeyLen * sizeof(WCHAR)); 02246 02247 if (dwMaxDataLen > sizeof(buff)) 02248 lpBuff = HeapAlloc(GetProcessHeap(), 0, dwMaxDataLen); 02249 02250 if (!lpszName || !lpBuff) 02251 dwRet = ERROR_NOT_ENOUGH_MEMORY; 02252 } 02253 } 02254 } 02255 02256 /* Copy all the sub keys */ 02257 for(i = 0; i < dwKeyCount && !dwRet; i++) 02258 { 02259 HKEY hSubKeySrc, hSubKeyDst; 02260 DWORD dwSize = dwMaxKeyLen; 02261 02262 dwRet = RegEnumKeyExW(hKeySrc, i, lpszName, &dwSize, NULL, NULL, NULL, NULL); 02263 02264 if(!dwRet) 02265 { 02266 /* Open source sub key */ 02267 dwRet = RegOpenKeyExW(hKeySrc, lpszName, 0, KEY_READ, &hSubKeySrc); 02268 02269 if(!dwRet) 02270 { 02271 /* Create destination sub key */ 02272 dwRet = RegCreateKeyW(hKeyDst, lpszName, &hSubKeyDst); 02273 02274 if(!dwRet) 02275 { 02276 /* Recursively copy keys and values from the sub key */ 02277 dwRet = SHCopyKeyW(hSubKeySrc, NULL, hSubKeyDst, 0); 02278 RegCloseKey(hSubKeyDst); 02279 } 02280 } 02281 RegCloseKey(hSubKeySrc); 02282 } 02283 } 02284 02285 /* Copy all the values in this key */ 02286 for (i = 0; i < dwValueCount && !dwRet; i++) 02287 { 02288 DWORD dwNameSize = dwMaxKeyLen, dwType, dwLen = dwMaxDataLen; 02289 02290 dwRet = RegEnumValueW(hKeySrc, i, lpszName, &dwNameSize, NULL, &dwType, lpBuff, &dwLen); 02291 02292 if (!dwRet) 02293 dwRet = SHSetValueW(hKeyDst, NULL, lpszName, dwType, lpBuff, dwLen); 02294 } 02295 02296 /* Free buffers if allocated */ 02297 if (lpszName != szName) 02298 HeapFree(GetProcessHeap(), 0, lpszName); 02299 if (lpBuff != buff) 02300 HeapFree(GetProcessHeap(), 0, lpBuff); 02301 02302 if (lpszSrcSubKey && hKeyDst) 02303 RegCloseKey(hKeyDst); 02304 return dwRet; 02305 } 02306 02307 /* 02308 * The following functions are ORDINAL ONLY: 02309 */ 02310 02311 /************************************************************************* 02312 * @ [SHLWAPI.280] 02313 * 02314 * Read an integer value from the registry, falling back to a default. 02315 * 02316 * PARAMS 02317 * hKey [I] Registry key to read from 02318 * lpszValue [I] Value name to read 02319 * iDefault [I] Default value to return 02320 * 02321 * RETURNS 02322 * The value contained in the given registry value if present, otherwise 02323 * iDefault. 02324 */ 02325 int WINAPI SHRegGetIntW(HKEY hKey, LPCWSTR lpszValue, int iDefault) 02326 { 02327 TRACE("(%p,%s,%d)\n", hKey, debugstr_w(lpszValue), iDefault); 02328 02329 if (hKey) 02330 { 02331 WCHAR szBuff[32]; 02332 DWORD dwSize = sizeof(szBuff); 02333 szBuff[0] = '\0'; 02334 SHQueryValueExW(hKey, lpszValue, 0, 0, szBuff, &dwSize); 02335 02336 if(*szBuff >= '0' && *szBuff <= '9') 02337 return StrToIntW(szBuff); 02338 } 02339 return iDefault; 02340 } 02341 02342 /************************************************************************* 02343 * @ [SHLWAPI.343] 02344 * 02345 * Create or open an explorer ClassId Key. 02346 * 02347 * PARAMS 02348 * guid [I] Explorer ClassId key to open 02349 * lpszValue [I] Value name under the ClassId Key 02350 * bUseHKCU [I] TRUE=Use HKEY_CURRENT_USER, FALSE=Use HKEY_CLASSES_ROOT 02351 * bCreate [I] TRUE=Create the key if it doesn't exist, FALSE=Don't 02352 * phKey [O] Destination for the resulting key handle 02353 * 02354 * RETURNS 02355 * Success: S_OK. phKey contains the resulting registry handle. 02356 * Failure: An HRESULT error code indicating the problem. 02357 */ 02358 HRESULT WINAPI SHRegGetCLSIDKeyA(REFGUID guid, LPCSTR lpszValue, BOOL bUseHKCU, BOOL bCreate, PHKEY phKey) 02359 { 02360 WCHAR szValue[MAX_PATH]; 02361 02362 if (lpszValue) 02363 MultiByteToWideChar(CP_ACP, 0, lpszValue, -1, szValue, sizeof(szValue)/sizeof(WCHAR)); 02364 02365 return SHRegGetCLSIDKeyW(guid, lpszValue ? szValue : NULL, bUseHKCU, bCreate, phKey); 02366 } 02367 02368 /************************************************************************* 02369 * @ [SHLWAPI.344] 02370 * 02371 * Unicode version of SHRegGetCLSIDKeyA. 02372 */ 02373 HRESULT WINAPI SHRegGetCLSIDKeyW(REFGUID guid, LPCWSTR lpszValue, BOOL bUseHKCU, 02374 BOOL bCreate, PHKEY phKey) 02375 { 02376 static const WCHAR szClassIdKey[] = { 'S','o','f','t','w','a','r','e','\\', 02377 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\', 02378 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 02379 'E','x','p','l','o','r','e','r','\\','C','L','S','I','D','\\' }; 02380 #define szClassIdKeyLen (sizeof(szClassIdKey)/sizeof(WCHAR)) 02381 WCHAR szKey[MAX_PATH]; 02382 DWORD dwRet; 02383 HKEY hkey; 02384 02385 /* Create the key string */ 02386 memcpy(szKey, szClassIdKey, sizeof(szClassIdKey)); 02387 SHStringFromGUIDW(guid, szKey + szClassIdKeyLen, 39); /* Append guid */ 02388 02389 if(lpszValue) 02390 { 02391 szKey[szClassIdKeyLen + 39] = '\\'; 02392 strcpyW(szKey + szClassIdKeyLen + 40, lpszValue); /* Append value name */ 02393 } 02394 02395 hkey = bUseHKCU ? HKEY_CURRENT_USER : HKEY_CLASSES_ROOT; 02396 02397 if(bCreate) 02398 dwRet = RegCreateKeyW(hkey, szKey, phKey); 02399 else 02400 dwRet = RegOpenKeyExW(hkey, szKey, 0, KEY_READ, phKey); 02401 02402 return dwRet ? HRESULT_FROM_WIN32(dwRet) : S_OK; 02403 } 02404 02405 /************************************************************************* 02406 * SHRegisterValidateTemplate [SHLWAPI.@] 02407 * 02408 * observed from the ie 5.5 installer: 02409 * - allocates a buffer with the size of the given file 02410 * - read the file content into the buffer 02411 * - creates the key szTemplateKey 02412 * - sets "205523652929647911071668590831910975402"=dword:00002e37 at 02413 * the key 02414 * 02415 * PARAMS 02416 * filename [I] An existing file its content is read into an allocated 02417 * buffer 02418 * unknown [I] 02419 * 02420 * RETURNS 02421 * Success: ERROR_SUCCESS. 02422 */ 02423 HRESULT WINAPI SHRegisterValidateTemplate(LPCWSTR filename, BOOL unknown) 02424 { 02425 /* static const WCHAR szTemplateKey[] = { 'S','o','f','t','w','a','r','e','\\', 02426 * 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\', 02427 * 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 02428 * 'E','x','p','l','o','r','e','r','\\', 02429 * 'T','e','m','p','l','a','t','e','R','e','g','i','s','t','r','y',0 }; 02430 */ 02431 FIXME("stub: %s, %08x\n", debugstr_w(filename), unknown); 02432 02433 return S_OK; 02434 } Generated on Sun May 27 2012 04:16:33 for ReactOS by
1.7.6.1
|