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 if (url2 != L"") 415 key.SetStringValue(L"url2", url2); 416 } 417 418 static void 419 test_IACLCustomMRU_TypedURLs() // TypedURLs is special case 420 { 421 CStringW url1, url2; // Save values 422 { 423 CRegKey key; 424 key.Open(HKEY_CURRENT_USER, TYPED_URLS_KEY, KEY_READ | KEY_WRITE); 425 426 WCHAR Value[MAX_PATH]; 427 ULONG cch = _countof(Value); 428 LSTATUS Status = key.QueryStringValue(L"url1", Value, &cch); 429 if (!Status) 430 url1 = Value; 431 432 cch = _countof(Value); 433 Status = key.QueryStringValue(L"url2", Value, &cch); 434 if (!Status) 435 url2 = Value; 436 437 // Set values 438 key.SetStringValue(L"url1", L"aaa"); 439 key.SetStringValue(L"url2", L"bbb"); 440 } 441 442 CComPtr<IACLCustomMRU> CustomMRU; 443 HRESULT hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_ALL, 444 IID_PPV_ARG(IACLCustomMRU, &CustomMRU)); 445 ok_hex(hr, S_OK); 446 if (FAILED(hr)) 447 { 448 skip("IACLCustomMRU was NULL\n"); 449 RestoreTypedURLs(url1, url2); 450 return; 451 } 452 453 CComPtr<IACList> ACList; 454 hr = CustomMRU->QueryInterface(IID_PPV_ARG(IACList, &ACList)); 455 ok_hex(hr, S_OK); 456 if (SUCCEEDED(hr)) 457 { 458 hr = ACList->Expand(L"C:"); 459 ok_hex(hr, E_NOTIMPL); 460 hr = ACList->Expand(L"C:\\"); 461 ok_hex(hr, E_NOTIMPL); 462 hr = ACList->Expand(L"C:\\Program Files"); 463 ok_hex(hr, E_NOTIMPL); 464 hr = ACList->Expand(L"C:\\Program Files\\"); 465 ok_hex(hr, E_NOTIMPL); 466 hr = ACList->Expand(L"http://"); 467 ok_hex(hr, E_NOTIMPL); 468 hr = ACList->Expand(L"https://"); 469 ok_hex(hr, E_NOTIMPL); 470 hr = ACList->Expand(L"https://google.co.jp/"); 471 ok_hex(hr, E_NOTIMPL); 472 } 473 474 hr = CustomMRU->Initialize(TYPED_URLS_KEY, 64); 475 ok_hex(hr, S_OK); 476 477 if (ACList) 478 { 479 hr = ACList->Expand(L"C:"); 480 ok_hex(hr, E_NOTIMPL); 481 hr = ACList->Expand(L"C:\\"); 482 ok_hex(hr, E_NOTIMPL); 483 hr = ACList->Expand(L"C:\\Program Files"); 484 ok_hex(hr, E_NOTIMPL); 485 hr = ACList->Expand(L"C:\\Program Files\\"); 486 ok_hex(hr, E_NOTIMPL); 487 hr = ACList->Expand(L"http://"); 488 ok_hex(hr, E_NOTIMPL); 489 hr = ACList->Expand(L"https://"); 490 ok_hex(hr, E_NOTIMPL); 491 hr = ACList->Expand(L"https://google.co.jp/"); 492 ok_hex(hr, E_NOTIMPL); 493 } 494 495 CComPtr<IEnumString> pEnum; 496 hr = CustomMRU->QueryInterface(IID_PPV_ARG(IEnumString, &pEnum)); 497 ok_hex(hr, S_OK); 498 if (FAILED(hr)) 499 { 500 skip("IEnumString was NULL\n"); 501 RestoreTypedURLs(url1, url2); 502 return; 503 } 504 505 CComPtr<IEnumString> pEnumClone; 506 hr = pEnum->Clone(&pEnumClone); 507 ok_hex(hr, E_NOTIMPL); 508 509 hr = pEnum->Skip(1); 510 ok_hex(hr, E_NOTIMPL); 511 512 #define INVALID_LPOLESTR ((LPOLESTR)(LONG_PTR)0xDEADBEEF) 513 LPOLESTR apsz[2] = { NULL, INVALID_LPOLESTR }; 514 ULONG c = 0; 515 hr = pEnum->Next(2, apsz, &c); 516 ok_hex(hr, S_OK); 517 ok_wstri(apsz[0], L"aaa"); 518 ok_int(c, 1); 519 ok(apsz[1] == INVALID_LPOLESTR, "apsz[1] was '%S'\n", apsz[1]); 520 CoTaskMemFree(apsz[0]); 521 522 LPOLESTR psz = INVALID_LPOLESTR; 523 c = 0; 524 hr = pEnum->Next(0, &psz, &c); 525 ok_hex(hr, S_OK); 526 ok(psz == INVALID_LPOLESTR, "psz was '%S'\n", psz); 527 ok_int(c, 0); 528 529 psz = NULL; 530 c = 0; 531 hr = pEnum->Next(1, &psz, &c); 532 ok_hex(hr, S_OK); 533 ok_wstri(psz, L"bbb"); 534 ok_int(c, 1); 535 CoTaskMemFree(psz); 536 537 hr = CustomMRU->AddMRUString(L"https://google.co.jp"); 538 ok_hex(hr, E_FAIL); 539 hr = CustomMRU->AddMRUString(L"C:"); 540 ok_hex(hr, E_FAIL); 541 hr = CustomMRU->AddMRUString(L"C:\\"); 542 ok_hex(hr, E_FAIL); 543 544 RestoreTypedURLs(url1, url2); 545 } 546 547 START_TEST(IACLCustomMRU) 548 { 549 CCoInit init; 550 ok_hex(init.hres, S_OK); 551 if (!SUCCEEDED(init.hres)) 552 return; 553 554 test_IACLCustomMRU_Basics(); 555 test_IACLCustomMRU_UpdateOrder(); 556 test_IACLCustomMRU_ExtraChars(); 557 test_IACLCustomMRU_Continue(); 558 test_IACLCustomMRU_TypedURLs(); 559 560 Cleanup_Testdata(); 561 } 562