1 /* 2 * Copyright 2012 Jacek Caban for CodeWeavers 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 17 */ 18 19 #include <stdarg.h> 20 #include <stdio.h> 21 22 #define COBJMACROS 23 #define CONST_VTABLE 24 25 #include <windef.h> 26 #include <winbase.h> 27 #include <winuser.h> 28 #include <exdisp.h> 29 30 #include <wine/atlbase.h> 31 #include <mshtml.h> 32 33 #include <wine/test.h> 34 35 static const GUID CLSID_Test = 36 {0x178fc163,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x46}}; 37 #define CLSID_TEST_STR "178fc163-0000-0000-0000-000000000046" 38 39 static const GUID CATID_CatTest1 = 40 {0x178fc163,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x46}}; 41 #define CATID_CATTEST1_STR "178fc163-0000-0000-0000-000000000146" 42 43 static const GUID CATID_CatTest2 = 44 {0x178fc163,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x46}}; 45 #define CATID_CATTEST2_STR "178fc163-0000-0000-0000-000000000246" 46 47 static const WCHAR emptyW[] = {'\0'}; 48 static const WCHAR randomW[] = {'r','a','n','d','o','m','\0'}; 49 static const WCHAR progid1W[] = {'S','h','e','l','l','.','E','x','p','l','o','r','e','r','.','2','\0'}; 50 static const WCHAR clsid1W[] = {'{','8','8','5','6','f','9','6','1','-','3','4','0','a','-', 51 '1','1','d','0','-','a','9','6','b','-', 52 '0','0','c','0','4','f','d','7','0','5','a','2','}','\0'}; 53 static const WCHAR url1W[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q', 54 '.','o','r','g','/','t','e','s','t','s','/','w','i','n','e','h','q','_', 55 's','n','a','p','s','h','o','t','/','\0'}; 56 static const WCHAR mshtml1W[] = {'m','s','h','t','m','l',':','<','h','t','m','l','>','<','b','o','d','y','>', 57 't','e','s','t','<','/','b','o','d','y','>','<','/','h','t','m','l','>','\0'}; 58 static const WCHAR mshtml2W[] = {'M','S','H','T','M','L',':','<','h','t','m','l','>','<','b','o','d','y','>', 59 't','e','s','t','<','/','b','o','d','y','>','<','/','h','t','m','l','>','\0'}; 60 static const WCHAR mshtml3W[] = {'<','h','t','m','l','>','<','b','o','d','y','>', 't','e','s','t', 61 '<','/','b','o','d','y','>','<','/','h','t','m','l','>','\0'}; 62 static const WCHAR fileW[] = {'f','i','l','e',':','/','/','/','\0'}; 63 static const WCHAR html_fileW[] = {'t','e','s','t','.','h','t','m','l','\0'}; 64 static const char html_str[] = "<html><body>test</body><html>"; 65 66 static BOOL is_token_admin(HANDLE token) 67 { 68 PSID administrators = NULL; 69 SID_IDENTIFIER_AUTHORITY nt_authority = { SECURITY_NT_AUTHORITY }; 70 DWORD groups_size; 71 PTOKEN_GROUPS groups; 72 DWORD group_index; 73 74 /* Create a well-known SID for the Administrators group. */ 75 if (! AllocateAndInitializeSid(&nt_authority, 2, SECURITY_BUILTIN_DOMAIN_RID, 76 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, 77 &administrators)) 78 return FALSE; 79 80 /* Get the group info from the token */ 81 groups_size = 0; 82 GetTokenInformation(token, TokenGroups, NULL, 0, &groups_size); 83 groups = HeapAlloc(GetProcessHeap(), 0, groups_size); 84 if (groups == NULL) 85 { 86 FreeSid(administrators); 87 return FALSE; 88 } 89 if (! GetTokenInformation(token, TokenGroups, groups, groups_size, &groups_size)) 90 { 91 HeapFree(GetProcessHeap(), 0, groups); 92 FreeSid(administrators); 93 return FALSE; 94 } 95 96 /* Now check if the token groups include the Administrators group */ 97 for (group_index = 0; group_index < groups->GroupCount; group_index++) 98 { 99 if (EqualSid(groups->Groups[group_index].Sid, administrators)) 100 { 101 HeapFree(GetProcessHeap(), 0, groups); 102 FreeSid(administrators); 103 return TRUE; 104 } 105 } 106 107 /* If we end up here we didn't find the Administrators group */ 108 HeapFree(GetProcessHeap(), 0, groups); 109 FreeSid(administrators); 110 return FALSE; 111 } 112 113 static BOOL is_process_limited(void) 114 { 115 static BOOL (WINAPI *pOpenProcessToken)(HANDLE, DWORD, PHANDLE) = NULL; 116 HANDLE token; 117 BOOL result=FALSE; 118 119 if (!pOpenProcessToken) 120 { 121 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll"); 122 pOpenProcessToken = (void*)GetProcAddress(hadvapi32, "OpenProcessToken"); 123 if (!pOpenProcessToken) 124 return FALSE; 125 } 126 127 if (pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) 128 { 129 BOOL ret; 130 TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault; 131 DWORD size; 132 133 ret = GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size); 134 if (ret) 135 { 136 if (type == TokenElevationTypeDefault) 137 /* UAC is disabled, check for administrators group */ 138 result = !is_token_admin(token); 139 else if (type == TokenElevationTypeFull) 140 result = FALSE; 141 else if (type == TokenElevationTypeLimited) 142 result = TRUE; 143 } 144 CloseHandle(token); 145 } 146 return result; 147 } 148 149 static void test_winmodule(void) 150 { 151 _AtlCreateWndData create_data[3]; 152 _ATL_WIN_MODULE winmod; 153 void *p; 154 HRESULT hres; 155 156 winmod.cbSize = 0xdeadbeef; 157 hres = AtlWinModuleInit(&winmod); 158 ok(hres == E_INVALIDARG, "AtlWinModuleInit failed: %08x\n", hres); 159 160 winmod.cbSize = sizeof(winmod); 161 winmod.m_pCreateWndList = (void*)0xdeadbeef; 162 winmod.m_csWindowCreate.LockCount = 0xdeadbeef; 163 winmod.m_rgWindowClassAtoms.m_aT = (void*)0xdeadbeef; 164 winmod.m_rgWindowClassAtoms.m_nSize = 0xdeadbeef; 165 winmod.m_rgWindowClassAtoms.m_nAllocSize = 0xdeadbeef; 166 hres = AtlWinModuleInit(&winmod); 167 ok(hres == S_OK, "AtlWinModuleInit failed: %08x\n", hres); 168 ok(!winmod.m_pCreateWndList, "winmod.m_pCreateWndList = %p\n", winmod.m_pCreateWndList); 169 ok(winmod.m_csWindowCreate.LockCount == -1, "winmod.m_csWindowCreate.LockCount = %d\n", 170 winmod.m_csWindowCreate.LockCount); 171 ok(winmod.m_rgWindowClassAtoms.m_aT == (void*)0xdeadbeef, "winmod.m_rgWindowClassAtoms.m_aT = %p\n", 172 winmod.m_rgWindowClassAtoms.m_aT); 173 ok(winmod.m_rgWindowClassAtoms.m_nSize == 0xdeadbeef, "winmod.m_rgWindowClassAtoms.m_nSize = %d\n", 174 winmod.m_rgWindowClassAtoms.m_nSize); 175 ok(winmod.m_rgWindowClassAtoms.m_nAllocSize == 0xdeadbeef, "winmod.m_rgWindowClassAtoms.m_nAllocSize = %d\n", 176 winmod.m_rgWindowClassAtoms.m_nAllocSize); 177 178 InitializeCriticalSection(&winmod.m_csWindowCreate); 179 180 AtlWinModuleAddCreateWndData(&winmod, create_data, (void*)0xdead0001); 181 ok(winmod.m_pCreateWndList == create_data, "winmod.m_pCreateWndList != create_data\n"); 182 ok(create_data[0].m_pThis == (void*)0xdead0001, "unexpected create_data[0].m_pThis %p\n", create_data[0].m_pThis); 183 ok(create_data[0].m_dwThreadID == GetCurrentThreadId(), "unexpected create_data[0].m_dwThreadID %x\n", 184 create_data[0].m_dwThreadID); 185 ok(!create_data[0].m_pNext, "unexpected create_data[0].m_pNext %p\n", create_data[0].m_pNext); 186 187 AtlWinModuleAddCreateWndData(&winmod, create_data+1, (void*)0xdead0002); 188 ok(winmod.m_pCreateWndList == create_data+1, "winmod.m_pCreateWndList != create_data\n"); 189 ok(create_data[1].m_pThis == (void*)0xdead0002, "unexpected create_data[1].m_pThis %p\n", create_data[1].m_pThis); 190 ok(create_data[1].m_dwThreadID == GetCurrentThreadId(), "unexpected create_data[1].m_dwThreadID %x\n", 191 create_data[1].m_dwThreadID); 192 ok(create_data[1].m_pNext == create_data, "unexpected create_data[1].m_pNext %p\n", create_data[1].m_pNext); 193 194 AtlWinModuleAddCreateWndData(&winmod, create_data+2, (void*)0xdead0003); 195 ok(winmod.m_pCreateWndList == create_data+2, "winmod.m_pCreateWndList != create_data\n"); 196 ok(create_data[2].m_pThis == (void*)0xdead0003, "unexpected create_data[2].m_pThis %p\n", create_data[2].m_pThis); 197 ok(create_data[2].m_dwThreadID == GetCurrentThreadId(), "unexpected create_data[2].m_dwThreadID %x\n", 198 create_data[2].m_dwThreadID); 199 ok(create_data[2].m_pNext == create_data+1, "unexpected create_data[2].m_pNext %p\n", create_data[2].m_pNext); 200 201 p = AtlWinModuleExtractCreateWndData(&winmod); 202 ok(p == (void*)0xdead0003, "unexpected AtlWinModuleExtractCreateWndData result %p\n", p); 203 ok(winmod.m_pCreateWndList == create_data+1, "winmod.m_pCreateWndList != create_data\n"); 204 ok(create_data[2].m_pNext == create_data+1, "unexpected create_data[2].m_pNext %p\n", create_data[2].m_pNext); 205 206 create_data[1].m_dwThreadID = 0xdeadbeef; 207 208 p = AtlWinModuleExtractCreateWndData(&winmod); 209 ok(p == (void*)0xdead0001, "unexpected AtlWinModuleExtractCreateWndData result %p\n", p); 210 ok(winmod.m_pCreateWndList == create_data+1, "winmod.m_pCreateWndList != create_data\n"); 211 ok(!create_data[0].m_pNext, "unexpected create_data[0].m_pNext %p\n", create_data[0].m_pNext); 212 ok(!create_data[1].m_pNext, "unexpected create_data[1].m_pNext %p\n", create_data[1].m_pNext); 213 214 p = AtlWinModuleExtractCreateWndData(&winmod); 215 ok(!p, "unexpected AtlWinModuleExtractCreateWndData result %p\n", p); 216 ok(winmod.m_pCreateWndList == create_data+1, "winmod.m_pCreateWndList != create_data\n"); 217 } 218 219 #define test_key_exists(a,b) _test_key_exists(__LINE__,a,b) 220 static void _test_key_exists(unsigned line, HKEY root, const char *key_name) 221 { 222 HKEY key; 223 DWORD res; 224 225 res = RegOpenKeyA(root, key_name, &key); 226 ok_(__FILE__,line)(res == ERROR_SUCCESS, "Could not open key %s\n", key_name); 227 if(res == ERROR_SUCCESS) 228 RegCloseKey(key); 229 } 230 231 #define test_key_not_exists(a,b) _test_key_not_exists(__LINE__,a,b) 232 static void _test_key_not_exists(unsigned line, HKEY root, const char *key_name) 233 { 234 HKEY key; 235 DWORD res; 236 237 res = RegOpenKeyA(root, key_name, &key); 238 ok_(__FILE__,line)(res == ERROR_FILE_NOT_FOUND, "Attempting to open %s returned %u\n", key_name, res); 239 if(res == ERROR_SUCCESS) 240 RegCloseKey(key); 241 } 242 243 static void test_regcat(void) 244 { 245 unsigned char b; 246 HRESULT hres; 247 248 const struct _ATL_CATMAP_ENTRY catmap[] = { 249 {_ATL_CATMAP_ENTRY_IMPLEMENTED, &CATID_CatTest1}, 250 {_ATL_CATMAP_ENTRY_REQUIRED, &CATID_CatTest2}, 251 {_ATL_CATMAP_ENTRY_END} 252 }; 253 254 if (is_process_limited()) 255 { 256 skip("process is limited\n"); 257 return; 258 } 259 260 hres = AtlRegisterClassCategoriesHelper(&CLSID_Test, catmap, TRUE); 261 ok(hres == S_OK, "AtlRegisterClassCategoriesHelper failed: %08x\n", hres); 262 263 test_key_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}"); 264 test_key_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}\\Implemented Categories\\{" CATID_CATTEST1_STR "}"); 265 test_key_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}\\Required Categories\\{" CATID_CATTEST2_STR "}"); 266 267 hres = AtlRegisterClassCategoriesHelper(&CLSID_Test, catmap, FALSE); 268 ok(hres == S_OK, "AtlRegisterClassCategoriesHelper failed: %08x\n", hres); 269 270 test_key_not_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}\\Implemented Categories"); 271 test_key_not_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}\\Required Categories"); 272 test_key_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}"); 273 274 ok(RegDeleteKeyA(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}") == ERROR_SUCCESS, "Could not delete key\n"); 275 276 hres = AtlRegisterClassCategoriesHelper(&CLSID_Test, NULL, TRUE); 277 ok(hres == S_OK, "AtlRegisterClassCategoriesHelper failed: %08x\n", hres); 278 279 test_key_not_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}"); 280 281 b = 10; 282 hres = AtlGetPerUserRegistration(&b); 283 ok(hres == S_OK, "AtlGetPerUserRegistration failed: %08x\n", hres); 284 ok(!b, "AtlGetPerUserRegistration returned %x\n", b); 285 } 286 287 static void test_typelib(void) 288 { 289 ITypeLib *typelib; 290 HINSTANCE inst; 291 size_t len; 292 BSTR path; 293 HRESULT hres; 294 295 static const WCHAR scrrun_dll_suffixW[] = {'\\','s','c','r','r','u','n','.','d','l','l',0}; 296 static const WCHAR mshtml_tlb_suffixW[] = {'\\','m','s','h','t','m','l','.','t','l','b',0}; 297 298 inst = LoadLibraryA("scrrun.dll"); 299 ok(inst != NULL, "Could not load scrrun.dll\n"); 300 301 typelib = NULL; 302 hres = AtlLoadTypeLib(inst, NULL, &path, &typelib); 303 ok(hres == S_OK, "AtlLoadTypeLib failed: %08x\n", hres); 304 FreeLibrary(inst); 305 306 len = SysStringLen(path); 307 ok(len > sizeof(scrrun_dll_suffixW)/sizeof(WCHAR) 308 && lstrcmpiW(path+len-sizeof(scrrun_dll_suffixW)/sizeof(WCHAR), scrrun_dll_suffixW), 309 "unexpected path %s\n", wine_dbgstr_w(path)); 310 SysFreeString(path); 311 ok(typelib != NULL, "typelib == NULL\n"); 312 ITypeLib_Release(typelib); 313 314 inst = LoadLibraryA("mshtml.dll"); 315 ok(inst != NULL, "Could not load mshtml.dll\n"); 316 317 typelib = NULL; 318 hres = AtlLoadTypeLib(inst, NULL, &path, &typelib); 319 ok(hres == S_OK, "AtlLoadTypeLib failed: %08x\n", hres); 320 FreeLibrary(inst); 321 322 len = SysStringLen(path); 323 ok(len > sizeof(mshtml_tlb_suffixW)/sizeof(WCHAR) 324 && lstrcmpiW(path+len-sizeof(mshtml_tlb_suffixW)/sizeof(WCHAR), mshtml_tlb_suffixW), 325 "unexpected path %s\n", wine_dbgstr_w(path)); 326 SysFreeString(path); 327 ok(typelib != NULL, "typelib == NULL\n"); 328 ITypeLib_Release(typelib); 329 } 330 331 static HRESULT WINAPI ConnectionPoint_QueryInterface(IConnectionPoint *iface, REFIID riid, void **ppv) 332 { 333 if(IsEqualGUID(&IID_IConnectionPoint, riid)) { 334 *ppv = iface; 335 return S_OK; 336 } 337 338 ok(0, "unexpected call\n"); 339 return E_NOINTERFACE; 340 } 341 342 static ULONG WINAPI ConnectionPoint_AddRef(IConnectionPoint *iface) 343 { 344 return 2; 345 } 346 347 static ULONG WINAPI ConnectionPoint_Release(IConnectionPoint *iface) 348 { 349 return 1; 350 } 351 352 static HRESULT WINAPI ConnectionPoint_GetConnectionInterface(IConnectionPoint *iface, IID *pIID) 353 { 354 ok(0, "unexpected call\n"); 355 return E_NOTIMPL; 356 } 357 358 static HRESULT WINAPI ConnectionPoint_GetConnectionPointContainer(IConnectionPoint *iface, 359 IConnectionPointContainer **ppCPC) 360 { 361 ok(0, "unexpected call\n"); 362 return E_NOTIMPL; 363 } 364 365 static int advise_cnt; 366 367 static HRESULT WINAPI ConnectionPoint_Advise(IConnectionPoint *iface, IUnknown *pUnkSink, 368 DWORD *pdwCookie) 369 { 370 ok(pUnkSink == (IUnknown*)0xdead0000, "pUnkSink = %p\n", pUnkSink); 371 *pdwCookie = 0xdeadbeef; 372 advise_cnt++; 373 return S_OK; 374 } 375 376 static HRESULT WINAPI ConnectionPoint_Unadvise(IConnectionPoint *iface, DWORD dwCookie) 377 { 378 ok(dwCookie == 0xdeadbeef, "dwCookie = %x\n", dwCookie); 379 advise_cnt--; 380 return S_OK; 381 } 382 383 static HRESULT WINAPI ConnectionPoint_EnumConnections(IConnectionPoint *iface, 384 IEnumConnections **ppEnum) 385 { 386 ok(0, "unexpected call\n"); 387 return E_NOTIMPL; 388 } 389 390 static const IConnectionPointVtbl ConnectionPointVtbl = 391 { 392 ConnectionPoint_QueryInterface, 393 ConnectionPoint_AddRef, 394 ConnectionPoint_Release, 395 ConnectionPoint_GetConnectionInterface, 396 ConnectionPoint_GetConnectionPointContainer, 397 ConnectionPoint_Advise, 398 ConnectionPoint_Unadvise, 399 ConnectionPoint_EnumConnections 400 }; 401 402 static IConnectionPoint ConnectionPoint = { &ConnectionPointVtbl }; 403 404 static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface, 405 REFIID riid, void **ppv) 406 { 407 if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) { 408 *ppv = iface; 409 return S_OK; 410 } 411 412 ok(0, "unexpected call\n"); 413 return E_NOTIMPL; 414 } 415 416 static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface) 417 { 418 return 2; 419 } 420 421 static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface) 422 { 423 return 1; 424 } 425 426 static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface, 427 IEnumConnectionPoints **ppEnum) 428 { 429 ok(0, "unexpected call\n"); 430 return E_NOTIMPL; 431 } 432 433 static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface, 434 REFIID riid, IConnectionPoint **ppCP) 435 { 436 ok(IsEqualGUID(riid, &CLSID_Test), "unexpected riid\n"); 437 *ppCP = &ConnectionPoint; 438 return S_OK; 439 } 440 441 static const IConnectionPointContainerVtbl ConnectionPointContainerVtbl = { 442 ConnectionPointContainer_QueryInterface, 443 ConnectionPointContainer_AddRef, 444 ConnectionPointContainer_Release, 445 ConnectionPointContainer_EnumConnectionPoints, 446 ConnectionPointContainer_FindConnectionPoint 447 }; 448 449 static IConnectionPointContainer ConnectionPointContainer = { &ConnectionPointContainerVtbl }; 450 451 static void test_cp(void) 452 { 453 DWORD cookie = 0; 454 HRESULT hres; 455 456 hres = AtlAdvise(NULL, (IUnknown*)0xdeed0000, &CLSID_Test, &cookie); 457 ok(hres == E_INVALIDARG, "expect E_INVALIDARG, returned %08x\n", hres); 458 459 hres = AtlUnadvise(NULL, &CLSID_Test, 0xdeadbeef); 460 ok(hres == E_INVALIDARG, "expect E_INVALIDARG, returned %08x\n", hres); 461 462 hres = AtlAdvise((IUnknown*)&ConnectionPointContainer, (IUnknown*)0xdead0000, &CLSID_Test, &cookie); 463 ok(hres == S_OK, "AtlAdvise failed: %08x\n", hres); 464 ok(cookie == 0xdeadbeef, "cookie = %x\n", cookie); 465 ok(advise_cnt == 1, "advise_cnt = %d\n", advise_cnt); 466 467 hres = AtlUnadvise((IUnknown*)&ConnectionPointContainer, &CLSID_Test, 0xdeadbeef); 468 ok(hres == S_OK, "AtlUnadvise failed: %08x\n", hres); 469 ok(!advise_cnt, "advise_cnt = %d\n", advise_cnt); 470 } 471 472 static CLSID persist_clsid; 473 474 static HRESULT WINAPI Persist_QueryInterface(IPersist *iface, REFIID riid, void **ppv) 475 { 476 ok(0, "unexpected call\n"); 477 return E_NOINTERFACE; 478 } 479 480 static ULONG WINAPI Persist_AddRef(IPersist *iface) 481 { 482 return 2; 483 } 484 485 static ULONG WINAPI Persist_Release(IPersist *iface) 486 { 487 return 1; 488 } 489 490 static HRESULT WINAPI Persist_GetClassID(IPersist *iface, CLSID *pClassID) 491 { 492 *pClassID = persist_clsid; 493 return S_OK; 494 } 495 496 static const IPersistVtbl PersistVtbl = { 497 Persist_QueryInterface, 498 Persist_AddRef, 499 Persist_Release, 500 Persist_GetClassID 501 }; 502 503 static IPersist Persist = { &PersistVtbl }; 504 505 static HRESULT WINAPI ProvideClassInfo2_QueryInterface(IProvideClassInfo2 *iface, REFIID riid, void **ppv) 506 { 507 ok(0, "unexpected call\n"); 508 return E_NOINTERFACE; 509 } 510 511 static ULONG WINAPI ProvideClassInfo2_AddRef(IProvideClassInfo2 *iface) 512 { 513 return 2; 514 } 515 516 static ULONG WINAPI ProvideClassInfo2_Release(IProvideClassInfo2 *iface) 517 { 518 return 1; 519 } 520 521 static HRESULT WINAPI ProvideClassInfo2_GetClassInfo(IProvideClassInfo2 *iface, ITypeInfo **ppTI) 522 { 523 ok(0, "unexpected call\n"); 524 return E_NOTIMPL; 525 } 526 527 static HRESULT WINAPI ProvideClassInfo2_GetGUID(IProvideClassInfo2 *iface, DWORD dwGuidKind, GUID *pGUID) 528 { 529 ok(dwGuidKind == GUIDKIND_DEFAULT_SOURCE_DISP_IID, "unexpected dwGuidKind %x\n", dwGuidKind); 530 *pGUID = DIID_DispHTMLBody; 531 return S_OK; 532 } 533 534 static const IProvideClassInfo2Vtbl ProvideClassInfo2Vtbl = { 535 ProvideClassInfo2_QueryInterface, 536 ProvideClassInfo2_AddRef, 537 ProvideClassInfo2_Release, 538 ProvideClassInfo2_GetClassInfo, 539 ProvideClassInfo2_GetGUID 540 }; 541 542 static IProvideClassInfo2 ProvideClassInfo2 = { &ProvideClassInfo2Vtbl }; 543 static BOOL support_classinfo2; 544 545 static HRESULT WINAPI Dispatch_QueryInterface(IDispatch *iface, REFIID riid, void **ppv) 546 { 547 *ppv = NULL; 548 549 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IDispatch, riid)) { 550 *ppv = iface; 551 return S_OK; 552 } 553 554 if(IsEqualGUID(&IID_IProvideClassInfo2, riid)) { 555 if(!support_classinfo2) 556 return E_NOINTERFACE; 557 *ppv = &ProvideClassInfo2; 558 return S_OK; 559 } 560 561 if(IsEqualGUID(&IID_IPersist, riid)) { 562 *ppv = &Persist; 563 return S_OK; 564 } 565 566 ok(0, "unexpected riid: %s\n", wine_dbgstr_guid(riid)); 567 return E_NOINTERFACE; 568 } 569 570 static ULONG WINAPI Dispatch_AddRef(IDispatch *iface) 571 { 572 return 2; 573 } 574 575 static ULONG WINAPI Dispatch_Release(IDispatch *iface) 576 { 577 return 1; 578 } 579 580 static HRESULT WINAPI Dispatch_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo) 581 { 582 ok(0, "unexpected call\n"); 583 return E_NOTIMPL; 584 } 585 586 static HRESULT WINAPI Dispatch_GetTypeInfo(IDispatch *iface, UINT iTInfo, LCID lcid, 587 ITypeInfo **ppTInfo) 588 { 589 ITypeLib *typelib; 590 HRESULT hres; 591 592 static const WCHAR mshtml_tlbW[] = {'m','s','h','t','m','l','.','t','l','b',0}; 593 594 ok(!iTInfo, "iTInfo = %d\n", iTInfo); 595 ok(!lcid, "lcid = %x\n", lcid); 596 597 hres = LoadTypeLib(mshtml_tlbW, &typelib); 598 ok(hres == S_OK, "LoadTypeLib failed: %08x\n", hres); 599 600 hres = ITypeLib_GetTypeInfoOfGuid(typelib, &IID_IHTMLElement, ppTInfo); 601 ok(hres == S_OK, "GetTypeInfoOfGuid failed: %08x\n", hres); 602 603 ITypeLib_Release(typelib); 604 return S_OK; 605 } 606 607 static HRESULT WINAPI Dispatch_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *rgszNames, 608 UINT cNames, LCID lcid, DISPID *rgDispId) 609 { 610 ok(0, "unexpected call\n"); 611 return E_NOTIMPL; 612 } 613 614 static HRESULT WINAPI Dispatch_Invoke(IDispatch *iface, DISPID dispIdMember, REFIID riid, 615 LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, 616 EXCEPINFO *pExcepInfo, UINT *puArgErr) 617 { 618 ok(0, "unexpected call\n"); 619 return E_NOTIMPL; 620 } 621 622 static const IDispatchVtbl DispatchVtbl = { 623 Dispatch_QueryInterface, 624 Dispatch_AddRef, 625 Dispatch_Release, 626 Dispatch_GetTypeInfoCount, 627 Dispatch_GetTypeInfo, 628 Dispatch_GetIDsOfNames, 629 Dispatch_Invoke 630 }; 631 632 static IDispatch Dispatch = { &DispatchVtbl }; 633 634 static void test_source_iface(void) 635 { 636 unsigned short maj_ver, min_ver; 637 IID libid, iid; 638 HRESULT hres; 639 640 support_classinfo2 = TRUE; 641 642 maj_ver = min_ver = 0xdead; 643 hres = AtlGetObjectSourceInterface((IUnknown*)&Dispatch, &libid, &iid, &maj_ver, &min_ver); 644 ok(hres == S_OK, "AtlGetObjectSourceInterface failed: %08x\n", hres); 645 ok(IsEqualGUID(&libid, &LIBID_MSHTML), "libid = %s\n", wine_dbgstr_guid(&libid)); 646 ok(IsEqualGUID(&iid, &DIID_DispHTMLBody), "iid = %s\n", wine_dbgstr_guid(&iid)); 647 ok(maj_ver == 4 && min_ver == 0, "ver = %d.%d\n", maj_ver, min_ver); 648 649 support_classinfo2 = FALSE; 650 persist_clsid = CLSID_HTMLDocument; 651 652 maj_ver = min_ver = 0xdead; 653 hres = AtlGetObjectSourceInterface((IUnknown*)&Dispatch, &libid, &iid, &maj_ver, &min_ver); 654 ok(hres == S_OK, "AtlGetObjectSourceInterface failed: %08x\n", hres); 655 ok(IsEqualGUID(&libid, &LIBID_MSHTML), "libid = %s\n", wine_dbgstr_guid(&libid)); 656 ok(IsEqualGUID(&iid, &DIID_HTMLDocumentEvents), "iid = %s\n", wine_dbgstr_guid(&iid)); 657 ok(maj_ver == 4 && min_ver == 0, "ver = %d.%d\n", maj_ver, min_ver); 658 659 persist_clsid = CLSID_HTMLStyle; 660 661 maj_ver = min_ver = 0xdead; 662 hres = AtlGetObjectSourceInterface((IUnknown*)&Dispatch, &libid, &iid, &maj_ver, &min_ver); 663 ok(hres == S_OK, "AtlGetObjectSourceInterface failed: %08x\n", hres); 664 ok(IsEqualGUID(&libid, &LIBID_MSHTML), "libid = %s\n", wine_dbgstr_guid(&libid)); 665 ok(IsEqualGUID(&iid, &IID_NULL), "iid = %s\n", wine_dbgstr_guid(&iid)); 666 ok(maj_ver == 4 && min_ver == 0, "ver = %d.%d\n", maj_ver, min_ver); 667 } 668 669 static void test_ax_win(void) 670 { 671 DWORD ret, ret_size, i; 672 HRESULT res; 673 HWND hwnd; 674 HANDLE hfile; 675 IUnknown *control; 676 WNDPROC wndproc[2] = {NULL, NULL}; 677 WCHAR file_uri1W[MAX_PATH], pathW[MAX_PATH]; 678 WNDCLASSEXW wcex; 679 static HMODULE hinstance = 0; 680 static const WCHAR cls_names[][16] = 681 { 682 {'A','t','l','A','x','W','i','n','1','0','0',0}, 683 {'A','t','l','A','x','W','i','n','L','i','c','1','0','0',0} 684 }; 685 686 ret = AtlAxWinInit(); 687 ok(ret, "AtlAxWinInit failed\n"); 688 689 hinstance = GetModuleHandleA(NULL); 690 691 for (i = 0; i < 2; i++) 692 { 693 memset(&wcex, 0, sizeof(wcex)); 694 wcex.cbSize = sizeof(wcex); 695 ret = GetClassInfoExW(hinstance, cls_names[i], &wcex); 696 ok(ret, "%s has not registered\n", wine_dbgstr_w(cls_names[i])); 697 ok(wcex.style == (CS_GLOBALCLASS | CS_DBLCLKS), "wcex.style %08x\n", wcex.style); 698 wndproc[i] = wcex.lpfnWndProc; 699 700 hwnd = CreateWindowW(cls_names[i], NULL, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL); 701 ok(hwnd != NULL, "CreateWindow failed!\n"); 702 control = (IUnknown *)0xdeadbeef; 703 res = AtlAxGetControl(hwnd, &control); 704 ok(res == E_FAIL, "Expected E_FAIL, returned %08x\n", res); 705 ok(!control, "returned %p\n", control); 706 if (control) IUnknown_Release(control); 707 DestroyWindow(hwnd); 708 709 hwnd = CreateWindowW(cls_names[i], emptyW, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL); 710 ok(hwnd != NULL, "CreateWindow failed!\n"); 711 control = (IUnknown *)0xdeadbeef; 712 res = AtlAxGetControl(hwnd, &control); 713 ok(res == E_FAIL, "Expected E_FAIL, returned %08x\n", res); 714 ok(!control, "returned %p\n", control); 715 if (control) IUnknown_Release(control); 716 DestroyWindow(hwnd); 717 718 hwnd = CreateWindowW(cls_names[i], randomW, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL); 719 todo_wine ok(!hwnd, "returned %p\n", hwnd); 720 if(hwnd) DestroyWindow(hwnd); 721 722 hwnd = CreateWindowW(cls_names[i], progid1W, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL); 723 ok(hwnd != NULL, "CreateWindow failed!\n"); 724 control = NULL; 725 res = AtlAxGetControl(hwnd, &control); 726 ok(res == S_OK, "AtlAxGetControl failed with res %08x\n", res); 727 ok(control != NULL, "AtlAxGetControl failed!\n"); 728 IUnknown_Release(control); 729 DestroyWindow(hwnd); 730 731 hwnd = CreateWindowW(cls_names[i], clsid1W, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL); 732 ok(hwnd != NULL, "CreateWindow failed!\n"); 733 control = NULL; 734 res = AtlAxGetControl(hwnd, &control); 735 ok(res == S_OK, "AtlAxGetControl failed with res %08x\n", res); 736 ok(control != NULL, "AtlAxGetControl failed!\n"); 737 IUnknown_Release(control); 738 DestroyWindow(hwnd); 739 740 hwnd = CreateWindowW(cls_names[i], url1W, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL); 741 ok(hwnd != NULL, "CreateWindow failed!\n"); 742 control = NULL; 743 res = AtlAxGetControl(hwnd, &control); 744 ok(res == S_OK, "AtlAxGetControl failed with res %08x\n", res); 745 ok(control != NULL, "AtlAxGetControl failed!\n"); 746 IUnknown_Release(control); 747 DestroyWindow(hwnd); 748 749 /* test html stream with "MSHTML:" prefix */ 750 hwnd = CreateWindowW(cls_names[i], mshtml1W, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL); 751 ok(hwnd != NULL, "CreateWindow failed!\n"); 752 control = NULL; 753 res = AtlAxGetControl(hwnd, &control); 754 ok(res == S_OK, "AtlAxGetControl failed with res %08x\n", res); 755 ok(control != NULL, "AtlAxGetControl failed!\n"); 756 IUnknown_Release(control); 757 DestroyWindow(hwnd); 758 759 hwnd = CreateWindowW(cls_names[i], mshtml2W, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL); 760 ok(hwnd != NULL, "CreateWindow failed!\n"); 761 control = NULL; 762 res = AtlAxGetControl(hwnd, &control); 763 ok(res == S_OK, "AtlAxGetControl failed with res %08x\n", res); 764 ok(control != NULL, "AtlAxGetControl failed!\n"); 765 IUnknown_Release(control); 766 DestroyWindow(hwnd); 767 768 /* test html stream without "MSHTML:" prefix */ 769 hwnd = CreateWindowW(cls_names[i], mshtml3W, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL); 770 todo_wine ok(!hwnd, "returned %p\n", hwnd); 771 if(hwnd) DestroyWindow(hwnd); 772 773 ret = GetTempPathW(MAX_PATH, pathW); 774 ok(ret, "GetTempPath failed!\n"); 775 lstrcatW(pathW, html_fileW); 776 hfile = CreateFileW(pathW, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, 0); 777 ok(hfile != INVALID_HANDLE_VALUE, "failed to create file\n"); 778 ret = WriteFile(hfile, html_str, sizeof(html_str), &ret_size, NULL); 779 ok(ret, "WriteFile failed\n"); 780 CloseHandle(hfile); 781 782 /* test C:// scheme */ 783 hwnd = CreateWindowW(cls_names[i], pathW, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL); 784 ok(hwnd != NULL, "CreateWindow failed!\n"); 785 control = NULL; 786 res = AtlAxGetControl(hwnd, &control); 787 ok(res == S_OK, "AtlAxGetControl failed with res %08x\n", res); 788 ok(control != NULL, "AtlAxGetControl failed!\n"); 789 IUnknown_Release(control); 790 DestroyWindow(hwnd); 791 792 /* test file:// scheme */ 793 lstrcpyW(file_uri1W, fileW); 794 lstrcatW(file_uri1W, pathW); 795 hwnd = CreateWindowW(cls_names[i], file_uri1W, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL); 796 ok(hwnd != NULL, "CreateWindow failed!\n"); 797 control = NULL; 798 res = AtlAxGetControl(hwnd, &control); 799 ok(res == S_OK, "AtlAxGetControl failed with res %08x\n", res); 800 ok(control != NULL, "AtlAxGetControl failed!\n"); 801 IUnknown_Release(control); 802 DestroyWindow(hwnd); 803 804 /* test file:// scheme on non-existent file */ 805 ret = DeleteFileW(pathW); 806 ok(ret, "DeleteFile failed!\n"); 807 hwnd = CreateWindowW(cls_names[i], file_uri1W, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL); 808 ok(hwnd != NULL, "CreateWindow failed!\n"); 809 control = NULL; 810 res = AtlAxGetControl(hwnd, &control); 811 ok(res == S_OK, "AtlAxGetControl failed with res %08x\n", res); 812 ok(control != NULL, "AtlAxGetControl failed!\n"); 813 IUnknown_Release(control); 814 DestroyWindow(hwnd); 815 } 816 todo_wine ok(wndproc[0] != wndproc[1], "expected different proc!\n"); 817 } 818 819 static ATOM register_class(void) 820 { 821 WNDCLASSA wndclassA; 822 823 wndclassA.style = 0; 824 wndclassA.lpfnWndProc = DefWindowProcA; 825 wndclassA.cbClsExtra = 0; 826 wndclassA.cbWndExtra = 0; 827 wndclassA.hInstance = GetModuleHandleA(NULL); 828 wndclassA.hIcon = NULL; 829 wndclassA.hCursor = LoadCursorA(NULL, (LPSTR)IDC_ARROW); 830 wndclassA.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); 831 wndclassA.lpszMenuName = NULL; 832 wndclassA.lpszClassName = "WineAtlTestClass"; 833 834 return RegisterClassA(&wndclassA); 835 } 836 837 static HWND create_container_window(void) 838 { 839 return CreateWindowA("WineAtlTestClass", "Wine ATL Test Window", 0, 840 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 841 CW_USEDEFAULT, NULL, NULL, NULL, NULL); 842 } 843 844 static void test_AtlAxAttachControl(void) 845 { 846 HWND hwnd; 847 HRESULT hr; 848 IUnknown *control, *container; 849 LONG val; 850 851 hr = AtlAxAttachControl(NULL, NULL, NULL); 852 ok(hr == E_INVALIDARG, "Expected AtlAxAttachControl to return E_INVALIDARG, got 0x%08x\n", hr); 853 854 container = (IUnknown *)0xdeadbeef; 855 hr = AtlAxAttachControl(NULL, NULL, &container); 856 ok(hr == E_INVALIDARG, "Expected AtlAxAttachControl to return E_INVALIDARG, got 0x%08x\n", hr); 857 ok(container == (IUnknown *)0xdeadbeef, 858 "Expected the output container pointer to be untouched, got %p\n", container); 859 860 hwnd = create_container_window(); 861 hr = AtlAxAttachControl(NULL, hwnd, NULL); 862 ok(hr == E_INVALIDARG, "Expected AtlAxAttachControl to return E_INVALIDARG, got 0x%08x\n", hr); 863 DestroyWindow(hwnd); 864 865 hwnd = create_container_window(); 866 container = (IUnknown *)0xdeadbeef; 867 hr = AtlAxAttachControl(NULL, hwnd, &container); 868 ok(hr == E_INVALIDARG, "Expected AtlAxAttachControl to return E_INVALIDARG, got 0x%08x\n", hr); 869 ok(container == (IUnknown *)0xdeadbeef, "returned %p\n", container); 870 DestroyWindow(hwnd); 871 872 hr = CoCreateInstance(&CLSID_WebBrowser, NULL, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, 873 &IID_IOleObject, (void **)&control); 874 ok(hr == S_OK, "Expected CoCreateInstance to return S_OK, got 0x%08x\n", hr); 875 876 if (FAILED(hr)) 877 { 878 skip("Couldn't obtain a test IOleObject instance\n"); 879 return; 880 } 881 882 hr = AtlAxAttachControl(control, NULL, NULL); 883 ok(hr == S_FALSE, "Expected AtlAxAttachControl to return S_FALSE, got 0x%08x\n", hr); 884 885 container = NULL; 886 hr = AtlAxAttachControl(control, NULL, &container); 887 ok(hr == S_FALSE, "Expected AtlAxAttachControl to return S_FALSE, got 0x%08x\n", hr); 888 ok(container != NULL, "got %p\n", container); 889 IUnknown_Release(container); 890 891 hwnd = create_container_window(); 892 SetWindowLongW(hwnd, GWLP_USERDATA, 0xdeadbeef); 893 hr = AtlAxAttachControl(control, hwnd, NULL); 894 ok(hr == S_OK, "Expected AtlAxAttachControl to return S_OK, got 0x%08x\n", hr); 895 val = GetWindowLongW(hwnd, GWLP_USERDATA); 896 ok(val == 0xdeadbeef, "returned %08x\n", val); 897 DestroyWindow(hwnd); 898 899 hwnd = create_container_window(); 900 SetWindowLongW(hwnd, GWLP_USERDATA, 0xdeadbeef); 901 container = NULL; 902 hr = AtlAxAttachControl(control, hwnd, &container); 903 ok(hr == S_OK, "Expected AtlAxAttachControl to return S_OK, got 0x%08x\n", hr); 904 ok(container != NULL, "Expected not NULL!\n"); 905 val = GetWindowLongW(hwnd, GWLP_USERDATA); 906 ok(val == 0xdeadbeef, "Expected unchanged, returned %08x\n", val); 907 DestroyWindow(hwnd); 908 909 IUnknown_Release(control); 910 } 911 912 static void test_AtlAxCreateControl(void) 913 { 914 HWND hwnd; 915 IUnknown *control, *container; 916 HRESULT hr; 917 DWORD ret, ret_size; 918 HANDLE hfile; 919 WCHAR file_uri1W[MAX_PATH], pathW[MAX_PATH]; 920 921 container = NULL; 922 control = (IUnknown *)0xdeadbeef; 923 hr = AtlAxCreateControlEx(NULL, NULL, NULL, &container, &control, NULL, NULL); 924 todo_wine ok(hr == S_FALSE, "got 0x%08x\n", hr); 925 todo_wine ok(container != NULL, "returned %p\n", container); 926 ok(!control, "returned %p\n", control); 927 928 container = NULL; 929 control = (IUnknown *)0xdeadbeef; 930 hwnd = create_container_window(); 931 ok(hwnd != NULL, "create window failed!\n"); 932 hr = AtlAxCreateControlEx(NULL, hwnd, NULL, &container, &control, &IID_NULL, NULL); 933 ok(hr == S_OK, "got 0x%08x\n", hr); 934 todo_wine ok(container != NULL, "returned %p!\n", container); 935 ok(!control, "returned %p\n", control); 936 DestroyWindow(hwnd); 937 938 container = NULL; 939 control = (IUnknown *)0xdeadbeef; 940 hwnd = create_container_window(); 941 ok(hwnd != NULL, "create window failed!\n"); 942 hr = AtlAxCreateControlEx(emptyW, hwnd, NULL, &container, &control, &IID_NULL, NULL); 943 ok(hr == S_OK, "got 0x%08x\n", hr); 944 todo_wine ok(container != NULL, "returned %p!\n", container); 945 ok(!control, "returned %p\n", control); 946 DestroyWindow(hwnd); 947 948 container = (IUnknown *)0xdeadbeef; 949 control = (IUnknown *)0xdeadbeef; 950 hwnd = create_container_window(); 951 ok(hwnd != NULL, "create window failed!\n"); 952 hr = AtlAxCreateControlEx(randomW, hwnd, NULL, &container, &control, &IID_NULL, NULL); 953 ok(hr == CO_E_CLASSSTRING, "got 0x%08x\n", hr); 954 ok(!container, "returned %p!\n", container); 955 ok(!control, "returned %p\n", control); 956 DestroyWindow(hwnd); 957 958 container = NULL; 959 control = NULL; 960 hwnd = create_container_window(); 961 ok(hwnd != NULL, "create window failed!\n"); 962 hr = AtlAxCreateControlEx(progid1W, hwnd, NULL, &container, &control, &IID_NULL, NULL); 963 ok(hr == S_OK, "got 0x%08x\n", hr); 964 ok(container != NULL, "returned %p!\n", container); 965 ok(control != NULL, "returned %p\n", control); 966 DestroyWindow(hwnd); 967 968 container = NULL; 969 control = NULL; 970 hwnd = create_container_window(); 971 ok(hwnd != NULL, "create window failed!\n"); 972 hr = AtlAxCreateControlEx(clsid1W, hwnd, NULL, &container, &control, &IID_NULL, NULL); 973 ok(hr == S_OK, "got 0x%08x\n", hr); 974 ok(container != NULL, "returned %p!\n", container); 975 ok(control != NULL, "returned %p\n", control); 976 IUnknown_Release(container); 977 IUnknown_Release(control); 978 DestroyWindow(hwnd); 979 980 container = NULL; 981 control = NULL; 982 hwnd = create_container_window(); 983 ok(hwnd != NULL, "create window failed!\n"); 984 hr = AtlAxCreateControlEx(url1W, hwnd, NULL, &container, &control, &IID_NULL, NULL); 985 ok(hr == S_OK, "got 0x%08x\n", hr); 986 ok(container != NULL, "returned %p!\n", container); 987 ok(control != NULL, "returned %p\n", control); 988 IUnknown_Release(container); 989 IUnknown_Release(control); 990 DestroyWindow(hwnd); 991 992 container = NULL; 993 control = NULL; 994 hwnd = create_container_window(); 995 ok(hwnd != NULL, "create window failed!\n"); 996 hr = AtlAxCreateControlEx(mshtml1W, hwnd, NULL, &container, &control, &IID_NULL, NULL); 997 ok(hr == S_OK, "got 0x%08x\n", hr); 998 ok(container != NULL, "returned %p!\n", container); 999 ok(control != NULL, "returned %p\n", control); 1000 IUnknown_Release(container); 1001 IUnknown_Release(control); 1002 DestroyWindow(hwnd); 1003 1004 container = NULL; 1005 control = NULL; 1006 hwnd = create_container_window(); 1007 ok(hwnd != NULL, "create window failed!\n"); 1008 hr = AtlAxCreateControlEx(mshtml2W, hwnd, NULL, &container, &control, &IID_NULL, NULL); 1009 ok(hr == S_OK, "got 0x%08x\n", hr); 1010 ok(container != NULL, "returned %p!\n", container); 1011 ok(control != NULL, "returned %p\n", control); 1012 IUnknown_Release(container); 1013 IUnknown_Release(control); 1014 DestroyWindow(hwnd); 1015 1016 container = (IUnknown *)0xdeadbeef; 1017 control = (IUnknown *)0xdeadbeef; 1018 hwnd = create_container_window(); 1019 ok(hwnd != NULL, "create window failed!\n"); 1020 hr = AtlAxCreateControlEx(mshtml3W, hwnd, NULL, &container, &control, &IID_NULL, NULL); 1021 ok(hr == CO_E_CLASSSTRING, "got 0x%08x\n", hr); 1022 ok(!container, "returned %p!\n", container); 1023 ok(!control, "returned %p\n", control); 1024 DestroyWindow(hwnd); 1025 1026 ret = GetTempPathW(MAX_PATH, pathW); 1027 ok(ret, "GetTempPath failed!\n"); 1028 lstrcatW(pathW, html_fileW); 1029 hfile = CreateFileW(pathW, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, 0); 1030 ok(hfile != INVALID_HANDLE_VALUE, "failed to create file\n"); 1031 ret = WriteFile(hfile, html_str, sizeof(html_str), &ret_size, NULL); 1032 ok(ret, "WriteFile failed\n"); 1033 CloseHandle(hfile); 1034 1035 /* test C:// scheme */ 1036 container = NULL; 1037 control = NULL; 1038 hwnd = create_container_window(); 1039 ok(hwnd != NULL, "create window failed!\n"); 1040 hr = AtlAxCreateControlEx(pathW, hwnd, NULL, &container, &control, &IID_NULL, NULL); 1041 ok(hr == S_OK, "got 0x%08x\n", hr); 1042 ok(container != NULL, "returned %p!\n", container); 1043 ok(control != NULL, "returned %p\n", control); 1044 IUnknown_Release(container); 1045 IUnknown_Release(control); 1046 DestroyWindow(hwnd); 1047 1048 /* test file:// scheme */ 1049 lstrcpyW(file_uri1W, fileW); 1050 lstrcatW(file_uri1W, pathW); 1051 container = NULL; 1052 control = NULL; 1053 hwnd = create_container_window(); 1054 ok(hwnd != NULL, "create window failed!\n"); 1055 hr = AtlAxCreateControlEx(file_uri1W, hwnd, NULL, &container, &control, &IID_NULL, NULL); 1056 ok(hr == S_OK, "got 0x%08x\n", hr); 1057 ok(container != NULL, "returned %p!\n", container); 1058 ok(control != NULL, "returned %p\n", control); 1059 IUnknown_Release(container); 1060 IUnknown_Release(control); 1061 DestroyWindow(hwnd); 1062 1063 /* test file:// scheme on non-existent file. */ 1064 ret = DeleteFileW(pathW); 1065 ok(ret, "DeleteFile failed!\n"); 1066 container = NULL; 1067 control = NULL; 1068 hwnd = create_container_window(); 1069 ok(hwnd != NULL, "create window failed!\n"); 1070 hr = AtlAxCreateControlEx(file_uri1W, hwnd, NULL, &container, &control, &IID_NULL, NULL); 1071 ok(hr == S_OK, "got 0x%08x\n", hr); 1072 ok(container != NULL, "returned %p!\n", container); 1073 ok(control != NULL, "returned %p\n", control); 1074 IUnknown_Release(container); 1075 IUnknown_Release(control); 1076 DestroyWindow(hwnd); 1077 } 1078 1079 START_TEST(atl) 1080 { 1081 if (!register_class()) 1082 return; 1083 1084 CoInitialize(NULL); 1085 1086 test_winmodule(); 1087 test_regcat(); 1088 test_typelib(); 1089 test_cp(); 1090 test_source_iface(); 1091 test_ax_win(); 1092 test_AtlAxAttachControl(); 1093 test_AtlAxCreateControl(); 1094 1095 CoUninitialize(); 1096 } 1097