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