1 /* 2 * PROJECT: ReactOS api tests 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: Test for IACLCustomMRU objects 5 * COPYRIGHT: Copyright 2017-2020 Mark Jansen (mark.jansen@reactos.org) 6 */ 7 8 #define _UNICODE 9 #define UNICODE 10 #include <apitest.h> 11 #include <shlobj.h> 12 #include <atlbase.h> 13 #include <atlstr.h> 14 #include <atlcom.h> 15 #include <atlwin.h> 16 17 // Yes, gcc at it again, let's validate everything found inside unused templates! 18 ULONG DbgPrint(PCH Format,...); 19 20 #include <shellutils.h> 21 #include <shlwapi.h> 22 #include <strsafe.h> 23 #include <initguid.h> 24 25 #define ok_hex2(file, line, key, expression, result) \ 26 do { \ 27 int _value = (expression); \ 28 ok_(file, line)(_value == (result), "Wrong value for '%s', expected: " #result " (0x%x), got: 0x%x for %c\n", \ 29 #expression, (int)(result), _value, (char)key); \ 30 } while (0) 31 32 #define ok_wstri(x, y) \ 33 ok(lstrcmpiW(x, y) == 0, "Wrong string. Expected '%S', got '%S'\n", y, x) 34 35 36 DEFINE_GUID(IID_IACLCustomMRU, 0xf729fc5e, 0x8769, 0x4f3e, 0xbd, 0xb2, 0xd7, 0xb5, 0x0f, 0xd2, 0x27, 0x5b); 37 static const WCHAR szTestPath[] = L"TESTPATH_BROWSEUI_APITEST"; 38 39 #undef INTERFACE 40 #define INTERFACE IACLCustomMRU 41 42 /* based on https://msdn.microsoft.com/en-gb/library/windows/desktop/bb776380(v=vs.85).aspx */ 43 DECLARE_INTERFACE_IID_(IACLCustomMRU, IUnknown, "F729FC5E-8769-4F3E-BDB2-D7B50FD2275B") 44 { 45 // *** IUnknown methods *** 46 STDMETHOD(QueryInterface) (THIS_ REFIID riid, void **ppv) PURE; 47 STDMETHOD_(ULONG, AddRef) (THIS)PURE; 48 STDMETHOD_(ULONG, Release) (THIS)PURE; 49 50 // *** IACLCustomMRU methods *** 51 STDMETHOD(Initialize) (THIS_ LPCWSTR pwszMRURegKey, DWORD dwMax) PURE; 52 STDMETHOD(AddMRUString) (THIS_ LPCWSTR pwszEntry) PURE; 53 }; 54 55 56 static void Cleanup_Testdata() 57 { 58 CRegKey tmp; 59 if (!tmp.Open(HKEY_CURRENT_USER, NULL, KEY_READ | KEY_WRITE)) 60 tmp.DeleteSubKey(szTestPath); 61 } 62 63 #define verify_mru(mru, ...) verify_mru_(__FILE__, __LINE__, mru, __VA_ARGS__, NULL) 64 static void verify_mru_(const char* file, int line, IACLCustomMRU* mru, PCWSTR MRUString, ...) 65 { 66 67 CRegKey key; 68 key.Open(HKEY_CURRENT_USER, szTestPath); 69 70 va_list args; 71 va_start(args, MRUString); 72 PCWSTR Entry; 73 WCHAR Key = L'a'; 74 while ((Entry = va_arg(args, PCWSTR))) 75 { 76 WCHAR Value[MAX_PATH]; 77 ULONG nChars = _countof(Value); 78 CStringW tmp; 79 tmp += Key; 80 LSTATUS Status = key.QueryStringValue(tmp, Value, &nChars); 81 ok_hex2(file, line, Key, Status, ERROR_SUCCESS); 82 if (Status == ERROR_SUCCESS) 83 { 84 ok_(file, line)(!wcscmp(Value, Entry), "Expected value %c to be %S, was %S\n", (char)Key, Entry, Value); 85 } 86 Key++; 87 } 88 va_end(args); 89 90 if (Key != L'a') 91 { 92 WCHAR Value[MAX_PATH]; 93 ULONG nChars = _countof(Value); 94 LSTATUS Status = key.QueryStringValue(L"MRUList", Value, &nChars); 95 ok_hex2(file, line, Key, Status, ERROR_SUCCESS); 96 if (Status == ERROR_SUCCESS) 97 { 98 ok_(file, line)(!wcscmp(Value, MRUString), "Expected MRUList to be %S, was %S\n", MRUString, Value); 99 } 100 } 101 } 102 103 104 static void 105 test_IACLCustomMRU_Basics() 106 { 107 CComPtr<IACLCustomMRU> CustomMRU; 108 HRESULT hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU)); 109 ok_hex(hr, S_OK); 110 if (!SUCCEEDED(hr)) 111 return; 112 113 Cleanup_Testdata(); 114 115 /* Initialize with a NULL name will cause an AV */ 116 //hr = CustomMRU->Initialize(NULL, 0); 117 118 hr = CustomMRU->Initialize(szTestPath, 0); 119 ok_hex(hr, S_OK); 120 /* Adding an entry with a dwMax of 0 will cause an AV */ 121 122 /* Calling it again will resize */ 123 hr = CustomMRU->Initialize(szTestPath, 3); 124 ok_hex(hr, S_OK); 125 verify_mru(CustomMRU, L""); 126 127 hr = CustomMRU->AddMRUString(L"FIRST_ENTRY"); 128 ok_hex(hr, S_OK); 129 verify_mru(CustomMRU, L"a", L"FIRST_ENTRY"); 130 131 hr = CustomMRU->AddMRUString(L"SECOND_ENTRY"); 132 ok_hex(hr, S_OK); 133 verify_mru(CustomMRU, L"ba", L"FIRST_ENTRY", L"SECOND_ENTRY"); 134 135 hr = CustomMRU->AddMRUString(L"THIRD_ENTRY"); 136 ok_hex(hr, S_OK); 137 verify_mru(CustomMRU, L"cba", L"FIRST_ENTRY", L"SECOND_ENTRY", L"THIRD_ENTRY"); 138 139 /* First entry is replaced */ 140 hr = CustomMRU->AddMRUString(L"FOURTH_ENTRY"); 141 ok_hex(hr, S_OK); 142 verify_mru(CustomMRU, L"acb", L"FOURTH_ENTRY", L"SECOND_ENTRY", L"THIRD_ENTRY"); 143 144 /* Second entry is replaced */ 145 hr = CustomMRU->AddMRUString(L"FIFTH_ENTRY"); 146 ok_hex(hr, S_OK); 147 verify_mru(CustomMRU, L"bac", L"FOURTH_ENTRY", L"FIFTH_ENTRY", L"THIRD_ENTRY"); 148 } 149 150 151 static void FillDefault(IACLCustomMRU* CustomMRU) 152 { 153 Cleanup_Testdata(); 154 HRESULT hr = CustomMRU->Initialize(szTestPath, 3); 155 ok_hex(hr, S_OK); 156 hr = CustomMRU->AddMRUString(L"FIRST_ENTRY"); 157 ok_hex(hr, S_OK); 158 hr = CustomMRU->AddMRUString(L"SECOND_ENTRY"); 159 ok_hex(hr, S_OK); 160 hr = CustomMRU->AddMRUString(L"THIRD_ENTRY"); 161 ok_hex(hr, S_OK); 162 } 163 164 static void 165 test_IACLCustomMRU_UpdateOrder() 166 { 167 CComPtr<IACLCustomMRU> CustomMRU; 168 HRESULT hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU)); 169 ok_hex(hr, S_OK); 170 if (!SUCCEEDED(hr)) 171 return; 172 173 Cleanup_Testdata(); 174 FillDefault(CustomMRU); 175 verify_mru(CustomMRU, L"cba", L"FIRST_ENTRY", L"SECOND_ENTRY", L"THIRD_ENTRY"); 176 177 /* Add the first entry again */ 178 hr = CustomMRU->AddMRUString(L"FIRST_ENTRY"); 179 ok_hex(hr, S_OK); 180 /* No change */ 181 verify_mru(CustomMRU, L"cba", L"FIRST_ENTRY", L"SECOND_ENTRY", L"THIRD_ENTRY"); 182 183 CustomMRU.Release(); 184 /* Now the order is updated */ 185 verify_mru(NULL, L"acb", L"FIRST_ENTRY", L"SECOND_ENTRY", L"THIRD_ENTRY"); 186 187 188 hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU)); 189 ok_hex(hr, S_OK); 190 if (!SUCCEEDED(hr)) 191 return; 192 193 Cleanup_Testdata(); 194 FillDefault(CustomMRU); 195 verify_mru(CustomMRU, L"cba", L"FIRST_ENTRY", L"SECOND_ENTRY", L"THIRD_ENTRY"); 196 197 198 /* Add the first entry again */ 199 hr = CustomMRU->AddMRUString(L"FIRST_ENTRY"); 200 ok_hex(hr, S_OK); 201 /* No change */ 202 verify_mru(CustomMRU, L"cba", L"FIRST_ENTRY", L"SECOND_ENTRY", L"THIRD_ENTRY"); 203 204 hr = CustomMRU->AddMRUString(L"SOMETHING_ELSE"); 205 ok_hex(hr, S_OK); 206 /* Now all changes are persisted */ 207 verify_mru(CustomMRU, L"bac", L"FIRST_ENTRY", L"SOMETHING_ELSE", L"THIRD_ENTRY"); 208 } 209 210 static void 211 test_IACLCustomMRU_ExtraChars() 212 { 213 CComPtr<IACLCustomMRU> CustomMRU; 214 HRESULT hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU)); 215 ok_hex(hr, S_OK); 216 if (!SUCCEEDED(hr)) 217 return; 218 219 Cleanup_Testdata(); 220 221 /* Still returnes success */ 222 hr = CustomMRU->Initialize(szTestPath, 30); 223 ok_hex(hr, S_OK); 224 225 for (int n = 0; n < 30; ++n) 226 { 227 CStringW tmp; 228 tmp.Format(L"%d", n); 229 230 hr = CustomMRU->AddMRUString(tmp); 231 ok_hex(hr, S_OK); 232 } 233 /* But is starting to wrap around */ 234 verify_mru(CustomMRU, L"a}|{zyxwvutsrqponmlkjihgfedcb", L"29", 235 L"1", L"2", L"3", L"4", L"5", L"6", L"7", L"8", L"9", 236 L"10", L"11", L"12", L"13", L"14", L"15", L"16", L"17", L"18", L"19", 237 L"20", L"21", L"22", L"23", L"24", L"25", L"26", L"27", L"28"); 238 239 Cleanup_Testdata(); 240 } 241 242 static void 243 test_IACLCustomMRU_Continue() 244 { 245 CComPtr<IACLCustomMRU> CustomMRU; 246 HRESULT hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU)); 247 ok_hex(hr, S_OK); 248 if (!SUCCEEDED(hr)) 249 return; 250 251 Cleanup_Testdata(); 252 FillDefault(CustomMRU); 253 verify_mru(CustomMRU, L"cba", L"FIRST_ENTRY", L"SECOND_ENTRY", L"THIRD_ENTRY"); 254 255 CustomMRU.Release(); 256 257 hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU)); 258 ok_hex(hr, S_OK); 259 if (!SUCCEEDED(hr)) 260 return; 261 262 hr = CustomMRU->Initialize(szTestPath, 3); 263 ok_hex(hr, S_OK); 264 265 /* First entry is replaced */ 266 hr = CustomMRU->AddMRUString(L"FOURTH_ENTRY"); 267 ok_hex(hr, S_OK); 268 verify_mru(CustomMRU, L"acb", L"FOURTH_ENTRY", L"SECOND_ENTRY", L"THIRD_ENTRY"); 269 270 CustomMRU.Release(); 271 272 hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU)); 273 ok_hex(hr, S_OK); 274 if (!SUCCEEDED(hr)) 275 return; 276 277 hr = CustomMRU->Initialize(szTestPath, 3); 278 ok_hex(hr, S_OK); 279 280 /* Second entry is replaced */ 281 hr = CustomMRU->AddMRUString(L"FIFTH_ENTRY"); 282 ok_hex(hr, S_OK); 283 verify_mru(CustomMRU, L"bac", L"FOURTH_ENTRY", L"FIFTH_ENTRY", L"THIRD_ENTRY"); 284 285 CustomMRU.Release(); 286 287 hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU)); 288 ok_hex(hr, S_OK); 289 if (!SUCCEEDED(hr)) 290 return; 291 292 293 /* Save some garbage */ 294 CRegKey key; 295 key.Open(HKEY_CURRENT_USER, szTestPath); 296 key.SetStringValue(L"MRUList", L"b**"); 297 key.Close(); 298 299 hr = CustomMRU->Initialize(szTestPath, 3); 300 ok_hex(hr, S_OK); 301 302 CustomMRU.Release(); 303 304 /* Not cleaned up */ 305 verify_mru(CustomMRU, L"b**", L"FOURTH_ENTRY", L"FIFTH_ENTRY", L"THIRD_ENTRY"); 306 307 hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU)); 308 ok_hex(hr, S_OK); 309 if (!SUCCEEDED(hr)) 310 return; 311 312 hr = CustomMRU->Initialize(szTestPath, 3); 313 ok_hex(hr, S_OK); 314 315 /* Now it's just cleaned up */ 316 hr = CustomMRU->AddMRUString(L"SIXTH_ENTRY"); 317 ok_hex(hr, S_OK); 318 verify_mru(CustomMRU, L"ab", L"SIXTH_ENTRY"); 319 320 CustomMRU.Release(); 321 322 hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU)); 323 ok_hex(hr, S_OK); 324 if (!SUCCEEDED(hr)) 325 return; 326 327 Cleanup_Testdata(); 328 FillDefault(CustomMRU); 329 verify_mru(CustomMRU, L"cba", L"FIRST_ENTRY", L"SECOND_ENTRY", L"THIRD_ENTRY"); 330 331 CustomMRU.Release(); 332 333 hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU)); 334 ok_hex(hr, S_OK); 335 if (!SUCCEEDED(hr)) 336 return; 337 338 key.Open(HKEY_CURRENT_USER, szTestPath); 339 key.SetStringValue(L"MRUList", L"baccccc"); 340 key.Close(); 341 342 hr = CustomMRU->Initialize(szTestPath, 3); 343 ok_hex(hr, S_OK); 344 CustomMRU.Release(); 345 346 verify_mru(CustomMRU, L"baccccc", L"FIRST_ENTRY", L"SECOND_ENTRY", L"THIRD_ENTRY"); 347 348 hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU)); 349 ok_hex(hr, S_OK); 350 if (!SUCCEEDED(hr)) 351 return; 352 353 hr = CustomMRU->Initialize(szTestPath, 3); 354 ok_hex(hr, S_OK); 355 356 hr = CustomMRU->AddMRUString(L"FOURTH_ENTRY"); 357 ok_hex(hr, S_OK); 358 verify_mru(CustomMRU, L"a", L"FOURTH_ENTRY", L"SECOND_ENTRY", L"THIRD_ENTRY"); 359 360 CustomMRU.Release(); 361 Cleanup_Testdata(); 362 363 hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU)); 364 ok_hex(hr, S_OK); 365 if (!SUCCEEDED(hr)) 366 return; 367 368 hr = CustomMRU->Initialize(szTestPath, 3); 369 ok_hex(hr, S_OK); 370 if (!SUCCEEDED(hr)) 371 return; 372 373 hr = CustomMRU->AddMRUString(L"FIRST_ENTRY"); 374 ok_hex(hr, S_OK); 375 verify_mru(CustomMRU, L"a", L"FIRST_ENTRY"); 376 377 CustomMRU.Release(); 378 379 key.Open(HKEY_CURRENT_USER, szTestPath); 380 key.SetStringValue(L"MRUList", L"aaa"); 381 key.Close(); 382 383 hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, IID_PPV_ARG(IACLCustomMRU, &CustomMRU)); 384 ok_hex(hr, S_OK); 385 if (!SUCCEEDED(hr)) 386 return; 387 388 hr = CustomMRU->Initialize(szTestPath, 3); 389 ok_hex(hr, S_OK); 390 if (!SUCCEEDED(hr)) 391 return; 392 393 hr = CustomMRU->AddMRUString(L"SECOND_ENTRY"); 394 ok_hex(hr, S_OK); 395 verify_mru(CustomMRU, L"ba", L"FIRST_ENTRY", L"SECOND_ENTRY"); 396 } 397 398 #define TYPED_URLS_KEY L"Software\\Microsoft\\Internet Explorer\\TypedURLs" 399 400 static void 401 RestoreTypedURLs(const CStringW& url1, const CStringW& url2) 402 { 403 CRegKey key; 404 key.Open(HKEY_CURRENT_USER, TYPED_URLS_KEY, KEY_WRITE); 405 if (url1 != L"") 406 key.SetStringValue(L"url1", url1); 407 else 408 key.DeleteValue(L"url1"); 409 if (url2 != L"") 410 key.SetStringValue(L"url2", url2); 411 else 412 key.DeleteValue(L"url2"); 413 } 414 415 static void 416 test_IACLCustomMRU_TypedURLs() // TypedURLs is special case 417 { 418 CStringW url1, url2; // Save values 419 { 420 CRegKey key; 421 key.Create(HKEY_CURRENT_USER, TYPED_URLS_KEY); 422 423 WCHAR Value[MAX_PATH]; 424 ULONG cch = _countof(Value); 425 LSTATUS Status = key.QueryStringValue(L"url1", Value, &cch); 426 if (!Status) 427 url1 = Value; 428 429 cch = _countof(Value); 430 Status = key.QueryStringValue(L"url2", Value, &cch); 431 if (!Status) 432 url2 = Value; 433 434 // Set values 435 key.SetStringValue(L"url1", L"aaa"); 436 key.SetStringValue(L"url2", L"bbb"); 437 } 438 439 CComPtr<IACLCustomMRU> CustomMRU; 440 HRESULT hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, 441 IID_PPV_ARG(IACLCustomMRU, &CustomMRU)); 442 ok_hex(hr, S_OK); 443 if (FAILED(hr)) 444 { 445 skip("IACLCustomMRU was NULL\n"); 446 RestoreTypedURLs(url1, url2); 447 return; 448 } 449 450 CComPtr<IACList> ACList; 451 hr = CustomMRU->QueryInterface(IID_PPV_ARG(IACList, &ACList)); 452 ok_hex(hr, S_OK); 453 if (SUCCEEDED(hr)) 454 { 455 hr = ACList->Expand(L"C:"); 456 ok_hex(hr, E_NOTIMPL); 457 hr = ACList->Expand(L"C:\\"); 458 ok_hex(hr, E_NOTIMPL); 459 hr = ACList->Expand(L"C:\\Program Files"); 460 ok_hex(hr, E_NOTIMPL); 461 hr = ACList->Expand(L"C:\\Program Files\\"); 462 ok_hex(hr, E_NOTIMPL); 463 hr = ACList->Expand(L"http://"); 464 ok_hex(hr, E_NOTIMPL); 465 hr = ACList->Expand(L"https://"); 466 ok_hex(hr, E_NOTIMPL); 467 hr = ACList->Expand(L"https://google.co.jp/"); 468 ok_hex(hr, E_NOTIMPL); 469 } 470 471 hr = CustomMRU->Initialize(TYPED_URLS_KEY, 64); 472 ok_hex(hr, S_OK); 473 474 if (ACList) 475 { 476 hr = ACList->Expand(L"C:"); 477 ok_hex(hr, E_NOTIMPL); 478 hr = ACList->Expand(L"C:\\"); 479 ok_hex(hr, E_NOTIMPL); 480 hr = ACList->Expand(L"C:\\Program Files"); 481 ok_hex(hr, E_NOTIMPL); 482 hr = ACList->Expand(L"C:\\Program Files\\"); 483 ok_hex(hr, E_NOTIMPL); 484 hr = ACList->Expand(L"http://"); 485 ok_hex(hr, E_NOTIMPL); 486 hr = ACList->Expand(L"https://"); 487 ok_hex(hr, E_NOTIMPL); 488 hr = ACList->Expand(L"https://google.co.jp/"); 489 ok_hex(hr, E_NOTIMPL); 490 } 491 492 CComPtr<IEnumString> pEnum; 493 hr = CustomMRU->QueryInterface(IID_PPV_ARG(IEnumString, &pEnum)); 494 ok_hex(hr, S_OK); 495 if (FAILED(hr)) 496 { 497 skip("IEnumString was NULL\n"); 498 RestoreTypedURLs(url1, url2); 499 return; 500 } 501 502 CComPtr<IEnumString> pEnumClone; 503 hr = pEnum->Clone(&pEnumClone); 504 ok_hex(hr, E_NOTIMPL); 505 506 hr = pEnum->Skip(1); 507 ok_hex(hr, E_NOTIMPL); 508 509 #define INVALID_LPOLESTR ((LPOLESTR)(LONG_PTR)0xDEADBEEF) 510 LPOLESTR apsz[2] = { NULL, INVALID_LPOLESTR }; 511 ULONG c = 0; 512 hr = pEnum->Next(2, apsz, &c); 513 ok_hex(hr, S_OK); 514 ok_wstri(apsz[0], L"aaa"); 515 ok_int(c, 1); 516 ok(apsz[1] == INVALID_LPOLESTR, "apsz[1] was '%S'\n", apsz[1]); 517 CoTaskMemFree(apsz[0]); 518 519 LPOLESTR psz = INVALID_LPOLESTR; 520 c = 0; 521 hr = pEnum->Next(0, &psz, &c); 522 ok_hex(hr, S_OK); 523 ok(psz == INVALID_LPOLESTR, "psz was '%S'\n", psz); 524 ok_int(c, 0); 525 526 psz = NULL; 527 c = 0; 528 hr = pEnum->Next(1, &psz, &c); 529 ok_hex(hr, S_OK); 530 ok_wstri(psz, L"bbb"); 531 ok_int(c, 1); 532 CoTaskMemFree(psz); 533 534 hr = CustomMRU->AddMRUString(L"https://google.co.jp"); 535 ok_hex(hr, E_FAIL); 536 hr = CustomMRU->AddMRUString(L"C:"); 537 ok_hex(hr, E_FAIL); 538 hr = CustomMRU->AddMRUString(L"C:\\"); 539 ok_hex(hr, E_FAIL); 540 541 RestoreTypedURLs(url1, url2); 542 } 543 544 START_TEST(IACLCustomMRU) 545 { 546 CCoInit init; 547 ok_hex(init.hr, S_OK); 548 if (!SUCCEEDED(init.hr)) 549 return; 550 551 test_IACLCustomMRU_Basics(); 552 test_IACLCustomMRU_UpdateOrder(); 553 test_IACLCustomMRU_ExtraChars(); 554 test_IACLCustomMRU_Continue(); 555 test_IACLCustomMRU_TypedURLs(); 556 557 Cleanup_Testdata(); 558 } 559