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