1 /* Unit test suite for SHReg* functions 2 * 3 * Copyright 2002 Juergen Schmied 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 18 */ 19 20 #include "precomp.h" 21 22 /* Keys used for testing */ 23 #define REG_TEST_KEY "Software\\Wine\\Test" 24 #define REG_CURRENT_VERSION "Software\\Microsoft\\Windows\\CurrentVersion\\explorer" 25 26 static HMODULE hshlwapi; 27 28 static DWORD (WINAPI *pSHCopyKeyA)(HKEY,LPCSTR,HKEY,DWORD); 29 static DWORD (WINAPI *pSHRegGetPathA)(HKEY,LPCSTR,LPCSTR,LPSTR,DWORD); 30 static LSTATUS (WINAPI *pSHRegGetValueA)(HKEY,LPCSTR,LPCSTR,SRRF,LPDWORD,LPVOID,LPDWORD); 31 static LSTATUS (WINAPI *pSHRegCreateUSKeyW)(LPCWSTR,REGSAM,HUSKEY,PHUSKEY,DWORD); 32 static LSTATUS (WINAPI *pSHRegOpenUSKeyW)(LPCWSTR,REGSAM,HUSKEY,PHUSKEY,BOOL); 33 static LSTATUS (WINAPI *pSHRegCloseUSKey)(HUSKEY); 34 35 static const char sTestpath1[] = "%LONGSYSTEMVAR%\\subdir1"; 36 static const char sTestpath2[] = "%FOO%\\subdir1"; 37 38 static const char * sEnvvar1 = "bar"; 39 static const char * sEnvvar2 = "ImARatherLongButIndeedNeededString"; 40 41 static char sExpTestpath1[MAX_PATH]; 42 static char sExpTestpath2[MAX_PATH]; 43 static DWORD nExpLen1; 44 static DWORD nExpLen2; 45 46 static const char * sEmptyBuffer ="0123456789"; 47 48 /* delete key and all its subkeys */ 49 static DWORD delete_key( HKEY hkey, LPCSTR parent, LPCSTR keyname ) 50 { 51 HKEY parentKey; 52 DWORD ret; 53 54 RegCloseKey(hkey); 55 56 /* open the parent of the key to close */ 57 ret = RegOpenKeyExA( HKEY_CURRENT_USER, parent, 0, KEY_ALL_ACCESS, &parentKey); 58 if (ret != ERROR_SUCCESS) 59 return ret; 60 61 ret = SHDeleteKeyA( parentKey, keyname ); 62 RegCloseKey(parentKey); 63 64 return ret; 65 } 66 67 static HKEY create_test_entries(void) 68 { 69 HKEY hKey; 70 DWORD ret; 71 DWORD nExpectedLen1, nExpectedLen2; 72 73 SetEnvironmentVariableA("LONGSYSTEMVAR", sEnvvar1); 74 SetEnvironmentVariableA("FOO", sEnvvar2); 75 76 ret = RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_KEY, &hKey); 77 ok( ERROR_SUCCESS == ret, "RegCreateKeyA failed, ret=%u\n", ret); 78 79 if (hKey) 80 { 81 ok(!RegSetValueExA(hKey,"Test1",0,REG_EXPAND_SZ, (LPBYTE) sTestpath1, strlen(sTestpath1)+1), "RegSetValueExA failed\n"); 82 ok(!RegSetValueExA(hKey,"Test2",0,REG_SZ, (LPBYTE) sTestpath1, strlen(sTestpath1)+1), "RegSetValueExA failed\n"); 83 ok(!RegSetValueExA(hKey,"Test3",0,REG_EXPAND_SZ, (LPBYTE) sTestpath2, strlen(sTestpath2)+1), "RegSetValueExA failed\n"); 84 } 85 86 nExpLen1 = ExpandEnvironmentStringsA(sTestpath1, sExpTestpath1, sizeof(sExpTestpath1)); 87 nExpLen2 = ExpandEnvironmentStringsA(sTestpath2, sExpTestpath2, sizeof(sExpTestpath2)); 88 89 nExpectedLen1 = strlen(sTestpath1) - strlen("%LONGSYSTEMVAR%") + strlen(sEnvvar1) + 1; 90 nExpectedLen2 = strlen(sTestpath2) - strlen("%FOO%") + strlen(sEnvvar2) + 1; 91 /* ExpandEnvironmentStringsA on NT4 returns 2x the correct result */ 92 trace("sExplen1 = (%d)\n", nExpLen1); 93 if (nExpectedLen1 != nExpLen1) 94 trace( "Expanding %s failed (expected %d) - known bug in NT4\n", sTestpath1, nExpectedLen1 ); 95 96 trace("sExplen2 = (%d)\n", nExpLen2); 97 if (nExpectedLen2 != nExpLen2) 98 trace( "Expanding %s failed (expected %d) - known bug in NT4\n", sTestpath2, nExpectedLen2 ); 99 100 /* Make sure we carry on with correct values */ 101 nExpLen1 = nExpectedLen1; 102 nExpLen2 = nExpectedLen2; 103 return hKey; 104 } 105 106 static void test_SHGetValue(void) 107 { 108 DWORD dwSize; 109 DWORD dwType; 110 DWORD dwRet; 111 char buf[MAX_PATH]; 112 113 strcpy(buf, sEmptyBuffer); 114 dwSize = MAX_PATH; 115 dwType = -1; 116 dwRet = SHGetValueA(HKEY_CURRENT_USER, REG_TEST_KEY, "Test1", &dwType, buf, &dwSize); 117 ok( ERROR_SUCCESS == dwRet, "SHGetValueA failed, ret=%u\n", dwRet); 118 ok( 0 == strcmp(sExpTestpath1, buf) || 119 broken(0 == strcmp(sTestpath1, buf)), /* IE4.x */ 120 "Comparing of (%s) with (%s) failed\n", buf, sExpTestpath1); 121 ok( REG_SZ == dwType || 122 broken(REG_EXPAND_SZ == dwType), /* IE4.x */ 123 "Expected REG_SZ, got (%u)\n", dwType); 124 125 strcpy(buf, sEmptyBuffer); 126 dwSize = MAX_PATH; 127 dwType = -1; 128 dwRet = SHGetValueA(HKEY_CURRENT_USER, REG_TEST_KEY, "Test2", &dwType, buf, &dwSize); 129 ok( ERROR_SUCCESS == dwRet, "SHGetValueA failed, ret=%u\n", dwRet); 130 ok( 0 == strcmp(sTestpath1, buf) , "Comparing of (%s) with (%s) failed\n", buf, sTestpath1); 131 ok( REG_SZ == dwType , "Expected REG_SZ, got (%u)\n", dwType); 132 } 133 134 static void test_SHRegGetValue(void) 135 { 136 LSTATUS ret; 137 DWORD size, type; 138 char data[MAX_PATH]; 139 140 if(!pSHRegGetValueA) 141 return; 142 143 size = MAX_PATH; 144 ret = pSHRegGetValueA(HKEY_CURRENT_USER, REG_TEST_KEY, "Test1", SRRF_RT_REG_EXPAND_SZ, &type, data, &size); 145 ok(ret == ERROR_INVALID_PARAMETER, "SHRegGetValue failed, ret=%u\n", ret); 146 147 size = MAX_PATH; 148 ret = pSHRegGetValueA(HKEY_CURRENT_USER, REG_TEST_KEY, "Test1", SRRF_RT_REG_SZ, &type, data, &size); 149 ok(ret == ERROR_SUCCESS, "SHRegGetValue failed, ret=%u\n", ret); 150 ok(!strcmp(data, sExpTestpath1), "data = %s, expected %s\n", data, sExpTestpath1); 151 ok(type == REG_SZ, "type = %d, expected REG_SZ\n", type); 152 153 size = MAX_PATH; 154 ret = pSHRegGetValueA(HKEY_CURRENT_USER, REG_TEST_KEY, "Test1", SRRF_RT_REG_DWORD, &type, data, &size); 155 ok(ret == ERROR_UNSUPPORTED_TYPE, "SHRegGetValue failed, ret=%u\n", ret); 156 157 size = MAX_PATH; 158 ret = pSHRegGetValueA(HKEY_CURRENT_USER, REG_TEST_KEY, "Test2", SRRF_RT_REG_EXPAND_SZ, &type, data, &size); 159 ok(ret == ERROR_INVALID_PARAMETER, "SHRegGetValue failed, ret=%u\n", ret); 160 161 size = MAX_PATH; 162 ret = pSHRegGetValueA(HKEY_CURRENT_USER, REG_TEST_KEY, "Test2", SRRF_RT_REG_SZ, &type, data, &size); 163 ok(ret == ERROR_SUCCESS, "SHRegGetValue failed, ret=%u\n", ret); 164 ok(!strcmp(data, sTestpath1), "data = %s, expected %s\n", data, sTestpath1); 165 ok(type == REG_SZ, "type = %d, expected REG_SZ\n", type); 166 167 size = MAX_PATH; 168 ret = pSHRegGetValueA(HKEY_CURRENT_USER, REG_TEST_KEY, "Test2", SRRF_RT_REG_QWORD, &type, data, &size); 169 ok(ret == ERROR_UNSUPPORTED_TYPE, "SHRegGetValue failed, ret=%u\n", ret); 170 } 171 172 static void test_SHGetRegPath(void) 173 { 174 char buf[MAX_PATH]; 175 DWORD dwRet; 176 177 if (!pSHRegGetPathA) 178 return; 179 180 strcpy(buf, sEmptyBuffer); 181 dwRet = (*pSHRegGetPathA)(HKEY_CURRENT_USER, REG_TEST_KEY, "Test1", buf, 0); 182 ok( ERROR_SUCCESS == dwRet, "SHRegGetPathA failed, ret=%u\n", dwRet); 183 ok( 0 == strcmp(sExpTestpath1, buf) , "Comparing (%s) with (%s) failed\n", buf, sExpTestpath1); 184 } 185 186 static void test_SHQueryValueEx(void) 187 { 188 HKEY hKey; 189 DWORD dwSize; 190 DWORD dwType; 191 char buf[MAX_PATH]; 192 DWORD dwRet; 193 const char * sTestedFunction = ""; 194 DWORD nUsedBuffer1,nUsedBuffer2; 195 196 sTestedFunction = "RegOpenKeyExA"; 197 dwRet = RegOpenKeyExA(HKEY_CURRENT_USER, REG_TEST_KEY, 0, KEY_QUERY_VALUE, &hKey); 198 ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%u\n", sTestedFunction, dwRet); 199 200 /****** SHQueryValueExA ******/ 201 202 sTestedFunction = "SHQueryValueExA"; 203 nUsedBuffer1 = max(strlen(sExpTestpath1)+1, strlen(sTestpath1)+1); 204 nUsedBuffer2 = max(strlen(sExpTestpath2)+1, strlen(sTestpath2)+1); 205 /* 206 * Case 1.1 All arguments are NULL 207 */ 208 dwRet = SHQueryValueExA( hKey, "Test1", NULL, NULL, NULL, NULL); 209 ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%u\n", sTestedFunction, dwRet); 210 211 /* 212 * Case 1.2 dwType is set 213 */ 214 dwType = -1; 215 dwRet = SHQueryValueExA( hKey, "Test1", NULL, &dwType, NULL, NULL); 216 ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%u\n", sTestedFunction, dwRet); 217 ok( REG_SZ == dwType , "Expected REG_SZ, got (%u)\n", dwType); 218 219 /* 220 * dwSize is set 221 * dwExpanded < dwUnExpanded 222 */ 223 dwSize = 6; 224 dwRet = SHQueryValueExA( hKey, "Test1", NULL, NULL, NULL, &dwSize); 225 ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%u\n", sTestedFunction, dwRet); 226 ok( dwSize == nUsedBuffer1, "Buffer sizes (%u) and (%u) are not equal\n", dwSize, nUsedBuffer1); 227 228 /* 229 * dwExpanded > dwUnExpanded 230 */ 231 dwSize = 6; 232 dwRet = SHQueryValueExA( hKey, "Test3", NULL, NULL, NULL, &dwSize); 233 ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%u\n", sTestedFunction, dwRet); 234 ok( dwSize >= nUsedBuffer2 || 235 broken(dwSize == (strlen(sTestpath2) + 1)), /* < IE4.x */ 236 "Buffer size (%u) should be >= (%u)\n", dwSize, nUsedBuffer2); 237 238 /* 239 * Case 1 string shrinks during expanding 240 */ 241 strcpy(buf, sEmptyBuffer); 242 dwSize = 6; 243 dwType = -1; 244 dwRet = SHQueryValueExA( hKey, "Test1", NULL, &dwType, buf, &dwSize); 245 ok( ERROR_MORE_DATA == dwRet, "Expected ERROR_MORE_DATA, got (%u)\n", dwRet); 246 ok( 0 == strcmp(sEmptyBuffer, buf) , "Comparing (%s) with (%s) failed\n", buf, sEmptyBuffer); 247 ok( dwSize == nUsedBuffer1, "Buffer sizes (%u) and (%u) are not equal\n", dwSize, nUsedBuffer1); 248 ok( REG_SZ == dwType || 249 broken(REG_EXPAND_SZ == dwType), /* < IE6 */ 250 "Expected REG_SZ, got (%u)\n", dwType); 251 252 /* 253 * string grows during expanding 254 * dwSize is smaller than the size of the unexpanded string 255 */ 256 strcpy(buf, sEmptyBuffer); 257 dwSize = 6; 258 dwType = -1; 259 dwRet = SHQueryValueExA( hKey, "Test3", NULL, &dwType, buf, &dwSize); 260 ok( ERROR_MORE_DATA == dwRet, "Expected ERROR_MORE_DATA, got (%u)\n", dwRet); 261 ok( 0 == strcmp(sEmptyBuffer, buf) , "Comparing (%s) with (%s) failed\n", buf, sEmptyBuffer); 262 ok( dwSize >= nUsedBuffer2 || 263 broken(dwSize == (strlen(sTestpath2) + 1)), /* < IE6 */ 264 "Buffer size (%u) should be >= (%u)\n", dwSize, nUsedBuffer2); 265 ok( REG_SZ == dwType || 266 broken(REG_EXPAND_SZ == dwType), /* < IE6 */ 267 "Expected REG_SZ, got (%u)\n", dwType); 268 269 /* 270 * string grows during expanding 271 * dwSize is larger than the size of the unexpanded string, but 272 * smaller than the part before the backslash. If the unexpanded 273 * string fits into the buffer, it can get cut when expanded. 274 */ 275 strcpy(buf, sEmptyBuffer); 276 dwSize = strlen(sEnvvar2) - 2; 277 dwType = -1; 278 dwRet = SHQueryValueExA( hKey, "Test3", NULL, &dwType, buf, &dwSize); 279 ok( ERROR_MORE_DATA == dwRet || 280 broken(ERROR_ENVVAR_NOT_FOUND == dwRet) || /* IE5.5 */ 281 broken(ERROR_SUCCESS == dwRet), /* < IE5.5*/ 282 "Expected ERROR_MORE_DATA, got (%u)\n", dwRet); 283 284 todo_wine 285 { 286 ok( (0 == strcmp("", buf)) || (0 == strcmp(sTestpath2, buf)), 287 "Expected empty or unexpanded string (win98), got (%s)\n", buf); 288 } 289 290 ok( dwSize >= nUsedBuffer2 || 291 broken(dwSize == (strlen("") + 1)), /* < IE 5.5 */ 292 "Buffer size (%u) should be >= (%u)\n", dwSize, nUsedBuffer2); 293 ok( REG_SZ == dwType , "Expected REG_SZ, got (%u)\n", dwType); 294 295 /* 296 * string grows during expanding 297 * dwSize is larger than the size of the part before the backslash, 298 * but smaller than the expanded string. If the unexpanded string fits 299 * into the buffer, it can get cut when expanded. 300 */ 301 strcpy(buf, sEmptyBuffer); 302 dwSize = nExpLen2 - 4; 303 dwType = -1; 304 dwRet = SHQueryValueExA( hKey, "Test3", NULL, &dwType, buf, &dwSize); 305 ok( ERROR_MORE_DATA == dwRet || 306 broken(ERROR_ENVVAR_NOT_FOUND == dwRet) || /* IE5.5 */ 307 broken(ERROR_SUCCESS == dwRet), /* < IE5.5 */ 308 "Expected ERROR_MORE_DATA, got (%u)\n", dwRet); 309 310 todo_wine 311 { 312 ok( (0 == strcmp("", buf)) || (0 == strcmp(sEnvvar2, buf)) || 313 broken(0 == strcmp(sTestpath2, buf)), /* IE 5.5 */ 314 "Expected empty or first part of the string \"%s\", got \"%s\"\n", sEnvvar2, buf); 315 } 316 317 ok( dwSize >= nUsedBuffer2 || 318 broken(dwSize == (strlen(sEnvvar2) + 1)) || /* IE4.01 SP1 (W98) and IE5 (W98SE) */ 319 broken(dwSize == (strlen("") + 1)), /* IE4.01 (NT4) and IE5.x (W2K) */ 320 "Buffer size (%u) should be >= (%u)\n", dwSize, nUsedBuffer2); 321 ok( REG_SZ == dwType , "Expected REG_SZ, got (%u)\n", dwType); 322 323 /* 324 * The buffer is NULL but the size is set 325 */ 326 strcpy(buf, sEmptyBuffer); 327 dwSize = 6; 328 dwType = -1; 329 dwRet = SHQueryValueExA( hKey, "Test3", NULL, &dwType, NULL, &dwSize); 330 ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%u\n", sTestedFunction, dwRet); 331 ok( dwSize >= nUsedBuffer2 || 332 broken(dwSize == (strlen(sTestpath2) + 1)), /* IE4.01 SP1 (Win98) */ 333 "Buffer size (%u) should be >= (%u)\n", dwSize, nUsedBuffer2); 334 ok( REG_SZ == dwType , "Expected REG_SZ, got (%u)\n", dwType); 335 336 RegCloseKey(hKey); 337 } 338 339 static void test_SHCopyKey(void) 340 { 341 HKEY hKeySrc, hKeyDst; 342 DWORD dwRet; 343 344 if (!pSHCopyKeyA) 345 { 346 win_skip("SHCopyKeyA is not available\n"); 347 return; 348 } 349 350 /* Delete existing destination sub keys */ 351 hKeyDst = NULL; 352 if (!RegOpenKeyA(HKEY_CURRENT_USER, REG_TEST_KEY "\\CopyDestination", &hKeyDst) && hKeyDst) 353 { 354 SHDeleteKeyA(hKeyDst, NULL); 355 RegCloseKey(hKeyDst); 356 } 357 358 hKeyDst = NULL; 359 dwRet = RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_KEY "\\CopyDestination", &hKeyDst); 360 if (dwRet || !hKeyDst) 361 { 362 ok( 0, "Destination couldn't be created, RegCreateKeyA returned (%u)\n", dwRet); 363 return; 364 } 365 366 hKeySrc = NULL; 367 dwRet = RegOpenKeyA(HKEY_LOCAL_MACHINE, REG_CURRENT_VERSION, &hKeySrc); 368 if (dwRet || !hKeySrc) 369 { 370 ok( 0, "Source couldn't be opened, RegOpenKeyA returned (%u)\n", dwRet); 371 RegCloseKey(hKeyDst); 372 return; 373 } 374 375 dwRet = (*pSHCopyKeyA)(hKeySrc, NULL, hKeyDst, 0); 376 ok ( ERROR_SUCCESS == dwRet, "Copy failed, ret=(%u)\n", dwRet); 377 378 RegCloseKey(hKeySrc); 379 RegCloseKey(hKeyDst); 380 381 /* Check we copied the sub keys, i.e. something that's on every windows system (including Wine) */ 382 hKeyDst = NULL; 383 dwRet = RegOpenKeyA(HKEY_CURRENT_USER, REG_TEST_KEY "\\CopyDestination\\Shell Folders", &hKeyDst); 384 if (dwRet || !hKeyDst) 385 { 386 ok ( 0, "Copy couldn't be opened, RegOpenKeyA returned (%u)\n", dwRet); 387 return; 388 } 389 390 /* And the we copied the values too */ 391 ok(!SHQueryValueExA(hKeyDst, "Common AppData", NULL, NULL, NULL, NULL), "SHQueryValueExA failed\n"); 392 393 RegCloseKey(hKeyDst); 394 } 395 396 static void test_SHDeleteKey(void) 397 { 398 HKEY hKeyTest, hKeyS; 399 DWORD dwRet; 400 int sysfail = 1; 401 402 if (!RegOpenKeyA(HKEY_CURRENT_USER, REG_TEST_KEY, &hKeyTest)) 403 { 404 if (!RegCreateKeyA(hKeyTest, "ODBC", &hKeyS)) 405 { 406 HKEY hKeyO; 407 408 if (!RegCreateKeyA(hKeyS, "ODBC.INI", &hKeyO)) 409 { 410 RegCloseKey (hKeyO); 411 412 if (!RegCreateKeyA(hKeyS, "ODBCINST.INI", &hKeyO)) 413 { 414 RegCloseKey (hKeyO); 415 sysfail = 0; 416 } 417 } 418 RegCloseKey (hKeyS); 419 } 420 RegCloseKey (hKeyTest); 421 } 422 423 if (!sysfail) 424 { 425 426 dwRet = SHDeleteKeyA(HKEY_CURRENT_USER, REG_TEST_KEY "\\ODBC"); 427 ok ( ERROR_SUCCESS == dwRet, "SHDeleteKey failed, ret=(%u)\n", dwRet); 428 429 dwRet = RegOpenKeyA(HKEY_CURRENT_USER, REG_TEST_KEY "\\ODBC", &hKeyS); 430 ok ( ERROR_FILE_NOT_FOUND == dwRet, "SHDeleteKey did not delete\n"); 431 432 if (dwRet == ERROR_SUCCESS) 433 RegCloseKey (hKeyS); 434 } 435 else 436 ok( 0, "Could not set up SHDeleteKey test\n"); 437 } 438 439 static void test_SHRegCreateUSKeyW(void) 440 { 441 static const WCHAR subkeyW[] = {'s','u','b','k','e','y',0}; 442 LONG ret; 443 444 if (!pSHRegCreateUSKeyW) 445 { 446 win_skip("SHRegCreateUSKeyW not available\n"); 447 return; 448 } 449 450 ret = pSHRegCreateUSKeyW(subkeyW, KEY_ALL_ACCESS, NULL, NULL, SHREGSET_FORCE_HKCU); 451 ok(ret == ERROR_INVALID_PARAMETER, "got %d\n", ret); 452 } 453 454 static void test_SHRegCloseUSKey(void) 455 { 456 static const WCHAR localW[] = {'S','o','f','t','w','a','r','e',0}; 457 LONG ret; 458 HUSKEY key; 459 460 if (!pSHRegOpenUSKeyW || !pSHRegCloseUSKey) 461 { 462 win_skip("SHRegOpenUSKeyW or SHRegCloseUSKey not available\n"); 463 return; 464 } 465 466 ret = pSHRegCloseUSKey(NULL); 467 ok(ret == ERROR_INVALID_PARAMETER, "got %d\n", ret); 468 469 ret = pSHRegOpenUSKeyW(localW, KEY_ALL_ACCESS, NULL, &key, FALSE); 470 ok(ret == ERROR_SUCCESS, "got %d\n", ret); 471 472 ret = pSHRegCloseUSKey(key); 473 ok(ret == ERROR_SUCCESS, "got %d\n", ret); 474 475 /* Test with limited rights, specially without KEY_SET_VALUE */ 476 ret = pSHRegOpenUSKeyW(localW, KEY_QUERY_VALUE, NULL, &key, FALSE); 477 ok(ret == ERROR_SUCCESS, "got %d\n", ret); 478 479 ret = pSHRegCloseUSKey(key); 480 ok(ret == ERROR_SUCCESS, "got %d\n", ret); 481 } 482 483 START_TEST(shreg) 484 { 485 HKEY hkey = create_test_entries(); 486 487 if (!hkey) return; 488 489 hshlwapi = GetModuleHandleA("shlwapi.dll"); 490 491 /* SHCreateStreamOnFileEx was introduced in shlwapi v6.0 */ 492 if(!GetProcAddress(hshlwapi, "SHCreateStreamOnFileEx")){ 493 win_skip("Too old shlwapi version\n"); 494 return; 495 } 496 497 pSHCopyKeyA = (void*)GetProcAddress(hshlwapi,"SHCopyKeyA"); 498 pSHRegGetPathA = (void*)GetProcAddress(hshlwapi,"SHRegGetPathA"); 499 pSHRegGetValueA = (void*)GetProcAddress(hshlwapi,"SHRegGetValueA"); 500 pSHRegCreateUSKeyW = (void*)GetProcAddress(hshlwapi, "SHRegCreateUSKeyW"); 501 pSHRegOpenUSKeyW = (void*)GetProcAddress(hshlwapi, "SHRegOpenUSKeyW"); 502 pSHRegCloseUSKey = (void*)GetProcAddress(hshlwapi, "SHRegCloseUSKey"); 503 504 test_SHGetValue(); 505 test_SHRegGetValue(); 506 test_SHQueryValueEx(); 507 test_SHGetRegPath(); 508 test_SHCopyKey(); 509 test_SHDeleteKey(); 510 test_SHRegCreateUSKeyW(); 511 test_SHRegCloseUSKey(); 512 513 delete_key( hkey, "Software\\Wine", "Test" ); 514 } 515