* The Shell.. for a long time we dreamed of having a compatible, properly working...
[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
37 #include <wine/atlbase.h>
38 #include <mshtml.h>
39
40 #include <wine/test.h>
41
42 static const GUID CLSID_Test =
43 {0x178fc163,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
44 #define CLSID_TEST_STR "178fc163-0000-0000-0000-000000000046"
45
46 static const GUID CATID_CatTest1 =
47 {0x178fc163,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x46}};
48 #define CATID_CATTEST1_STR "178fc163-0000-0000-0000-000000000146"
49
50 static const GUID CATID_CatTest2 =
51 {0x178fc163,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x46}};
52 #define CATID_CATTEST2_STR "178fc163-0000-0000-0000-000000000246"
53
54 static BOOL is_process_limited(void)
55 {
56 static BOOL (WINAPI *pOpenProcessToken)(HANDLE, DWORD, PHANDLE) = NULL;
57 HANDLE token;
58
59 if (!pOpenProcessToken)
60 {
61 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
62 pOpenProcessToken = (void*)GetProcAddress(hadvapi32, "OpenProcessToken");
63 if (!pOpenProcessToken)
64 return FALSE;
65 }
66
67 if (pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
68 {
69 BOOL ret;
70 TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault;
71 DWORD size;
72
73 ret = GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size);
74 CloseHandle(token);
75 return (ret && type == TokenElevationTypeLimited);
76 }
77 return FALSE;
78 }
79
80 static void test_winmodule(void)
81 {
82 _AtlCreateWndData create_data[3];
83 _ATL_WIN_MODULE winmod;
84 void *p;
85 HRESULT hres;
86
87 winmod.cbSize = 0xdeadbeef;
88 hres = AtlWinModuleInit(&winmod);
89 ok(hres == E_INVALIDARG, "AtlWinModuleInit failed: %08x\n", hres);
90
91 winmod.cbSize = sizeof(winmod);
92 winmod.m_pCreateWndList = (void*)0xdeadbeef;
93 winmod.m_csWindowCreate.LockCount = 0xdeadbeef;
94 winmod.m_rgWindowClassAtoms.m_aT = (void*)0xdeadbeef;
95 winmod.m_rgWindowClassAtoms.m_nSize = 0xdeadbeef;
96 winmod.m_rgWindowClassAtoms.m_nAllocSize = 0xdeadbeef;
97 hres = AtlWinModuleInit(&winmod);
98 ok(hres == S_OK, "AtlWinModuleInit failed: %08x\n", hres);
99 ok(!winmod.m_pCreateWndList, "winmod.m_pCreateWndList = %p\n", winmod.m_pCreateWndList);
100 ok(winmod.m_csWindowCreate.LockCount == -1, "winmod.m_csWindowCreate.LockCount = %d\n",
101 winmod.m_csWindowCreate.LockCount);
102 ok(winmod.m_rgWindowClassAtoms.m_aT == (void*)0xdeadbeef, "winmod.m_rgWindowClassAtoms.m_aT = %p\n",
103 winmod.m_rgWindowClassAtoms.m_aT);
104 ok(winmod.m_rgWindowClassAtoms.m_nSize == 0xdeadbeef, "winmod.m_rgWindowClassAtoms.m_nSize = %d\n",
105 winmod.m_rgWindowClassAtoms.m_nSize);
106 ok(winmod.m_rgWindowClassAtoms.m_nAllocSize == 0xdeadbeef, "winmod.m_rgWindowClassAtoms.m_nAllocSize = %d\n",
107 winmod.m_rgWindowClassAtoms.m_nAllocSize);
108
109 InitializeCriticalSection(&winmod.m_csWindowCreate);
110
111 AtlWinModuleAddCreateWndData(&winmod, create_data, (void*)0xdead0001);
112 ok(winmod.m_pCreateWndList == create_data, "winmod.m_pCreateWndList != create_data\n");
113 ok(create_data[0].m_pThis == (void*)0xdead0001, "unexpected create_data[0].m_pThis %p\n", create_data[0].m_pThis);
114 ok(create_data[0].m_dwThreadID == GetCurrentThreadId(), "unexpected create_data[0].m_dwThreadID %x\n",
115 create_data[0].m_dwThreadID);
116 ok(!create_data[0].m_pNext, "unexpected create_data[0].m_pNext %p\n", create_data[0].m_pNext);
117
118 AtlWinModuleAddCreateWndData(&winmod, create_data+1, (void*)0xdead0002);
119 ok(winmod.m_pCreateWndList == create_data+1, "winmod.m_pCreateWndList != create_data\n");
120 ok(create_data[1].m_pThis == (void*)0xdead0002, "unexpected create_data[1].m_pThis %p\n", create_data[1].m_pThis);
121 ok(create_data[1].m_dwThreadID == GetCurrentThreadId(), "unexpected create_data[1].m_dwThreadID %x\n",
122 create_data[1].m_dwThreadID);
123 ok(create_data[1].m_pNext == create_data, "unexpected create_data[1].m_pNext %p\n", create_data[1].m_pNext);
124
125 AtlWinModuleAddCreateWndData(&winmod, create_data+2, (void*)0xdead0003);
126 ok(winmod.m_pCreateWndList == create_data+2, "winmod.m_pCreateWndList != create_data\n");
127 ok(create_data[2].m_pThis == (void*)0xdead0003, "unexpected create_data[2].m_pThis %p\n", create_data[2].m_pThis);
128 ok(create_data[2].m_dwThreadID == GetCurrentThreadId(), "unexpected create_data[2].m_dwThreadID %x\n",
129 create_data[2].m_dwThreadID);
130 ok(create_data[2].m_pNext == create_data+1, "unexpected create_data[2].m_pNext %p\n", create_data[2].m_pNext);
131
132 p = AtlWinModuleExtractCreateWndData(&winmod);
133 ok(p == (void*)0xdead0003, "unexpected AtlWinModuleExtractCreateWndData result %p\n", p);
134 ok(winmod.m_pCreateWndList == create_data+1, "winmod.m_pCreateWndList != create_data\n");
135 ok(create_data[2].m_pNext == create_data+1, "unexpected create_data[2].m_pNext %p\n", create_data[2].m_pNext);
136
137 create_data[1].m_dwThreadID = 0xdeadbeef;
138
139 p = AtlWinModuleExtractCreateWndData(&winmod);
140 ok(p == (void*)0xdead0001, "unexpected AtlWinModuleExtractCreateWndData result %p\n", p);
141 ok(winmod.m_pCreateWndList == create_data+1, "winmod.m_pCreateWndList != create_data\n");
142 ok(!create_data[0].m_pNext, "unexpected create_data[0].m_pNext %p\n", create_data[0].m_pNext);
143 ok(!create_data[1].m_pNext, "unexpected create_data[1].m_pNext %p\n", create_data[1].m_pNext);
144
145 p = AtlWinModuleExtractCreateWndData(&winmod);
146 ok(!p, "unexpected AtlWinModuleExtractCreateWndData result %p\n", p);
147 ok(winmod.m_pCreateWndList == create_data+1, "winmod.m_pCreateWndList != create_data\n");
148 }
149
150 #define test_key_exists(a,b) _test_key_exists(__LINE__,a,b)
151 static void _test_key_exists(unsigned line, HKEY root, const char *key_name)
152 {
153 HKEY key;
154 DWORD res;
155
156 res = RegOpenKeyA(root, key_name, &key);
157 ok_(__FILE__,line)(res == ERROR_SUCCESS, "Could not open key %s\n", key_name);
158 if(res == ERROR_SUCCESS)
159 RegCloseKey(key);
160 }
161
162 #define test_key_not_exists(a,b) _test_key_not_exists(__LINE__,a,b)
163 static void _test_key_not_exists(unsigned line, HKEY root, const char *key_name)
164 {
165 HKEY key;
166 DWORD res;
167
168 res = RegOpenKeyA(root, key_name, &key);
169 ok_(__FILE__,line)(res == ERROR_FILE_NOT_FOUND, "Attempting to open %s returned %u\n", key_name, res);
170 if(res == ERROR_SUCCESS)
171 RegCloseKey(key);
172 }
173
174 static void test_regcat(void)
175 {
176 unsigned char b;
177 HRESULT hres;
178
179 const struct _ATL_CATMAP_ENTRY catmap[] = {
180 {_ATL_CATMAP_ENTRY_IMPLEMENTED, &CATID_CatTest1},
181 {_ATL_CATMAP_ENTRY_REQUIRED, &CATID_CatTest2},
182 {_ATL_CATMAP_ENTRY_END}
183 };
184
185 if (is_process_limited())
186 {
187 skip("process is limited\n");
188 return;
189 }
190
191 hres = AtlRegisterClassCategoriesHelper(&CLSID_Test, catmap, TRUE);
192 ok(hres == S_OK, "AtlRegisterClassCategoriesHelper failed: %08x\n", hres);
193
194 test_key_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}");
195 test_key_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}\\Implemented Categories\\{" CATID_CATTEST1_STR "}");
196 test_key_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}\\Required Categories\\{" CATID_CATTEST2_STR "}");
197
198 hres = AtlRegisterClassCategoriesHelper(&CLSID_Test, catmap, FALSE);
199 ok(hres == S_OK, "AtlRegisterClassCategoriesHelper failed: %08x\n", hres);
200
201 test_key_not_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}\\Implemented Categories");
202 test_key_not_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}\\Required Categories");
203 test_key_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}");
204
205 ok(RegDeleteKeyA(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}") == ERROR_SUCCESS, "Could not delete key\n");
206
207 hres = AtlRegisterClassCategoriesHelper(&CLSID_Test, NULL, TRUE);
208 ok(hres == S_OK, "AtlRegisterClassCategoriesHelper failed: %08x\n", hres);
209
210 test_key_not_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}");
211
212 b = 10;
213 hres = AtlGetPerUserRegistration(&b);
214 ok(hres == S_OK, "AtlGetPerUserRegistration failed: %08x\n", hres);
215 ok(!b, "AtlGetPerUserRegistration returned %x\n", b);
216 }
217
218 static void test_typelib(void)
219 {
220 ITypeLib *typelib;
221 HINSTANCE inst;
222 size_t len;
223 BSTR path;
224 HRESULT hres;
225
226 static const WCHAR scrrun_dll_suffixW[] = {'\\','s','c','r','r','u','n','.','d','l','l',0};
227 static const WCHAR mshtml_tlb_suffixW[] = {'\\','m','s','h','t','m','l','.','t','l','b',0};
228
229 inst = LoadLibraryA("scrrun.dll");
230 ok(inst != NULL, "Could not load scrrun.dll\n");
231
232 typelib = NULL;
233 hres = AtlLoadTypeLib(inst, NULL, &path, &typelib);
234 ok(hres == S_OK, "AtlLoadTypeLib failed: %08x\n", hres);
235 FreeLibrary(inst);
236
237 len = SysStringLen(path);
238 ok(len > sizeof(scrrun_dll_suffixW)/sizeof(WCHAR)
239 && lstrcmpiW(path+len-sizeof(scrrun_dll_suffixW)/sizeof(WCHAR), scrrun_dll_suffixW),
240 "unexpected path %s\n", wine_dbgstr_w(path));
241 SysFreeString(path);
242 ok(typelib != NULL, "typelib == NULL\n");
243 ITypeLib_Release(typelib);
244
245 inst = LoadLibraryA("mshtml.dll");
246 ok(inst != NULL, "Could not load mshtml.dll\n");
247
248 typelib = NULL;
249 hres = AtlLoadTypeLib(inst, NULL, &path, &typelib);
250 ok(hres == S_OK, "AtlLoadTypeLib failed: %08x\n", hres);
251 FreeLibrary(inst);
252
253 len = SysStringLen(path);
254 ok(len > sizeof(mshtml_tlb_suffixW)/sizeof(WCHAR)
255 && lstrcmpiW(path+len-sizeof(mshtml_tlb_suffixW)/sizeof(WCHAR), mshtml_tlb_suffixW),
256 "unexpected path %s\n", wine_dbgstr_w(path));
257 SysFreeString(path);
258 ok(typelib != NULL, "typelib == NULL\n");
259 ITypeLib_Release(typelib);
260 }
261
262 static HRESULT WINAPI ConnectionPoint_QueryInterface(IConnectionPoint *iface, REFIID riid, void **ppv)
263 {
264 if(IsEqualGUID(&IID_IConnectionPoint, riid)) {
265 *ppv = iface;
266 return S_OK;
267 }
268
269 ok(0, "unexpected call\n");
270 return E_NOINTERFACE;
271 }
272
273 static ULONG WINAPI ConnectionPoint_AddRef(IConnectionPoint *iface)
274 {
275 return 2;
276 }
277
278 static ULONG WINAPI ConnectionPoint_Release(IConnectionPoint *iface)
279 {
280 return 1;
281 }
282
283 static HRESULT WINAPI ConnectionPoint_GetConnectionInterface(IConnectionPoint *iface, IID *pIID)
284 {
285 ok(0, "unexpected call\n");
286 return E_NOTIMPL;
287 }
288
289 static HRESULT WINAPI ConnectionPoint_GetConnectionPointContainer(IConnectionPoint *iface,
290 IConnectionPointContainer **ppCPC)
291 {
292 ok(0, "unexpected call\n");
293 return E_NOTIMPL;
294 }
295
296 static int advise_cnt;
297
298 static HRESULT WINAPI ConnectionPoint_Advise(IConnectionPoint *iface, IUnknown *pUnkSink,
299 DWORD *pdwCookie)
300 {
301 ok(pUnkSink == (IUnknown*)0xdead0000, "pUnkSink = %p\n", pUnkSink);
302 *pdwCookie = 0xdeadbeef;
303 advise_cnt++;
304 return S_OK;
305 }
306
307 static HRESULT WINAPI ConnectionPoint_Unadvise(IConnectionPoint *iface, DWORD dwCookie)
308 {
309 ok(dwCookie == 0xdeadbeef, "dwCookie = %x\n", dwCookie);
310 advise_cnt--;
311 return S_OK;
312 }
313
314 static HRESULT WINAPI ConnectionPoint_EnumConnections(IConnectionPoint *iface,
315 IEnumConnections **ppEnum)
316 {
317 ok(0, "unexpected call\n");
318 return E_NOTIMPL;
319 }
320
321 static const IConnectionPointVtbl ConnectionPointVtbl =
322 {
323 ConnectionPoint_QueryInterface,
324 ConnectionPoint_AddRef,
325 ConnectionPoint_Release,
326 ConnectionPoint_GetConnectionInterface,
327 ConnectionPoint_GetConnectionPointContainer,
328 ConnectionPoint_Advise,
329 ConnectionPoint_Unadvise,
330 ConnectionPoint_EnumConnections
331 };
332
333 static IConnectionPoint ConnectionPoint = { &ConnectionPointVtbl };
334
335 static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface,
336 REFIID riid, void **ppv)
337 {
338 if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) {
339 *ppv = iface;
340 return S_OK;
341 }
342
343 ok(0, "unexpected call\n");
344 return E_NOTIMPL;
345 }
346
347 static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface)
348 {
349 return 2;
350 }
351
352 static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface)
353 {
354 return 1;
355 }
356
357 static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface,
358 IEnumConnectionPoints **ppEnum)
359 {
360 ok(0, "unexpected call\n");
361 return E_NOTIMPL;
362 }
363
364 static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface,
365 REFIID riid, IConnectionPoint **ppCP)
366 {
367 ok(IsEqualGUID(riid, &CLSID_Test), "unexpected riid\n");
368 *ppCP = &ConnectionPoint;
369 return S_OK;
370 }
371
372 static const IConnectionPointContainerVtbl ConnectionPointContainerVtbl = {
373 ConnectionPointContainer_QueryInterface,
374 ConnectionPointContainer_AddRef,
375 ConnectionPointContainer_Release,
376 ConnectionPointContainer_EnumConnectionPoints,
377 ConnectionPointContainer_FindConnectionPoint
378 };
379
380 static IConnectionPointContainer ConnectionPointContainer = { &ConnectionPointContainerVtbl };
381
382 static void test_cp(void)
383 {
384 DWORD cookie = 0;
385 HRESULT hres;
386
387 hres = AtlAdvise(NULL, (IUnknown*)0xdeed0000, &CLSID_Test, &cookie);
388 ok(hres == E_INVALIDARG, "expect E_INVALIDARG, returned %08x\n", hres);
389
390 hres = AtlUnadvise(NULL, &CLSID_Test, 0xdeadbeef);
391 ok(hres == E_INVALIDARG, "expect E_INVALIDARG, returned %08x\n", hres);
392
393 hres = AtlAdvise((IUnknown*)&ConnectionPointContainer, (IUnknown*)0xdead0000, &CLSID_Test, &cookie);
394 ok(hres == S_OK, "AtlAdvise failed: %08x\n", hres);
395 ok(cookie == 0xdeadbeef, "cookie = %x\n", cookie);
396 ok(advise_cnt == 1, "advise_cnt = %d\n", advise_cnt);
397
398 hres = AtlUnadvise((IUnknown*)&ConnectionPointContainer, &CLSID_Test, 0xdeadbeef);
399 ok(hres == S_OK, "AtlUnadvise failed: %08x\n", hres);
400 ok(!advise_cnt, "advise_cnt = %d\n", advise_cnt);
401 }
402
403 static CLSID persist_clsid;
404
405 static HRESULT WINAPI Persist_QueryInterface(IPersist *iface, REFIID riid, void **ppv)
406 {
407 ok(0, "unexpected call\n");
408 return E_NOINTERFACE;
409 }
410
411 static ULONG WINAPI Persist_AddRef(IPersist *iface)
412 {
413 return 2;
414 }
415
416 static ULONG WINAPI Persist_Release(IPersist *iface)
417 {
418 return 1;
419 }
420
421 static HRESULT WINAPI Persist_GetClassID(IPersist *iface, CLSID *pClassID)
422 {
423 *pClassID = persist_clsid;
424 return S_OK;
425 }
426
427 static const IPersistVtbl PersistVtbl = {
428 Persist_QueryInterface,
429 Persist_AddRef,
430 Persist_Release,
431 Persist_GetClassID
432 };
433
434 static IPersist Persist = { &PersistVtbl };
435
436 static HRESULT WINAPI ProvideClassInfo2_QueryInterface(IProvideClassInfo2 *iface, REFIID riid, void **ppv)
437 {
438 ok(0, "unexpected call\n");
439 return E_NOINTERFACE;
440 }
441
442 static ULONG WINAPI ProvideClassInfo2_AddRef(IProvideClassInfo2 *iface)
443 {
444 return 2;
445 }
446
447 static ULONG WINAPI ProvideClassInfo2_Release(IProvideClassInfo2 *iface)
448 {
449 return 1;
450 }
451
452 static HRESULT WINAPI ProvideClassInfo2_GetClassInfo(IProvideClassInfo2 *iface, ITypeInfo **ppTI)
453 {
454 ok(0, "unexpected call\n");
455 return E_NOTIMPL;
456 }
457
458 static HRESULT WINAPI ProvideClassInfo2_GetGUID(IProvideClassInfo2 *iface, DWORD dwGuidKind, GUID *pGUID)
459 {
460 ok(dwGuidKind == GUIDKIND_DEFAULT_SOURCE_DISP_IID, "unexpected dwGuidKind %x\n", dwGuidKind);
461 *pGUID = DIID_DispHTMLBody;
462 return S_OK;
463 }
464
465 static const IProvideClassInfo2Vtbl ProvideClassInfo2Vtbl = {
466 ProvideClassInfo2_QueryInterface,
467 ProvideClassInfo2_AddRef,
468 ProvideClassInfo2_Release,
469 ProvideClassInfo2_GetClassInfo,
470 ProvideClassInfo2_GetGUID
471 };
472
473 static IProvideClassInfo2 ProvideClassInfo2 = { &ProvideClassInfo2Vtbl };
474 static BOOL support_classinfo2;
475
476 static HRESULT WINAPI Dispatch_QueryInterface(IDispatch *iface, REFIID riid, void **ppv)
477 {
478 *ppv = NULL;
479
480 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IDispatch, riid)) {
481 *ppv = iface;
482 return S_OK;
483 }
484
485 if(IsEqualGUID(&IID_IProvideClassInfo2, riid)) {
486 if(!support_classinfo2)
487 return E_NOINTERFACE;
488 *ppv = &ProvideClassInfo2;
489 return S_OK;
490 }
491
492 if(IsEqualGUID(&IID_IPersist, riid)) {
493 *ppv = &Persist;
494 return S_OK;
495 }
496
497 ok(0, "unexpected riid: %s\n", wine_dbgstr_guid(riid));
498 return E_NOINTERFACE;
499 }
500
501 static ULONG WINAPI Dispatch_AddRef(IDispatch *iface)
502 {
503 return 2;
504 }
505
506 static ULONG WINAPI Dispatch_Release(IDispatch *iface)
507 {
508 return 1;
509 }
510
511 static HRESULT WINAPI Dispatch_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
512 {
513 ok(0, "unexpected call\n");
514 return E_NOTIMPL;
515 }
516
517 static HRESULT WINAPI Dispatch_GetTypeInfo(IDispatch *iface, UINT iTInfo, LCID lcid,
518 ITypeInfo **ppTInfo)
519 {
520 ITypeLib *typelib;
521 HRESULT hres;
522
523 static const WCHAR mshtml_tlbW[] = {'m','s','h','t','m','l','.','t','l','b',0};
524
525 ok(!iTInfo, "iTInfo = %d\n", iTInfo);
526 ok(!lcid, "lcid = %x\n", lcid);
527
528 hres = LoadTypeLib(mshtml_tlbW, &typelib);
529 ok(hres == S_OK, "LoadTypeLib failed: %08x\n", hres);
530
531 hres = ITypeLib_GetTypeInfoOfGuid(typelib, &IID_IHTMLElement, ppTInfo);
532 ok(hres == S_OK, "GetTypeInfoOfGuid failed: %08x\n", hres);
533
534 ITypeLib_Release(typelib);
535 return S_OK;
536 }
537
538 static HRESULT WINAPI Dispatch_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *rgszNames,
539 UINT cNames, LCID lcid, DISPID *rgDispId)
540 {
541 ok(0, "unexpected call\n");
542 return E_NOTIMPL;
543 }
544
545 static HRESULT WINAPI Dispatch_Invoke(IDispatch *iface, DISPID dispIdMember, REFIID riid,
546 LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
547 EXCEPINFO *pExcepInfo, UINT *puArgErr)
548 {
549 ok(0, "unexpected call\n");
550 return E_NOTIMPL;
551 }
552
553 static const IDispatchVtbl DispatchVtbl = {
554 Dispatch_QueryInterface,
555 Dispatch_AddRef,
556 Dispatch_Release,
557 Dispatch_GetTypeInfoCount,
558 Dispatch_GetTypeInfo,
559 Dispatch_GetIDsOfNames,
560 Dispatch_Invoke
561 };
562
563 static IDispatch Dispatch = { &DispatchVtbl };
564
565 static void test_source_iface(void)
566 {
567 unsigned short maj_ver, min_ver;
568 IID libid, iid;
569 HRESULT hres;
570
571 support_classinfo2 = TRUE;
572
573 maj_ver = min_ver = 0xdead;
574 hres = AtlGetObjectSourceInterface((IUnknown*)&Dispatch, &libid, &iid, &maj_ver, &min_ver);
575 ok(hres == S_OK, "AtlGetObjectSourceInterface failed: %08x\n", hres);
576 ok(IsEqualGUID(&libid, &LIBID_MSHTML), "libid = %s\n", wine_dbgstr_guid(&libid));
577 ok(IsEqualGUID(&iid, &DIID_DispHTMLBody), "iid = %s\n", wine_dbgstr_guid(&iid));
578 ok(maj_ver == 4 && min_ver == 0, "ver = %d.%d\n", maj_ver, min_ver);
579
580 support_classinfo2 = FALSE;
581 persist_clsid = CLSID_HTMLDocument;
582
583 maj_ver = min_ver = 0xdead;
584 hres = AtlGetObjectSourceInterface((IUnknown*)&Dispatch, &libid, &iid, &maj_ver, &min_ver);
585 ok(hres == S_OK, "AtlGetObjectSourceInterface failed: %08x\n", hres);
586 ok(IsEqualGUID(&libid, &LIBID_MSHTML), "libid = %s\n", wine_dbgstr_guid(&libid));
587 ok(IsEqualGUID(&iid, &DIID_HTMLDocumentEvents), "iid = %s\n", wine_dbgstr_guid(&iid));
588 ok(maj_ver == 4 && min_ver == 0, "ver = %d.%d\n", maj_ver, min_ver);
589
590 persist_clsid = CLSID_HTMLStyle;
591
592 maj_ver = min_ver = 0xdead;
593 hres = AtlGetObjectSourceInterface((IUnknown*)&Dispatch, &libid, &iid, &maj_ver, &min_ver);
594 ok(hres == S_OK, "AtlGetObjectSourceInterface failed: %08x\n", hres);
595 ok(IsEqualGUID(&libid, &LIBID_MSHTML), "libid = %s\n", wine_dbgstr_guid(&libid));
596 ok(IsEqualGUID(&iid, &IID_NULL), "iid = %s\n", wine_dbgstr_guid(&iid));
597 ok(maj_ver == 4 && min_ver == 0, "ver = %d.%d\n", maj_ver, min_ver);
598 }
599
600 static void test_ax_win(void)
601 {
602 BOOL ret;
603 WNDCLASSEXW wcex;
604 static const WCHAR AtlAxWin100[] = {'A','t','l','A','x','W','i','n','1','0','0',0};
605 static const WCHAR AtlAxWinLic100[] = {'A','t','l','A','x','W','i','n','L','i','c','1','0','0',0};
606 static HMODULE hinstance = 0;
607
608 ret = AtlAxWinInit();
609 ok(ret, "AtlAxWinInit failed\n");
610
611 hinstance = GetModuleHandleA(NULL);
612
613 memset(&wcex, 0, sizeof(wcex));
614 wcex.cbSize = sizeof(wcex);
615 ret = GetClassInfoExW(hinstance, AtlAxWin100, &wcex);
616 ok(ret, "AtlAxWin100 has not registered\n");
617 ok(wcex.style == (CS_GLOBALCLASS | CS_DBLCLKS), "wcex.style %08x\n", wcex.style);
618
619 memset(&wcex, 0, sizeof(wcex));
620 wcex.cbSize = sizeof(wcex);
621 ret = GetClassInfoExW(hinstance, AtlAxWinLic100, &wcex);
622 ok(ret, "AtlAxWinLic100 has not registered\n");
623 ok(wcex.style == (CS_GLOBALCLASS | CS_DBLCLKS), "wcex.style %08x\n", wcex.style);
624 }
625
626 START_TEST(atl)
627 {
628 CoInitialize(NULL);
629
630 test_winmodule();
631 test_regcat();
632 test_typelib();
633 test_cp();
634 test_source_iface();
635 test_ax_win();
636
637 CoUninitialize();
638 }