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