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