Release 1.5.29.
[wine] / dlls / mshtml / tests / activex.c
1 /*
2  * Copyright 2010 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 #define COBJMACROS
20 #define CONST_VTABLE
21
22 #include <wine/test.h>
23 #include <stdarg.h>
24 #include <stdio.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "ole2.h"
29 #include "mshtml.h"
30 #include "docobj.h"
31 #include "hlink.h"
32 #include "dispex.h"
33 #include "mshtmhst.h"
34 #include "activscp.h"
35 #include "objsafe.h"
36 #include "mshtmdid.h"
37 #include "mshtml_test.h"
38
39 #include "initguid.h"
40 #include "test_tlb.h"
41
42 #define DEFINE_EXPECT(func) \
43     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
44
45 #define SET_EXPECT(func) \
46     do { called_ ## func = FALSE; expect_ ## func = TRUE; } while(0)
47
48 #define CHECK_EXPECT2(func) \
49     do { \
50         ok(expect_ ##func, "unexpected call " #func "\n"); \
51         called_ ## func = TRUE; \
52     }while(0)
53
54 #define CHECK_EXPECT(func) \
55     do { \
56         CHECK_EXPECT2(func); \
57         expect_ ## func = FALSE; \
58     }while(0)
59
60 #define CHECK_CALLED(func) \
61     do { \
62         ok(called_ ## func, "expected " #func "\n"); \
63         expect_ ## func = called_ ## func = FALSE; \
64     }while(0)
65
66 #define CLEAR_CALLED(func) \
67     expect_ ## func = called_ ## func = FALSE
68
69 #undef GetClassInfo
70
71 DEFINE_EXPECT(CreateInstance);
72 DEFINE_EXPECT(FreezeEvents_TRUE);
73 DEFINE_EXPECT(FreezeEvents_FALSE);
74 DEFINE_EXPECT(QuickActivate);
75 DEFINE_EXPECT(IPersistPropertyBag_InitNew);
76 DEFINE_EXPECT(IPersistPropertyBag_Load);
77 DEFINE_EXPECT(Invoke_READYSTATE);
78 DEFINE_EXPECT(Invoke_ENABLED);
79 DEFINE_EXPECT(Invoke_VALID);
80 DEFINE_EXPECT(Invoke_SECURITYCTX);
81 DEFINE_EXPECT(Invoke_SCRIPTPROP);
82 DEFINE_EXPECT(Invoke_SCRIPTCALL);
83 DEFINE_EXPECT(GetIDsOfNames_scriptprop);
84 DEFINE_EXPECT(DoVerb);
85 DEFINE_EXPECT(SetExtent);
86 DEFINE_EXPECT(GetExtent);
87 DEFINE_EXPECT(SetClientSite);
88 DEFINE_EXPECT(SetClientSite_NULL);
89 DEFINE_EXPECT(Close);
90 DEFINE_EXPECT(InPlaceObject_GetWindow);
91 DEFINE_EXPECT(SetObjectRects);
92 DEFINE_EXPECT(InPlaceDeactivate);
93 DEFINE_EXPECT(UIDeactivate);
94 DEFINE_EXPECT(QueryService_TestActiveX);
95 DEFINE_EXPECT(GetMiscStatus);
96 DEFINE_EXPECT(SetAdvise);
97 DEFINE_EXPECT(GetViewStatus);
98 DEFINE_EXPECT(QI_ITestActiveX);
99 DEFINE_EXPECT(wrapped_AddRef);
100 DEFINE_EXPECT(wrapped_Release);
101 DEFINE_EXPECT(wrapped_func);
102 DEFINE_EXPECT(OnAmbientPropertyChange_UNKNOWN);
103 DEFINE_EXPECT(GetTypeInfo);
104 DEFINE_EXPECT(GetClassInfo);
105 DEFINE_EXPECT(FindConnectionPoint);
106 DEFINE_EXPECT(Advise);
107 DEFINE_EXPECT(Unadvise);
108
109 #define DISPID_SCRIPTPROP 1000
110 #define DISPID_SCRIPTCALL 1001
111
112 enum {
113     TEST_FLASH,
114     TEST_NOQUICKACT,
115     TEST_DISPONLY
116 };
117
118 static ITypeInfo *actxtest_typeinfo, *class_typeinfo;
119 static HWND container_hwnd, plugin_hwnd;
120 static int plugin_behavior;
121 static BOOL no_quickact;
122
123 #define TESTACTIVEX_CLSID "{178fc163-f585-4e24-9c13-4bb7f6680746}"
124
125 static const GUID CLSID_TestActiveX =
126     {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xf6,0x68,0x07,0x46}};
127
128 static const GUID IID_ITestActiveX =
129     {0x178fc663,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xf6,0x68,0x07,0x46}};
130
131 static const char object_ax_str[] =
132     "<html><head></head><body>"
133     "<object classid=\"clsid:" TESTACTIVEX_CLSID "\" width=\"300\" height=\"200\" id=\"objid\">"
134     "<param name=\"param_name\" value=\"param_value\">"
135     "<param name=\"num_param\" value=\"3\">"
136     "</object>"
137     "<script>"
138     "objid.scriptCall();"
139     "</script>"
140     "</body></html>";
141
142 static const char event_binding_str[] =
143     "<html><head></head><body>"
144     "<object classid=\"clsid:" TESTACTIVEX_CLSID "\" width=\"300\" height=\"200\" id=\"objid\">"
145     "<param name=\"param_name\" value=\"param_value\">"
146     "<param name=\"num_param\" value=\"3\">"
147     "</object>"
148     "<script for=\"objid\" event=\"testfunc\">return 6;</script>"
149     "<script for=\"objid\" event=\"testfunc2(x,y)\">return x+2*y;</script>"
150     "</body></html>";
151
152 static REFIID pluginhost_iids[] = {
153     &IID_IOleClientSite,
154     &IID_IAdviseSink,
155     &IID_IAdviseSinkEx,
156     &IID_IPropertyNotifySink,
157     &IID_IDispatch,
158     &IID_IOleWindow,
159     &IID_IOleInPlaceSite,
160     &IID_IOleInPlaceSiteEx,
161     &IID_IOleControlSite,
162     &IID_IBindHost,
163     &IID_IServiceProvider,
164     NULL
165 };
166
167 static const char *debugstr_guid(REFIID riid)
168 {
169     static char buf[50];
170
171     sprintf(buf, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
172             riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
173             riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
174             riid->Data4[5], riid->Data4[6], riid->Data4[7]);
175
176     return buf;
177 }
178
179 static BOOL iface_cmp(IUnknown *iface1, IUnknown *iface2)
180 {
181     IUnknown *unk1, *unk2;
182
183     if(iface1 == iface2)
184         return TRUE;
185
186     IUnknown_QueryInterface(iface1, &IID_IUnknown, (void**)&unk1);
187     IUnknown_Release(unk1);
188     IUnknown_QueryInterface(iface2, &IID_IUnknown, (void**)&unk2);
189     IUnknown_Release(unk2);
190
191     return unk1 == unk2;
192 }
193
194 #define test_ifaces(i,ids) _test_ifaces(__LINE__,i,ids)
195 static void _test_ifaces(unsigned line, IUnknown *iface, REFIID *iids)
196 {
197     const IID * const *piid;
198     IUnknown *unk;
199     HRESULT hres;
200
201      for(piid = iids; *piid; piid++) {
202         hres = IUnknown_QueryInterface(iface, *piid, (void**)&unk);
203         ok_(__FILE__,line) (hres == S_OK, "Could not get %s interface: %08x\n", debugstr_guid(*piid), hres);
204         if(SUCCEEDED(hres))
205             IUnknown_Release(unk);
206     }
207 }
208
209 static int strcmp_wa(LPCWSTR strw, const char *stra)
210 {
211     CHAR buf[512];
212     WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL);
213     return lstrcmpA(stra, buf);
214 }
215
216 static BSTR a2bstr(const char *str)
217 {
218     BSTR ret;
219     int len;
220
221     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
222     ret = SysAllocStringLen(NULL, len);
223     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
224
225     return ret;
226 }
227
228 static IOleClientSite *client_site;
229 static IDispatch *sink_disp;
230 static READYSTATE plugin_readystate = READYSTATE_UNINITIALIZED;
231
232 static void set_plugin_readystate(READYSTATE state)
233 {
234     IPropertyNotifySink *prop_notif;
235     HRESULT hres;
236
237     plugin_readystate = state;
238
239     hres = IOleClientSite_QueryInterface(client_site, &IID_IPropertyNotifySink, (void**)&prop_notif);
240     ok(hres == S_OK, "Could not get IPropertyNotifySink iface: %08x\n", hres);
241
242     hres = IPropertyNotifySink_OnChanged(prop_notif, DISPID_READYSTATE);
243     ok(hres == S_OK, "OnChanged(DISPID_READYSTATE) failed: %08x\n", hres);
244
245     IPropertyNotifySink_Release(prop_notif);
246 }
247
248 static void test_mon_displayname(IMoniker *mon, const char *exname, const char *broken_name)
249 {
250     LPOLESTR display_name;
251     DWORD mksys;
252     HRESULT hres;
253
254     hres = IMoniker_GetDisplayName(mon, NULL, NULL, &display_name);
255     ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres);
256     ok(!strcmp_wa(display_name, exname) || broken(broken_name && !strcmp_wa(display_name, broken_name)),
257         "display_name = %s\n", wine_dbgstr_w(display_name));
258     CoTaskMemFree(display_name);
259
260     hres = IMoniker_IsSystemMoniker(mon, &mksys);
261     ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres);
262     ok(mksys == MKSYS_URLMONIKER, "mksys = %d\n", mksys);
263 }
264
265 static LRESULT WINAPI plugin_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
266 {
267     switch(msg) {
268     case WM_PAINT: {
269         PAINTSTRUCT ps;
270         HBRUSH brush;
271         RECT rect;
272         HDC dc;
273
274         GetClientRect(hwnd, &rect);
275
276         dc = BeginPaint(hwnd, &ps);
277         brush = CreateSolidBrush(RGB(255,0,0));
278         SelectObject(dc, brush);
279         Rectangle(dc, rect.left, rect.top, rect.right, rect.bottom);
280         DeleteObject(brush);
281         EndPaint(hwnd, &ps);
282         break;
283     }
284     }
285
286     return DefWindowProc(hwnd, msg, wParam, lParam);
287 }
288
289 static void create_plugin_window(HWND parent, const RECT *rect)
290 {
291     static const WCHAR plugin_testW[] =
292         {'p','l','u','g','i','n',' ','t','e','s','t',0};
293     static WNDCLASSEXW wndclass = {
294         sizeof(WNDCLASSEXW),
295         0,
296         plugin_proc,
297         0, 0, NULL, NULL, NULL, NULL, NULL,
298         plugin_testW,
299         NULL
300     };
301
302     RegisterClassExW(&wndclass);
303     plugin_hwnd = CreateWindowW(plugin_testW, plugin_testW,
304             WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN, rect->left, rect->top,
305             rect->right-rect->left, rect->bottom-rect->top, parent, NULL, NULL, NULL);
306 }
307
308 static HRESULT WINAPI ConnectionPoint_QueryInterface(IConnectionPoint *iface, REFIID riid, void **ppv)
309 {
310     ok(0, "unexpected QI call %s\n", debugstr_guid(riid));
311     return E_NOINTERFACE;
312 }
313
314 static ULONG WINAPI ConnectionPoint_AddRef(IConnectionPoint *iface)
315 {
316     return 2;
317 }
318
319 static ULONG WINAPI ConnectionPoint_Release(IConnectionPoint *iface)
320 {
321     return 1;
322 }
323
324 static HRESULT WINAPI ConnectionPoint_GetConnectionInterface(IConnectionPoint *iface, IID *pIID)
325 {
326     ok(0, "unexpected call\n");
327     return E_NOTIMPL;
328 }
329
330 static HRESULT WINAPI ConnectionPoint_GetConnectionPointContainer(IConnectionPoint *iface,
331         IConnectionPointContainer **ppCPC)
332 {
333     ok(0, "unexpected call\n");
334     return E_NOTIMPL;
335 }
336
337 static HRESULT WINAPI ConnectionPoint_Advise(IConnectionPoint *iface, IUnknown *pUnkSink, DWORD *pdwCookie)
338 {
339     DispActiveXTest *ax_test;
340     IDispatchEx *dispex;
341     HRESULT hres;
342
343     CHECK_EXPECT(Advise);
344
345     hres = IUnknown_QueryInterface(pUnkSink, &IID_IDispatch, (void**)&sink_disp);
346     ok(hres == S_OK, "Could not get IDispatch iface: %08x\n", hres);
347
348     hres = IUnknown_QueryInterface(pUnkSink, &IID_IDispatchEx, (void**)&dispex);
349     ok(hres == E_NOINTERFACE, "QueryInterface(IID_IDispatchEx) returned: %08x\n", hres);
350
351     hres = IUnknown_QueryInterface(pUnkSink, &DIID_DispActiveXTest, (void**)&ax_test);
352     ok(hres == S_OK, "Could not get DispActiveXTest iface: %08x\n", hres);
353     DispActiveXTest_Release(ax_test);
354
355     *pdwCookie = 0xdeadbeef;
356     return S_OK;
357 }
358
359 static HRESULT WINAPI ConnectionPoint_Unadvise(IConnectionPoint *iface, DWORD dwCookie)
360 {
361     CHECK_EXPECT(Unadvise);
362
363     ok(dwCookie == 0xdeadbeef, "dwCookie = %x\n", dwCookie);
364
365     if(sink_disp) {
366         IDispatch_Release(sink_disp);
367         sink_disp = NULL;
368     }
369
370     return S_OK;
371 }
372
373 static HRESULT WINAPI ConnectionPoint_EnumConnections(IConnectionPoint *iface, IEnumConnections **ppEnum)
374 {
375     ok(0, "unexpected call\n");
376     return E_NOTIMPL;
377 }
378
379 static const IConnectionPointVtbl ConnectionPointVtbl = {
380     ConnectionPoint_QueryInterface,
381     ConnectionPoint_AddRef,
382     ConnectionPoint_Release,
383     ConnectionPoint_GetConnectionInterface,
384     ConnectionPoint_GetConnectionPointContainer,
385     ConnectionPoint_Advise,
386     ConnectionPoint_Unadvise,
387     ConnectionPoint_EnumConnections
388 };
389
390 static IConnectionPoint ConnectionPoint = { &ConnectionPointVtbl };
391
392 static HRESULT ax_qi(REFIID,void**);
393
394 static HRESULT WINAPI OleControl_QueryInterface(IOleControl *iface, REFIID riid, void **ppv)
395 {
396     return ax_qi(riid, ppv);
397 }
398
399 static ULONG WINAPI OleControl_AddRef(IOleControl *iface)
400 {
401     return 2;
402 }
403
404 static ULONG WINAPI OleControl_Release(IOleControl *iface)
405 {
406     return 1;
407 }
408
409 static HRESULT WINAPI OleControl_GetControlInfo(IOleControl *iface, CONTROLINFO *pCI)
410 {
411     ok(0, "unexpected call\n");
412     return E_NOTIMPL;
413 }
414
415 static HRESULT WINAPI OleControl_OnMnemonic(IOleControl *iface, MSG *mMsg)
416 {
417     ok(0, "unexpected call\n");
418     return E_NOTIMPL;
419 }
420
421 static HRESULT WINAPI OleControl_OnAmbientPropertyChange(IOleControl *iface, DISPID dispID)
422 {
423     switch(dispID) {
424     case DISPID_UNKNOWN:
425         CHECK_EXPECT2(OnAmbientPropertyChange_UNKNOWN);
426         break;
427     default:
428         ok(0, "unexpected call %d\n", dispID);
429     }
430
431     return S_OK;
432 }
433
434 static HRESULT WINAPI OleControl_FreezeEvents(IOleControl *iface, BOOL bFreeze)
435 {
436     if(bFreeze)
437         CHECK_EXPECT2(FreezeEvents_TRUE);
438     else
439         CHECK_EXPECT2(FreezeEvents_FALSE);
440     return S_OK;
441 }
442
443 static const IOleControlVtbl OleControlVtbl = {
444     OleControl_QueryInterface,
445     OleControl_AddRef,
446     OleControl_Release,
447     OleControl_GetControlInfo,
448     OleControl_OnMnemonic,
449     OleControl_OnAmbientPropertyChange,
450     OleControl_FreezeEvents
451 };
452
453 static IOleControl OleControl = { &OleControlVtbl };
454
455 static HRESULT WINAPI QuickActivate_QueryInterface(IQuickActivate *iface, REFIID riid, void **ppv)
456 {
457     return ax_qi(riid, ppv);
458 }
459
460 static ULONG WINAPI QuickActivate_AddRef(IQuickActivate *iface)
461 {
462     return 2;
463 }
464
465 static ULONG WINAPI QuickActivate_Release(IQuickActivate *iface)
466 {
467     return 1;
468 }
469
470 static HRESULT WINAPI QuickActivate_QuickActivate(IQuickActivate *iface, QACONTAINER *container, QACONTROL *control)
471 {
472     CHECK_EXPECT(QuickActivate);
473
474     ok(container != NULL, "container == NULL\n");
475     ok(container->cbSize == sizeof(*container), "container->cbSize = %d\n", container->cbSize);
476     ok(container->pClientSite != NULL, "container->pClientSite == NULL\n");
477     ok(container->pAdviseSink != NULL, "container->pAdviseSink == NULL\n");
478     ok(container->pPropertyNotifySink != NULL, "container->pPropertyNotifySink == NULL\n");
479     ok(!container->pUnkEventSink, "container->pUnkEventSink != NULL\n");
480     ok(container->dwAmbientFlags == (QACONTAINER_SUPPORTSMNEMONICS|QACONTAINER_MESSAGEREFLECT|QACONTAINER_USERMODE),
481        "container->dwAmbientFlags = %x\n", container->dwAmbientFlags);
482     ok(!container->colorFore, "container->colorFore == 0\n"); /* FIXME */
483     todo_wine
484     ok(container->colorBack, "container->colorBack == 0\n"); /* FIXME */
485     todo_wine
486     ok(container->pFont != NULL, "container->pFont == NULL\n");
487     todo_wine
488     ok(container->pUndoMgr != NULL, "container->pUndoMgr == NULL\n");
489     ok(!container->dwAppearance, "container->dwAppearance = %x\n", container->dwAppearance);
490     ok(!container->lcid, "container->lcid = %x\n", container->lcid);
491     ok(!container->hpal, "container->hpal = %p\n", container->hpal);
492     ok(!container->pBindHost, "container->pBindHost != NULL\n");
493     ok(!container->pOleControlSite, "container->pOleControlSite != NULL\n");
494     ok(!container->pServiceProvider, "container->pServiceProvider != NULL\n");
495
496     ok(control->cbSize == sizeof(*control), "control->cbSize = %d\n", control->cbSize);
497     ok(!control->dwMiscStatus, "control->dwMiscStatus = %x\n", control->dwMiscStatus);
498     ok(!control->dwViewStatus, "control->dwViewStatus = %x\n", control->dwViewStatus);
499     ok(!control->dwEventCookie, "control->dwEventCookie = %x\n", control->dwEventCookie);
500     ok(!control->dwPropNotifyCookie, "control->dwPropNotifyCookie = %x\n", control->dwPropNotifyCookie);
501     ok(!control->dwPointerActivationPolicy, "control->dwPointerActivationPolicy = %x\n", control->dwPointerActivationPolicy);
502
503     ok(iface_cmp((IUnknown*)container->pClientSite, (IUnknown*)container->pAdviseSink),
504        "container->pClientSite != container->pAdviseSink\n");
505     ok(iface_cmp((IUnknown*)container->pClientSite, (IUnknown*)container->pPropertyNotifySink),
506        "container->pClientSite != container->pPropertyNotifySink\n");
507     test_ifaces((IUnknown*)container->pClientSite, pluginhost_iids);
508
509     IOleClientSite_AddRef(container->pClientSite);
510     client_site = container->pClientSite;
511
512     control->dwMiscStatus = OLEMISC_SETCLIENTSITEFIRST|OLEMISC_ACTIVATEWHENVISIBLE|OLEMISC_INSIDEOUT
513         |OLEMISC_CANTLINKINSIDE|OLEMISC_RECOMPOSEONRESIZE;
514     control->dwViewStatus = 0x18;
515     control->dwPropNotifyCookie = 1;
516
517     return S_OK;
518 }
519
520 static HRESULT WINAPI QuickActivate_SetContentExtent(IQuickActivate *iface, LPSIZEL pSizel)
521 {
522     ok(0, "unexpected call\n");
523     return E_NOTIMPL;
524 }
525
526 static HRESULT WINAPI QuickActivate_GetContentExtent(IQuickActivate *iface, LPSIZEL pSizel)
527 {
528     ok(0, "unexpected call\n");
529     return E_NOTIMPL;
530 }
531
532 static const IQuickActivateVtbl QuickActivateVtbl = {
533     QuickActivate_QueryInterface,
534     QuickActivate_AddRef,
535     QuickActivate_Release,
536     QuickActivate_QuickActivate,
537     QuickActivate_GetContentExtent,
538     QuickActivate_SetContentExtent
539 };
540
541 static IQuickActivate QuickActivate = { &QuickActivateVtbl };
542
543 static HRESULT WINAPI PersistPropertyBag_QueryInterface(IPersistPropertyBag *iface, REFIID riid, void **ppv)
544 {
545     return ax_qi(riid, ppv);
546 }
547
548 static ULONG WINAPI PersistPropertyBag_AddRef(IPersistPropertyBag *iface)
549 {
550     return 2;
551 }
552
553 static ULONG WINAPI PersistPropertyBag_Release(IPersistPropertyBag *iface)
554 {
555     return 1;
556 }
557
558 static HRESULT WINAPI PersistPropertyBag_GetClassID(IPersistPropertyBag *face, CLSID *pClassID)
559 {
560     ok(0, "unexpected call\n");
561     return E_NOTIMPL;
562 }
563
564 static HRESULT WINAPI PersistPropertyBag_InitNew(IPersistPropertyBag *face)
565 {
566     CHECK_EXPECT(IPersistPropertyBag_InitNew);
567     return S_OK;
568 }
569
570 static HRESULT WINAPI PersistPropertyBag_Load(IPersistPropertyBag *face, IPropertyBag *pPropBag, IErrorLog *pErrorLog)
571 {
572     IBindHost *bind_host, *bind_host2;
573     IServiceProvider *sp;
574     IMoniker *mon;
575     VARIANT v;
576     HRESULT hres;
577
578     static const WCHAR param_nameW[] = {'p','a','r','a','m','_','n','a','m','e',0};
579     static const WCHAR num_paramW[] = {'n','u','m','_','p','a','r','a','m',0};
580     static const WCHAR no_paramW[] = {'n','o','_','p','a','r','a','m',0};
581     static WCHAR test_swfW[] = {'t','e','s','t','.','s','w','f',0};
582
583     static const IID *propbag_ifaces[] = {
584         &IID_IPropertyBag,
585         &IID_IPropertyBag2,
586         NULL
587     };
588
589     CHECK_EXPECT(IPersistPropertyBag_Load);
590
591     ok(pPropBag != NULL, "pPropBag == NULL\n");
592     ok(!pErrorLog, "pErrorLog != NULL\n");
593
594     test_ifaces((IUnknown*)pPropBag, propbag_ifaces);
595
596     V_VT(&v) = VT_BSTR;
597     hres = IPropertyBag_Read(pPropBag, param_nameW, &v, NULL);
598     ok(hres == S_OK, "Read failed: %08x\n", hres);
599     ok(V_VT(&v) == VT_BSTR, "V_VT(&v) = %d\n", V_VT(&v));
600     ok(!strcmp_wa(V_BSTR(&v), "param_value"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
601
602     V_VT(&v) = VT_I4;
603     V_I4(&v) = 0xdeadbeef;
604     hres = IPropertyBag_Read(pPropBag, param_nameW, &v, NULL);
605     ok(hres == DISP_E_TYPEMISMATCH, "Read failed: %08x, expected DISP_E_TYPEMISMATCH\n", hres);
606     ok(V_VT(&v) == VT_I4, "V_VT(&v) = %d\n", V_VT(&v));
607     ok(V_I4(&v) == 0xdeadbeef, "V_I4(v) = %x\n", V_I4(&v));
608
609     V_VT(&v) = VT_BSTR;
610     hres = IPropertyBag_Read(pPropBag, num_paramW, &v, NULL);
611     ok(hres == S_OK, "Read failed: %08x\n", hres);
612     ok(V_VT(&v) == VT_BSTR, "V_VT(&v) = %d\n", V_VT(&v));
613     ok(!strcmp_wa(V_BSTR(&v), "3"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
614     SysFreeString(V_BSTR(&v));
615
616     V_VT(&v) = VT_I4;
617     V_I4(&v) = 0xdeadbeef;
618     hres = IPropertyBag_Read(pPropBag, num_paramW, &v, NULL);
619     ok(hres == S_OK, "Read failed: %08x\n", hres);
620     ok(V_VT(&v) == VT_I4, "V_VT(&v) = %d\n", V_VT(&v));
621     ok(V_I4(&v) == 3, "V_I4(v) = %x\n", V_I4(&v));
622
623     V_VT(&v) = VT_BSTR;
624     V_BSTR(&v) = (BSTR)0xdeadbeef;
625     hres = IPropertyBag_Read(pPropBag, no_paramW, &v, NULL);
626     ok(hres == E_INVALIDARG, "Read failed: %08x\n", hres);
627     ok(V_VT(&v) == VT_BSTR, "V_VT(&v) = %d\n", V_VT(&v));
628     ok(V_BSTR(&v) == (BSTR)0xdeadbeef, "V_BSTR(v) = %p\n", V_BSTR(&v));
629
630     set_plugin_readystate(READYSTATE_INTERACTIVE);
631
632     hres = IOleClientSite_QueryInterface(client_site, &IID_IBindHost, (void**)&bind_host);
633     ok(hres == S_OK, "Could not get IBindHost iface: %08x\n", hres);
634
635     hres = IOleClientSite_QueryInterface(client_site, &IID_IServiceProvider, (void**)&sp);
636     ok(hres == S_OK, "Could not get IServiceProvider iface: %08x\n", hres);
637
638     hres = IServiceProvider_QueryService(sp, &SID_SBindHost, &IID_IBindHost, (void**)&bind_host2);
639     ok(hres == S_OK, "QueryService(SID_SBindHost) failed: %08x\n", hres);
640     IServiceProvider_Release(sp);
641
642     ok(iface_cmp((IUnknown*)bind_host, (IUnknown*)bind_host2), "bind_host != bind_host2\n");
643     IBindHost_Release(bind_host2);
644
645     mon = NULL;
646     hres = IBindHost_CreateMoniker(bind_host, test_swfW, NULL, &mon, 0);
647     ok(hres == S_OK, "CreateMoniker failed: %08x\n", hres);
648     ok(mon != NULL, "mon == NULL\n");
649     test_mon_displayname(mon, "about:test.swf", "about:blanktest.swf");
650     IMoniker_Release(mon);
651
652     IBindHost_Release(bind_host);
653
654     mon = NULL;
655     hres = IOleClientSite_GetMoniker(client_site, OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_CONTAINER, &mon);
656     ok(hres == S_OK, "GetMoniker failed: %08x\n", hres);
657     ok(mon != NULL, "mon == NULL\n");
658     test_mon_displayname(mon, "about:blank", NULL);
659     IMoniker_Release(mon);
660
661     set_plugin_readystate(READYSTATE_COMPLETE);
662
663     return S_OK;
664 }
665
666 static HRESULT WINAPI PersistPropertyBag_Save(IPersistPropertyBag *face, IPropertyBag *pPropBag, BOOL fClearDisrty, BOOL fSaveAllProperties)
667 {
668     ok(0, "unexpected call\n");
669     return E_NOTIMPL;
670 }
671
672 static const IPersistPropertyBagVtbl PersistPropertyBagVtbl = {
673     PersistPropertyBag_QueryInterface,
674     PersistPropertyBag_AddRef,
675     PersistPropertyBag_Release,
676     PersistPropertyBag_GetClassID,
677     PersistPropertyBag_InitNew,
678     PersistPropertyBag_Load,
679     PersistPropertyBag_Save
680
681 };
682
683 static IPersistPropertyBag PersistPropertyBag = { &PersistPropertyBagVtbl };
684
685 static HRESULT WINAPI Dispatch_QueryInterface(IDispatch *iface, REFIID riid, void **ppv)
686 {
687     return ax_qi(riid, ppv);
688 }
689
690 static ULONG WINAPI Dispatch_AddRef(IDispatch *iface)
691 {
692     return 2;
693 }
694
695 static ULONG WINAPI Dispatch_Release(IDispatch *iface)
696 {
697     return 1;
698 }
699
700 static HRESULT WINAPI Dispatch_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
701 {
702     ok(0, "unexpected call\n");
703     return E_NOTIMPL;
704 }
705
706 static HRESULT WINAPI Dispatch_GetTypeInfo(IDispatch *iface, UINT iTInfo, LCID lcid,
707         ITypeInfo **ppTInfo)
708 {
709     CHECK_EXPECT(GetTypeInfo);
710
711     ITypeInfo_AddRef(actxtest_typeinfo);
712     *ppTInfo = actxtest_typeinfo;
713     return S_OK;
714 }
715
716 static HRESULT WINAPI Dispatch_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *rgszNames,
717         UINT cNames, LCID lcid, DISPID *rgDispId)
718 {
719     ok(IsEqualGUID(riid, &IID_NULL), "riid = %s\n", debugstr_guid(riid));
720     ok(cNames == 1, "cNames = %d\n", cNames);
721     ok(rgszNames != NULL, "rgszNames == NULL\n");
722     ok(rgDispId != NULL, "rgDispId == NULL\n");
723
724     if(!strcmp_wa(rgszNames[0], "scriptprop")) {
725         CHECK_EXPECT(GetIDsOfNames_scriptprop);
726         *rgDispId = DISPID_SCRIPTPROP;
727     }else if(!strcmp_wa(rgszNames[0], "scriptCall")) {
728         *rgDispId = DISPID_SCRIPTCALL;
729     }else {
730         ok(0, "rgszNames[0] = %s\n", wine_dbgstr_w(rgszNames[0]));
731     }
732
733     return S_OK;
734 }
735
736 static HRESULT WINAPI Dispatch_Invoke(IDispatch *iface, DISPID dispIdMember, REFIID riid,
737         LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
738         EXCEPINFO *pExcepInfo, UINT *puArgErr)
739 {
740     ok(IsEqualGUID(riid, &IID_NULL), "riid = %s\n", debugstr_guid(riid));
741     ok(pDispParams != NULL, "pDispParams == NULL\n");
742     ok(!pDispParams->cNamedArgs, "pDispParams->cNamedArgs = %d\n", pDispParams->cNamedArgs);
743     ok(!pDispParams->rgdispidNamedArgs, "pDispParams->rgdispidNamedArgs != NULL\n");
744
745     switch(dispIdMember) {
746     case DISPID_READYSTATE:
747         CHECK_EXPECT2(Invoke_READYSTATE);
748         ok(wFlags == DISPATCH_PROPERTYGET, "wFlags = %x\n", wFlags);
749         ok(!pDispParams->cArgs, "pDispParams->cArgs = %d\n", pDispParams->cArgs);
750         ok(!pDispParams->rgvarg, "pDispParams->rgvarg != NULL\n");
751         ok(!pExcepInfo, "pExcepInfo != NULL\n");
752         ok(puArgErr != NULL, "puArgErr == NULL\n");
753         ok(pVarResult != NULL, "pVarResult == NULL\n");
754
755         V_VT(pVarResult) = VT_I4;
756         V_I4(pVarResult) = plugin_readystate;
757         return S_OK;
758      case DISPID_ENABLED:
759         CHECK_EXPECT2(Invoke_ENABLED);
760         ok(wFlags == DISPATCH_PROPERTYGET, "wFlags = %x\n", wFlags);
761         ok(!pDispParams->cArgs, "pDispParams->cArgs = %d\n", pDispParams->cArgs);
762         ok(!pDispParams->rgvarg, "pDispParams->rgvarg != NULL\n");
763         ok(!pExcepInfo, "pExcepInfo != NULL\n");
764         ok(puArgErr != NULL, "puArgErr == NULL\n");
765         ok(pVarResult != NULL, "pVarResult == NULL\n");
766         return DISP_E_MEMBERNOTFOUND;
767     case DISPID_VALID:
768         CHECK_EXPECT(Invoke_VALID);
769         ok(wFlags == DISPATCH_PROPERTYGET, "wFlags = %x\n", wFlags);
770         ok(!pDispParams->cArgs, "pDispParams->cArgs = %d\n", pDispParams->cArgs);
771         ok(!pDispParams->rgvarg, "pDispParams->rgvarg != NULL\n");
772         ok(!pExcepInfo, "pExcepInfo != NULL\n");
773         ok(puArgErr != NULL, "puArgErr == NULL\n");
774         ok(pVarResult != NULL, "pVarResult == NULL\n");
775         return DISP_E_MEMBERNOTFOUND;
776     case DISPID_SECURITYCTX:
777         CHECK_EXPECT(Invoke_SECURITYCTX);
778         ok(wFlags == DISPATCH_PROPERTYGET, "wFlags = %x\n", wFlags);
779         ok(!pDispParams->cArgs, "pDispParams->cArgs = %d\n", pDispParams->cArgs);
780         ok(!pDispParams->rgvarg, "pDispParams->rgvarg != NULL\n");
781         ok(!pExcepInfo, "pExcepInfo != NULL\n");
782         ok(puArgErr != NULL, "puArgErr == NULL\n");
783         ok(pVarResult != NULL, "pVarResult == NULL\n");
784         return DISP_E_MEMBERNOTFOUND;
785     case DISPID_SCRIPTPROP:
786         CHECK_EXPECT(Invoke_SCRIPTPROP);
787         ok(wFlags == DISPATCH_PROPERTYGET, "wFlags = %x\n", wFlags);
788         ok(!pDispParams->cArgs, "pDispParams->cArgs = %d\n", pDispParams->cArgs);
789         ok(!pDispParams->rgvarg, "pDispParams->rgvarg != NULL\n");
790         ok(pExcepInfo != NULL, "pExcepInfo == NULL\n");
791         ok(!puArgErr, "puArgErr != NULL\n");
792         ok(pVarResult != NULL, "pVarResult == NULL\n");
793
794         V_VT(pVarResult) = VT_I4;
795         V_I4(pVarResult) = 4;
796         return S_OK;
797     case DISPID_SCRIPTCALL:
798         CHECK_EXPECT(Invoke_SCRIPTCALL);
799         ok(wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags);
800         ok(!pDispParams->cArgs, "pDispParams->cArgs = %d\n", pDispParams->cArgs);
801         ok(pExcepInfo != NULL, "pExcepInfo == NULL\n");
802         ok(!puArgErr, "puArgErr != NULL\n");
803         ok(!pVarResult, "pVarResult != NULL\n");
804         /*
805         V_VT(pVarResult) = VT_I4;
806         V_I4(pVarResult) = 4;
807         */
808         return S_OK;
809     default:
810         ok(0, "unexpected call %d\n", dispIdMember);
811     }
812
813     return E_NOTIMPL;
814 }
815
816 static const IDispatchVtbl DispatchVtbl = {
817     Dispatch_QueryInterface,
818     Dispatch_AddRef,
819     Dispatch_Release,
820     Dispatch_GetTypeInfoCount,
821     Dispatch_GetTypeInfo,
822     Dispatch_GetIDsOfNames,
823     Dispatch_Invoke
824 };
825
826 static IDispatch Dispatch = { &DispatchVtbl };
827
828 static HRESULT WINAPI ProvideClassInfo_QueryInterface(IProvideClassInfo *iface, REFIID riid, void **ppv)
829 {
830     return ax_qi(riid, ppv);
831 }
832
833 static ULONG WINAPI ProvideClassInfo_AddRef(IProvideClassInfo *iface)
834 {
835     return 2;
836 }
837
838 static ULONG WINAPI ProvideClassInfo_Release(IProvideClassInfo *iface)
839 {
840     return 1;
841 }
842
843 static HRESULT WINAPI ProvideClassInfo_GetClassInfo(IProvideClassInfo *iface, ITypeInfo **ppTI)
844 {
845     CHECK_EXPECT(GetClassInfo);
846
847     ITypeInfo_AddRef(class_typeinfo);
848     *ppTI = class_typeinfo;
849     return S_OK;
850 }
851
852 static const IProvideClassInfoVtbl ProvideClassInfoVtbl = {
853     ProvideClassInfo_QueryInterface,
854     ProvideClassInfo_AddRef,
855     ProvideClassInfo_Release,
856     ProvideClassInfo_GetClassInfo
857 };
858
859 static IProvideClassInfo ProvideClassInfo = { &ProvideClassInfoVtbl };
860
861 static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface, REFIID riid, void **ppv)
862 {
863     return ax_qi(riid, ppv);
864 }
865
866 static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface)
867 {
868     return 2;
869 }
870
871 static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface)
872 {
873     return 1;
874 }
875
876 static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface,
877         IEnumConnectionPoints **ppEnum)
878 {
879     ok(0, "unexpected call\n");
880     return E_NOTIMPL;
881 }
882
883 static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface,
884         REFIID riid, IConnectionPoint **ppCP)
885 {
886     if(IsEqualGUID(riid, &IID_IPropertyNotifySink)) {
887         /* TODO */
888         trace("FindConnectionPoint(IID_IPropertyNotifySink)\n");
889         return CONNECT_E_NOCONNECTION;
890     }
891
892     CHECK_EXPECT(FindConnectionPoint);
893     ok(IsEqualGUID(riid, &DIID_DispActiveXTest), "riid = %s\n", debugstr_guid(riid));
894
895     *ppCP = &ConnectionPoint;
896     return S_OK;
897 }
898
899 static const IConnectionPointContainerVtbl ConnectionPointContainerVtbl = {
900     ConnectionPointContainer_QueryInterface,
901     ConnectionPointContainer_AddRef,
902     ConnectionPointContainer_Release,
903     ConnectionPointContainer_EnumConnectionPoints,
904     ConnectionPointContainer_FindConnectionPoint
905 };
906
907 static IConnectionPointContainer ConnectionPointContainer = { &ConnectionPointContainerVtbl };
908
909 static HRESULT WINAPI ViewObjectEx_QueryInterface(IViewObjectEx *iface, REFIID riid, void **ppv)
910 {
911     return ax_qi(riid, ppv);
912 }
913
914 static ULONG WINAPI ViewObjectEx_AddRef(IViewObjectEx *iface)
915 {
916     return 2;
917 }
918
919 static ULONG WINAPI ViewObjectEx_Release(IViewObjectEx *iface)
920 {
921     return 1;
922 }
923
924 static HRESULT WINAPI ViewObjectEx_Draw(IViewObjectEx *iface, DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd,
925         HDC hdcTargetDev, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBoungs, BOOL (WINAPI*pfnContinue)(ULONG_PTR), ULONG_PTR dwContinue)
926 {
927     ok(0, "unexpected call\n");
928     return E_NOTIMPL;
929 }
930
931 static HRESULT WINAPI ViewObjectEx_GetColorSet(IViewObjectEx *iface, DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd,
932         HDC hicTargetDev, LOGPALETTE **ppColorSet)
933 {
934     ok(0, "unexpected call\n");
935     return E_NOTIMPL;
936 }
937
938 static HRESULT WINAPI ViewObjectEx_Freeze(IViewObjectEx *iface, DWORD dwDrawAspect, LONG lindex, void *pvAspect, DWORD *pdwFreeze)
939 {
940     ok(0, "unexpected call\n");
941     return E_NOTIMPL;
942 }
943
944 static HRESULT WINAPI ViewObjectEx_Unfreeze(IViewObjectEx *iface, DWORD dwFreeze)
945 {
946     ok(0, "unexpected call\n");
947     return E_NOTIMPL;
948 }
949
950 static HRESULT WINAPI ViewObjectEx_SetAdvise(IViewObjectEx *iface, DWORD aspects, DWORD advf, IAdviseSink *pAdvSink)
951 {
952     CHECK_EXPECT(SetAdvise);
953
954     ok(aspects == DVASPECT_CONTENT, "aspects = %x\n", aspects);
955     ok(!advf, "advf = %x\n", advf);
956     ok(pAdvSink != NULL, "pAdvSink = NULL\n");
957
958     return S_OK;
959 }
960
961 static HRESULT WINAPI ViewObjectEx_GetAdvise(IViewObjectEx *iface, DWORD *pAspects, DWORD *pAdvf, IAdviseSink **ppAdvSink)
962 {
963     ok(0, "unexpected call\n");
964     return E_NOTIMPL;
965 }
966
967 static HRESULT WINAPI ViewObjectEx_GetExtent(IViewObjectEx *iface, DWORD dwDrawAspect, LONG lindex, DVTARGETDEVICE *ptd, LPSIZEL lpsizel)
968 {
969     ok(0, "unexpected call\n");
970     return E_NOTIMPL;
971 }
972
973 static HRESULT WINAPI ViewObjectEx_GetRect(IViewObjectEx *iface, DWORD dwAspect, LPRECTL pRect)
974 {
975     ok(0, "unexpected call\n");
976     return E_NOTIMPL;
977 }
978
979 static HRESULT WINAPI ViewObjectEx_GetViewStatus(IViewObjectEx *iface, DWORD *pdwStatus)
980 {
981     CHECK_EXPECT(GetViewStatus);
982
983     *pdwStatus = VIEWSTATUS_OPAQUE|VIEWSTATUS_SOLIDBKGND;
984     return S_OK;
985 }
986
987 static HRESULT WINAPI ViewObjectEx_QueryHitPoint(IViewObjectEx *iface, DWORD dwAspect, LPCRECT pRectBounds, POINT ptlLoc,
988         LONG lCloseHint, DWORD *pHitResult)
989 {
990     ok(0, "unexpected call\n");
991     return E_NOTIMPL;
992 }
993
994 static HRESULT WINAPI ViewObjectEx_QueryHitRect(IViewObjectEx *iface, DWORD dwAspect, LPCRECT pRectBounds, LPCRECT pRectLoc,
995         LONG lCloseHint, DWORD *pHitResult)
996 {
997     ok(0, "unexpected call\n");
998     return E_NOTIMPL;
999 }
1000
1001 static HRESULT WINAPI ViewObjectEx_GetNaturalExtent(IViewObjectEx *iface, DWORD dwAspect, LONG lindex, DVTARGETDEVICE *ptd,
1002         HDC hicTargetDev, DVEXTENTINFO *pExtentIngo, LPSIZEL pSizel)
1003 {
1004     ok(0, "unexpected call\n");
1005     return E_NOTIMPL;
1006 }
1007
1008 static const IViewObjectExVtbl ViewObjectExVtbl = {
1009     ViewObjectEx_QueryInterface,
1010     ViewObjectEx_AddRef,
1011     ViewObjectEx_Release,
1012     ViewObjectEx_Draw,
1013     ViewObjectEx_GetColorSet,
1014     ViewObjectEx_Freeze,
1015     ViewObjectEx_Unfreeze,
1016     ViewObjectEx_SetAdvise,
1017     ViewObjectEx_GetAdvise,
1018     ViewObjectEx_GetExtent,
1019     ViewObjectEx_GetRect,
1020     ViewObjectEx_GetViewStatus,
1021     ViewObjectEx_QueryHitPoint,
1022     ViewObjectEx_QueryHitRect,
1023     ViewObjectEx_GetNaturalExtent
1024 };
1025
1026 static IViewObjectEx ViewObjectEx = { &ViewObjectExVtbl };
1027
1028 static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **ppv)
1029 {
1030     return ax_qi(riid, ppv);
1031 }
1032
1033 static ULONG WINAPI OleObject_AddRef(IOleObject *iface)
1034 {
1035     return 2;
1036 }
1037
1038 static ULONG WINAPI OleObject_Release(IOleObject *iface)
1039 {
1040     return 1;
1041 }
1042
1043 static HRESULT WINAPI OleObject_SetClientSite(IOleObject *iface, IOleClientSite *pClientSite)
1044 {
1045     if(!pClientSite) {
1046         CHECK_EXPECT(SetClientSite_NULL);
1047         return S_OK;
1048     }
1049
1050     CHECK_EXPECT(SetClientSite);
1051
1052     IOleClientSite_AddRef(pClientSite);
1053     client_site = pClientSite;
1054     return S_OK;
1055 }
1056
1057 static HRESULT WINAPI OleObject_GetClientSite(IOleObject *iface, IOleClientSite **ppClientSite)
1058 {
1059     ok(0, "unexpected call\n");
1060     return E_NOTIMPL;
1061 }
1062
1063 static HRESULT WINAPI OleObject_SetHostNames(IOleObject *iface, LPCOLESTR szContainerApp, LPCOLESTR szContainerObj)
1064 {
1065     ok(0, "unexpected call\n");
1066     return E_NOTIMPL;
1067 }
1068
1069 static HRESULT WINAPI OleObject_Close(IOleObject *iface, DWORD dwSaveOption)
1070 {
1071     CHECK_EXPECT(Close);
1072
1073     ok(dwSaveOption == OLECLOSE_NOSAVE, "dwSaveOption = %d\n", dwSaveOption);
1074     return S_OK;
1075 }
1076
1077 static HRESULT WINAPI OleObject_SetMoniker(IOleObject *iface, DWORD dwWhichMoniker, IMoniker *pmk)
1078 {
1079     ok(0, "unexpected call\n");
1080     return E_NOTIMPL;
1081 }
1082
1083 static HRESULT WINAPI OleObject_GetMoniker(IOleObject *iface, DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk)
1084 {
1085     ok(0, "unexpected call\n");
1086     return E_NOTIMPL;
1087 }
1088
1089 static HRESULT WINAPI OleObject_InitFromData(IOleObject *iface, IDataObject *pDataObject, BOOL fCreation,
1090         DWORD dwReserved)
1091 {
1092     ok(0, "unexpected call\n");
1093     return E_NOTIMPL;
1094 }
1095
1096 static HRESULT WINAPI OleObject_GetClipboardData(IOleObject *iface, DWORD dwReserved, IDataObject **ppDataObject)
1097 {
1098     ok(0, "unexpected call\n");
1099     return E_NOTIMPL;
1100 }
1101
1102 static HRESULT WINAPI OleObject_DoVerb(IOleObject *iface, LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite,
1103         LONG lindex, HWND hwndParent, LPCRECT lprcPosRect)
1104 {
1105     OLEINPLACEFRAMEINFO frame_info = {0xdeadbeef};
1106     IOleInPlaceUIWindow *ip_uiwindow;
1107     IOleInPlaceFrame *ip_frame;
1108     IOleInPlaceSiteEx *ip_site;
1109     RECT pos_rect, clip_rect;
1110     BOOL no_redraw;
1111     HWND hwnd;
1112     HRESULT hres;
1113
1114     CHECK_EXPECT(DoVerb);
1115
1116     ok(iVerb == OLEIVERB_INPLACEACTIVATE, "iVerb = %d\n", iVerb);
1117     ok(!lpmsg, "lpmsg != NULL\n");
1118     ok(pActiveSite != NULL, "pActiveSite == NULL\n");
1119     ok(!lindex, "lindex = %d\n", lindex);
1120     ok(hwndParent != NULL, "hwndParent == NULL\n");
1121     ok(lprcPosRect != NULL, "lprcPosRect == NULL\n");
1122
1123     hres = IOleClientSite_QueryInterface(pActiveSite, &IID_IOleInPlaceSiteEx, (void**)&ip_site);
1124     ok(hres == S_OK, "Could not get IOleInPlaceSiteEx iface: %08x\n", hres);
1125
1126     hres = IOleInPlaceSiteEx_CanInPlaceActivate(ip_site);
1127     ok(hres == S_OK, "CanInPlaceActivate failed: %08x\n", hres);
1128
1129     SET_EXPECT(InPlaceObject_GetWindow);
1130     no_redraw = 0xdeadbeef;
1131     hres = IOleInPlaceSiteEx_OnInPlaceActivateEx(ip_site, &no_redraw, 0);
1132     ok(hres == S_OK, "InPlaceActivateEx failed: %08x\n", hres);
1133     ok(!no_redraw, "no_redraw = %x\n", no_redraw);
1134     CHECK_CALLED(InPlaceObject_GetWindow);
1135
1136     no_redraw = 0xdeadbeef;
1137     hres = IOleInPlaceSiteEx_OnInPlaceActivateEx(ip_site, &no_redraw, 0);
1138     ok(hres == S_OK, "InPlaceActivateEx failed: %08x\n", hres);
1139     ok(no_redraw == 0xdeadbeef, "no_redraw = %x\n", no_redraw);
1140
1141     hwnd = NULL;
1142     hres = IOleInPlaceSiteEx_GetWindow(ip_site, &hwnd);
1143     ok(hres == S_OK, "GetWindow failed: %08x\n", hres);
1144     ok(hwnd != NULL, "hwnd == NULL\n");
1145     ok(hwnd == hwndParent, "hwnd != hwndParent\n");
1146
1147     create_plugin_window(hwnd, lprcPosRect);
1148
1149     ip_frame = NULL;
1150     ip_uiwindow = NULL;
1151     frame_info.cb = sizeof(OLEINPLACEFRAMEINFO);
1152     hres = IOleInPlaceSiteEx_GetWindowContext(ip_site, &ip_frame, &ip_uiwindow, &pos_rect, &clip_rect, &frame_info);
1153     ok(hres == S_OK, "GetWindowContext failed: %08x\n", hres);
1154     ok(ip_frame != NULL, "ip_frame == NULL\n");
1155     ok(ip_uiwindow != NULL, "ip_uiwindow == NULL\n");
1156     ok((IOleInPlaceUIWindow*)ip_frame != ip_uiwindow, "ip_frame == ip_uiwindow\n");
1157     ok(!memcmp(&pos_rect, lprcPosRect, sizeof(RECT)), "pos_rect != lpecPosRect\n");
1158     ok(!memcmp(&clip_rect, lprcPosRect, sizeof(RECT)), "clip_rect != lpecPosRect\n");
1159     ok(frame_info.cb == sizeof(frame_info), "frame_info.cb = %d\n", frame_info.cb);
1160     ok(!frame_info.fMDIApp, "frame_info.fMDIApp = %x\n", frame_info.fMDIApp);
1161     ok(frame_info.hwndFrame != NULL, "frame_info.hwnd == NULL\n");
1162     ok(frame_info.hwndFrame == container_hwnd, "frame_info.hwnd != container_hwnd\n");
1163     ok(!frame_info.haccel, "frame_info.haccel != 0\n");
1164     ok(!frame_info.cAccelEntries, "frame_info.cAccelEntried != 0\n");
1165
1166     IOleInPlaceFrame_Release(ip_frame);
1167     IOleInPlaceUIWindow_Release(ip_uiwindow);
1168
1169
1170     IOleInPlaceSiteEx_Release(ip_site);
1171
1172     hres = IOleClientSite_ShowObject(client_site);
1173     ok(hres == S_OK, "ShowObject failed: %08x\n", hres);
1174
1175     SET_EXPECT(InPlaceObject_GetWindow);
1176     SET_EXPECT(SetObjectRects);
1177
1178     return S_OK;
1179 }
1180
1181 static HRESULT WINAPI OleObject_EnumVerbs(IOleObject *iface, IEnumOLEVERB **ppEnumOleVerb)
1182 {
1183     ok(0, "unexpected call\n");
1184     return E_NOTIMPL;
1185 }
1186
1187 static HRESULT WINAPI OleObject_Update(IOleObject *iface)
1188 {
1189     ok(0, "unexpected call\n");
1190     return E_NOTIMPL;
1191 }
1192
1193 static HRESULT WINAPI OleObject_IsUpToDate(IOleObject *iface)
1194 {
1195     ok(0, "unexpected call\n");
1196     return E_NOTIMPL;
1197 }
1198
1199 static HRESULT WINAPI OleObject_GetUserClassID(IOleObject *iface, CLSID *pClsid)
1200 {
1201     ok(0, "unexpected call\n");
1202     return E_NOTIMPL;
1203 }
1204
1205 static HRESULT WINAPI OleObject_GetUserType(IOleObject *iface, DWORD dwFormOfType, LPOLESTR *pszUserType)
1206 {
1207     ok(0, "unexpected call\n");
1208     return E_NOTIMPL;
1209 }
1210
1211 static HRESULT WINAPI OleObject_SetExtent(IOleObject *iface, DWORD dwDrawAspect, SIZEL *psizel)
1212 {
1213     CHECK_EXPECT(SetExtent);
1214     return E_NOTIMPL;
1215 }
1216
1217 static HRESULT WINAPI OleObject_GetExtent(IOleObject *iface, DWORD dwDrawAspect, SIZEL *psizel)
1218 {
1219     CHECK_EXPECT(GetExtent);
1220     return E_NOTIMPL;
1221 }
1222
1223 static HRESULT WINAPI OleObject_Advise(IOleObject *iface, IAdviseSink *pAdvSink, DWORD *pdwConnection)
1224 {
1225     ok(0, "unexpected call\n");
1226     return E_NOTIMPL;
1227 }
1228
1229 static HRESULT WINAPI OleObject_Unadvise(IOleObject *iface, DWORD dwConnection)
1230 {
1231     ok(0, "unexpected call\n");
1232     return E_NOTIMPL;
1233 }
1234
1235 static HRESULT WINAPI OleObject_EnumAdvise(IOleObject *iface, IEnumSTATDATA **ppenumAdvise)
1236 {
1237     ok(0, "unexpected call\n");
1238     return E_NOTIMPL;
1239 }
1240
1241 static HRESULT WINAPI OleObject_GetMiscStatus(IOleObject *iface, DWORD dwAspect, DWORD *pdwStatus)
1242 {
1243     CHECK_EXPECT(GetMiscStatus);
1244     ok(dwAspect == DVASPECT_CONTENT, "dwAspect = %d\n", dwAspect);
1245     ok(pdwStatus != NULL, "pdwStatus == NULL\n");
1246     *pdwStatus = OLEMISC_SETCLIENTSITEFIRST|OLEMISC_ACTIVATEWHENVISIBLE
1247         |OLEMISC_INSIDEOUT|OLEMISC_CANTLINKINSIDE|OLEMISC_RECOMPOSEONRESIZE;
1248     return S_OK;
1249 }
1250
1251 static HRESULT WINAPI OleObject_SetColorScheme(IOleObject *iface, LOGPALETTE *pLogpal)
1252 {
1253     ok(0, "unexpected call\n");
1254     return E_NOTIMPL;
1255 }
1256
1257 static const IOleObjectVtbl OleObjectVtbl = {
1258     OleObject_QueryInterface,
1259     OleObject_AddRef,
1260     OleObject_Release,
1261     OleObject_SetClientSite,
1262     OleObject_GetClientSite,
1263     OleObject_SetHostNames,
1264     OleObject_Close,
1265     OleObject_SetMoniker,
1266     OleObject_GetMoniker,
1267     OleObject_InitFromData,
1268     OleObject_GetClipboardData,
1269     OleObject_DoVerb,
1270     OleObject_EnumVerbs,
1271     OleObject_Update,
1272     OleObject_IsUpToDate,
1273     OleObject_GetUserClassID,
1274     OleObject_GetUserType,
1275     OleObject_SetExtent,
1276     OleObject_GetExtent,
1277     OleObject_Advise,
1278     OleObject_Unadvise,
1279     OleObject_EnumAdvise,
1280     OleObject_GetMiscStatus,
1281     OleObject_SetColorScheme
1282 };
1283
1284 static IOleObject OleObject = { &OleObjectVtbl };
1285
1286 static HRESULT WINAPI OleInPlaceObject_QueryInterface(IOleInPlaceObjectWindowless *iface,
1287         REFIID riid, void **ppv)
1288 {
1289     return ax_qi(riid, ppv);
1290 }
1291
1292 static ULONG WINAPI OleInPlaceObject_AddRef(IOleInPlaceObjectWindowless *iface)
1293 {
1294     return 2;
1295 }
1296
1297 static ULONG WINAPI OleInPlaceObject_Release(IOleInPlaceObjectWindowless *iface)
1298 {
1299     return 1;
1300 }
1301
1302 static HRESULT WINAPI OleInPlaceObject_GetWindow(IOleInPlaceObjectWindowless *iface,
1303         HWND *phwnd)
1304 {
1305     CHECK_EXPECT2(InPlaceObject_GetWindow);
1306
1307     ok(phwnd != NULL, "phwnd == NULL\n");
1308
1309     *phwnd = plugin_hwnd;
1310     return *phwnd ? S_OK : E_UNEXPECTED;
1311 }
1312
1313 static HRESULT WINAPI OleInPlaceObject_ContextSensitiveHelp(IOleInPlaceObjectWindowless *iface,
1314         BOOL fEnterMode)
1315 {
1316     ok(0, "unexpected call\n");
1317     return E_NOTIMPL;
1318 }
1319
1320 static HRESULT WINAPI OleInPlaceObject_InPlaceDeactivate(IOleInPlaceObjectWindowless *iface)
1321 {
1322     IOleInPlaceSite *ip_site;
1323     HRESULT hres;
1324
1325     CHECK_EXPECT(InPlaceDeactivate);
1326
1327     hres = IOleClientSite_QueryInterface(client_site, &IID_IOleInPlaceSite, (void**)&ip_site);
1328     ok(hres == S_OK, "Could not get IOleInPlaceSite iface: %08x\n", hres);
1329
1330     hres = IOleInPlaceSite_OnInPlaceDeactivate(ip_site);
1331     ok(hres == S_OK, "OnInPlaceDeactivate failed: %08x\n", hres);
1332
1333     IOleInPlaceSite_Release(ip_site);
1334     return S_OK;
1335 }
1336
1337 static HRESULT WINAPI OleInPlaceObject_UIDeactivate(IOleInPlaceObjectWindowless *iface)
1338 {
1339     CHECK_EXPECT2(UIDeactivate);
1340     return S_OK;
1341 }
1342
1343 static HRESULT WINAPI OleInPlaceObject_SetObjectRects(IOleInPlaceObjectWindowless *iface,
1344         LPCRECT lprcPosRect, LPCRECT lprcClipRect)
1345 {
1346     CHECK_EXPECT(SetObjectRects);
1347     return S_OK;
1348 }
1349
1350 static HRESULT WINAPI OleInPlaceObjectWindowless_ReactivateAndUndo(IOleInPlaceObjectWindowless *iface)
1351 {
1352     ok(0, "unexpected call\n");
1353     return E_NOTIMPL;
1354 }
1355
1356 static HRESULT WINAPI OleInPlaceObjectWindowless_OnWindowMessage(IOleInPlaceObjectWindowless *iface,
1357         UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *lpResult)
1358 {
1359     ok(0, "unexpected call\n");
1360     return E_NOTIMPL;
1361 }
1362
1363 static HRESULT WINAPI OleInPlaceObjectWindowless_GetDropTarget(IOleInPlaceObjectWindowless *iface,
1364         IDropTarget **ppDropTarget)
1365 {
1366     ok(0, "unexpected call\n");
1367     return E_NOTIMPL;
1368 }
1369
1370 static const IOleInPlaceObjectWindowlessVtbl OleInPlaceObjectWindowlessVtbl = {
1371     OleInPlaceObject_QueryInterface,
1372     OleInPlaceObject_AddRef,
1373     OleInPlaceObject_Release,
1374     OleInPlaceObject_GetWindow,
1375     OleInPlaceObject_ContextSensitiveHelp,
1376     OleInPlaceObject_InPlaceDeactivate,
1377     OleInPlaceObject_UIDeactivate,
1378     OleInPlaceObject_SetObjectRects,
1379     OleInPlaceObjectWindowless_ReactivateAndUndo,
1380     OleInPlaceObjectWindowless_OnWindowMessage,
1381     OleInPlaceObjectWindowless_GetDropTarget
1382 };
1383
1384 static IOleInPlaceObjectWindowless OleInPlaceObjectWindowless = { &OleInPlaceObjectWindowlessVtbl };
1385
1386 static void *wrapped_iface_vtbl[100];
1387 static IUnknown wrapped_iface = { (IUnknownVtbl*)wrapped_iface_vtbl };
1388
1389 static HRESULT WINAPI wrapped_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
1390 {
1391     ok(0, "unexpected wrapped_QueryInterface call\n");
1392     *ppv = NULL;
1393     return E_NOINTERFACE;
1394 }
1395
1396 static ULONG WINAPI wrapped_AddRef(IUnknown *iface)
1397 {
1398     CHECK_EXPECT(wrapped_AddRef);
1399     return 2;
1400 }
1401
1402 static ULONG WINAPI wrapped_Release(IUnknown *iface)
1403 {
1404     CHECK_EXPECT(wrapped_Release);
1405     return 1;
1406 }
1407
1408 static HRESULT WINAPI wrapped_func_nocall(IUnknown *iface, int i, double d)
1409 {
1410     ok(0, "unexpected call\n");
1411     return E_FAIL;
1412 }
1413
1414 static HRESULT WINAPI wrapped_func(IUnknown *iface, int i, double d)
1415 {
1416     CHECK_EXPECT(wrapped_func);
1417     ok(iface == &wrapped_iface, "iface != wrapped_iface\n");
1418     ok(i == 10, "i = %d\n", i);
1419     ok(d == 32.0, "d = %lf\n", d);
1420     return S_OK;
1421 }
1422
1423 static void init_wrapped_iface(void)
1424 {
1425     unsigned i;
1426
1427     wrapped_iface_vtbl[0] = wrapped_QueryInterface;
1428     wrapped_iface_vtbl[1] = wrapped_AddRef;
1429     wrapped_iface_vtbl[2] = wrapped_Release;
1430
1431     for(i=3; i<100; i++)
1432         wrapped_iface_vtbl[i] = wrapped_func_nocall;
1433
1434     wrapped_iface_vtbl[63] = wrapped_func;
1435 }
1436
1437 static HRESULT ax_qi(REFIID riid, void **ppv)
1438 {
1439     if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IOleControl)) {
1440         *ppv = plugin_behavior == TEST_DISPONLY ? NULL : &OleControl;
1441     }else if(IsEqualGUID(riid, &IID_IQuickActivate)) {
1442         *ppv = no_quickact ? NULL : &QuickActivate;
1443     }else if(IsEqualGUID(riid, &IID_IPersistPropertyBag)) {
1444         *ppv = no_quickact ? NULL : &PersistPropertyBag;
1445     }else if(IsEqualGUID(riid, &IID_IDispatch)) {
1446         *ppv = &Dispatch;
1447     }else if(IsEqualGUID(riid, &IID_IProvideClassInfo)) {
1448         *ppv = &ProvideClassInfo;
1449     }else if(IsEqualGUID(riid, &IID_IConnectionPointContainer)) {
1450         *ppv = plugin_behavior != TEST_DISPONLY ? &ConnectionPointContainer : NULL;
1451     }else if(IsEqualGUID(riid, &IID_IViewObject) || IsEqualGUID(riid, &IID_IViewObject2)
1452             || IsEqualGUID(riid, &IID_IViewObjectEx)) {
1453         *ppv = plugin_behavior == TEST_DISPONLY ? NULL : &ViewObjectEx;
1454     }else if(IsEqualGUID(riid, &IID_IOleObject)) {
1455         *ppv = plugin_behavior == TEST_DISPONLY ? NULL : &OleObject;
1456     }else if(IsEqualGUID(riid, &IID_ITestActiveX)) {
1457         CHECK_EXPECT(QI_ITestActiveX);
1458         *ppv = &wrapped_iface;
1459     }else  if(IsEqualGUID(riid, &IID_IOleWindow) || IsEqualGUID(riid, &IID_IOleInPlaceObject)
1460        || IsEqualGUID(&IID_IOleInPlaceObjectWindowless, riid)) {
1461         *ppv = plugin_behavior == TEST_DISPONLY ? NULL : &OleInPlaceObjectWindowless;
1462     }else {
1463         trace("QI %s\n", debugstr_guid(riid));
1464         *ppv = NULL;
1465     }
1466
1467     return *ppv ? S_OK : E_NOINTERFACE;
1468 }
1469
1470 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
1471 {
1472     *ppv = NULL;
1473
1474     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) {
1475         *ppv = iface;
1476         return S_OK;
1477     }
1478
1479     if(IsEqualGUID(&IID_IMarshal, riid))
1480         return E_NOINTERFACE;
1481     if(IsEqualGUID(&CLSID_IdentityUnmarshal, riid))
1482         return E_NOINTERFACE;
1483     if(IsEqualGUID(&IID_IClassFactoryEx, riid))
1484         return E_NOINTERFACE; /* TODO */
1485
1486     ok(0, "unexpected riid %s\n", debugstr_guid(riid));
1487     return E_NOTIMPL;
1488 }
1489
1490 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
1491 {
1492     return 2;
1493 }
1494
1495 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
1496 {
1497     return 1;
1498 }
1499
1500 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
1501 {
1502     CHECK_EXPECT(CreateInstance);
1503
1504     ok(!outer, "outer = %p\n", outer);
1505     ok(IsEqualGUID(riid, &IID_IUnknown), "riid = %s\n", debugstr_guid(riid));
1506
1507     *ppv = &OleControl;
1508     return S_OK;
1509 }
1510
1511 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
1512 {
1513     ok(0, "unexpected call\n");
1514     return S_OK;
1515 }
1516
1517 static const IClassFactoryVtbl ClassFactoryVtbl = {
1518     ClassFactory_QueryInterface,
1519     ClassFactory_AddRef,
1520     ClassFactory_Release,
1521     ClassFactory_CreateInstance,
1522     ClassFactory_LockServer
1523 };
1524
1525 static IClassFactory activex_cf = { &ClassFactoryVtbl };
1526
1527 static void test_elem_dispex(IDispatchEx *dispex)
1528 {
1529     DISPPARAMS dp;
1530     EXCEPINFO ei;
1531     VARIANT v;
1532     DISPID id;
1533     BSTR str;
1534     HRESULT hres;
1535
1536     str = a2bstr("scriptprop");
1537     SET_EXPECT(GetIDsOfNames_scriptprop);
1538     hres = IDispatchEx_GetDispID(dispex, str, 0, &id);
1539     CHECK_CALLED(GetIDsOfNames_scriptprop);
1540     SysFreeString(str);
1541     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
1542     todo_wine
1543     ok(id == DISPID_SCRIPTPROP, "id = %d\n", id);
1544
1545     SET_EXPECT(Invoke_SECURITYCTX);
1546     SET_EXPECT(Invoke_SCRIPTPROP);
1547     memset(&dp, 0, sizeof(dp));
1548     memset(&ei, 0, sizeof(ei));
1549     V_VT(&v) = VT_EMPTY;
1550     hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
1551     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1552     ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
1553     ok(V_I4(&v) == 4, "V_I4(v) = %d\n", V_I4(&v));
1554     CHECK_CALLED(Invoke_SECURITYCTX);
1555     CHECK_CALLED(Invoke_SCRIPTPROP);
1556 }
1557
1558 static void test_iface_wrapping(IHTMLObjectElement *elem)
1559 {
1560     IHTMLObjectElement *elem2;
1561     IUnknown *unk, *unk2;
1562     ULONG ref;
1563     void **vtbl;
1564     HRESULT hres;
1565
1566     SET_EXPECT(QI_ITestActiveX);
1567     SET_EXPECT(wrapped_AddRef);
1568     SET_EXPECT(wrapped_Release);
1569     unk = (void*)0xdeadbeef;
1570     hres = IHTMLObjectElement_QueryInterface(elem, &IID_ITestActiveX, (void**)&unk);
1571     ok(hres == S_OK, "QueryInerface(IID_ITestActiveX failed: %08x\n", hres);
1572     CHECK_CALLED(QI_ITestActiveX);
1573     CHECK_CALLED(wrapped_AddRef);
1574     CHECK_CALLED(wrapped_Release);
1575
1576     /* See dlls/mshtml/ifacewrap.c */
1577     ok(unk != &wrapped_iface, "Unexpected unk %p, expected %p (%p, %p)\n", unk, &ViewObjectEx, unk->lpVtbl, &ViewObjectExVtbl);
1578     ok(unk->lpVtbl != wrapped_iface.lpVtbl, "unk->lpVtbl == wrapped_iface->lpVtbl\n");
1579     ok(unk->lpVtbl->QueryInterface != wrapped_QueryInterface, "QueryInterface not wrapped\n");
1580     ok(unk->lpVtbl->AddRef != wrapped_AddRef, "AddRef not wrapped\n");
1581     ok(unk->lpVtbl->Release != wrapped_Release, "Release not wrapped\n");
1582
1583     vtbl = (void**)unk->lpVtbl;
1584     ok(vtbl[4] != wrapped_func_nocall, "func not wrapped\n");
1585     ok(vtbl[63] != wrapped_func, "func not wrapped\n");
1586
1587     SET_EXPECT(wrapped_func);
1588     hres = ((HRESULT (WINAPI*)(IUnknown*,int,double))vtbl[63])(unk, 10, 32.0);
1589     ok(hres == S_OK, "wrapped_func returned %08x\n", hres);
1590     CHECK_CALLED(wrapped_func);
1591
1592     hres = IUnknown_QueryInterface(unk, &IID_IHTMLObjectElement, (void**)&elem2);
1593     ok(hres == S_OK, "Could not get IHTMLObjectElement from wrapped iface: %08x\n", hres);
1594     ok(iface_cmp((IUnknown*)elem2, (IUnknown*)elem), "elem2 != elem\n");
1595     IHTMLObjectElement_Release(elem2);
1596
1597     SET_EXPECT(wrapped_Release);
1598     ref = IUnknown_Release(unk);
1599     ok(!ref, "ref=%d\n", ref);
1600     CHECK_CALLED(wrapped_Release);
1601
1602     SET_EXPECT(QI_ITestActiveX);
1603     SET_EXPECT(wrapped_AddRef);
1604     SET_EXPECT(wrapped_Release);
1605     unk = (void*)0xdeadbeef;
1606     hres = IHTMLObjectElement_QueryInterface(elem, &IID_ITestActiveX, (void**)&unk2);
1607     ok(hres == S_OK, "QueryInerface(IID_ITestActiveX failed: %08x\n", hres);
1608     CHECK_CALLED(QI_ITestActiveX);
1609     CHECK_CALLED(wrapped_AddRef);
1610     CHECK_CALLED(wrapped_Release);
1611
1612     ok(unk != unk2, "unk == unk2\n");
1613
1614     SET_EXPECT(wrapped_Release);
1615     ref = IUnknown_Release(unk2);
1616     ok(!ref, "ref=%d\n", ref);
1617     CHECK_CALLED(wrapped_Release);
1618 }
1619
1620 static void test_object_elem(IHTMLDocument2 *doc)
1621 {
1622     IHTMLObjectElement *objelem;
1623     IHTMLDocument3 *doc3;
1624     IDispatchEx *dispex;
1625     IHTMLElement *elem;
1626     IDispatch *disp;
1627     VARIANT v;
1628     BSTR str;
1629     HRESULT hres;
1630
1631     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3);
1632     ok(hres == S_OK, "Could not get IHTMLDocument3 iface: %08x\n", hres);
1633
1634     str = a2bstr("objid");
1635     elem = (void*)0xdeadbeef;
1636     hres = IHTMLDocument3_getElementById(doc3, str, &elem);
1637     IHTMLDocument3_Release(doc3);
1638     SysFreeString(str);
1639     ok(hres == S_OK, "getElementById failed: %08x\n", hres);
1640     ok(elem != NULL, "elem == NULL\n");
1641
1642     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLObjectElement, (void**)&objelem);
1643     IHTMLElement_Release(elem);
1644     ok(hres == S_OK, "Could not get IHTMLObjectElement iface: %08x\n", hres);
1645
1646     SET_EXPECT(Invoke_SECURITYCTX);
1647     hres = IHTMLObjectElement_get_object(objelem, &disp);
1648     ok(hres == S_OK, "get_object failed: %08x\n", hres);
1649     ok(disp == &Dispatch, "disp != Dispatch\n");
1650     CHECK_CALLED(Invoke_SECURITYCTX);
1651
1652     hres = IHTMLObjectElement_QueryInterface(objelem, &IID_IDispatchEx, (void**)&dispex);
1653     ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
1654     test_elem_dispex(dispex);
1655     IDispatchEx_Release(dispex);
1656
1657     test_iface_wrapping(objelem);
1658
1659     hres = IHTMLObjectElement_get_width(objelem, &v);
1660     ok(hres == S_OK, "get_width failed: %08x\n", hres);
1661     ok(V_VT(&v) == VT_BSTR, "V_VT(width) = %d\n", V_VT(&v));
1662     ok(!strcmp_wa(V_BSTR(&v), "300"), "V_BSTR(width) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
1663     VariantClear(&v);
1664
1665     hres = IHTMLObjectElement_get_height(objelem, &v);
1666     ok(hres == S_OK, "get_height failed: %08x\n", hres);
1667     ok(V_VT(&v) == VT_BSTR, "V_VT(height) = %d\n", V_VT(&v));
1668     ok(!strcmp_wa(V_BSTR(&v), "200"), "V_BSTR(height) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
1669     VariantClear(&v);
1670
1671     V_VT(&v) = VT_I4;
1672     V_I4(&v) = 400;
1673     SET_EXPECT(OnAmbientPropertyChange_UNKNOWN);
1674     SET_EXPECT(Invoke_ENABLED);
1675     hres = IHTMLObjectElement_put_width(objelem, v);
1676     ok(hres == S_OK, "put_width failed: %08x\n", hres);
1677     CHECK_CALLED(OnAmbientPropertyChange_UNKNOWN);
1678     CHECK_CALLED(Invoke_ENABLED);
1679
1680     hres = IHTMLObjectElement_get_width(objelem, &v);
1681     ok(hres == S_OK, "get_width failed: %08x\n", hres);
1682     ok(V_VT(&v) == VT_BSTR, "V_VT(width) = %d\n", V_VT(&v));
1683     ok(!strcmp_wa(V_BSTR(&v), "400"), "V_BSTR(width) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
1684     VariantClear(&v);
1685
1686     V_VT(&v) = VT_I4;
1687     V_I4(&v) = 250;
1688     SET_EXPECT(OnAmbientPropertyChange_UNKNOWN);
1689     SET_EXPECT(Invoke_ENABLED);
1690     hres = IHTMLObjectElement_put_height(objelem, v);
1691     ok(hres == S_OK, "put_height failed: %08x\n", hres);
1692     CHECK_CALLED(OnAmbientPropertyChange_UNKNOWN);
1693     CHECK_CALLED(Invoke_ENABLED);
1694
1695     hres = IHTMLObjectElement_get_height(objelem, &v);
1696     ok(hres == S_OK, "get_height failed: %08x\n", hres);
1697     ok(V_VT(&v) == VT_BSTR, "V_VT(height) = %d\n", V_VT(&v));
1698     ok(!strcmp_wa(V_BSTR(&v), "250"), "V_BSTR(height) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
1699     VariantClear(&v);
1700
1701     IHTMLObjectElement_Release(objelem);
1702 }
1703
1704 static void test_container(IHTMLDocument2 *doc_obj)
1705 {
1706     IHTMLWindow2 *parent_window, *html_window;
1707     IServiceProvider *serv_prov;
1708     IOleContainer *container;
1709     IHTMLDocument2 *doc;
1710     IUnknown *unk;
1711     HRESULT hres;
1712
1713     container = NULL;
1714     hres = IOleClientSite_GetContainer(client_site, &container);
1715     ok(hres == S_OK, "GetContainer failed: %08x\n", hres);
1716     ok(container != NULL, "container == NULL\n");
1717
1718     hres = IHTMLDocument2_get_parentWindow(doc_obj, &parent_window);
1719     ok(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
1720     ok(parent_window != NULL, "parentWindow == NULL\n");
1721
1722     hres = IHTMLWindow2_get_document(parent_window, &doc);
1723     ok(hres == S_OK, "get_document failed: %08x\n", hres);
1724     ok(doc != NULL, "doc == NULL\n");
1725     ok(iface_cmp((IUnknown*)doc, (IUnknown*)container), "container != doc\n");
1726     IHTMLDocument2_Release(doc);
1727
1728     hres = IOleClientSite_QueryInterface(client_site, &IID_IServiceProvider, (void**)&serv_prov);
1729     ok(hres == S_OK, "Could not get IServiceProvider iface: %08x\n", hres);
1730
1731     hres = IServiceProvider_QueryService(serv_prov, &IID_IHTMLWindow2, &IID_IHTMLWindow2, (void**)&html_window);
1732     ok(hres == S_OK, "Could not get IHTMLWindow2 service: %08x\n", hres);
1733     todo_wine
1734     ok(!iface_cmp((IUnknown*)html_window, (IUnknown*)parent_window), "html_window != parent_window\n");
1735     IHTMLWindow2_Release(html_window);
1736
1737     SET_EXPECT(QueryService_TestActiveX);
1738     hres = IServiceProvider_QueryService(serv_prov, &CLSID_TestActiveX, &IID_IUnknown, (void**)&unk);
1739     ok(hres == S_OK, "QueryService(CLSID_TestActiveX) failed: %08x\n", hres);
1740     ok(unk == (IUnknown*)&OleObject, "unexpected unk %p\n", unk);
1741     CHECK_CALLED(QueryService_TestActiveX);
1742
1743     IServiceProvider_Release(serv_prov);
1744
1745     IHTMLWindow2_Release(parent_window);
1746     IOleContainer_Release(container);
1747 }
1748
1749 static void test_ui_activate(void)
1750 {
1751     IOleInPlaceSite *ip_site;
1752     HRESULT hres;
1753
1754     hres = IOleClientSite_QueryInterface(client_site, &IID_IOleInPlaceSite, (void**)&ip_site);
1755     ok(hres == S_OK, "Could not get IOleInPlaceSite iface: %08x\n", hres);
1756
1757     SET_EXPECT(Invoke_ENABLED);
1758     hres = IOleInPlaceSite_OnUIActivate(ip_site);
1759     ok(hres == S_OK, "OnUIActivate failed: %08x\n", hres);
1760     CHECK_CALLED(Invoke_ENABLED);
1761
1762     IOleInPlaceSite_Release(ip_site);
1763 }
1764
1765 static HRESULT cs_qi(REFIID,void **);
1766 static IOleDocumentView *view;
1767
1768 static HRESULT WINAPI InPlaceFrame_QueryInterface(IOleInPlaceFrame *iface, REFIID riid, void **ppv)
1769 {
1770     static const GUID undocumented_frame_iid = {0xfbece6c9,0x48d7,0x4a37,{0x8f,0xe3,0x6a,0xd4,0x27,0x2f,0xdd,0xac}};
1771
1772     if(!IsEqualGUID(&undocumented_frame_iid, riid))
1773         ok(0, "unexpected riid %s\n", debugstr_guid(riid));
1774
1775     *ppv = NULL;
1776     return E_NOINTERFACE;
1777 }
1778
1779 static ULONG WINAPI InPlaceFrame_AddRef(IOleInPlaceFrame *iface)
1780 {
1781     return 2;
1782 }
1783
1784 static ULONG WINAPI InPlaceFrame_Release(IOleInPlaceFrame *iface)
1785 {
1786     return 1;
1787 }
1788
1789 static HRESULT WINAPI InPlaceFrame_GetWindow(IOleInPlaceFrame *iface, HWND *phwnd)
1790 {
1791     return E_NOTIMPL;
1792 }
1793
1794 static HRESULT WINAPI InPlaceFrame_ContextSensitiveHelp(IOleInPlaceFrame *iface, BOOL fEnterMode)
1795 {
1796     return E_NOTIMPL;
1797 }
1798
1799 static HRESULT WINAPI InPlaceFrame_GetBorder(IOleInPlaceFrame *iface, LPRECT lprectBorder)
1800 {
1801     return E_NOTIMPL;
1802 }
1803
1804 static HRESULT WINAPI InPlaceFrame_RequestBorderSpace(IOleInPlaceFrame *iface,
1805         LPCBORDERWIDTHS pborderwidths)
1806 {
1807     return E_NOTIMPL;
1808 }
1809
1810 static HRESULT WINAPI InPlaceFrame_SetBorderSpace(IOleInPlaceFrame *iface,
1811         LPCBORDERWIDTHS pborderwidths)
1812 {
1813     return S_OK;
1814 }
1815
1816 static HRESULT WINAPI InPlaceUIWindow_SetActiveObject(IOleInPlaceFrame *iface,
1817         IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
1818 {
1819     return S_OK;
1820 }
1821
1822 static HRESULT WINAPI InPlaceFrame_SetActiveObject(IOleInPlaceFrame *iface,
1823         IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
1824 {
1825     return S_OK;
1826 }
1827
1828 static HRESULT WINAPI InPlaceFrame_InsertMenus(IOleInPlaceFrame *iface, HMENU hmenuShared,
1829         LPOLEMENUGROUPWIDTHS lpMenuWidths)
1830 {
1831     return E_NOTIMPL;
1832 }
1833
1834 static HRESULT WINAPI InPlaceFrame_SetMenu(IOleInPlaceFrame *iface, HMENU hmenuShared,
1835         HOLEMENU holemenu, HWND hwndActiveObject)
1836 {
1837     ok(0, "unexpected call\n");
1838     return E_NOTIMPL;
1839 }
1840
1841 static HRESULT WINAPI InPlaceFrame_RemoveMenus(IOleInPlaceFrame *iface, HMENU hmenuShared)
1842 {
1843     ok(0, "unexpected call\n");
1844     return E_NOTIMPL;
1845 }
1846
1847 static HRESULT WINAPI InPlaceFrame_SetStatusText(IOleInPlaceFrame *iface, LPCOLESTR pszStatusText)
1848 {
1849     return S_OK;
1850 }
1851
1852 static HRESULT WINAPI InPlaceFrame_EnableModeless(IOleInPlaceFrame *iface, BOOL fEnable)
1853 {
1854     return E_NOTIMPL;
1855 }
1856
1857 static HRESULT WINAPI InPlaceFrame_TranslateAccelerator(IOleInPlaceFrame *iface, LPMSG lpmsg, WORD wID)
1858 {
1859     ok(0, "unexpected call\n");
1860     return E_NOTIMPL;
1861 }
1862
1863 static const IOleInPlaceFrameVtbl InPlaceFrameVtbl = {
1864     InPlaceFrame_QueryInterface,
1865     InPlaceFrame_AddRef,
1866     InPlaceFrame_Release,
1867     InPlaceFrame_GetWindow,
1868     InPlaceFrame_ContextSensitiveHelp,
1869     InPlaceFrame_GetBorder,
1870     InPlaceFrame_RequestBorderSpace,
1871     InPlaceFrame_SetBorderSpace,
1872     InPlaceFrame_SetActiveObject,
1873     InPlaceFrame_InsertMenus,
1874     InPlaceFrame_SetMenu,
1875     InPlaceFrame_RemoveMenus,
1876     InPlaceFrame_SetStatusText,
1877     InPlaceFrame_EnableModeless,
1878     InPlaceFrame_TranslateAccelerator
1879 };
1880
1881 static IOleInPlaceFrame InPlaceFrame = { &InPlaceFrameVtbl };
1882
1883 static const IOleInPlaceFrameVtbl InPlaceUIWindowVtbl = {
1884     InPlaceFrame_QueryInterface,
1885     InPlaceFrame_AddRef,
1886     InPlaceFrame_Release,
1887     InPlaceFrame_GetWindow,
1888     InPlaceFrame_ContextSensitiveHelp,
1889     InPlaceFrame_GetBorder,
1890     InPlaceFrame_RequestBorderSpace,
1891     InPlaceFrame_SetBorderSpace,
1892     InPlaceUIWindow_SetActiveObject,
1893 };
1894
1895 static IOleInPlaceFrame InPlaceUIWindow = { &InPlaceUIWindowVtbl };
1896
1897 static HRESULT WINAPI InPlaceSite_QueryInterface(IOleInPlaceSite *iface, REFIID riid, void **ppv)
1898 {
1899     return cs_qi(riid, ppv);
1900 }
1901
1902 static ULONG WINAPI InPlaceSite_AddRef(IOleInPlaceSite *iface)
1903 {
1904     return 2;
1905 }
1906
1907 static ULONG WINAPI InPlaceSite_Release(IOleInPlaceSite *iface)
1908 {
1909     return 1;
1910 }
1911
1912 static HRESULT WINAPI InPlaceSite_GetWindow(IOleInPlaceSite *iface, HWND *phwnd)
1913 {
1914     *phwnd = container_hwnd;
1915     return S_OK;
1916 }
1917
1918 static HRESULT WINAPI InPlaceSite_ContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode)
1919 {
1920     ok(0, "unexpected call\n");
1921     return E_NOTIMPL;
1922 }
1923
1924 static HRESULT WINAPI InPlaceSite_CanInPlaceActivate(IOleInPlaceSite *iface)
1925 {
1926     return S_OK;
1927 }
1928
1929 static HRESULT WINAPI InPlaceSite_OnInPlaceActivate(IOleInPlaceSite *iface)
1930 {
1931     return S_OK;
1932 }
1933
1934 static HRESULT WINAPI InPlaceSite_OnUIActivate(IOleInPlaceSite *iface)
1935 {
1936     return S_OK;
1937 }
1938
1939 static HRESULT WINAPI InPlaceSite_GetWindowContext(IOleInPlaceSite *iface,
1940         IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
1941         LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
1942 {
1943     static const RECT rect = {0,0,500,500};
1944
1945     *ppFrame = &InPlaceFrame;
1946     *ppDoc = (IOleInPlaceUIWindow*)&InPlaceUIWindow;
1947     *lprcPosRect = rect;
1948     *lprcClipRect = rect;
1949
1950     lpFrameInfo->fMDIApp = FALSE;
1951     lpFrameInfo->hwndFrame = container_hwnd;
1952     lpFrameInfo->haccel = NULL;
1953     lpFrameInfo->cAccelEntries = 0;
1954
1955     return S_OK;
1956 }
1957
1958 static HRESULT WINAPI InPlaceSite_Scroll(IOleInPlaceSite *iface, SIZE scrollExtant)
1959 {
1960     return E_NOTIMPL;
1961 }
1962
1963 static HRESULT WINAPI InPlaceSite_OnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable)
1964 {
1965     return S_OK;
1966 }
1967
1968 static HRESULT WINAPI InPlaceSite_OnInPlaceDeactivate(IOleInPlaceSite *iface)
1969 {
1970     return S_OK;
1971 }
1972
1973 static HRESULT WINAPI InPlaceSite_DiscardUndoState(IOleInPlaceSite *iface)
1974 {
1975     return E_NOTIMPL;
1976 }
1977
1978 static HRESULT WINAPI InPlaceSite_DeactivateAndUndo(IOleInPlaceSite *iface)
1979 {
1980     return E_NOTIMPL;
1981 }
1982
1983 static HRESULT WINAPI InPlaceSite_OnPosRectChange(IOleInPlaceSite *iface, LPCRECT lprcPosRect)
1984 {
1985     return E_NOTIMPL;
1986 }
1987
1988 static const IOleInPlaceSiteVtbl InPlaceSiteVtbl = {
1989     InPlaceSite_QueryInterface,
1990     InPlaceSite_AddRef,
1991     InPlaceSite_Release,
1992     InPlaceSite_GetWindow,
1993     InPlaceSite_ContextSensitiveHelp,
1994     InPlaceSite_CanInPlaceActivate,
1995     InPlaceSite_OnInPlaceActivate,
1996     InPlaceSite_OnUIActivate,
1997     InPlaceSite_GetWindowContext,
1998     InPlaceSite_Scroll,
1999     InPlaceSite_OnUIDeactivate,
2000     InPlaceSite_OnInPlaceDeactivate,
2001     InPlaceSite_DiscardUndoState,
2002     InPlaceSite_DeactivateAndUndo,
2003     InPlaceSite_OnPosRectChange,
2004 };
2005
2006 static IOleInPlaceSite InPlaceSite = { &InPlaceSiteVtbl };
2007
2008 static HRESULT WINAPI ClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv)
2009 {
2010     return cs_qi(riid, ppv);
2011 }
2012
2013 static ULONG WINAPI ClientSite_AddRef(IOleClientSite *iface)
2014 {
2015     return 2;
2016 }
2017
2018 static ULONG WINAPI ClientSite_Release(IOleClientSite *iface)
2019 {
2020     return 1;
2021 }
2022
2023 static HRESULT WINAPI ClientSite_SaveObject(IOleClientSite *iface)
2024 {
2025     ok(0, "unexpected call\n");
2026     return E_NOTIMPL;
2027 }
2028
2029 static HRESULT WINAPI ClientSite_GetMoniker(IOleClientSite *iface, DWORD dwAssign, DWORD dwWhichMoniker,
2030         IMoniker **ppmon)
2031 {
2032     ok(0, "unexpected call\n");
2033     return E_NOTIMPL;
2034 }
2035
2036 static HRESULT WINAPI ClientSite_GetContainer(IOleClientSite *iface, IOleContainer **ppContainer)
2037 {
2038     return E_NOTIMPL;
2039 }
2040
2041 static HRESULT WINAPI ClientSite_ShowObject(IOleClientSite *iface)
2042 {
2043     ok(0, "unexpected call\n");
2044     return E_NOTIMPL;
2045 }
2046
2047 static HRESULT WINAPI ClientSite_OnShowWindow(IOleClientSite *iface, BOOL fShow)
2048 {
2049     ok(0, "unexpected call\n");
2050     return E_NOTIMPL;
2051 }
2052
2053 static HRESULT WINAPI ClientSite_RequestNewObjectLayout(IOleClientSite *iface)
2054 {
2055     ok(0, "unexpected call\n");
2056     return E_NOTIMPL;
2057 }
2058
2059 static const IOleClientSiteVtbl ClientSiteVtbl = {
2060     ClientSite_QueryInterface,
2061     ClientSite_AddRef,
2062     ClientSite_Release,
2063     ClientSite_SaveObject,
2064     ClientSite_GetMoniker,
2065     ClientSite_GetContainer,
2066     ClientSite_ShowObject,
2067     ClientSite_OnShowWindow,
2068     ClientSite_RequestNewObjectLayout
2069 };
2070
2071 static IOleClientSite ClientSite = { &ClientSiteVtbl };
2072
2073 static HRESULT WINAPI DocumentSite_QueryInterface(IOleDocumentSite *iface, REFIID riid, void **ppv)
2074 {
2075     return cs_qi(riid, ppv);
2076 }
2077
2078 static ULONG WINAPI DocumentSite_AddRef(IOleDocumentSite *iface)
2079 {
2080     return 2;
2081 }
2082
2083 static ULONG WINAPI DocumentSite_Release(IOleDocumentSite *iface)
2084 {
2085     return 1;
2086 }
2087
2088 static HRESULT WINAPI DocumentSite_ActivateMe(IOleDocumentSite *iface, IOleDocumentView *pViewToActivate)
2089 {
2090     RECT rect = {0,0,400,500};
2091     IOleDocument *document;
2092     HRESULT hres;
2093
2094     hres = IOleDocumentView_QueryInterface(pViewToActivate, &IID_IOleDocument, (void**)&document);
2095     ok(hres == S_OK, "could not get IOleDocument: %08x\n", hres);
2096
2097     hres = IOleDocument_CreateView(document, &InPlaceSite, NULL, 0, &view);
2098     IOleDocument_Release(document);
2099     ok(hres == S_OK, "CreateView failed: %08x\n", hres);
2100
2101     hres = IOleDocumentView_SetInPlaceSite(view, &InPlaceSite);
2102     ok(hres == S_OK, "SetInPlaceSite failed: %08x\n", hres);
2103
2104     hres = IOleDocumentView_UIActivate(view, TRUE);
2105     ok(hres == S_OK, "UIActivate failed: %08x\n", hres);
2106
2107     hres = IOleDocumentView_SetRect(view, &rect);
2108     ok(hres == S_OK, "SetRect failed: %08x\n", hres);
2109
2110     hres = IOleDocumentView_Show(view, TRUE);
2111     ok(hres == S_OK, "Show failed: %08x\n", hres);
2112
2113     return S_OK;
2114 }
2115
2116 static const IOleDocumentSiteVtbl DocumentSiteVtbl = {
2117     DocumentSite_QueryInterface,
2118     DocumentSite_AddRef,
2119     DocumentSite_Release,
2120     DocumentSite_ActivateMe
2121 };
2122
2123 static IOleDocumentSite DocumentSite = { &DocumentSiteVtbl };
2124
2125 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface,
2126                                                      REFIID riid, void **ppv)
2127 {
2128     return cs_qi(riid, ppv);
2129 }
2130
2131 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
2132 {
2133     return 2;
2134 }
2135
2136 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
2137 {
2138     return 1;
2139 }
2140
2141 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService,
2142         REFIID riid, void **ppv)
2143 {
2144     if(IsEqualGUID(&CLSID_TestActiveX, guidService)) {
2145         CHECK_EXPECT(QueryService_TestActiveX);
2146         ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", debugstr_guid(riid));
2147         *ppv = &OleObject;
2148         return S_OK;
2149     }
2150
2151     *ppv = NULL;
2152     return E_NOINTERFACE;
2153 }
2154
2155 static const IServiceProviderVtbl ServiceProviderVtbl = {
2156     ServiceProvider_QueryInterface,
2157     ServiceProvider_AddRef,
2158     ServiceProvider_Release,
2159     ServiceProvider_QueryService
2160 };
2161
2162 static IServiceProvider ServiceProvider = { &ServiceProviderVtbl };
2163
2164 static HRESULT cs_qi(REFIID riid, void **ppv)
2165 {
2166     *ppv = NULL;
2167
2168     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IOleClientSite, riid))
2169         *ppv = &ClientSite;
2170     else if(IsEqualGUID(&IID_IOleDocumentSite, riid))
2171         *ppv = &DocumentSite;
2172     else if(IsEqualGUID(&IID_IOleWindow, riid) || IsEqualGUID(&IID_IOleInPlaceSite, riid))
2173         *ppv = &InPlaceSite;
2174     else if(IsEqualGUID(riid, &IID_IServiceProvider))
2175         *ppv = &ServiceProvider;
2176
2177     return *ppv ? S_OK : E_NOINTERFACE;
2178 }
2179
2180 static IHTMLDocument2 *notif_doc;
2181 static BOOL doc_complete;
2182
2183 static HRESULT WINAPI PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface,
2184         REFIID riid, void**ppv)
2185 {
2186     if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) {
2187         *ppv = iface;
2188         return S_OK;
2189     }
2190
2191     ok(0, "unexpected call\n");
2192     return E_NOINTERFACE;
2193 }
2194
2195 static ULONG WINAPI PropertyNotifySink_AddRef(IPropertyNotifySink *iface)
2196 {
2197     return 2;
2198 }
2199
2200 static ULONG WINAPI PropertyNotifySink_Release(IPropertyNotifySink *iface)
2201 {
2202     return 1;
2203 }
2204
2205 static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID)
2206 {
2207     if(dispID == DISPID_READYSTATE){
2208         BSTR state;
2209         HRESULT hres;
2210
2211         static const WCHAR completeW[] = {'c','o','m','p','l','e','t','e',0};
2212
2213         hres = IHTMLDocument2_get_readyState(notif_doc, &state);
2214         ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
2215
2216         if(!lstrcmpW(state, completeW))
2217             doc_complete = TRUE;
2218
2219         SysFreeString(state);
2220     }
2221
2222     return S_OK;
2223 }
2224
2225 static HRESULT WINAPI PropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID)
2226 {
2227     ok(0, "unexpected call\n");
2228     return E_NOTIMPL;
2229 }
2230
2231 static IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = {
2232     PropertyNotifySink_QueryInterface,
2233     PropertyNotifySink_AddRef,
2234     PropertyNotifySink_Release,
2235     PropertyNotifySink_OnChanged,
2236     PropertyNotifySink_OnRequestEdit
2237 };
2238
2239 static IPropertyNotifySink PropertyNotifySink = { &PropertyNotifySinkVtbl };
2240
2241 static void doc_load_string(IHTMLDocument2 *doc, const char *str)
2242 {
2243     IPersistStreamInit *init;
2244     IStream *stream;
2245     HGLOBAL mem;
2246     SIZE_T len;
2247
2248     notif_doc = doc;
2249
2250     doc_complete = FALSE;
2251     len = strlen(str);
2252     mem = GlobalAlloc(0, len);
2253     memcpy(mem, str, len);
2254     CreateStreamOnHGlobal(mem, TRUE, &stream);
2255
2256     IHTMLDocument2_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&init);
2257
2258     IPersistStreamInit_Load(init, stream);
2259     IPersistStreamInit_Release(init);
2260     IStream_Release(stream);
2261 }
2262
2263 static void do_advise(IUnknown *unk, REFIID riid, IUnknown *unk_advise)
2264 {
2265     IConnectionPointContainer *container;
2266     IConnectionPoint *cp;
2267     DWORD cookie;
2268     HRESULT hres;
2269
2270     hres = IUnknown_QueryInterface(unk, &IID_IConnectionPointContainer, (void**)&container);
2271     ok(hres == S_OK, "QueryInterface(IID_IConnectionPointContainer) failed: %08x\n", hres);
2272
2273     hres = IConnectionPointContainer_FindConnectionPoint(container, riid, &cp);
2274     IConnectionPointContainer_Release(container);
2275     ok(hres == S_OK, "FindConnectionPoint failed: %08x\n", hres);
2276
2277     hres = IConnectionPoint_Advise(cp, unk_advise, &cookie);
2278     IConnectionPoint_Release(cp);
2279     ok(hres == S_OK, "Advise failed: %08x\n", hres);
2280 }
2281
2282 static void set_client_site(IHTMLDocument2 *doc, BOOL set)
2283 {
2284     IOleObject *oleobj;
2285     HRESULT hres;
2286
2287     if(!set && view) {
2288         IOleDocumentView_Show(view, FALSE);
2289         IOleDocumentView_CloseView(view, 0);
2290         IOleDocumentView_SetInPlaceSite(view, NULL);
2291         IOleDocumentView_Release(view);
2292         view = NULL;
2293     }
2294
2295     hres = IHTMLDocument2_QueryInterface(doc, &IID_IOleObject, (void**)&oleobj);
2296     ok(hres == S_OK, "Could not et IOleObject: %08x\n", hres);
2297
2298     hres = IOleObject_SetClientSite(oleobj, set ? &ClientSite : NULL);
2299     ok(hres == S_OK, "SetClientSite failed: %08x\n", hres);
2300
2301     if(set) {
2302         IHlinkTarget *hlink;
2303
2304         hres = IOleObject_QueryInterface(oleobj, &IID_IHlinkTarget, (void**)&hlink);
2305         ok(hres == S_OK, "Could not get IHlinkTarget iface: %08x\n", hres);
2306
2307         hres = IHlinkTarget_Navigate(hlink, 0, NULL);
2308         ok(hres == S_OK, "Navgate failed: %08x\n", hres);
2309
2310         IHlinkTarget_Release(hlink);
2311     }
2312
2313     IOleObject_Release(oleobj);
2314 }
2315 static IHTMLDocument2 *create_document(void)
2316 {
2317     IHTMLDocument2 *doc;
2318     HRESULT hres;
2319
2320     hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2321             &IID_IHTMLDocument2, (void**)&doc);
2322     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
2323
2324     return doc;
2325 }
2326
2327 static IHTMLDocument2 *create_doc(const char *str)
2328 {
2329     IHTMLDocument2 *doc;
2330     MSG msg;
2331
2332     doc = create_document();
2333     set_client_site(doc, TRUE);
2334     doc_load_string(doc, str);
2335     do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
2336
2337     while(!doc_complete && GetMessage(&msg, NULL, 0, 0)) {
2338         TranslateMessage(&msg);
2339         DispatchMessage(&msg);
2340     }
2341
2342     return doc;
2343 }
2344
2345 static void release_doc(IHTMLDocument2 *doc)
2346 {
2347     ULONG ref;
2348
2349     set_client_site(doc, FALSE);
2350     ref = IHTMLDocument2_Release(doc);
2351     ok(!ref || broken(ref == 1) /* Vista */, "ref = %d\n", ref);
2352
2353     if(client_site) {
2354         IOleClientSite_Release(client_site);
2355         client_site = NULL;
2356     }
2357
2358     if(plugin_hwnd) {
2359         DestroyWindow(plugin_hwnd);
2360         plugin_hwnd = NULL;
2361     }
2362 }
2363
2364 static void init_test(int behavior)
2365 {
2366     plugin_behavior = behavior;
2367
2368     no_quickact = behavior == TEST_NOQUICKACT || behavior == TEST_DISPONLY;
2369 }
2370
2371 static void test_event_call(void)
2372 {
2373     VARIANT res, args[2];
2374     DISPPARAMS dp = {args};
2375     EXCEPINFO ei = {0};
2376     HRESULT hres;
2377
2378     V_VT(&res) = VT_EMPTY;
2379     hres = IDispatch_Invoke(sink_disp, 1, &IID_NULL, 0, DISPATCH_METHOD, &dp, &res, &ei, NULL);
2380     ok(hres == S_OK, "Invoke failed: %08x\n", hres);
2381     ok(V_VT(&res) == VT_I4 && V_I4(&res) == 6, "unexpected result\n");
2382
2383     V_VT(args) = VT_I4;
2384     V_I4(args) = 2;
2385     V_VT(args+1) = VT_I4;
2386     V_I4(args+1) = 3;
2387     dp.cArgs = 2;
2388     V_VT(&res) = VT_EMPTY;
2389     hres = IDispatch_Invoke(sink_disp, 2, &IID_NULL, 0, DISPATCH_METHOD, &dp, &res, &ei, NULL);
2390     ok(hres == S_OK, "Invoke failed: %08x\n", hres);
2391     ok(V_VT(&res) == VT_I4 && V_I4(&res) == 7, "unexpected result: %d\n", V_I4(&res));
2392
2393     V_VT(&res) = VT_ERROR;
2394     hres = IDispatch_Invoke(sink_disp, 10, &IID_NULL, 0, DISPATCH_METHOD, &dp, &res, &ei, NULL);
2395     ok(hres == S_OK, "Invoke failed: %08x\n", hres);
2396     ok(V_VT(&res) == VT_EMPTY, "V_VT(res) = %d\n", V_VT(&res));
2397 }
2398
2399 static void test_flash_ax(void)
2400 {
2401     IHTMLDocument2 *doc;
2402
2403     init_test(TEST_FLASH);
2404
2405     SET_EXPECT(CreateInstance);
2406     SET_EXPECT(FreezeEvents_TRUE);
2407     SET_EXPECT(QuickActivate);
2408     SET_EXPECT(FreezeEvents_FALSE);
2409     SET_EXPECT(IPersistPropertyBag_Load);
2410     SET_EXPECT(Invoke_READYSTATE);
2411     SET_EXPECT(Invoke_SECURITYCTX);
2412     SET_EXPECT(Invoke_SCRIPTCALL);
2413     SET_EXPECT(SetExtent);
2414     SET_EXPECT(GetExtent);
2415     SET_EXPECT(DoVerb);
2416
2417     doc = create_doc(object_ax_str);
2418
2419     CHECK_CALLED(CreateInstance);
2420     todo_wine
2421     CHECK_CALLED(FreezeEvents_TRUE);
2422     CHECK_CALLED(QuickActivate);
2423     todo_wine
2424     CHECK_CALLED(FreezeEvents_FALSE);
2425     CHECK_CALLED(IPersistPropertyBag_Load);
2426     CHECK_CALLED(Invoke_READYSTATE);
2427     CHECK_CALLED(Invoke_SECURITYCTX);
2428     CHECK_CALLED(Invoke_SCRIPTCALL);
2429     todo_wine
2430     CHECK_CALLED(SetExtent);
2431     todo_wine
2432     CHECK_CALLED(GetExtent);
2433     CHECK_CALLED(DoVerb);
2434
2435     /* Set in DoVerb */
2436     CHECK_CALLED(InPlaceObject_GetWindow);
2437     CHECK_CALLED(SetObjectRects);
2438
2439     test_ui_activate();
2440     test_container(notif_doc);
2441     test_object_elem(notif_doc);
2442
2443     SET_EXPECT(UIDeactivate);
2444     SET_EXPECT(Invoke_ENABLED);
2445     SET_EXPECT(Invoke_VALID);
2446     SET_EXPECT(InPlaceDeactivate);
2447     SET_EXPECT(Close);
2448     SET_EXPECT(SetClientSite_NULL);
2449     release_doc(doc);
2450     CHECK_CALLED(UIDeactivate);
2451     todo_wine
2452     CHECK_CALLED(Invoke_ENABLED);
2453     todo_wine
2454     CHECK_CALLED(Invoke_VALID);
2455     CHECK_CALLED(InPlaceDeactivate);
2456     CHECK_CALLED(Close);
2457     CHECK_CALLED(SetClientSite_NULL);
2458 }
2459
2460 static void test_noquickact_ax(void)
2461 {
2462     IHTMLDocument2 *doc;
2463
2464     init_test(TEST_NOQUICKACT);
2465
2466     SET_EXPECT(CreateInstance);
2467     SET_EXPECT(FreezeEvents_TRUE);
2468     SET_EXPECT(GetMiscStatus);
2469     SET_EXPECT(SetClientSite);
2470     SET_EXPECT(SetAdvise);
2471     SET_EXPECT(GetViewStatus);
2472     SET_EXPECT(FreezeEvents_FALSE);
2473     SET_EXPECT(Invoke_READYSTATE);
2474     SET_EXPECT(Invoke_SECURITYCTX);
2475     SET_EXPECT(Invoke_SCRIPTCALL);
2476     SET_EXPECT(SetExtent);
2477     SET_EXPECT(GetExtent);
2478     SET_EXPECT(DoVerb);
2479
2480     doc = create_doc(object_ax_str);
2481
2482     CHECK_CALLED(CreateInstance);
2483     todo_wine CHECK_CALLED(FreezeEvents_TRUE);
2484     CHECK_CALLED(GetMiscStatus);
2485     CHECK_CALLED(SetClientSite);
2486     CHECK_CALLED(SetAdvise);
2487     CHECK_CALLED(GetViewStatus);
2488     todo_wine CHECK_CALLED(FreezeEvents_FALSE);
2489     CHECK_CALLED(Invoke_READYSTATE);
2490     CHECK_CALLED(Invoke_SECURITYCTX);
2491     CHECK_CALLED(Invoke_SCRIPTCALL);
2492     todo_wine CHECK_CALLED(SetExtent);
2493     todo_wine CHECK_CALLED(GetExtent);
2494     CHECK_CALLED(DoVerb);
2495
2496     /* Set in DoVerb */
2497     CHECK_CALLED(InPlaceObject_GetWindow);
2498     CHECK_CALLED(SetObjectRects);
2499
2500     SET_EXPECT(InPlaceDeactivate);
2501     SET_EXPECT(Close);
2502     SET_EXPECT(SetClientSite_NULL);
2503     release_doc(doc);
2504     CHECK_CALLED(InPlaceDeactivate);
2505     CHECK_CALLED(Close);
2506     CHECK_CALLED(SetClientSite_NULL);
2507 }
2508
2509 static void test_event_binding(void)
2510 {
2511     IHTMLDocument2 *doc;
2512
2513     init_test(TEST_FLASH);
2514
2515     SET_EXPECT(CreateInstance);
2516     SET_EXPECT(FreezeEvents_TRUE);
2517     SET_EXPECT(QuickActivate);
2518     SET_EXPECT(FreezeEvents_FALSE);
2519     SET_EXPECT(IPersistPropertyBag_Load);
2520     SET_EXPECT(Invoke_READYSTATE);
2521     SET_EXPECT(SetExtent);
2522     SET_EXPECT(GetExtent);
2523     SET_EXPECT(DoVerb);
2524
2525     SET_EXPECT(GetClassInfo);
2526     SET_EXPECT(OnAmbientPropertyChange_UNKNOWN);
2527     SET_EXPECT(FindConnectionPoint);
2528     SET_EXPECT(Advise);
2529
2530     doc = create_doc(event_binding_str);
2531
2532     CHECK_CALLED(CreateInstance);
2533     todo_wine
2534     CHECK_CALLED(FreezeEvents_TRUE);
2535     CHECK_CALLED(QuickActivate);
2536     todo_wine
2537     CHECK_CALLED(FreezeEvents_FALSE);
2538     CHECK_CALLED(IPersistPropertyBag_Load);
2539     CHECK_CALLED(Invoke_READYSTATE);
2540     todo_wine
2541     CHECK_CALLED(SetExtent);
2542     todo_wine
2543     CHECK_CALLED(GetExtent);
2544     CHECK_CALLED(DoVerb);
2545
2546     /* Set in DoVerb */
2547     CHECK_CALLED(InPlaceObject_GetWindow);
2548     CHECK_CALLED(SetObjectRects);
2549
2550     CHECK_CALLED(GetClassInfo);
2551     todo_wine
2552     CHECK_CALLED(OnAmbientPropertyChange_UNKNOWN);
2553     CHECK_CALLED(FindConnectionPoint);
2554     CHECK_CALLED(Advise);
2555
2556     test_event_call();
2557
2558     SET_EXPECT(InPlaceDeactivate);
2559     SET_EXPECT(Close);
2560     SET_EXPECT(SetClientSite_NULL);
2561     SET_EXPECT(FindConnectionPoint);
2562     SET_EXPECT(Unadvise);
2563     release_doc(doc);
2564     CHECK_CALLED(InPlaceDeactivate);
2565     CHECK_CALLED(Close);
2566     CHECK_CALLED(SetClientSite_NULL);
2567     CHECK_CALLED(FindConnectionPoint);
2568     CHECK_CALLED(Unadvise);
2569 }
2570
2571 static void test_nooleobj_ax(void)
2572 {
2573     IHTMLDocument2 *doc;
2574
2575     init_test(TEST_DISPONLY);
2576
2577     SET_EXPECT(CreateInstance);
2578     SET_EXPECT(Invoke_READYSTATE);
2579     SET_EXPECT(Invoke_SECURITYCTX);
2580     SET_EXPECT(Invoke_SCRIPTCALL);
2581
2582     doc = create_doc(object_ax_str);
2583
2584     CHECK_CALLED(CreateInstance);
2585     CHECK_CALLED(Invoke_READYSTATE);
2586     CHECK_CALLED(Invoke_SECURITYCTX);
2587     CHECK_CALLED(Invoke_SCRIPTCALL);
2588
2589     release_doc(doc);
2590 }
2591
2592 static LRESULT WINAPI wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
2593 {
2594     return DefWindowProc(hwnd, msg, wParam, lParam);
2595 }
2596
2597 static HWND create_container_window(void)
2598 {
2599     static const WCHAR html_document_testW[] =
2600         {'H','T','M','L','D','o','c','u','m','e','n','t','T','e','s','t',0};
2601     static WNDCLASSEXW wndclass = {
2602         sizeof(WNDCLASSEXW),
2603         0,
2604         wnd_proc,
2605         0, 0, NULL, NULL, NULL, NULL, NULL,
2606         html_document_testW,
2607         NULL
2608     };
2609
2610     RegisterClassExW(&wndclass);
2611     return CreateWindowW(html_document_testW, html_document_testW,
2612             WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
2613             515, 530, NULL, NULL, NULL, NULL);
2614 }
2615
2616 static void load_typelib(void)
2617 {
2618     WCHAR path[MAX_PATH];
2619     ITypeLib *typelib;
2620     HRESULT hres;
2621
2622     GetModuleFileNameW(NULL, path, MAX_PATH);
2623
2624     hres = LoadTypeLib(path, &typelib);
2625     ok(hres == S_OK, "LoadTypeLib failed: %08x\n", hres);
2626
2627     hres = ITypeLib_GetTypeInfoOfGuid(typelib, &DIID_DispActiveXTest, &actxtest_typeinfo);
2628     ok(hres == S_OK, "GetTypeInfoOfGuid(DIID_DispActiveXTest) failed: %08x\n", hres);
2629
2630     hres = ITypeLib_GetTypeInfoOfGuid(typelib, &CLSID_ActiveXTest, &class_typeinfo);
2631     ok(hres == S_OK, "GetTypeInfoOfGuid(CLSID_ActiveXTest) failed: %08x\n", hres);
2632
2633     ITypeLib_Release(typelib);
2634 }
2635
2636 static BOOL init_key(const char *key_name, const char *def_value, BOOL init)
2637 {
2638     HKEY hkey;
2639     DWORD res;
2640
2641     if(!init) {
2642         RegDeleteKey(HKEY_CLASSES_ROOT, key_name);
2643         return TRUE;
2644     }
2645
2646     res = RegCreateKeyA(HKEY_CLASSES_ROOT, key_name, &hkey);
2647     if(res != ERROR_SUCCESS)
2648         return FALSE;
2649
2650     if(def_value)
2651         res = RegSetValueA(hkey, NULL, REG_SZ, def_value, strlen(def_value));
2652
2653     RegCloseKey(hkey);
2654
2655     return res == ERROR_SUCCESS;
2656 }
2657
2658 static BOOL init_registry(BOOL init)
2659 {
2660     return init_key("TestActiveX\\CLSID", TESTACTIVEX_CLSID, init)
2661         && init_key("CLSID\\"TESTACTIVEX_CLSID"\\Implemented Categories\\{7dd95801-9882-11cf-9fa9-00aa006c42c4}",
2662                     NULL, init)
2663         && init_key("CLSID\\"TESTACTIVEX_CLSID"\\Implemented Categories\\{7dd95802-9882-11cf-9fa9-00aa006c42c4}",
2664                     NULL, init);
2665 }
2666
2667 static BOOL register_activex(void)
2668 {
2669     DWORD regid;
2670     HRESULT hres;
2671
2672     if(!init_registry(TRUE)) {
2673         init_registry(FALSE);
2674         return FALSE;
2675     }
2676
2677     hres = CoRegisterClassObject(&CLSID_TestActiveX, (IUnknown*)&activex_cf,
2678             CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &regid);
2679     ok(hres == S_OK, "Could not register control: %08x\n", hres);
2680
2681     return TRUE;
2682 }
2683
2684 static BOOL check_ie(void)
2685 {
2686     IHTMLDocument5 *doc;
2687     HRESULT hres;
2688
2689     static const WCHAR xW[] = {'x',0};
2690     static const WCHAR yW[] = {'y',0};
2691
2692     if(!lstrcmpW(xW, yW))
2693         return FALSE;
2694
2695     hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2696             &IID_IHTMLDocument5, (void**)&doc);
2697     if(FAILED(hres))
2698         return FALSE;
2699
2700     IHTMLDocument5_Release(doc);
2701     return TRUE;
2702 }
2703
2704 START_TEST(activex)
2705 {
2706     CoInitialize(NULL);
2707
2708     if(!check_ie()) {
2709         CoUninitialize();
2710         win_skip("Too old IE\n");
2711         return;
2712     }
2713
2714     if(is_ie_hardened()) {
2715         CoUninitialize();
2716         win_skip("IE running in Enhanced Security Configuration\n");
2717         return;
2718     }
2719
2720     init_wrapped_iface();
2721     load_typelib();
2722     container_hwnd = create_container_window();
2723     ShowWindow(container_hwnd, SW_SHOW);
2724
2725     if(register_activex()) {
2726         trace("Testing emulated flash embedding...\n");
2727         test_flash_ax();
2728         trace("Testing plugin without IQuickActivate iface...\n");
2729         test_noquickact_ax();
2730         trace("Testing plugin with IDispatch iface only...\n");
2731         test_nooleobj_ax();
2732         trace("Testing event object binding...\n");
2733         test_event_binding();
2734         init_registry(FALSE);
2735     }else {
2736         skip("Could not register ActiveX\n");
2737     }
2738
2739     if(actxtest_typeinfo)
2740         ITypeInfo_Release(actxtest_typeinfo);
2741     if(class_typeinfo)
2742         ITypeInfo_Release(class_typeinfo);
2743     DestroyWindow(container_hwnd);
2744     CoUninitialize();
2745 }