atl100/tests: Added tests for AtlAxCreateControlEx.
[wine/multimedia.git] / dlls / atl100 / tests / atl.c
blobf6cc85bbfa46f29485889a01c9821db232b37185
1 /*
2 * Copyright 2012 Jacek Caban for CodeWeavers
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.
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.
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
19 #include <stdarg.h>
20 #include <stdio.h>
22 #define COBJMACROS
23 #define CONST_VTABLE
25 #include <windef.h>
26 #include <winbase.h>
27 #include <winuser.h>
28 #include <exdisp.h>
30 #include <atlbase.h>
31 #include <mshtml.h>
33 #include <wine/test.h>
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"
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"
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"
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>";
66 static BOOL is_process_limited(void)
68 static BOOL (WINAPI *pOpenProcessToken)(HANDLE, DWORD, PHANDLE) = NULL;
69 HANDLE token;
71 if (!pOpenProcessToken)
73 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
74 pOpenProcessToken = (void*)GetProcAddress(hadvapi32, "OpenProcessToken");
75 if (!pOpenProcessToken)
76 return FALSE;
79 if (pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
81 BOOL ret;
82 TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault;
83 DWORD size;
85 ret = GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size);
86 CloseHandle(token);
87 return (ret && type == TokenElevationTypeLimited);
89 return FALSE;
92 static void test_winmodule(void)
94 _AtlCreateWndData create_data[3];
95 _ATL_WIN_MODULE winmod;
96 void *p;
97 HRESULT hres;
99 winmod.cbSize = 0xdeadbeef;
100 hres = AtlWinModuleInit(&winmod);
101 ok(hres == E_INVALIDARG, "AtlWinModuleInit failed: %08x\n", hres);
103 winmod.cbSize = sizeof(winmod);
104 winmod.m_pCreateWndList = (void*)0xdeadbeef;
105 winmod.m_csWindowCreate.LockCount = 0xdeadbeef;
106 winmod.m_rgWindowClassAtoms.m_aT = (void*)0xdeadbeef;
107 winmod.m_rgWindowClassAtoms.m_nSize = 0xdeadbeef;
108 winmod.m_rgWindowClassAtoms.m_nAllocSize = 0xdeadbeef;
109 hres = AtlWinModuleInit(&winmod);
110 ok(hres == S_OK, "AtlWinModuleInit failed: %08x\n", hres);
111 ok(!winmod.m_pCreateWndList, "winmod.m_pCreateWndList = %p\n", winmod.m_pCreateWndList);
112 ok(winmod.m_csWindowCreate.LockCount == -1, "winmod.m_csWindowCreate.LockCount = %d\n",
113 winmod.m_csWindowCreate.LockCount);
114 ok(winmod.m_rgWindowClassAtoms.m_aT == (void*)0xdeadbeef, "winmod.m_rgWindowClassAtoms.m_aT = %p\n",
115 winmod.m_rgWindowClassAtoms.m_aT);
116 ok(winmod.m_rgWindowClassAtoms.m_nSize == 0xdeadbeef, "winmod.m_rgWindowClassAtoms.m_nSize = %d\n",
117 winmod.m_rgWindowClassAtoms.m_nSize);
118 ok(winmod.m_rgWindowClassAtoms.m_nAllocSize == 0xdeadbeef, "winmod.m_rgWindowClassAtoms.m_nAllocSize = %d\n",
119 winmod.m_rgWindowClassAtoms.m_nAllocSize);
121 InitializeCriticalSection(&winmod.m_csWindowCreate);
123 AtlWinModuleAddCreateWndData(&winmod, create_data, (void*)0xdead0001);
124 ok(winmod.m_pCreateWndList == create_data, "winmod.m_pCreateWndList != create_data\n");
125 ok(create_data[0].m_pThis == (void*)0xdead0001, "unexpected create_data[0].m_pThis %p\n", create_data[0].m_pThis);
126 ok(create_data[0].m_dwThreadID == GetCurrentThreadId(), "unexpected create_data[0].m_dwThreadID %x\n",
127 create_data[0].m_dwThreadID);
128 ok(!create_data[0].m_pNext, "unexpected create_data[0].m_pNext %p\n", create_data[0].m_pNext);
130 AtlWinModuleAddCreateWndData(&winmod, create_data+1, (void*)0xdead0002);
131 ok(winmod.m_pCreateWndList == create_data+1, "winmod.m_pCreateWndList != create_data\n");
132 ok(create_data[1].m_pThis == (void*)0xdead0002, "unexpected create_data[1].m_pThis %p\n", create_data[1].m_pThis);
133 ok(create_data[1].m_dwThreadID == GetCurrentThreadId(), "unexpected create_data[1].m_dwThreadID %x\n",
134 create_data[1].m_dwThreadID);
135 ok(create_data[1].m_pNext == create_data, "unexpected create_data[1].m_pNext %p\n", create_data[1].m_pNext);
137 AtlWinModuleAddCreateWndData(&winmod, create_data+2, (void*)0xdead0003);
138 ok(winmod.m_pCreateWndList == create_data+2, "winmod.m_pCreateWndList != create_data\n");
139 ok(create_data[2].m_pThis == (void*)0xdead0003, "unexpected create_data[2].m_pThis %p\n", create_data[2].m_pThis);
140 ok(create_data[2].m_dwThreadID == GetCurrentThreadId(), "unexpected create_data[2].m_dwThreadID %x\n",
141 create_data[2].m_dwThreadID);
142 ok(create_data[2].m_pNext == create_data+1, "unexpected create_data[2].m_pNext %p\n", create_data[2].m_pNext);
144 p = AtlWinModuleExtractCreateWndData(&winmod);
145 ok(p == (void*)0xdead0003, "unexpected AtlWinModuleExtractCreateWndData result %p\n", p);
146 ok(winmod.m_pCreateWndList == create_data+1, "winmod.m_pCreateWndList != create_data\n");
147 ok(create_data[2].m_pNext == create_data+1, "unexpected create_data[2].m_pNext %p\n", create_data[2].m_pNext);
149 create_data[1].m_dwThreadID = 0xdeadbeef;
151 p = AtlWinModuleExtractCreateWndData(&winmod);
152 ok(p == (void*)0xdead0001, "unexpected AtlWinModuleExtractCreateWndData result %p\n", p);
153 ok(winmod.m_pCreateWndList == create_data+1, "winmod.m_pCreateWndList != create_data\n");
154 ok(!create_data[0].m_pNext, "unexpected create_data[0].m_pNext %p\n", create_data[0].m_pNext);
155 ok(!create_data[1].m_pNext, "unexpected create_data[1].m_pNext %p\n", create_data[1].m_pNext);
157 p = AtlWinModuleExtractCreateWndData(&winmod);
158 ok(!p, "unexpected AtlWinModuleExtractCreateWndData result %p\n", p);
159 ok(winmod.m_pCreateWndList == create_data+1, "winmod.m_pCreateWndList != create_data\n");
162 #define test_key_exists(a,b) _test_key_exists(__LINE__,a,b)
163 static void _test_key_exists(unsigned line, HKEY root, const char *key_name)
165 HKEY key;
166 DWORD res;
168 res = RegOpenKeyA(root, key_name, &key);
169 ok_(__FILE__,line)(res == ERROR_SUCCESS, "Could not open key %s\n", key_name);
170 if(res == ERROR_SUCCESS)
171 RegCloseKey(key);
174 #define test_key_not_exists(a,b) _test_key_not_exists(__LINE__,a,b)
175 static void _test_key_not_exists(unsigned line, HKEY root, const char *key_name)
177 HKEY key;
178 DWORD res;
180 res = RegOpenKeyA(root, key_name, &key);
181 ok_(__FILE__,line)(res == ERROR_FILE_NOT_FOUND, "Attempting to open %s returned %u\n", key_name, res);
182 if(res == ERROR_SUCCESS)
183 RegCloseKey(key);
186 static void test_regcat(void)
188 unsigned char b;
189 HRESULT hres;
191 const struct _ATL_CATMAP_ENTRY catmap[] = {
192 {_ATL_CATMAP_ENTRY_IMPLEMENTED, &CATID_CatTest1},
193 {_ATL_CATMAP_ENTRY_REQUIRED, &CATID_CatTest2},
194 {_ATL_CATMAP_ENTRY_END}
197 if (is_process_limited())
199 skip("process is limited\n");
200 return;
203 hres = AtlRegisterClassCategoriesHelper(&CLSID_Test, catmap, TRUE);
204 ok(hres == S_OK, "AtlRegisterClassCategoriesHelper failed: %08x\n", hres);
206 test_key_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}");
207 test_key_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}\\Implemented Categories\\{" CATID_CATTEST1_STR "}");
208 test_key_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}\\Required Categories\\{" CATID_CATTEST2_STR "}");
210 hres = AtlRegisterClassCategoriesHelper(&CLSID_Test, catmap, FALSE);
211 ok(hres == S_OK, "AtlRegisterClassCategoriesHelper failed: %08x\n", hres);
213 test_key_not_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}\\Implemented Categories");
214 test_key_not_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}\\Required Categories");
215 test_key_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}");
217 ok(RegDeleteKeyA(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}") == ERROR_SUCCESS, "Could not delete key\n");
219 hres = AtlRegisterClassCategoriesHelper(&CLSID_Test, NULL, TRUE);
220 ok(hres == S_OK, "AtlRegisterClassCategoriesHelper failed: %08x\n", hres);
222 test_key_not_exists(HKEY_CLASSES_ROOT, "CLSID\\{" CLSID_TEST_STR "}");
224 b = 10;
225 hres = AtlGetPerUserRegistration(&b);
226 ok(hres == S_OK, "AtlGetPerUserRegistration failed: %08x\n", hres);
227 ok(!b, "AtlGetPerUserRegistration returned %x\n", b);
230 static void test_typelib(void)
232 ITypeLib *typelib;
233 HINSTANCE inst;
234 size_t len;
235 BSTR path;
236 HRESULT hres;
238 static const WCHAR scrrun_dll_suffixW[] = {'\\','s','c','r','r','u','n','.','d','l','l',0};
239 static const WCHAR mshtml_tlb_suffixW[] = {'\\','m','s','h','t','m','l','.','t','l','b',0};
241 inst = LoadLibraryA("scrrun.dll");
242 ok(inst != NULL, "Could not load scrrun.dll\n");
244 typelib = NULL;
245 hres = AtlLoadTypeLib(inst, NULL, &path, &typelib);
246 ok(hres == S_OK, "AtlLoadTypeLib failed: %08x\n", hres);
247 FreeLibrary(inst);
249 len = SysStringLen(path);
250 ok(len > sizeof(scrrun_dll_suffixW)/sizeof(WCHAR)
251 && lstrcmpiW(path+len-sizeof(scrrun_dll_suffixW)/sizeof(WCHAR), scrrun_dll_suffixW),
252 "unexpected path %s\n", wine_dbgstr_w(path));
253 SysFreeString(path);
254 ok(typelib != NULL, "typelib == NULL\n");
255 ITypeLib_Release(typelib);
257 inst = LoadLibraryA("mshtml.dll");
258 ok(inst != NULL, "Could not load mshtml.dll\n");
260 typelib = NULL;
261 hres = AtlLoadTypeLib(inst, NULL, &path, &typelib);
262 ok(hres == S_OK, "AtlLoadTypeLib failed: %08x\n", hres);
263 FreeLibrary(inst);
265 len = SysStringLen(path);
266 ok(len > sizeof(mshtml_tlb_suffixW)/sizeof(WCHAR)
267 && lstrcmpiW(path+len-sizeof(mshtml_tlb_suffixW)/sizeof(WCHAR), mshtml_tlb_suffixW),
268 "unexpected path %s\n", wine_dbgstr_w(path));
269 SysFreeString(path);
270 ok(typelib != NULL, "typelib == NULL\n");
271 ITypeLib_Release(typelib);
274 static HRESULT WINAPI ConnectionPoint_QueryInterface(IConnectionPoint *iface, REFIID riid, void **ppv)
276 if(IsEqualGUID(&IID_IConnectionPoint, riid)) {
277 *ppv = iface;
278 return S_OK;
281 ok(0, "unexpected call\n");
282 return E_NOINTERFACE;
285 static ULONG WINAPI ConnectionPoint_AddRef(IConnectionPoint *iface)
287 return 2;
290 static ULONG WINAPI ConnectionPoint_Release(IConnectionPoint *iface)
292 return 1;
295 static HRESULT WINAPI ConnectionPoint_GetConnectionInterface(IConnectionPoint *iface, IID *pIID)
297 ok(0, "unexpected call\n");
298 return E_NOTIMPL;
301 static HRESULT WINAPI ConnectionPoint_GetConnectionPointContainer(IConnectionPoint *iface,
302 IConnectionPointContainer **ppCPC)
304 ok(0, "unexpected call\n");
305 return E_NOTIMPL;
308 static int advise_cnt;
310 static HRESULT WINAPI ConnectionPoint_Advise(IConnectionPoint *iface, IUnknown *pUnkSink,
311 DWORD *pdwCookie)
313 ok(pUnkSink == (IUnknown*)0xdead0000, "pUnkSink = %p\n", pUnkSink);
314 *pdwCookie = 0xdeadbeef;
315 advise_cnt++;
316 return S_OK;
319 static HRESULT WINAPI ConnectionPoint_Unadvise(IConnectionPoint *iface, DWORD dwCookie)
321 ok(dwCookie == 0xdeadbeef, "dwCookie = %x\n", dwCookie);
322 advise_cnt--;
323 return S_OK;
326 static HRESULT WINAPI ConnectionPoint_EnumConnections(IConnectionPoint *iface,
327 IEnumConnections **ppEnum)
329 ok(0, "unexpected call\n");
330 return E_NOTIMPL;
333 static const IConnectionPointVtbl ConnectionPointVtbl =
335 ConnectionPoint_QueryInterface,
336 ConnectionPoint_AddRef,
337 ConnectionPoint_Release,
338 ConnectionPoint_GetConnectionInterface,
339 ConnectionPoint_GetConnectionPointContainer,
340 ConnectionPoint_Advise,
341 ConnectionPoint_Unadvise,
342 ConnectionPoint_EnumConnections
345 static IConnectionPoint ConnectionPoint = { &ConnectionPointVtbl };
347 static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface,
348 REFIID riid, void **ppv)
350 if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) {
351 *ppv = iface;
352 return S_OK;
355 ok(0, "unexpected call\n");
356 return E_NOTIMPL;
359 static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface)
361 return 2;
364 static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface)
366 return 1;
369 static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface,
370 IEnumConnectionPoints **ppEnum)
372 ok(0, "unexpected call\n");
373 return E_NOTIMPL;
376 static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface,
377 REFIID riid, IConnectionPoint **ppCP)
379 ok(IsEqualGUID(riid, &CLSID_Test), "unexpected riid\n");
380 *ppCP = &ConnectionPoint;
381 return S_OK;
384 static const IConnectionPointContainerVtbl ConnectionPointContainerVtbl = {
385 ConnectionPointContainer_QueryInterface,
386 ConnectionPointContainer_AddRef,
387 ConnectionPointContainer_Release,
388 ConnectionPointContainer_EnumConnectionPoints,
389 ConnectionPointContainer_FindConnectionPoint
392 static IConnectionPointContainer ConnectionPointContainer = { &ConnectionPointContainerVtbl };
394 static void test_cp(void)
396 DWORD cookie = 0;
397 HRESULT hres;
399 hres = AtlAdvise(NULL, (IUnknown*)0xdeed0000, &CLSID_Test, &cookie);
400 ok(hres == E_INVALIDARG, "expect E_INVALIDARG, returned %08x\n", hres);
402 hres = AtlUnadvise(NULL, &CLSID_Test, 0xdeadbeef);
403 ok(hres == E_INVALIDARG, "expect E_INVALIDARG, returned %08x\n", hres);
405 hres = AtlAdvise((IUnknown*)&ConnectionPointContainer, (IUnknown*)0xdead0000, &CLSID_Test, &cookie);
406 ok(hres == S_OK, "AtlAdvise failed: %08x\n", hres);
407 ok(cookie == 0xdeadbeef, "cookie = %x\n", cookie);
408 ok(advise_cnt == 1, "advise_cnt = %d\n", advise_cnt);
410 hres = AtlUnadvise((IUnknown*)&ConnectionPointContainer, &CLSID_Test, 0xdeadbeef);
411 ok(hres == S_OK, "AtlUnadvise failed: %08x\n", hres);
412 ok(!advise_cnt, "advise_cnt = %d\n", advise_cnt);
415 static CLSID persist_clsid;
417 static HRESULT WINAPI Persist_QueryInterface(IPersist *iface, REFIID riid, void **ppv)
419 ok(0, "unexpected call\n");
420 return E_NOINTERFACE;
423 static ULONG WINAPI Persist_AddRef(IPersist *iface)
425 return 2;
428 static ULONG WINAPI Persist_Release(IPersist *iface)
430 return 1;
433 static HRESULT WINAPI Persist_GetClassID(IPersist *iface, CLSID *pClassID)
435 *pClassID = persist_clsid;
436 return S_OK;
439 static const IPersistVtbl PersistVtbl = {
440 Persist_QueryInterface,
441 Persist_AddRef,
442 Persist_Release,
443 Persist_GetClassID
446 static IPersist Persist = { &PersistVtbl };
448 static HRESULT WINAPI ProvideClassInfo2_QueryInterface(IProvideClassInfo2 *iface, REFIID riid, void **ppv)
450 ok(0, "unexpected call\n");
451 return E_NOINTERFACE;
454 static ULONG WINAPI ProvideClassInfo2_AddRef(IProvideClassInfo2 *iface)
456 return 2;
459 static ULONG WINAPI ProvideClassInfo2_Release(IProvideClassInfo2 *iface)
461 return 1;
464 static HRESULT WINAPI ProvideClassInfo2_GetClassInfo(IProvideClassInfo2 *iface, ITypeInfo **ppTI)
466 ok(0, "unexpected call\n");
467 return E_NOTIMPL;
470 static HRESULT WINAPI ProvideClassInfo2_GetGUID(IProvideClassInfo2 *iface, DWORD dwGuidKind, GUID *pGUID)
472 ok(dwGuidKind == GUIDKIND_DEFAULT_SOURCE_DISP_IID, "unexpected dwGuidKind %x\n", dwGuidKind);
473 *pGUID = DIID_DispHTMLBody;
474 return S_OK;
477 static const IProvideClassInfo2Vtbl ProvideClassInfo2Vtbl = {
478 ProvideClassInfo2_QueryInterface,
479 ProvideClassInfo2_AddRef,
480 ProvideClassInfo2_Release,
481 ProvideClassInfo2_GetClassInfo,
482 ProvideClassInfo2_GetGUID
485 static IProvideClassInfo2 ProvideClassInfo2 = { &ProvideClassInfo2Vtbl };
486 static BOOL support_classinfo2;
488 static HRESULT WINAPI Dispatch_QueryInterface(IDispatch *iface, REFIID riid, void **ppv)
490 *ppv = NULL;
492 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IDispatch, riid)) {
493 *ppv = iface;
494 return S_OK;
497 if(IsEqualGUID(&IID_IProvideClassInfo2, riid)) {
498 if(!support_classinfo2)
499 return E_NOINTERFACE;
500 *ppv = &ProvideClassInfo2;
501 return S_OK;
504 if(IsEqualGUID(&IID_IPersist, riid)) {
505 *ppv = &Persist;
506 return S_OK;
509 ok(0, "unexpected riid: %s\n", wine_dbgstr_guid(riid));
510 return E_NOINTERFACE;
513 static ULONG WINAPI Dispatch_AddRef(IDispatch *iface)
515 return 2;
518 static ULONG WINAPI Dispatch_Release(IDispatch *iface)
520 return 1;
523 static HRESULT WINAPI Dispatch_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
525 ok(0, "unexpected call\n");
526 return E_NOTIMPL;
529 static HRESULT WINAPI Dispatch_GetTypeInfo(IDispatch *iface, UINT iTInfo, LCID lcid,
530 ITypeInfo **ppTInfo)
532 ITypeLib *typelib;
533 HRESULT hres;
535 static const WCHAR mshtml_tlbW[] = {'m','s','h','t','m','l','.','t','l','b',0};
537 ok(!iTInfo, "iTInfo = %d\n", iTInfo);
538 ok(!lcid, "lcid = %x\n", lcid);
540 hres = LoadTypeLib(mshtml_tlbW, &typelib);
541 ok(hres == S_OK, "LoadTypeLib failed: %08x\n", hres);
543 hres = ITypeLib_GetTypeInfoOfGuid(typelib, &IID_IHTMLElement, ppTInfo);
544 ok(hres == S_OK, "GetTypeInfoOfGuid failed: %08x\n", hres);
546 ITypeLib_Release(typelib);
547 return S_OK;
550 static HRESULT WINAPI Dispatch_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *rgszNames,
551 UINT cNames, LCID lcid, DISPID *rgDispId)
553 ok(0, "unexpected call\n");
554 return E_NOTIMPL;
557 static HRESULT WINAPI Dispatch_Invoke(IDispatch *iface, DISPID dispIdMember, REFIID riid,
558 LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
559 EXCEPINFO *pExcepInfo, UINT *puArgErr)
561 ok(0, "unexpected call\n");
562 return E_NOTIMPL;
565 static const IDispatchVtbl DispatchVtbl = {
566 Dispatch_QueryInterface,
567 Dispatch_AddRef,
568 Dispatch_Release,
569 Dispatch_GetTypeInfoCount,
570 Dispatch_GetTypeInfo,
571 Dispatch_GetIDsOfNames,
572 Dispatch_Invoke
575 static IDispatch Dispatch = { &DispatchVtbl };
577 static void test_source_iface(void)
579 unsigned short maj_ver, min_ver;
580 IID libid, iid;
581 HRESULT hres;
583 support_classinfo2 = TRUE;
585 maj_ver = min_ver = 0xdead;
586 hres = AtlGetObjectSourceInterface((IUnknown*)&Dispatch, &libid, &iid, &maj_ver, &min_ver);
587 ok(hres == S_OK, "AtlGetObjectSourceInterface failed: %08x\n", hres);
588 ok(IsEqualGUID(&libid, &LIBID_MSHTML), "libid = %s\n", wine_dbgstr_guid(&libid));
589 ok(IsEqualGUID(&iid, &DIID_DispHTMLBody), "iid = %s\n", wine_dbgstr_guid(&iid));
590 ok(maj_ver == 4 && min_ver == 0, "ver = %d.%d\n", maj_ver, min_ver);
592 support_classinfo2 = FALSE;
593 persist_clsid = CLSID_HTMLDocument;
595 maj_ver = min_ver = 0xdead;
596 hres = AtlGetObjectSourceInterface((IUnknown*)&Dispatch, &libid, &iid, &maj_ver, &min_ver);
597 ok(hres == S_OK, "AtlGetObjectSourceInterface failed: %08x\n", hres);
598 ok(IsEqualGUID(&libid, &LIBID_MSHTML), "libid = %s\n", wine_dbgstr_guid(&libid));
599 ok(IsEqualGUID(&iid, &DIID_HTMLDocumentEvents), "iid = %s\n", wine_dbgstr_guid(&iid));
600 ok(maj_ver == 4 && min_ver == 0, "ver = %d.%d\n", maj_ver, min_ver);
602 persist_clsid = CLSID_HTMLStyle;
604 maj_ver = min_ver = 0xdead;
605 hres = AtlGetObjectSourceInterface((IUnknown*)&Dispatch, &libid, &iid, &maj_ver, &min_ver);
606 ok(hres == S_OK, "AtlGetObjectSourceInterface failed: %08x\n", hres);
607 ok(IsEqualGUID(&libid, &LIBID_MSHTML), "libid = %s\n", wine_dbgstr_guid(&libid));
608 ok(IsEqualGUID(&iid, &IID_NULL), "iid = %s\n", wine_dbgstr_guid(&iid));
609 ok(maj_ver == 4 && min_ver == 0, "ver = %d.%d\n", maj_ver, min_ver);
612 static void test_ax_win(void)
614 DWORD ret, ret_size, i;
615 HRESULT res;
616 HWND hwnd;
617 HANDLE hfile;
618 IUnknown *control;
619 WNDPROC wndproc[2] = {NULL, NULL};
620 WCHAR file_uri1W[MAX_PATH], pathW[MAX_PATH];
621 WNDCLASSEXW wcex;
622 static HMODULE hinstance = 0;
623 static const WCHAR cls_names[][16] =
625 {'A','t','l','A','x','W','i','n','1','0','0',0},
626 {'A','t','l','A','x','W','i','n','L','i','c','1','0','0',0}
629 ret = AtlAxWinInit();
630 ok(ret, "AtlAxWinInit failed\n");
632 hinstance = GetModuleHandleA(NULL);
634 for (i = 0; i < 2; i++)
636 memset(&wcex, 0, sizeof(wcex));
637 wcex.cbSize = sizeof(wcex);
638 ret = GetClassInfoExW(hinstance, cls_names[i], &wcex);
639 ok(ret, "%s has not registered\n", wine_dbgstr_w(cls_names[i]));
640 ok(wcex.style == (CS_GLOBALCLASS | CS_DBLCLKS), "wcex.style %08x\n", wcex.style);
641 wndproc[i] = wcex.lpfnWndProc;
643 hwnd = CreateWindowW(cls_names[i], NULL, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL);
644 ok(hwnd != NULL, "CreateWindow failed!\n");
645 control = (IUnknown *)0xdeadbeef;
646 res = AtlAxGetControl(hwnd, &control);
647 ok(res == E_FAIL, "Expected E_FAIL, returned %08x\n", res);
648 ok(!control, "returned %p\n", control);
649 if (control) IUnknown_Release(control);
650 DestroyWindow(hwnd);
652 hwnd = CreateWindowW(cls_names[i], emptyW, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL);
653 ok(hwnd != NULL, "CreateWindow failed!\n");
654 control = (IUnknown *)0xdeadbeef;
655 res = AtlAxGetControl(hwnd, &control);
656 ok(res == E_FAIL, "Expected E_FAIL, returned %08x\n", res);
657 ok(!control, "returned %p\n", control);
658 if (control) IUnknown_Release(control);
659 DestroyWindow(hwnd);
661 hwnd = CreateWindowW(cls_names[i], randomW, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL);
662 todo_wine ok(!hwnd, "returned %p\n", hwnd);
663 if(hwnd) DestroyWindow(hwnd);
665 hwnd = CreateWindowW(cls_names[i], progid1W, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL);
666 ok(hwnd != NULL, "CreateWindow failed!\n");
667 control = NULL;
668 res = AtlAxGetControl(hwnd, &control);
669 ok(res == S_OK, "AtlAxGetControl failed with res %08x\n", res);
670 ok(control != NULL, "AtlAxGetControl failed!\n");
671 IUnknown_Release(control);
672 DestroyWindow(hwnd);
674 hwnd = CreateWindowW(cls_names[i], clsid1W, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL);
675 ok(hwnd != NULL, "CreateWindow failed!\n");
676 control = NULL;
677 res = AtlAxGetControl(hwnd, &control);
678 ok(res == S_OK, "AtlAxGetControl failed with res %08x\n", res);
679 ok(control != NULL, "AtlAxGetControl failed!\n");
680 IUnknown_Release(control);
681 DestroyWindow(hwnd);
683 hwnd = CreateWindowW(cls_names[i], url1W, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL);
684 ok(hwnd != NULL, "CreateWindow failed!\n");
685 control = NULL;
686 res = AtlAxGetControl(hwnd, &control);
687 ok(res == S_OK, "AtlAxGetControl failed with res %08x\n", res);
688 ok(control != NULL, "AtlAxGetControl failed!\n");
689 IUnknown_Release(control);
690 DestroyWindow(hwnd);
692 /* test html stream with "MSHTML:" prefix */
693 hwnd = CreateWindowW(cls_names[i], mshtml1W, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL);
694 ok(hwnd != NULL, "CreateWindow failed!\n");
695 control = NULL;
696 res = AtlAxGetControl(hwnd, &control);
697 ok(res == S_OK, "AtlAxGetControl failed with res %08x\n", res);
698 ok(control != NULL, "AtlAxGetControl failed!\n");
699 IUnknown_Release(control);
700 DestroyWindow(hwnd);
702 hwnd = CreateWindowW(cls_names[i], mshtml2W, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL);
703 ok(hwnd != NULL, "CreateWindow failed!\n");
704 control = NULL;
705 res = AtlAxGetControl(hwnd, &control);
706 ok(res == S_OK, "AtlAxGetControl failed with res %08x\n", res);
707 ok(control != NULL, "AtlAxGetControl failed!\n");
708 IUnknown_Release(control);
709 DestroyWindow(hwnd);
711 /* test html stream without "MSHTML:" prefix */
712 hwnd = CreateWindowW(cls_names[i], mshtml3W, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL);
713 todo_wine ok(!hwnd, "returned %p\n", hwnd);
714 if(hwnd) DestroyWindow(hwnd);
716 ret = GetTempPathW(MAX_PATH, pathW);
717 ok(ret, "GetTempPath failed!\n");
718 lstrcatW(pathW, html_fileW);
719 hfile = CreateFileW(pathW, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, 0);
720 ok(hfile != INVALID_HANDLE_VALUE, "failed to create file\n");
721 ret = WriteFile(hfile, html_str, sizeof(html_str), &ret_size, NULL);
722 ok(ret, "WriteFile failed\n");
723 CloseHandle(hfile);
725 /* test C:// scheme */
726 hwnd = CreateWindowW(cls_names[i], pathW, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL);
727 ok(hwnd != NULL, "CreateWindow failed!\n");
728 control = NULL;
729 res = AtlAxGetControl(hwnd, &control);
730 ok(res == S_OK, "AtlAxGetControl failed with res %08x\n", res);
731 ok(control != NULL, "AtlAxGetControl failed!\n");
732 IUnknown_Release(control);
733 DestroyWindow(hwnd);
735 /* test file:// scheme */
736 lstrcpyW(file_uri1W, fileW);
737 lstrcatW(file_uri1W, pathW);
738 hwnd = CreateWindowW(cls_names[i], file_uri1W, 0, 100, 100, 100, 100, NULL, NULL, NULL, NULL);
739 ok(hwnd != NULL, "CreateWindow failed!\n");
740 control = NULL;
741 res = AtlAxGetControl(hwnd, &control);
742 ok(res == S_OK, "AtlAxGetControl failed with res %08x\n", res);
743 ok(control != NULL, "AtlAxGetControl failed!\n");
744 IUnknown_Release(control);
745 DestroyWindow(hwnd);
747 /* test file:// scheme on non-existent file */
748 ret = DeleteFileW(pathW);
749 ok(ret, "DeleteFile failed!\n");
750 hwnd = CreateWindowW(cls_names[i], file_uri1W, 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);
759 todo_wine ok(wndproc[0] != wndproc[1], "expected different proc!\n");
762 static ATOM register_class(void)
764 WNDCLASSA wndclassA;
766 wndclassA.style = 0;
767 wndclassA.lpfnWndProc = DefWindowProcA;
768 wndclassA.cbClsExtra = 0;
769 wndclassA.cbWndExtra = 0;
770 wndclassA.hInstance = GetModuleHandleA(NULL);
771 wndclassA.hIcon = NULL;
772 wndclassA.hCursor = LoadCursorA(NULL, (LPSTR)IDC_ARROW);
773 wndclassA.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
774 wndclassA.lpszMenuName = NULL;
775 wndclassA.lpszClassName = "WineAtlTestClass";
777 return RegisterClassA(&wndclassA);
780 static HWND create_container_window(void)
782 return CreateWindowA("WineAtlTestClass", "Wine ATL Test Window", 0,
783 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
784 CW_USEDEFAULT, NULL, NULL, NULL, NULL);
787 static void test_AtlAxAttachControl(void)
789 HWND hwnd;
790 HRESULT hr;
791 IUnknown *control, *container;
792 LONG val;
794 hr = AtlAxAttachControl(NULL, NULL, NULL);
795 ok(hr == E_INVALIDARG, "Expected AtlAxAttachControl to return E_INVALIDARG, got 0x%08x\n", hr);
797 container = (IUnknown *)0xdeadbeef;
798 hr = AtlAxAttachControl(NULL, NULL, &container);
799 ok(hr == E_INVALIDARG, "Expected AtlAxAttachControl to return E_INVALIDARG, got 0x%08x\n", hr);
800 ok(container == (IUnknown *)0xdeadbeef,
801 "Expected the output container pointer to be untouched, got %p\n", container);
803 hwnd = create_container_window();
804 hr = AtlAxAttachControl(NULL, hwnd, NULL);
805 ok(hr == E_INVALIDARG, "Expected AtlAxAttachControl to return E_INVALIDARG, got 0x%08x\n", hr);
806 DestroyWindow(hwnd);
808 hwnd = create_container_window();
809 container = (IUnknown *)0xdeadbeef;
810 hr = AtlAxAttachControl(NULL, hwnd, &container);
811 ok(hr == E_INVALIDARG, "Expected AtlAxAttachControl to return E_INVALIDARG, got 0x%08x\n", hr);
812 ok(container == (IUnknown *)0xdeadbeef, "returned %p\n", container);
813 DestroyWindow(hwnd);
815 hr = CoCreateInstance(&CLSID_WebBrowser, NULL, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER,
816 &IID_IOleObject, (void **)&control);
817 ok(hr == S_OK, "Expected CoCreateInstance to return S_OK, got 0x%08x\n", hr);
819 if (FAILED(hr))
821 skip("Couldn't obtain a test IOleObject instance\n");
822 return;
825 hr = AtlAxAttachControl(control, NULL, NULL);
826 ok(hr == S_FALSE, "Expected AtlAxAttachControl to return S_FALSE, got 0x%08x\n", hr);
828 container = NULL;
829 hr = AtlAxAttachControl(control, NULL, &container);
830 ok(hr == S_FALSE, "Expected AtlAxAttachControl to return S_FALSE, got 0x%08x\n", hr);
831 ok(container != NULL, "got %p\n", container);
832 IUnknown_Release(container);
834 hwnd = create_container_window();
835 SetWindowLongW(hwnd, GWLP_USERDATA, 0xdeadbeef);
836 hr = AtlAxAttachControl(control, hwnd, NULL);
837 ok(hr == S_OK, "Expected AtlAxAttachControl to return S_OK, got 0x%08x\n", hr);
838 val = GetWindowLongW(hwnd, GWLP_USERDATA);
839 ok(val == 0xdeadbeef, "returned %08x\n", val);
840 DestroyWindow(hwnd);
842 hwnd = create_container_window();
843 SetWindowLongW(hwnd, GWLP_USERDATA, 0xdeadbeef);
844 container = NULL;
845 hr = AtlAxAttachControl(control, hwnd, &container);
846 ok(hr == S_OK, "Expected AtlAxAttachControl to return S_OK, got 0x%08x\n", hr);
847 ok(container != NULL, "Expected not NULL!\n");
848 val = GetWindowLongW(hwnd, GWLP_USERDATA);
849 ok(val == 0xdeadbeef, "Expected unchanged, returned %08x\n", val);
850 DestroyWindow(hwnd);
852 IUnknown_Release(control);
855 static void test_AtlAxCreateControl(void)
857 HWND hwnd;
858 IUnknown *control, *container;
859 HRESULT hr;
860 DWORD ret, ret_size;
861 HANDLE hfile;
862 WCHAR file_uri1W[MAX_PATH], pathW[MAX_PATH];
864 container = NULL;
865 control = (IUnknown *)0xdeadbeef;
866 hr = AtlAxCreateControlEx(NULL, NULL, NULL, &container, &control, NULL, NULL);
867 todo_wine ok(hr == S_FALSE, "got 0x%08x\n", hr);
868 todo_wine ok(container != NULL, "returned %p\n", container);
869 ok(!control, "returned %p\n", control);
871 container = NULL;
872 control = (IUnknown *)0xdeadbeef;
873 hwnd = create_container_window();
874 ok(hwnd != NULL, "create window failed!\n");
875 hr = AtlAxCreateControlEx(NULL, hwnd, NULL, &container, &control, &IID_NULL, NULL);
876 ok(hr == S_OK, "got 0x%08x\n", hr);
877 todo_wine ok(container != NULL, "returned %p!\n", container);
878 ok(!control, "returned %p\n", control);
879 DestroyWindow(hwnd);
881 container = NULL;
882 control = (IUnknown *)0xdeadbeef;
883 hwnd = create_container_window();
884 ok(hwnd != NULL, "create window failed!\n");
885 hr = AtlAxCreateControlEx(emptyW, hwnd, NULL, &container, &control, &IID_NULL, NULL);
886 ok(hr == S_OK, "got 0x%08x\n", hr);
887 todo_wine ok(container != NULL, "returned %p!\n", container);
888 ok(!control, "returned %p\n", control);
889 DestroyWindow(hwnd);
891 container = (IUnknown *)0xdeadbeef;
892 control = (IUnknown *)0xdeadbeef;
893 hwnd = create_container_window();
894 ok(hwnd != NULL, "create window failed!\n");
895 hr = AtlAxCreateControlEx(randomW, hwnd, NULL, &container, &control, &IID_NULL, NULL);
896 ok(hr == CO_E_CLASSSTRING, "got 0x%08x\n", hr);
897 ok(!container, "returned %p!\n", container);
898 ok(!control, "returned %p\n", control);
899 DestroyWindow(hwnd);
901 container = NULL;
902 control = NULL;
903 hwnd = create_container_window();
904 ok(hwnd != NULL, "create window failed!\n");
905 hr = AtlAxCreateControlEx(progid1W, hwnd, NULL, &container, &control, &IID_NULL, NULL);
906 ok(hr == S_OK, "got 0x%08x\n", hr);
907 ok(container != NULL, "returned %p!\n", container);
908 ok(control != NULL, "returned %p\n", control);
909 DestroyWindow(hwnd);
911 container = NULL;
912 control = NULL;
913 hwnd = create_container_window();
914 ok(hwnd != NULL, "create window failed!\n");
915 hr = AtlAxCreateControlEx(clsid1W, hwnd, NULL, &container, &control, &IID_NULL, NULL);
916 ok(hr == S_OK, "got 0x%08x\n", hr);
917 ok(container != NULL, "returned %p!\n", container);
918 ok(control != NULL, "returned %p\n", control);
919 DestroyWindow(hwnd);
921 container = NULL;
922 control = NULL;
923 hwnd = create_container_window();
924 ok(hwnd != NULL, "create window failed!\n");
925 hr = AtlAxCreateControlEx(url1W, hwnd, NULL, &container, &control, &IID_NULL, NULL);
926 ok(hr == S_OK, "got 0x%08x\n", hr);
927 ok(container != NULL, "returned %p!\n", container);
928 ok(control != NULL, "returned %p\n", control);
929 DestroyWindow(hwnd);
931 container = NULL;
932 control = NULL;
933 hwnd = create_container_window();
934 ok(hwnd != NULL, "create window failed!\n");
935 hr = AtlAxCreateControlEx(mshtml1W, hwnd, NULL, &container, &control, &IID_NULL, NULL);
936 ok(hr == S_OK, "got 0x%08x\n", hr);
937 ok(container != NULL, "returned %p!\n", container);
938 ok(control != NULL, "returned %p\n", control);
939 DestroyWindow(hwnd);
941 container = NULL;
942 control = NULL;
943 hwnd = create_container_window();
944 ok(hwnd != NULL, "create window failed!\n");
945 hr = AtlAxCreateControlEx(mshtml2W, hwnd, NULL, &container, &control, &IID_NULL, NULL);
946 ok(hr == S_OK, "got 0x%08x\n", hr);
947 ok(container != NULL, "returned %p!\n", container);
948 ok(control != NULL, "returned %p\n", control);
949 DestroyWindow(hwnd);
951 container = (IUnknown *)0xdeadbeef;
952 control = (IUnknown *)0xdeadbeef;
953 hwnd = create_container_window();
954 ok(hwnd != NULL, "create window failed!\n");
955 hr = AtlAxCreateControlEx(mshtml3W, hwnd, NULL, &container, &control, &IID_NULL, NULL);
956 ok(hr == CO_E_CLASSSTRING, "got 0x%08x\n", hr);
957 ok(!container, "returned %p!\n", container);
958 ok(!control, "returned %p\n", control);
959 DestroyWindow(hwnd);
961 ret = GetTempPathW(MAX_PATH, pathW);
962 ok(ret, "GetTempPath failed!\n");
963 lstrcatW(pathW, html_fileW);
964 hfile = CreateFileW(pathW, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, 0);
965 ok(hfile != INVALID_HANDLE_VALUE, "failed to create file\n");
966 ret = WriteFile(hfile, html_str, sizeof(html_str), &ret_size, NULL);
967 ok(ret, "WriteFile failed\n");
968 CloseHandle(hfile);
970 /* test C:// scheme */
971 container = NULL;
972 control = NULL;
973 hwnd = create_container_window();
974 ok(hwnd != NULL, "create window failed!\n");
975 hr = AtlAxCreateControlEx(pathW, hwnd, NULL, &container, &control, &IID_NULL, NULL);
976 ok(hr == S_OK, "got 0x%08x\n", hr);
977 ok(container != NULL, "returned %p!\n", container);
978 ok(control != NULL, "returned %p\n", control);
979 DestroyWindow(hwnd);
981 /* test file:// scheme */
982 lstrcpyW(file_uri1W, fileW);
983 lstrcatW(file_uri1W, pathW);
984 container = NULL;
985 control = NULL;
986 hwnd = create_container_window();
987 ok(hwnd != NULL, "create window failed!\n");
988 hr = AtlAxCreateControlEx(file_uri1W, hwnd, NULL, &container, &control, &IID_NULL, NULL);
989 ok(hr == S_OK, "got 0x%08x\n", hr);
990 ok(container != NULL, "returned %p!\n", container);
991 ok(control != NULL, "returned %p\n", control);
992 DestroyWindow(hwnd);
994 /* test file:// scheme on non-existent file. */
995 ret = DeleteFileW(pathW);
996 ok(ret, "DeleteFile failed!\n");
997 container = NULL;
998 control = NULL;
999 hwnd = create_container_window();
1000 ok(hwnd != NULL, "create window failed!\n");
1001 hr = AtlAxCreateControlEx(file_uri1W, hwnd, NULL, &container, &control, &IID_NULL, NULL);
1002 ok(hr == S_OK, "got 0x%08x\n", hr);
1003 ok(container != NULL, "returned %p!\n", container);
1004 ok(control != NULL, "returned %p\n", control);
1005 DestroyWindow(hwnd);
1008 START_TEST(atl)
1010 if (!register_class())
1011 return;
1013 CoInitialize(NULL);
1015 test_winmodule();
1016 test_regcat();
1017 test_typelib();
1018 test_cp();
1019 test_source_iface();
1020 test_ax_win();
1021 test_AtlAxAttachControl();
1022 test_AtlAxCreateControl();
1024 CoUninitialize();