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