mshtml: Added more events tests.
[wine] / dlls / mshtml / tests / script.c
1 /*
2  * Copyright 2008-2009 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 "wininet.h"
30 #include "docobj.h"
31 #include "dispex.h"
32 #include "hlink.h"
33 #include "mshtml.h"
34 #include "mshtmhst.h"
35 #include "initguid.h"
36 #include "activscp.h"
37 #include "activdbg.h"
38 #include "objsafe.h"
39 #include "mshtmdid.h"
40 #include "mshtml_test.h"
41
42 DEFINE_GUID(CLSID_IdentityUnmarshal,0x0000001b,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
43
44 /* Defined as extern in urlmon.idl, but not exported by uuid.lib */
45 const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY =
46     {0x10200490,0xfa38,0x11d0,{0xac,0x0e,0x00,0xa0,0xc9,0xf,0xff,0xc0}};
47
48 #ifdef _WIN64
49
50 #define CTXARG_T DWORDLONG
51 #define IActiveScriptParseVtbl IActiveScriptParse64Vtbl
52 #define IActiveScriptParseProcedure2Vtbl IActiveScriptParseProcedure2_64Vtbl
53 #define IActiveScriptSiteDebug_Release IActiveScriptSiteDebug64_Release
54
55 #else
56
57 #define CTXARG_T DWORD
58 #define IActiveScriptParseVtbl IActiveScriptParse32Vtbl
59 #define IActiveScriptParseProcedure2Vtbl IActiveScriptParseProcedure2_32Vtbl
60 #define IActiveScriptSiteDebug_Release IActiveScriptSiteDebug32_Release
61
62 #endif
63
64 #define DEFINE_EXPECT(func) \
65     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
66
67 #define SET_EXPECT(func) \
68     do { called_ ## func = FALSE; expect_ ## func = TRUE; } while(0)
69
70 #define CHECK_EXPECT2(func) \
71     do { \
72         ok(expect_ ##func, "unexpected call " #func "\n"); \
73         called_ ## func = TRUE; \
74     }while(0)
75
76 #define CHECK_EXPECT(func) \
77     do { \
78         CHECK_EXPECT2(func); \
79         expect_ ## func = FALSE; \
80     }while(0)
81
82 #define CHECK_CALLED(func) \
83     do { \
84         ok(called_ ## func, "expected " #func "\n"); \
85         expect_ ## func = called_ ## func = FALSE; \
86     }while(0)
87
88 #define CHECK_CALLED_BROKEN(func) \
89     do { \
90         ok(called_ ## func || broken(!called_ ## func), "expected " #func "\n"); \
91         expect_ ## func = called_ ## func = FALSE; \
92     }while(0)
93
94 #define CHECK_NOT_CALLED(func) \
95     do { \
96         ok(!called_ ## func, "unexpected " #func "\n"); \
97         expect_ ## func = called_ ## func = FALSE; \
98     }while(0)
99
100 #define CLEAR_CALLED(func) \
101     expect_ ## func = called_ ## func = FALSE
102
103
104 DEFINE_EXPECT(CreateInstance);
105 DEFINE_EXPECT(GetInterfaceSafetyOptions);
106 DEFINE_EXPECT(SetInterfaceSafetyOptions);
107 DEFINE_EXPECT(InitNew);
108 DEFINE_EXPECT(Close);
109 DEFINE_EXPECT(SetProperty_HACK_TRIDENTEVENTSINK);
110 DEFINE_EXPECT(SetProperty_INVOKEVERSIONING);
111 DEFINE_EXPECT(SetProperty_ABBREVIATE_GLOBALNAME_RESOLUTION);
112 DEFINE_EXPECT(SetScriptSite);
113 DEFINE_EXPECT(GetScriptState);
114 DEFINE_EXPECT(SetScriptState_STARTED);
115 DEFINE_EXPECT(SetScriptState_CONNECTED);
116 DEFINE_EXPECT(SetScriptState_DISCONNECTED);
117 DEFINE_EXPECT(AddNamedItem);
118 DEFINE_EXPECT(ParseScriptText_script);
119 DEFINE_EXPECT(ParseScriptText_execScript);
120 DEFINE_EXPECT(GetScriptDispatch);
121 DEFINE_EXPECT(funcDisp);
122 DEFINE_EXPECT(script_divid_d);
123 DEFINE_EXPECT(script_testprop_d);
124 DEFINE_EXPECT(script_testprop_i);
125 DEFINE_EXPECT(script_testprop2_d);
126 DEFINE_EXPECT(AXQueryInterface_IActiveScript);
127 DEFINE_EXPECT(AXQueryInterface_IObjectSafety);
128 DEFINE_EXPECT(AXGetInterfaceSafetyOptions);
129 DEFINE_EXPECT(AXSetInterfaceSafetyOptions_IDispatch_caller);
130 DEFINE_EXPECT(AXSetInterfaceSafetyOptions_IDispatch_data);
131 DEFINE_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx_caller_secmgr);
132 DEFINE_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx_caller);
133 DEFINE_EXPECT(external_success);
134 DEFINE_EXPECT(QS_VariantConversion);
135 DEFINE_EXPECT(ChangeType);
136
137 #define TESTSCRIPT_CLSID "{178fc163-f585-4e24-9c13-4bb7faf80746}"
138 #define TESTACTIVEX_CLSID "{178fc163-f585-4e24-9c13-4bb7faf80646}"
139
140 #define DISPID_SCRIPT_TESTPROP   0x100000
141 #define DISPID_SCRIPT_TESTPROP2  0x100001
142
143 #define DISPID_EXTERNAL_OK             0x300000
144 #define DISPID_EXTERNAL_TRACE          0x300001
145 #define DISPID_EXTERNAL_REPORTSUCCESS  0x300002
146 #define DISPID_EXTERNAL_TODO_WINE_OK   0x300003
147
148 static const GUID CLSID_TestScript =
149     {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x07,0x46}};
150 static const GUID CLSID_TestActiveX =
151     {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x06,0x46}};
152
153 static IHTMLDocument2 *notif_doc;
154 static IOleDocumentView *view;
155 static IDispatchEx *window_dispex;
156 static BOOL doc_complete;
157 static IDispatch *script_disp;
158 static BOOL ax_objsafe;
159 static HWND container_hwnd;
160 static HRESULT ax_getopt_hres = S_OK, ax_setopt_dispex_hres = S_OK;
161 static HRESULT ax_setopt_disp_caller_hres = S_OK, ax_setopt_disp_data_hres = S_OK;
162 static BOOL skip_loadobject_tests;
163
164 static const char *debugstr_guid(REFIID riid)
165 {
166     static char buf[50];
167
168     sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
169             riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
170             riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
171             riid->Data4[5], riid->Data4[6], riid->Data4[7]);
172
173     return buf;
174 }
175
176 static int strcmp_wa(LPCWSTR strw, const char *stra)
177 {
178     CHAR buf[512];
179     WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL);
180     return lstrcmpA(stra, buf);
181 }
182
183 static BSTR a2bstr(const char *str)
184 {
185     BSTR ret;
186     int len;
187
188     if(!str)
189         return NULL;
190
191     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
192     ret = SysAllocStringLen(NULL, len);
193     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
194
195     return ret;
196 }
197
198 static BOOL init_key(const char *key_name, const char *def_value, BOOL init)
199 {
200     HKEY hkey;
201     DWORD res;
202
203     if(!init) {
204         RegDeleteKey(HKEY_CLASSES_ROOT, key_name);
205         return TRUE;
206     }
207
208     res = RegCreateKeyA(HKEY_CLASSES_ROOT, key_name, &hkey);
209     if(res != ERROR_SUCCESS)
210         return FALSE;
211
212     if(def_value)
213         res = RegSetValueA(hkey, NULL, REG_SZ, def_value, strlen(def_value));
214
215     RegCloseKey(hkey);
216
217     return res == ERROR_SUCCESS;
218 }
219
220 static HRESULT WINAPI PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface,
221         REFIID riid, void**ppv)
222 {
223     if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) {
224         *ppv = iface;
225         return S_OK;
226     }
227
228     return E_NOINTERFACE;
229 }
230
231 static ULONG WINAPI PropertyNotifySink_AddRef(IPropertyNotifySink *iface)
232 {
233     return 2;
234 }
235
236 static ULONG WINAPI PropertyNotifySink_Release(IPropertyNotifySink *iface)
237 {
238     return 1;
239 }
240
241 static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID)
242 {
243     if(dispID == DISPID_READYSTATE){
244         BSTR state;
245         HRESULT hres;
246
247         static const WCHAR completeW[] = {'c','o','m','p','l','e','t','e',0};
248
249         hres = IHTMLDocument2_get_readyState(notif_doc, &state);
250         ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
251
252         if(!lstrcmpW(state, completeW))
253             doc_complete = TRUE;
254
255         SysFreeString(state);
256     }
257
258     return S_OK;
259 }
260
261 static HRESULT WINAPI PropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID)
262 {
263     ok(0, "unexpected call\n");
264     return E_NOTIMPL;
265 }
266
267 static IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = {
268     PropertyNotifySink_QueryInterface,
269     PropertyNotifySink_AddRef,
270     PropertyNotifySink_Release,
271     PropertyNotifySink_OnChanged,
272     PropertyNotifySink_OnRequestEdit
273 };
274
275 static IPropertyNotifySink PropertyNotifySink = { &PropertyNotifySinkVtbl };
276
277 static HRESULT WINAPI VariantChangeType_QueryInterface(IVariantChangeType *iface, REFIID riid, void **ppv)
278 {
279     ok(0, "unexpected call %s\n", debugstr_guid(riid));
280     *ppv = NULL;
281     return E_NOINTERFACE;
282 }
283
284 static ULONG WINAPI VariantChangeType_AddRef(IVariantChangeType *iface)
285 {
286     return 2;
287 }
288
289 static ULONG WINAPI VariantChangeType_Release(IVariantChangeType *iface)
290 {
291     return 1;
292 }
293
294 static HRESULT WINAPI VariantChangeType_ChangeType(IVariantChangeType *iface, VARIANT *dst, VARIANT *src, LCID lcid, VARTYPE vt)
295 {
296     CHECK_EXPECT(ChangeType);
297
298     ok(dst != NULL, "dst = NULL\n");
299     ok(V_VT(dst) == VT_EMPTY, "V_VT(dst) = %d\n", V_VT(dst));
300     ok(src != NULL, "src = NULL\n");
301     ok(V_VT(src) == VT_I4, "V_VT(src) = %d\n", V_VT(src));
302     ok(V_I4(src) == 0xf0f0f0, "V_I4(src) = %x\n", V_I4(src));
303     ok(lcid == LOCALE_NEUTRAL, "lcid = %d\n", lcid);
304     ok(vt == VT_BSTR, "vt = %d\n", vt);
305
306     V_VT(dst) = VT_BSTR;
307     V_BSTR(dst) = a2bstr("red");
308     return S_OK;
309 }
310
311 static const IVariantChangeTypeVtbl VariantChangeTypeVtbl = {
312     VariantChangeType_QueryInterface,
313     VariantChangeType_AddRef,
314     VariantChangeType_Release,
315     VariantChangeType_ChangeType
316 };
317
318 static IVariantChangeType VChangeType = { &VariantChangeTypeVtbl };
319
320 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
321 {
322     ok(0, "unexpected call\n");
323     return E_NOINTERFACE;
324 }
325
326 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
327 {
328     return 2;
329 }
330
331 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
332 {
333     return 1;
334 }
335
336 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService,
337         REFIID riid, void **ppv)
338 {
339     if(IsEqualGUID(guidService, &SID_VariantConversion)) {
340         CHECK_EXPECT(QS_VariantConversion);
341         ok(IsEqualGUID(riid, &IID_IVariantChangeType), "uenxpected riid %s\n", debugstr_guid(riid));
342         *ppv = &VChangeType;
343         return S_OK;
344     }
345
346     ok(0, "unexpected service %s\n", debugstr_guid(guidService));
347     return E_NOINTERFACE;
348 }
349
350 static const IServiceProviderVtbl ServiceProviderVtbl = {
351     ServiceProvider_QueryInterface,
352     ServiceProvider_AddRef,
353     ServiceProvider_Release,
354     ServiceProvider_QueryService
355 };
356
357 static IServiceProvider caller_sp = { &ServiceProviderVtbl };
358
359 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
360 {
361     *ppv = NULL;
362
363     if(IsEqualGUID(riid, &IID_IUnknown)
364        || IsEqualGUID(riid, &IID_IDispatch)
365        || IsEqualGUID(riid, &IID_IDispatchEx))
366         *ppv = iface;
367     else
368         return E_NOINTERFACE;
369
370     return S_OK;
371 }
372
373 static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
374 {
375     return 2;
376 }
377
378 static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
379 {
380     return 1;
381 }
382
383 static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
384 {
385     ok(0, "unexpected call\n");
386     return E_NOTIMPL;
387 }
388
389 static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
390                                               LCID lcid, ITypeInfo **ppTInfo)
391 {
392     ok(0, "unexpected call\n");
393     return E_NOTIMPL;
394 }
395
396 static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
397                                                 LPOLESTR *rgszNames, UINT cNames,
398                                                 LCID lcid, DISPID *rgDispId)
399 {
400     ok(0, "unexpected call\n");
401     return E_NOTIMPL;
402 }
403
404 static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
405                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
406                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
407 {
408     ok(0, "unexpected call\n");
409     return E_NOTIMPL;
410 }
411
412 static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
413 {
414     ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
415     return E_NOTIMPL;
416 }
417
418 static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
419 {
420     ok(0, "unexpected call\n");
421     return E_NOTIMPL;
422 }
423
424 static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
425 {
426     ok(0, "unexpected call\n");
427     return E_NOTIMPL;
428 }
429
430 static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
431 {
432     ok(0, "unexpected call\n");
433     return E_NOTIMPL;
434 }
435
436 static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
437 {
438     ok(0, "unexpected call\n");
439     return E_NOTIMPL;
440 }
441
442 static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
443 {
444     ok(0, "unexpected call\n");
445     return E_NOTIMPL;
446 }
447
448 static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
449 {
450     ok(0, "unexpected call\n");
451     return E_NOTIMPL;
452 }
453
454 static HRESULT WINAPI funcDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
455         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
456 {
457     CHECK_EXPECT(funcDisp);
458
459     ok(id == DISPID_VALUE, "id = %d\n", id);
460     ok(lcid == 0, "lcid = %x\n", lcid);
461     ok(wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags);
462     ok(pdp != NULL, "pdp == NULL\n");
463     ok(pdp->cArgs == 2, "pdp->cArgs = %d\n", pdp->cArgs);
464     ok(pdp->cNamedArgs == 1, "pdp->cNamedArgs = %d\n", pdp->cNamedArgs);
465     ok(pdp->rgdispidNamedArgs[0] == DISPID_THIS, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
466     ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(rgvarg) = %d\n", V_VT(pdp->rgvarg));
467     ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(rgvarg[1]) = %d\n", V_VT(pdp->rgvarg));
468     ok(V_BOOL(pdp->rgvarg+1) == VARIANT_TRUE, "V_BOOL(rgvarg[1]) = %x\n", V_BOOL(pdp->rgvarg));
469     ok(pvarRes != NULL, "pvarRes == NULL\n");
470     ok(pei != NULL, "pei == NULL\n");
471     ok(!pspCaller, "pspCaller != NULL\n");
472
473     V_VT(pvarRes) = VT_I4;
474     V_I4(pvarRes) = 100;
475     return S_OK;
476 }
477
478 static IDispatchExVtbl testObjVtbl = {
479     DispatchEx_QueryInterface,
480     DispatchEx_AddRef,
481     DispatchEx_Release,
482     DispatchEx_GetTypeInfoCount,
483     DispatchEx_GetTypeInfo,
484     DispatchEx_GetIDsOfNames,
485     DispatchEx_Invoke,
486     DispatchEx_GetDispID,
487     funcDisp_InvokeEx,
488     DispatchEx_DeleteMemberByName,
489     DispatchEx_DeleteMemberByDispID,
490     DispatchEx_GetMemberProperties,
491     DispatchEx_GetMemberName,
492     DispatchEx_GetNextDispID,
493     DispatchEx_GetNameSpaceParent
494 };
495
496 static IDispatchEx funcDisp = { &testObjVtbl };
497
498 static HRESULT WINAPI scriptDisp_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
499 {
500     if(!strcmp_wa(bstrName, "testProp")) {
501         CHECK_EXPECT(script_testprop_d);
502         ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
503         *pid = DISPID_SCRIPT_TESTPROP;
504         return S_OK;
505     }
506
507     if(!strcmp_wa(bstrName, "testProp2")) {
508         CHECK_EXPECT(script_testprop2_d);
509         ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
510         *pid = DISPID_SCRIPT_TESTPROP2;
511         return S_OK;
512     }
513
514     if(!strcmp_wa(bstrName, "divid")) {
515         CHECK_EXPECT(script_divid_d);
516         ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
517         return E_FAIL;
518     }
519
520     ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName));
521     return E_NOTIMPL;
522 }
523
524 static HRESULT WINAPI scriptDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
525         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
526 {
527     switch(id) {
528     case DISPID_SCRIPT_TESTPROP:
529         CHECK_EXPECT(script_testprop_i);
530
531         ok(lcid == 0, "lcid = %x\n", lcid);
532         ok(wFlags == DISPATCH_PROPERTYGET, "wFlags = %x\n", wFlags);
533         ok(pdp != NULL, "pdp == NULL\n");
534         ok(pdp->cArgs == 0, "pdp->cArgs = %d\n", pdp->cArgs);
535         ok(pdp->cNamedArgs == 0, "pdp->cNamedArgs = %d\n", pdp->cNamedArgs);
536         ok(!pdp->rgdispidNamedArgs, "pdp->rgdispidNamedArgs != NULL\n");
537         ok(!pdp->rgvarg, "rgvarg != NULL\n");
538         ok(pvarRes != NULL, "pvarRes == NULL\n");
539         ok(pei != NULL, "pei == NULL\n");
540         ok(!pspCaller, "pspCaller != NULL\n");
541
542         V_VT(pvarRes) = VT_NULL;
543         break;
544     default:
545         ok(0, "unexpected call\n");
546         return E_NOTIMPL;
547     }
548
549     return S_OK;
550 }
551
552 static IDispatchExVtbl scriptDispVtbl = {
553     DispatchEx_QueryInterface,
554     DispatchEx_AddRef,
555     DispatchEx_Release,
556     DispatchEx_GetTypeInfoCount,
557     DispatchEx_GetTypeInfo,
558     DispatchEx_GetIDsOfNames,
559     DispatchEx_Invoke,
560     scriptDisp_GetDispID,
561     scriptDisp_InvokeEx,
562     DispatchEx_DeleteMemberByName,
563     DispatchEx_DeleteMemberByDispID,
564     DispatchEx_GetMemberProperties,
565     DispatchEx_GetMemberName,
566     DispatchEx_GetNextDispID,
567     DispatchEx_GetNameSpaceParent
568 };
569
570 static IDispatchEx scriptDisp = { &scriptDispVtbl };
571
572 static HRESULT WINAPI externalDisp_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
573 {
574     if(!strcmp_wa(bstrName, "ok")) {
575         *pid = DISPID_EXTERNAL_OK;
576         return S_OK;
577     }
578     if(!strcmp_wa(bstrName, "trace")) {
579         *pid = DISPID_EXTERNAL_TRACE;
580         return S_OK;
581     }
582     if(!strcmp_wa(bstrName, "reportSuccess")) {
583         *pid = DISPID_EXTERNAL_REPORTSUCCESS;
584         return S_OK;
585     }
586     if(!strcmp_wa(bstrName, "todo_wine_ok")) {
587         *pid = DISPID_EXTERNAL_TODO_WINE_OK;
588         return S_OK;
589     }
590
591     ok(0, "unexpected name %s\n", wine_dbgstr_w(bstrName));
592     return DISP_E_UNKNOWNNAME;
593 }
594
595 static HRESULT WINAPI externalDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
596         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
597 {
598     switch(id) {
599     case DISPID_EXTERNAL_OK: {
600         VARIANT *b, *m;
601
602         ok(wFlags == INVOKE_FUNC || wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
603         ok(pdp != NULL, "pdp == NULL\n");
604         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
605         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
606         ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
607         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
608         ok(pei != NULL, "pei == NULL\n");
609
610         m = pdp->rgvarg;
611         if(V_VT(m) == (VT_BYREF|VT_VARIANT))
612             m = V_BYREF(m);
613         ok(V_VT(m) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
614
615         b = pdp->rgvarg+1;
616         if(V_VT(b) == (VT_BYREF|VT_VARIANT))
617             b = V_BYREF(b);
618         ok(V_VT(b) == VT_BOOL, "V_VT(b) = %d\n", V_VT(b));
619
620         ok(V_BOOL(b), "%s\n", wine_dbgstr_w(V_BSTR(m)));
621         return S_OK;
622     }
623
624      case DISPID_EXTERNAL_TRACE:
625         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
626         ok(pdp != NULL, "pdp == NULL\n");
627         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
628         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
629         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
630         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
631         ok(!pvarRes, "pvarRes != NULL\n");
632         ok(pei != NULL, "pei == NULL\n");
633
634         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
635         if(V_VT(pdp->rgvarg) == VT_BSTR)
636             trace("%s\n", wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
637
638         return S_OK;
639
640     case DISPID_EXTERNAL_REPORTSUCCESS:
641         CHECK_EXPECT(external_success);
642
643         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
644         ok(pdp != NULL, "pdp == NULL\n");
645         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
646         ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
647         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
648         ok(!pvarRes, "pvarRes != NULL\n");
649         ok(pei != NULL, "pei == NULL\n");
650
651         return S_OK;
652
653     case DISPID_EXTERNAL_TODO_WINE_OK:
654         ok(wFlags == INVOKE_FUNC || wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
655         ok(pdp != NULL, "pdp == NULL\n");
656         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
657         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
658         ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
659         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
660         ok(pei != NULL, "pei == NULL\n");
661
662         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
663         ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(psp->rgvargs+1) = %d\n", V_VT(pdp->rgvarg));
664         todo_wine
665         ok(V_BOOL(pdp->rgvarg+1), "%s\n", wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
666
667         return S_OK;
668
669     default:
670         ok(0, "unexpected call\n");
671         return E_NOTIMPL;
672     }
673
674     return S_OK;
675 }
676
677 static IDispatchExVtbl externalDispVtbl = {
678     DispatchEx_QueryInterface,
679     DispatchEx_AddRef,
680     DispatchEx_Release,
681     DispatchEx_GetTypeInfoCount,
682     DispatchEx_GetTypeInfo,
683     DispatchEx_GetIDsOfNames,
684     DispatchEx_Invoke,
685     externalDisp_GetDispID,
686     externalDisp_InvokeEx,
687     DispatchEx_DeleteMemberByName,
688     DispatchEx_DeleteMemberByDispID,
689     DispatchEx_GetMemberProperties,
690     DispatchEx_GetMemberName,
691     DispatchEx_GetNextDispID,
692     DispatchEx_GetNameSpaceParent
693 };
694
695 static IDispatchEx externalDisp = { &externalDispVtbl };
696
697 static HRESULT QueryInterface(REFIID,void**);
698
699 static HRESULT WINAPI DocHostUIHandler_QueryInterface(IDocHostUIHandler2 *iface, REFIID riid, void **ppv)
700 {
701     return QueryInterface(riid, ppv);
702 }
703
704 static ULONG WINAPI DocHostUIHandler_AddRef(IDocHostUIHandler2 *iface)
705 {
706     return 2;
707 }
708
709 static ULONG WINAPI DocHostUIHandler_Release(IDocHostUIHandler2 *iface)
710 {
711     return 1;
712 }
713
714 static HRESULT WINAPI DocHostUIHandler_ShowContextMenu(IDocHostUIHandler2 *iface, DWORD dwID, POINT *ppt,
715         IUnknown *pcmdtReserved, IDispatch *pdicpReserved)
716 {
717     return E_NOTIMPL;
718 }
719
720 static HRESULT WINAPI DocHostUIHandler_GetHostInfo(IDocHostUIHandler2 *iface, DOCHOSTUIINFO *pInfo)
721 {
722     return E_NOTIMPL;
723 }
724
725 static HRESULT WINAPI DocHostUIHandler_ShowUI(IDocHostUIHandler2 *iface, DWORD dwID,
726         IOleInPlaceActiveObject *pActiveObject, IOleCommandTarget *pCommandTarget,
727         IOleInPlaceFrame *pFrame, IOleInPlaceUIWindow *pDoc)
728 {
729     return S_OK;
730 }
731
732 static HRESULT WINAPI DocHostUIHandler_HideUI(IDocHostUIHandler2 *iface)
733 {
734     return S_OK;
735 }
736
737 static HRESULT WINAPI DocHostUIHandler_UpdateUI(IDocHostUIHandler2 *iface)
738 {
739     return S_OK;
740 }
741
742 static HRESULT WINAPI DocHostUIHandler_EnableModeless(IDocHostUIHandler2 *iface, BOOL fEnable)
743 {
744     return E_NOTIMPL;
745 }
746
747 static HRESULT WINAPI DocHostUIHandler_OnDocWindowActivate(IDocHostUIHandler2 *iface, BOOL fActivate)
748 {
749     return E_NOTIMPL;
750 }
751
752 static HRESULT WINAPI DocHostUIHandler_OnFrameWindowActivate(IDocHostUIHandler2 *iface, BOOL fActivate)
753 {
754     return S_OK;
755 }
756
757 static HRESULT WINAPI DocHostUIHandler_ResizeBorder(IDocHostUIHandler2 *iface, LPCRECT prcBorder,
758         IOleInPlaceUIWindow *pUIWindow, BOOL fRameWindow)
759 {
760     return E_NOTIMPL;
761 }
762
763 static HRESULT WINAPI DocHostUIHandler_TranslateAccelerator(IDocHostUIHandler2 *iface, LPMSG lpMsg,
764         const GUID *pguidCmdGroup, DWORD nCmdID)
765 {
766     return E_NOTIMPL;
767 }
768
769 static HRESULT WINAPI DocHostUIHandler_GetOptionKeyPath(IDocHostUIHandler2 *iface,
770         LPOLESTR *pchKey, DWORD dw)
771 {
772     return S_OK;
773 }
774
775 static HRESULT WINAPI DocHostUIHandler_GetDropTarget(IDocHostUIHandler2 *iface,
776         IDropTarget *pDropTarget, IDropTarget **ppDropTarget)
777 {
778     return E_NOTIMPL;
779 }
780
781 static HRESULT WINAPI DocHostUIHandler_GetExternal(IDocHostUIHandler2 *iface, IDispatch **ppDispatch)
782 {
783     *ppDispatch = (IDispatch*)&externalDisp;
784     return S_OK;
785 }
786
787 static HRESULT WINAPI DocHostUIHandler_TranslateUrl(IDocHostUIHandler2 *iface, DWORD dwTranslate,
788         OLECHAR *pchURLIn, OLECHAR **ppchURLOut)
789 {
790     return S_FALSE;
791 }
792
793 static HRESULT WINAPI DocHostUIHandler_FilterDataObject(IDocHostUIHandler2 *iface, IDataObject *pDO,
794         IDataObject **ppPORet)
795 {
796     return E_NOTIMPL;
797 }
798
799 static HRESULT WINAPI DocHostUIHandler_GetOverrideKeyPath(IDocHostUIHandler2 *iface,
800         LPOLESTR *pchKey, DWORD dw)
801 {
802     return E_NOTIMPL;
803 }
804
805 static const IDocHostUIHandler2Vtbl DocHostUIHandlerVtbl = {
806     DocHostUIHandler_QueryInterface,
807     DocHostUIHandler_AddRef,
808     DocHostUIHandler_Release,
809     DocHostUIHandler_ShowContextMenu,
810     DocHostUIHandler_GetHostInfo,
811     DocHostUIHandler_ShowUI,
812     DocHostUIHandler_HideUI,
813     DocHostUIHandler_UpdateUI,
814     DocHostUIHandler_EnableModeless,
815     DocHostUIHandler_OnDocWindowActivate,
816     DocHostUIHandler_OnFrameWindowActivate,
817     DocHostUIHandler_ResizeBorder,
818     DocHostUIHandler_TranslateAccelerator,
819     DocHostUIHandler_GetOptionKeyPath,
820     DocHostUIHandler_GetDropTarget,
821     DocHostUIHandler_GetExternal,
822     DocHostUIHandler_TranslateUrl,
823     DocHostUIHandler_FilterDataObject,
824     DocHostUIHandler_GetOverrideKeyPath
825 };
826
827 static IDocHostUIHandler2 DocHostUIHandler = { &DocHostUIHandlerVtbl };
828
829 static HRESULT WINAPI InPlaceFrame_QueryInterface(IOleInPlaceFrame *iface, REFIID riid, void **ppv)
830 {
831     return E_NOINTERFACE;
832 }
833
834 static ULONG WINAPI InPlaceFrame_AddRef(IOleInPlaceFrame *iface)
835 {
836     return 2;
837 }
838
839 static ULONG WINAPI InPlaceFrame_Release(IOleInPlaceFrame *iface)
840 {
841     return 1;
842 }
843
844 static HRESULT WINAPI InPlaceFrame_GetWindow(IOleInPlaceFrame *iface, HWND *phwnd)
845 {
846     return E_NOTIMPL;
847 }
848
849 static HRESULT WINAPI InPlaceFrame_ContextSensitiveHelp(IOleInPlaceFrame *iface, BOOL fEnterMode)
850 {
851     return E_NOTIMPL;
852 }
853
854 static HRESULT WINAPI InPlaceFrame_GetBorder(IOleInPlaceFrame *iface, LPRECT lprectBorder)
855 {
856     return E_NOTIMPL;
857 }
858
859 static HRESULT WINAPI InPlaceFrame_RequestBorderSpace(IOleInPlaceFrame *iface,
860         LPCBORDERWIDTHS pborderwidths)
861 {
862     return E_NOTIMPL;
863 }
864
865 static HRESULT WINAPI InPlaceFrame_SetBorderSpace(IOleInPlaceFrame *iface,
866         LPCBORDERWIDTHS pborderwidths)
867 {
868     return S_OK;
869 }
870
871 static HRESULT WINAPI InPlaceFrame_SetActiveObject(IOleInPlaceFrame *iface,
872         IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
873 {
874     return S_OK;
875 }
876
877 static HRESULT WINAPI InPlaceFrame_InsertMenus(IOleInPlaceFrame *iface, HMENU hmenuShared,
878         LPOLEMENUGROUPWIDTHS lpMenuWidths)
879 {
880     return E_NOTIMPL;
881 }
882
883 static HRESULT WINAPI InPlaceFrame_SetMenu(IOleInPlaceFrame *iface, HMENU hmenuShared,
884         HOLEMENU holemenu, HWND hwndActiveObject)
885 {
886     ok(0, "unexpected call\n");
887     return E_NOTIMPL;
888 }
889
890 static HRESULT WINAPI InPlaceFrame_RemoveMenus(IOleInPlaceFrame *iface, HMENU hmenuShared)
891 {
892     ok(0, "unexpected call\n");
893     return E_NOTIMPL;
894 }
895
896 static HRESULT WINAPI InPlaceFrame_SetStatusText(IOleInPlaceFrame *iface, LPCOLESTR pszStatusText)
897 {
898     return S_OK;
899 }
900
901 static HRESULT WINAPI InPlaceFrame_EnableModeless(IOleInPlaceFrame *iface, BOOL fEnable)
902 {
903     return E_NOTIMPL;
904 }
905
906 static HRESULT WINAPI InPlaceFrame_TranslateAccelerator(IOleInPlaceFrame *iface, LPMSG lpmsg, WORD wID)
907 {
908     ok(0, "unexpected call\n");
909     return E_NOTIMPL;
910 }
911
912 static const IOleInPlaceFrameVtbl InPlaceFrameVtbl = {
913     InPlaceFrame_QueryInterface,
914     InPlaceFrame_AddRef,
915     InPlaceFrame_Release,
916     InPlaceFrame_GetWindow,
917     InPlaceFrame_ContextSensitiveHelp,
918     InPlaceFrame_GetBorder,
919     InPlaceFrame_RequestBorderSpace,
920     InPlaceFrame_SetBorderSpace,
921     InPlaceFrame_SetActiveObject,
922     InPlaceFrame_InsertMenus,
923     InPlaceFrame_SetMenu,
924     InPlaceFrame_RemoveMenus,
925     InPlaceFrame_SetStatusText,
926     InPlaceFrame_EnableModeless,
927     InPlaceFrame_TranslateAccelerator
928 };
929
930 static IOleInPlaceFrame InPlaceFrame = { &InPlaceFrameVtbl };
931
932 static HRESULT WINAPI InPlaceSite_QueryInterface(IOleInPlaceSite *iface, REFIID riid, void **ppv)
933 {
934     return QueryInterface(riid, ppv);
935 }
936
937 static ULONG WINAPI InPlaceSite_AddRef(IOleInPlaceSite *iface)
938 {
939     return 2;
940 }
941
942 static ULONG WINAPI InPlaceSite_Release(IOleInPlaceSite *iface)
943 {
944     return 1;
945 }
946
947 static HRESULT WINAPI InPlaceSite_GetWindow(IOleInPlaceSite *iface, HWND *phwnd)
948 {
949     *phwnd = container_hwnd;
950     return S_OK;
951 }
952
953 static HRESULT WINAPI InPlaceSite_ContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode)
954 {
955     ok(0, "unexpected call\n");
956     return E_NOTIMPL;
957 }
958
959 static HRESULT WINAPI InPlaceSite_CanInPlaceActivate(IOleInPlaceSite *iface)
960 {
961     return S_OK;
962 }
963
964 static HRESULT WINAPI InPlaceSite_OnInPlaceActivate(IOleInPlaceSite *iface)
965 {
966     return S_OK;
967 }
968
969 static HRESULT WINAPI InPlaceSite_OnUIActivate(IOleInPlaceSite *iface)
970 {
971     return S_OK;
972 }
973
974 static HRESULT WINAPI InPlaceSite_GetWindowContext(IOleInPlaceSite *iface,
975         IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
976         LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
977 {
978     static const RECT rect = {0,0,300,300};
979
980     *ppFrame = &InPlaceFrame;
981     *ppDoc = (IOleInPlaceUIWindow*)&InPlaceFrame;
982     *lprcPosRect = rect;
983     *lprcClipRect = rect;
984
985     ok(lpFrameInfo->cb == sizeof(*lpFrameInfo), "lpFrameInfo->cb = %u, expected %u\n", lpFrameInfo->cb, (unsigned)sizeof(*lpFrameInfo));
986     lpFrameInfo->fMDIApp = FALSE;
987     lpFrameInfo->hwndFrame = container_hwnd;
988     lpFrameInfo->haccel = NULL;
989     lpFrameInfo->cAccelEntries = 0;
990
991     return S_OK;
992 }
993
994 static HRESULT WINAPI InPlaceSite_Scroll(IOleInPlaceSite *iface, SIZE scrollExtant)
995 {
996     return E_NOTIMPL;
997 }
998
999 static HRESULT WINAPI InPlaceSite_OnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable)
1000 {
1001     return S_OK;
1002 }
1003
1004 static HRESULT WINAPI InPlaceSite_OnInPlaceDeactivate(IOleInPlaceSite *iface)
1005 {
1006     return S_OK;
1007 }
1008
1009 static HRESULT WINAPI InPlaceSite_DiscardUndoState(IOleInPlaceSite *iface)
1010 {
1011     return E_NOTIMPL;
1012 }
1013
1014 static HRESULT WINAPI InPlaceSite_DeactivateAndUndo(IOleInPlaceSite *iface)
1015 {
1016     return E_NOTIMPL;
1017 }
1018
1019 static HRESULT WINAPI InPlaceSite_OnPosRectChange(IOleInPlaceSite *iface, LPCRECT lprcPosRect)
1020 {
1021     return E_NOTIMPL;
1022 }
1023
1024 static const IOleInPlaceSiteVtbl InPlaceSiteVtbl = {
1025     InPlaceSite_QueryInterface,
1026     InPlaceSite_AddRef,
1027     InPlaceSite_Release,
1028     InPlaceSite_GetWindow,
1029     InPlaceSite_ContextSensitiveHelp,
1030     InPlaceSite_CanInPlaceActivate,
1031     InPlaceSite_OnInPlaceActivate,
1032     InPlaceSite_OnUIActivate,
1033     InPlaceSite_GetWindowContext,
1034     InPlaceSite_Scroll,
1035     InPlaceSite_OnUIDeactivate,
1036     InPlaceSite_OnInPlaceDeactivate,
1037     InPlaceSite_DiscardUndoState,
1038     InPlaceSite_DeactivateAndUndo,
1039     InPlaceSite_OnPosRectChange,
1040 };
1041
1042 static IOleInPlaceSite InPlaceSite = { &InPlaceSiteVtbl };
1043
1044 static HRESULT WINAPI ClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv)
1045 {
1046     return QueryInterface(riid, ppv);
1047 }
1048
1049 static ULONG WINAPI ClientSite_AddRef(IOleClientSite *iface)
1050 {
1051     return 2;
1052 }
1053
1054 static ULONG WINAPI ClientSite_Release(IOleClientSite *iface)
1055 {
1056     return 1;
1057 }
1058
1059 static HRESULT WINAPI ClientSite_SaveObject(IOleClientSite *iface)
1060 {
1061     ok(0, "unexpected call\n");
1062     return E_NOTIMPL;
1063 }
1064
1065 static HRESULT WINAPI ClientSite_GetMoniker(IOleClientSite *iface, DWORD dwAssign, DWORD dwWhichMoniker,
1066         IMoniker **ppmon)
1067 {
1068     ok(0, "unexpected call\n");
1069     return E_NOTIMPL;
1070 }
1071
1072 static HRESULT WINAPI ClientSite_GetContainer(IOleClientSite *iface, IOleContainer **ppContainer)
1073 {
1074     return E_NOTIMPL;
1075 }
1076
1077 static HRESULT WINAPI ClientSite_ShowObject(IOleClientSite *iface)
1078 {
1079     ok(0, "unexpected call\n");
1080     return E_NOTIMPL;
1081 }
1082
1083 static HRESULT WINAPI ClientSite_OnShowWindow(IOleClientSite *iface, BOOL fShow)
1084 {
1085     ok(0, "unexpected call\n");
1086     return E_NOTIMPL;
1087 }
1088
1089 static HRESULT WINAPI ClientSite_RequestNewObjectLayout(IOleClientSite *iface)
1090 {
1091     ok(0, "unexpected call\n");
1092     return E_NOTIMPL;
1093 }
1094
1095 static const IOleClientSiteVtbl ClientSiteVtbl = {
1096     ClientSite_QueryInterface,
1097     ClientSite_AddRef,
1098     ClientSite_Release,
1099     ClientSite_SaveObject,
1100     ClientSite_GetMoniker,
1101     ClientSite_GetContainer,
1102     ClientSite_ShowObject,
1103     ClientSite_OnShowWindow,
1104     ClientSite_RequestNewObjectLayout
1105 };
1106
1107 static IOleClientSite ClientSite = { &ClientSiteVtbl };
1108
1109 static HRESULT WINAPI DocumentSite_QueryInterface(IOleDocumentSite *iface, REFIID riid, void **ppv)
1110 {
1111     return QueryInterface(riid, ppv);
1112 }
1113
1114 static ULONG WINAPI DocumentSite_AddRef(IOleDocumentSite *iface)
1115 {
1116     return 2;
1117 }
1118
1119 static ULONG WINAPI DocumentSite_Release(IOleDocumentSite *iface)
1120 {
1121     return 1;
1122 }
1123
1124 static HRESULT WINAPI DocumentSite_ActivateMe(IOleDocumentSite *iface, IOleDocumentView *pViewToActivate)
1125 {
1126     RECT rect = {0,0,300,300};
1127     IOleDocument *document;
1128     HRESULT hres;
1129
1130     hres = IOleDocumentView_QueryInterface(pViewToActivate, &IID_IOleDocument, (void**)&document);
1131     ok(hres == S_OK, "could not get IOleDocument: %08x\n", hres);
1132
1133     hres = IOleDocument_CreateView(document, &InPlaceSite, NULL, 0, &view);
1134     IOleDocument_Release(document);
1135     ok(hres == S_OK, "CreateView failed: %08x\n", hres);
1136
1137     hres = IOleDocumentView_SetInPlaceSite(view, &InPlaceSite);
1138     ok(hres == S_OK, "SetInPlaceSite failed: %08x\n", hres);
1139
1140     hres = IOleDocumentView_UIActivate(view, TRUE);
1141     ok(hres == S_OK, "UIActivate failed: %08x\n", hres);
1142
1143     hres = IOleDocumentView_SetRect(view, &rect);
1144     ok(hres == S_OK, "SetRect failed: %08x\n", hres);
1145
1146     hres = IOleDocumentView_Show(view, TRUE);
1147     ok(hres == S_OK, "Show failed: %08x\n", hres);
1148
1149     return S_OK;
1150 }
1151
1152 static const IOleDocumentSiteVtbl DocumentSiteVtbl = {
1153     DocumentSite_QueryInterface,
1154     DocumentSite_AddRef,
1155     DocumentSite_Release,
1156     DocumentSite_ActivateMe
1157 };
1158
1159 static IOleDocumentSite DocumentSite = { &DocumentSiteVtbl };
1160
1161 static HRESULT QueryInterface(REFIID riid, void **ppv)
1162 {
1163     *ppv = NULL;
1164
1165     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IOleClientSite, riid))
1166         *ppv = &ClientSite;
1167     else if(IsEqualGUID(&IID_IOleDocumentSite, riid))
1168         *ppv = &DocumentSite;
1169     else if(IsEqualGUID(&IID_IOleWindow, riid) || IsEqualGUID(&IID_IOleInPlaceSite, riid))
1170         *ppv = &InPlaceSite;
1171     else if(IsEqualGUID(&IID_IDocHostUIHandler, riid) || IsEqualGUID(&IID_IDocHostUIHandler2, riid))
1172         *ppv = &DocHostUIHandler;
1173
1174     return *ppv ? S_OK : E_NOINTERFACE;
1175 }
1176
1177 static IHTMLDocument2 *create_document(void)
1178 {
1179     IHTMLDocument2 *doc;
1180     IHTMLDocument5 *doc5;
1181     HRESULT hres;
1182
1183     hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1184             &IID_IHTMLDocument2, (void**)&doc);
1185     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
1186     if (hres != S_OK) return NULL;
1187
1188     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument5, (void**)&doc5);
1189     if(FAILED(hres)) {
1190         win_skip("Could not get IHTMLDocument5, probably too old IE\n");
1191         IHTMLDocument2_Release(doc);
1192         return NULL;
1193     }
1194
1195     IHTMLDocument5_Release(doc5);
1196     return doc;
1197 }
1198
1199 static void load_string(IHTMLDocument2 *doc, const char *str)
1200 {
1201     IPersistStreamInit *init;
1202     IStream *stream;
1203     HGLOBAL mem;
1204     SIZE_T len;
1205
1206     doc_complete = FALSE;
1207     len = strlen(str);
1208     mem = GlobalAlloc(0, len);
1209     memcpy(mem, str, len);
1210     CreateStreamOnHGlobal(mem, TRUE, &stream);
1211
1212     IHTMLDocument2_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&init);
1213
1214     IPersistStreamInit_Load(init, stream);
1215     IPersistStreamInit_Release(init);
1216     IStream_Release(stream);
1217 }
1218
1219 static void do_advise(IHTMLDocument2 *doc, REFIID riid, IUnknown *unk_advise)
1220 {
1221     IConnectionPointContainer *container;
1222     IConnectionPoint *cp;
1223     DWORD cookie;
1224     HRESULT hres;
1225
1226     hres = IHTMLDocument2_QueryInterface(doc, &IID_IConnectionPointContainer, (void**)&container);
1227     ok(hres == S_OK, "QueryInterface(IID_IConnectionPointContainer) failed: %08x\n", hres);
1228
1229     hres = IConnectionPointContainer_FindConnectionPoint(container, riid, &cp);
1230     IConnectionPointContainer_Release(container);
1231     ok(hres == S_OK, "FindConnectionPoint failed: %08x\n", hres);
1232
1233     notif_doc = doc;
1234
1235     hres = IConnectionPoint_Advise(cp, unk_advise, &cookie);
1236     IConnectionPoint_Release(cp);
1237     ok(hres == S_OK, "Advise failed: %08x\n", hres);
1238 }
1239
1240 static void set_client_site(IHTMLDocument2 *doc, BOOL set)
1241 {
1242     IOleObject *oleobj;
1243     HRESULT hres;
1244
1245     if(!set && view) {
1246         IOleDocumentView_Show(view, FALSE);
1247         IOleDocumentView_CloseView(view, 0);
1248         IOleDocumentView_SetInPlaceSite(view, NULL);
1249         IOleDocumentView_Release(view);
1250         view = NULL;
1251     }
1252
1253     hres = IHTMLDocument2_QueryInterface(doc, &IID_IOleObject, (void**)&oleobj);
1254     ok(hres == S_OK, "Could not et IOleObject: %08x\n", hres);
1255
1256     hres = IOleObject_SetClientSite(oleobj, set ? &ClientSite : NULL);
1257     ok(hres == S_OK, "SetClientSite failed: %08x\n", hres);
1258
1259     if(set) {
1260         IHlinkTarget *hlink;
1261
1262         hres = IOleObject_QueryInterface(oleobj, &IID_IHlinkTarget, (void**)&hlink);
1263         ok(hres == S_OK, "Could not get IHlinkTarget iface: %08x\n", hres);
1264
1265         hres = IHlinkTarget_Navigate(hlink, 0, NULL);
1266         ok(hres == S_OK, "Navgate failed: %08x\n", hres);
1267
1268         IHlinkTarget_Release(hlink);
1269     }
1270
1271     IOleObject_Release(oleobj);
1272 }
1273
1274 typedef void (*domtest_t)(IHTMLDocument2*);
1275
1276 static void load_doc(IHTMLDocument2 *doc, const char *str)
1277 {
1278     IHTMLElement *body = NULL;
1279     MSG msg;
1280     HRESULT hres;
1281     static const WCHAR ucPtr[] = {'b','a','c','k','g','r','o','u','n','d',0};
1282     DISPID dispID = -1;
1283     OLECHAR *name;
1284
1285     load_string(doc, str);
1286     do_advise(doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
1287
1288     while(!doc_complete && GetMessage(&msg, NULL, 0, 0)) {
1289         TranslateMessage(&msg);
1290         DispatchMessage(&msg);
1291     }
1292
1293     hres = IHTMLDocument2_get_body(doc, &body);
1294     ok(hres == S_OK, "get_body failed: %08x\n", hres);
1295
1296     /* Check we can query for function on the IHTMLElementBody interface */
1297     name = (WCHAR*)ucPtr;
1298     hres = IHTMLElement_GetIDsOfNames(body, &IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &dispID);
1299     ok(hres == S_OK, "GetIDsOfNames(background) failed %08x\n", hres);
1300     ok(dispID == DISPID_IHTMLBODYELEMENT_BACKGROUND, "Incorrect dispID got (%d)\n", dispID);
1301
1302     IHTMLElement_Release(body);
1303 }
1304
1305 static IActiveScriptSite *site;
1306 static SCRIPTSTATE state;
1307
1308 static HRESULT WINAPI ObjectSafety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
1309 {
1310     *ppv = NULL;
1311     ok(0, "unexpected call %s\n", debugstr_guid(riid));
1312     return E_NOINTERFACE;
1313 }
1314
1315 static ULONG WINAPI ObjectSafety_AddRef(IObjectSafety *iface)
1316 {
1317     return 2;
1318 }
1319
1320 static ULONG WINAPI ObjectSafety_Release(IObjectSafety *iface)
1321 {
1322     return 1;
1323 }
1324
1325 static HRESULT WINAPI ObjectSafety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
1326         DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
1327 {
1328     CHECK_EXPECT(GetInterfaceSafetyOptions);
1329
1330     ok(IsEqualGUID(&IID_IActiveScriptParse, riid), "unexpected riid %s\n", debugstr_guid(riid));
1331     ok(pdwSupportedOptions != NULL, "pdwSupportedOptions == NULL\n");
1332     ok(pdwEnabledOptions != NULL, "pdwEnabledOptions == NULL\n");
1333
1334     *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER;
1335     *pdwEnabledOptions = INTERFACE_USES_DISPEX;
1336
1337     return S_OK;
1338 }
1339
1340 static HRESULT WINAPI ObjectSafety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
1341         DWORD dwOptionSetMask, DWORD dwEnabledOptions)
1342 {
1343     CHECK_EXPECT(SetInterfaceSafetyOptions);
1344
1345     ok(IsEqualGUID(&IID_IActiveScriptParse, riid), "unexpected riid %s\n", debugstr_guid(riid));
1346
1347     ok(dwOptionSetMask == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
1348        "dwOptionSetMask=%x\n", dwOptionSetMask);
1349     ok(dwEnabledOptions == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
1350        "dwEnabledOptions=%x\n", dwOptionSetMask);
1351
1352     return S_OK;
1353 }
1354
1355 static const IObjectSafetyVtbl ObjectSafetyVtbl = {
1356     ObjectSafety_QueryInterface,
1357     ObjectSafety_AddRef,
1358     ObjectSafety_Release,
1359     ObjectSafety_GetInterfaceSafetyOptions,
1360     ObjectSafety_SetInterfaceSafetyOptions
1361 };
1362
1363 static IObjectSafety ObjectSafety = { &ObjectSafetyVtbl };
1364
1365 static HRESULT WINAPI AXObjectSafety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
1366 {
1367     *ppv = NULL;
1368
1369     if(IsEqualGUID(&IID_IActiveScript, riid)) {
1370         CHECK_EXPECT(AXQueryInterface_IActiveScript);
1371         return E_NOINTERFACE;
1372     }
1373
1374     if(IsEqualGUID(&IID_IObjectSafety, riid)) {
1375         CHECK_EXPECT2(AXQueryInterface_IObjectSafety);
1376         if(!ax_objsafe)
1377             return E_NOINTERFACE;
1378         *ppv = iface;
1379         return S_OK;
1380     }
1381
1382     ok(0, "unexpected call %s\n", debugstr_guid(riid));
1383     return E_NOINTERFACE;
1384 }
1385
1386 static HRESULT WINAPI AXObjectSafety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
1387         DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
1388 {
1389     CHECK_EXPECT(AXGetInterfaceSafetyOptions);
1390
1391     ok(IsEqualGUID(&IID_IDispatchEx, riid), "unexpected riid %s\n", debugstr_guid(riid));
1392     ok(pdwSupportedOptions != NULL, "pdwSupportedOptions == NULL\n");
1393     ok(pdwEnabledOptions != NULL, "pdwEnabledOptions == NULL\n");
1394
1395     if(SUCCEEDED(ax_getopt_hres)) {
1396         *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER;
1397         *pdwEnabledOptions = INTERFACE_USES_DISPEX;
1398     }
1399
1400     return ax_getopt_hres;
1401 }
1402
1403 static HRESULT WINAPI AXObjectSafety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
1404         DWORD dwOptionSetMask, DWORD dwEnabledOptions)
1405 {
1406     if(IsEqualGUID(&IID_IDispatchEx, riid)) {
1407         switch(dwEnabledOptions) {
1408         case INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACE_USES_SECURITY_MANAGER:
1409             CHECK_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx_caller_secmgr);
1410             break;
1411         case INTERFACESAFE_FOR_UNTRUSTED_CALLER:
1412             CHECK_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx_caller);
1413             break;
1414         default:
1415             ok(0, "unexpected dwEnabledOptions %x\n", dwEnabledOptions);
1416         }
1417
1418         ok(dwOptionSetMask == dwEnabledOptions, "dwOptionSetMask=%x, expected %x\n", dwOptionSetMask, dwEnabledOptions);
1419         return ax_setopt_dispex_hres;
1420     }
1421
1422     if(IsEqualGUID(&IID_IDispatch, riid)) {
1423         HRESULT hres;
1424
1425         switch(dwEnabledOptions) {
1426         case INTERFACESAFE_FOR_UNTRUSTED_CALLER:
1427             CHECK_EXPECT(AXSetInterfaceSafetyOptions_IDispatch_caller);
1428             hres = ax_setopt_disp_caller_hres;
1429             break;
1430         case INTERFACESAFE_FOR_UNTRUSTED_DATA:
1431             CHECK_EXPECT(AXSetInterfaceSafetyOptions_IDispatch_data);
1432             hres = ax_setopt_disp_data_hres;
1433             break;
1434         default:
1435             ok(0, "unexpected dwEnabledOptions %x\n", dwEnabledOptions);
1436             hres = E_FAIL;
1437         }
1438         ok(dwOptionSetMask == dwEnabledOptions, "dwOptionSetMask=%x, expected %x\n", dwOptionSetMask, dwEnabledOptions);
1439         return hres;
1440     }
1441
1442     ok(0, "unexpected riid %s\n", debugstr_guid(riid));
1443     return E_NOINTERFACE;
1444 }
1445
1446 static const IObjectSafetyVtbl AXObjectSafetyVtbl = {
1447     AXObjectSafety_QueryInterface,
1448     ObjectSafety_AddRef,
1449     ObjectSafety_Release,
1450     AXObjectSafety_GetInterfaceSafetyOptions,
1451     AXObjectSafety_SetInterfaceSafetyOptions
1452 };
1453
1454 static IObjectSafety AXObjectSafety = { &AXObjectSafetyVtbl };
1455
1456 static BOOL set_safe_reg(BOOL safe_call, BOOL safe_data)
1457 {
1458     return init_key("CLSID\\"TESTACTIVEX_CLSID"\\Implemented Categories\\{7dd95801-9882-11cf-9fa9-00aa006c42c4}",
1459                     NULL, safe_call)
1460         && init_key("CLSID\\"TESTACTIVEX_CLSID"\\Implemented Categories\\{7dd95802-9882-11cf-9fa9-00aa006c42c4}",
1461                     NULL, safe_data);
1462 }
1463
1464 #define check_custom_policy(a,b,c,d) _check_custom_policy(__LINE__,a,b,c,d)
1465 static void _check_custom_policy(unsigned line, HRESULT hres, BYTE *ppolicy, DWORD policy_size, DWORD expolicy)
1466 {
1467     ok_(__FILE__,line)(hres == S_OK, "QueryCusromPolicy failed: %08x\n", hres);
1468     ok_(__FILE__,line)(policy_size == sizeof(DWORD), "policy_size = %d\n", policy_size);
1469     ok_(__FILE__,line)(*(DWORD*)ppolicy == expolicy, "policy = %x, expected %x\n", *(DWORD*)ppolicy, expolicy);
1470     CoTaskMemFree(ppolicy);
1471 }
1472
1473 static void test_security_reg(IInternetHostSecurityManager *sec_mgr, DWORD policy_caller, DWORD policy_load)
1474 {
1475     struct CONFIRMSAFETY cs;
1476     DWORD policy_size;
1477     BYTE *ppolicy;
1478     HRESULT hres;
1479
1480     cs.clsid = CLSID_TestActiveX;
1481     cs.pUnk = (IUnknown*)&AXObjectSafety;
1482
1483     cs.dwFlags = 0;
1484     ax_objsafe = FALSE;
1485     SET_EXPECT(AXQueryInterface_IActiveScript);
1486     SET_EXPECT(AXQueryInterface_IObjectSafety);
1487     hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
1488             &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
1489     CHECK_CALLED(AXQueryInterface_IActiveScript);
1490     CHECK_CALLED(AXQueryInterface_IObjectSafety);
1491     check_custom_policy(hres, ppolicy, policy_size, policy_caller);
1492
1493     ax_objsafe = TRUE;
1494     SET_EXPECT(AXQueryInterface_IActiveScript);
1495     SET_EXPECT(AXQueryInterface_IObjectSafety);
1496     SET_EXPECT(AXGetInterfaceSafetyOptions);
1497     SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx_caller_secmgr);
1498     hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
1499             &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
1500     CHECK_CALLED(AXQueryInterface_IActiveScript);
1501     CHECK_CALLED(AXQueryInterface_IObjectSafety);
1502     CHECK_CALLED(AXGetInterfaceSafetyOptions);
1503     CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatchEx_caller_secmgr);
1504     check_custom_policy(hres, ppolicy, policy_size, URLPOLICY_ALLOW);
1505
1506     if(skip_loadobject_tests)
1507         return;
1508
1509     cs.dwFlags = CONFIRMSAFETYACTION_LOADOBJECT;
1510     ax_objsafe = FALSE;
1511     SET_EXPECT(AXQueryInterface_IActiveScript);
1512     SET_EXPECT(AXQueryInterface_IObjectSafety);
1513     hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
1514             &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
1515     CHECK_CALLED(AXQueryInterface_IActiveScript);
1516     CHECK_CALLED(AXQueryInterface_IObjectSafety);
1517     check_custom_policy(hres, ppolicy, policy_size, policy_load);
1518
1519     ax_objsafe = TRUE;
1520     SET_EXPECT(AXQueryInterface_IActiveScript);
1521     SET_EXPECT(AXQueryInterface_IObjectSafety);
1522     SET_EXPECT(AXGetInterfaceSafetyOptions);
1523     SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx_caller_secmgr);
1524     SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatch_data);
1525     hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
1526             &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
1527     CHECK_CALLED(AXQueryInterface_IActiveScript);
1528     CHECK_CALLED(AXQueryInterface_IObjectSafety);
1529     CHECK_CALLED(AXGetInterfaceSafetyOptions);
1530     CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatchEx_caller_secmgr);
1531     CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatch_data);
1532     check_custom_policy(hres, ppolicy, policy_size, URLPOLICY_ALLOW);
1533 }
1534
1535 static void test_security(void)
1536 {
1537     IInternetHostSecurityManager *sec_mgr;
1538     IServiceProvider *sp;
1539     DWORD policy, policy_size;
1540     struct CONFIRMSAFETY cs;
1541     BYTE *ppolicy;
1542     HRESULT hres;
1543
1544     hres = IActiveScriptSite_QueryInterface(site, &IID_IServiceProvider, (void**)&sp);
1545     ok(hres == S_OK, "Could not get IServiceProvider iface: %08x\n", hres);
1546
1547     hres = IServiceProvider_QueryService(sp, &SID_SInternetHostSecurityManager,
1548             &IID_IInternetHostSecurityManager, (void**)&sec_mgr);
1549     IServiceProvider_Release(sp);
1550     ok(hres == S_OK, "QueryService failed: %08x\n", hres);
1551
1552     hres = IInternetHostSecurityManager_ProcessUrlAction(sec_mgr, URLACTION_ACTIVEX_RUN, (BYTE*)&policy, sizeof(policy),
1553                                                          (BYTE*)&CLSID_TestActiveX, sizeof(CLSID), 0, 0);
1554     ok(hres == S_OK, "ProcessUrlAction failed: %08x\n", hres);
1555     ok(policy == URLPOLICY_ALLOW, "policy = %x\n", policy);
1556
1557     cs.clsid = CLSID_TestActiveX;
1558     cs.pUnk = (IUnknown*)&AXObjectSafety;
1559     cs.dwFlags = 0;
1560
1561     ax_objsafe = TRUE;
1562     SET_EXPECT(AXQueryInterface_IActiveScript);
1563     SET_EXPECT(AXQueryInterface_IObjectSafety);
1564     SET_EXPECT(AXGetInterfaceSafetyOptions);
1565     SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx_caller_secmgr);
1566     hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
1567             &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
1568     CHECK_CALLED(AXQueryInterface_IActiveScript);
1569     CHECK_CALLED(AXQueryInterface_IObjectSafety);
1570     CHECK_CALLED(AXGetInterfaceSafetyOptions);
1571     CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatchEx_caller_secmgr);
1572     check_custom_policy(hres, ppolicy, policy_size, URLPOLICY_ALLOW);
1573
1574     cs.dwFlags = CONFIRMSAFETYACTION_LOADOBJECT;
1575     SET_EXPECT(AXQueryInterface_IActiveScript);
1576     SET_EXPECT(AXQueryInterface_IObjectSafety);
1577     SET_EXPECT(AXGetInterfaceSafetyOptions);
1578     SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx_caller_secmgr);
1579     SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatch_data);
1580     hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
1581             &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
1582     CHECK_CALLED(AXQueryInterface_IActiveScript);
1583     CHECK_CALLED(AXQueryInterface_IObjectSafety);
1584     CHECK_CALLED(AXGetInterfaceSafetyOptions);
1585     CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatchEx_caller_secmgr);
1586     if(called_AXSetInterfaceSafetyOptions_IDispatch_data) {
1587         CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatch_data);
1588     }else {
1589         win_skip("CONFIRMSAFETYACTION_LOADOBJECT flag not supported\n");
1590         skip_loadobject_tests = TRUE;
1591         CLEAR_CALLED(AXSetInterfaceSafetyOptions_IDispatch_data);
1592     }
1593     check_custom_policy(hres, ppolicy, policy_size, URLPOLICY_ALLOW);
1594
1595     cs.dwFlags = 0;
1596     ax_objsafe = FALSE;
1597     SET_EXPECT(AXQueryInterface_IActiveScript);
1598     SET_EXPECT(AXQueryInterface_IObjectSafety);
1599     hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
1600             &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
1601     CHECK_CALLED(AXQueryInterface_IActiveScript);
1602     CHECK_CALLED(AXQueryInterface_IObjectSafety);
1603     check_custom_policy(hres, ppolicy, policy_size, URLPOLICY_DISALLOW);
1604
1605     if(!skip_loadobject_tests) {
1606         cs.dwFlags = CONFIRMSAFETYACTION_LOADOBJECT;
1607         ax_objsafe = FALSE;
1608         SET_EXPECT(AXQueryInterface_IActiveScript);
1609         SET_EXPECT(AXQueryInterface_IObjectSafety);
1610         hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
1611                 &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
1612         CHECK_CALLED(AXQueryInterface_IActiveScript);
1613         CHECK_CALLED(AXQueryInterface_IObjectSafety);
1614         check_custom_policy(hres, ppolicy, policy_size, URLPOLICY_DISALLOW);
1615     }
1616
1617     if(set_safe_reg(TRUE, FALSE)) {
1618         test_security_reg(sec_mgr, URLPOLICY_ALLOW, URLPOLICY_DISALLOW);
1619
1620         set_safe_reg(FALSE, TRUE);
1621         test_security_reg(sec_mgr, URLPOLICY_DISALLOW, URLPOLICY_DISALLOW);
1622
1623         set_safe_reg(TRUE, TRUE);
1624         test_security_reg(sec_mgr, URLPOLICY_ALLOW, URLPOLICY_ALLOW);
1625
1626         set_safe_reg(FALSE, FALSE);
1627     }else {
1628         skip("Could not set safety registry\n");
1629     }
1630
1631     ax_objsafe = TRUE;
1632
1633     cs.dwFlags = 0;
1634     ax_setopt_dispex_hres = E_NOINTERFACE;
1635     SET_EXPECT(AXQueryInterface_IActiveScript);
1636     SET_EXPECT(AXQueryInterface_IObjectSafety);
1637     SET_EXPECT(AXGetInterfaceSafetyOptions);
1638     SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx_caller_secmgr);
1639     SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatch_caller);
1640     hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
1641             &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
1642     CHECK_CALLED(AXQueryInterface_IActiveScript);
1643     CHECK_CALLED(AXQueryInterface_IObjectSafety);
1644     CHECK_CALLED(AXGetInterfaceSafetyOptions);
1645     CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatchEx_caller_secmgr);
1646     CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatch_caller);
1647     check_custom_policy(hres, ppolicy, policy_size, URLPOLICY_ALLOW);
1648
1649     ax_setopt_dispex_hres = E_FAIL;
1650     ax_setopt_disp_caller_hres = E_NOINTERFACE;
1651     SET_EXPECT(AXQueryInterface_IActiveScript);
1652     SET_EXPECT(AXQueryInterface_IObjectSafety);
1653     SET_EXPECT(AXGetInterfaceSafetyOptions);
1654     SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx_caller_secmgr);
1655     SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatch_caller);
1656     hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
1657             &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
1658     CHECK_CALLED(AXQueryInterface_IActiveScript);
1659     CHECK_CALLED(AXQueryInterface_IObjectSafety);
1660     CHECK_CALLED(AXGetInterfaceSafetyOptions);
1661     CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatchEx_caller_secmgr);
1662     CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatch_caller);
1663     check_custom_policy(hres, ppolicy, policy_size, URLPOLICY_DISALLOW);
1664
1665     if(!skip_loadobject_tests) {
1666         cs.dwFlags = CONFIRMSAFETYACTION_LOADOBJECT;
1667         ax_setopt_dispex_hres = E_FAIL;
1668         ax_setopt_disp_caller_hres = E_NOINTERFACE;
1669         SET_EXPECT(AXQueryInterface_IActiveScript);
1670         SET_EXPECT(AXQueryInterface_IObjectSafety);
1671         SET_EXPECT(AXGetInterfaceSafetyOptions);
1672         SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx_caller_secmgr);
1673         SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatch_caller);
1674         hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
1675                 &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
1676         CHECK_CALLED(AXQueryInterface_IActiveScript);
1677         CHECK_CALLED(AXQueryInterface_IObjectSafety);
1678         CHECK_CALLED(AXGetInterfaceSafetyOptions);
1679         CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatchEx_caller_secmgr);
1680         CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatch_caller);
1681         check_custom_policy(hres, ppolicy, policy_size, URLPOLICY_DISALLOW);
1682     }
1683
1684     cs.dwFlags = 0;
1685     ax_setopt_dispex_hres = E_FAIL;
1686     ax_setopt_disp_caller_hres = S_OK;
1687     ax_getopt_hres = E_NOINTERFACE;
1688     SET_EXPECT(AXQueryInterface_IActiveScript);
1689     SET_EXPECT(AXQueryInterface_IObjectSafety);
1690     SET_EXPECT(AXGetInterfaceSafetyOptions);
1691     SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx_caller);
1692     SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatch_caller);
1693     hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
1694             &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
1695     CHECK_CALLED(AXQueryInterface_IActiveScript);
1696     CHECK_CALLED(AXQueryInterface_IObjectSafety);
1697     CHECK_CALLED(AXGetInterfaceSafetyOptions);
1698     CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatchEx_caller);
1699     CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatch_caller);
1700     check_custom_policy(hres, ppolicy, policy_size, URLPOLICY_ALLOW);
1701
1702     if(!skip_loadobject_tests) {
1703         cs.dwFlags = CONFIRMSAFETYACTION_LOADOBJECT;
1704         ax_setopt_dispex_hres = E_FAIL;
1705         ax_setopt_disp_caller_hres = S_OK;
1706         ax_setopt_disp_data_hres = E_FAIL;
1707         ax_getopt_hres = E_NOINTERFACE;
1708         SET_EXPECT(AXQueryInterface_IActiveScript);
1709         SET_EXPECT(AXQueryInterface_IObjectSafety);
1710         SET_EXPECT(AXGetInterfaceSafetyOptions);
1711         SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx_caller);
1712         SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatch_caller);
1713         SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatch_data);
1714         hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
1715                 &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
1716         CHECK_CALLED(AXQueryInterface_IActiveScript);
1717         CHECK_CALLED(AXQueryInterface_IObjectSafety);
1718         CHECK_CALLED(AXGetInterfaceSafetyOptions);
1719         CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatchEx_caller);
1720         CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatch_caller);
1721         CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatch_data);
1722         check_custom_policy(hres, ppolicy, policy_size, URLPOLICY_DISALLOW);
1723     }
1724
1725     IInternetHostSecurityManager_Release(sec_mgr);
1726 }
1727
1728 static HRESULT WINAPI ActiveScriptProperty_QueryInterface(IActiveScriptProperty *iface, REFIID riid, void **ppv)
1729 {
1730     *ppv = NULL;
1731     ok(0, "unexpected call\n");
1732     return E_NOINTERFACE;
1733 }
1734
1735 static ULONG WINAPI ActiveScriptProperty_AddRef(IActiveScriptProperty *iface)
1736 {
1737     return 2;
1738 }
1739
1740 static ULONG WINAPI ActiveScriptProperty_Release(IActiveScriptProperty *iface)
1741 {
1742     return 1;
1743 }
1744
1745 static HRESULT WINAPI ActiveScriptProperty_GetProperty(IActiveScriptProperty *iface, DWORD dwProperty,
1746         VARIANT *pvarIndex, VARIANT *pvarValue)
1747 {
1748     ok(0, "unexpected call\n");
1749     return E_NOTIMPL;
1750 }
1751
1752 static HRESULT WINAPI ActiveScriptProperty_SetProperty(IActiveScriptProperty *iface, DWORD dwProperty,
1753         VARIANT *pvarIndex, VARIANT *pvarValue)
1754 {
1755     switch(dwProperty) {
1756     case SCRIPTPROP_HACK_TRIDENTEVENTSINK:
1757         CHECK_EXPECT(SetProperty_HACK_TRIDENTEVENTSINK);
1758         ok(V_VT(pvarValue) == VT_BOOL, "V_VT(pvarValue)=%d\n", V_VT(pvarValue));
1759         ok(V_BOOL(pvarValue) == VARIANT_TRUE, "V_BOOL(pvarValue)=%x\n", V_BOOL(pvarValue));
1760         break;
1761     case SCRIPTPROP_INVOKEVERSIONING:
1762         CHECK_EXPECT(SetProperty_INVOKEVERSIONING);
1763         ok(V_VT(pvarValue) == VT_I4, "V_VT(pvarValue)=%d\n", V_VT(pvarValue));
1764         ok(V_I4(pvarValue) == 1, "V_I4(pvarValue)=%d\n", V_I4(pvarValue));
1765         break;
1766     case SCRIPTPROP_ABBREVIATE_GLOBALNAME_RESOLUTION:
1767         CHECK_EXPECT(SetProperty_ABBREVIATE_GLOBALNAME_RESOLUTION);
1768         ok(V_VT(pvarValue) == VT_BOOL, "V_VT(pvarValue)=%d\n", V_VT(pvarValue));
1769         ok(V_BOOL(pvarValue) == VARIANT_TRUE, "V_BOOL(pvarValue)=%x\n", V_BOOL(pvarValue));
1770         break;
1771     default:
1772         ok(0, "unexpected property %x\n", dwProperty);
1773         return E_NOTIMPL;
1774     }
1775
1776     ok(!pvarIndex, "pvarIndex != NULL\n");
1777     ok(pvarValue != NULL, "pvarValue == NULL\n");
1778
1779     return S_OK;
1780 }
1781
1782 static const IActiveScriptPropertyVtbl ActiveScriptPropertyVtbl = {
1783     ActiveScriptProperty_QueryInterface,
1784     ActiveScriptProperty_AddRef,
1785     ActiveScriptProperty_Release,
1786     ActiveScriptProperty_GetProperty,
1787     ActiveScriptProperty_SetProperty
1788 };
1789
1790 static IActiveScriptProperty ActiveScriptProperty = { &ActiveScriptPropertyVtbl };
1791
1792 static HRESULT WINAPI ActiveScriptParseProcedure_QueryInterface(IActiveScriptParseProcedure2 *iface, REFIID riid, void **ppv)
1793 {
1794     *ppv = NULL;
1795     ok(0, "unexpected call\n");
1796     return E_NOINTERFACE;
1797 }
1798
1799 static ULONG WINAPI ActiveScriptParseProcedure_AddRef(IActiveScriptParseProcedure2 *iface)
1800 {
1801     return 2;
1802 }
1803
1804 static ULONG WINAPI ActiveScriptParseProcedure_Release(IActiveScriptParseProcedure2 *iface)
1805 {
1806     return 1;
1807 }
1808
1809 static HRESULT WINAPI ActiveScriptParseProcedure_ParseProcedureText(IActiveScriptParseProcedure2 *iface,
1810         LPCOLESTR pstrCode, LPCOLESTR pstrFormalParams, LPCOLESTR pstrProcedureName,
1811         LPCOLESTR pstrItemName, IUnknown *punkContext, LPCOLESTR pstrDelimiter,
1812         CTXARG_T dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags, IDispatch **ppdisp)
1813 {
1814     ok(0, "unexpected call\n");
1815     return E_NOTIMPL;
1816 }
1817
1818 static const IActiveScriptParseProcedure2Vtbl ActiveScriptParseProcedureVtbl = {
1819     ActiveScriptParseProcedure_QueryInterface,
1820     ActiveScriptParseProcedure_AddRef,
1821     ActiveScriptParseProcedure_Release,
1822     ActiveScriptParseProcedure_ParseProcedureText
1823 };
1824
1825 static IActiveScriptParseProcedure2 ActiveScriptParseProcedure = { &ActiveScriptParseProcedureVtbl };
1826
1827 static HRESULT WINAPI ActiveScriptParse_QueryInterface(IActiveScriptParse *iface, REFIID riid, void **ppv)
1828 {
1829     *ppv = NULL;
1830     ok(0, "unexpected call\n");
1831     return E_NOINTERFACE;
1832 }
1833
1834 static ULONG WINAPI ActiveScriptParse_AddRef(IActiveScriptParse *iface)
1835 {
1836     return 2;
1837 }
1838
1839 static ULONG WINAPI ActiveScriptParse_Release(IActiveScriptParse *iface)
1840 {
1841     return 1;
1842 }
1843
1844 static HRESULT WINAPI ActiveScriptParse_InitNew(IActiveScriptParse *iface)
1845 {
1846     CHECK_EXPECT(InitNew);
1847     return S_OK;
1848 }
1849
1850 static HRESULT WINAPI ActiveScriptParse_AddScriptlet(IActiveScriptParse *iface,
1851         LPCOLESTR pstrDefaultName, LPCOLESTR pstrCode, LPCOLESTR pstrItemName,
1852         LPCOLESTR pstrSubItemName, LPCOLESTR pstrEventName, LPCOLESTR pstrDelimiter,
1853         CTXARG_T dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags,
1854         BSTR *pbstrName, EXCEPINFO *pexcepinfo)
1855 {
1856     ok(0, "unexpected call\n");
1857     return E_NOTIMPL;
1858 }
1859
1860 static HRESULT dispex_propput(IDispatchEx *obj, DISPID id, DWORD flags, VARIANT *var, IServiceProvider *caller_sp)
1861 {
1862     DISPID propput_arg = DISPID_PROPERTYPUT;
1863     DISPPARAMS dp = {var, &propput_arg, 1, 1};
1864     EXCEPINFO ei = {0};
1865
1866     return IDispatchEx_InvokeEx(obj, id, LOCALE_NEUTRAL, DISPATCH_PROPERTYPUT|flags, &dp, NULL, &ei, caller_sp);
1867 }
1868
1869 static HRESULT dispex_propget(IDispatchEx *obj, DISPID id, VARIANT *res, IServiceProvider *caller_sp)
1870 {
1871     DISPPARAMS dp = {NULL};
1872     EXCEPINFO ei = {0};
1873
1874     return IDispatchEx_InvokeEx(obj, id, LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dp, res, &ei, caller_sp);
1875 }
1876
1877 static void test_func(IDispatchEx *obj)
1878 {
1879     DISPID id;
1880     IDispatchEx *dispex;
1881     IDispatch *disp;
1882     EXCEPINFO ei;
1883     DISPPARAMS dp;
1884     BSTR str;
1885     VARIANT var;
1886     HRESULT hres;
1887
1888     str = a2bstr("toString");
1889     hres = IDispatchEx_GetDispID(obj, str, fdexNameCaseSensitive, &id);
1890     SysFreeString(str);
1891     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
1892     ok(id == DISPID_IOMNAVIGATOR_TOSTRING, "id = %x\n", id);
1893
1894     memset(&dp, 0, sizeof(dp));
1895     memset(&ei, 0, sizeof(ei));
1896     VariantInit(&var);
1897     hres = IDispatchEx_InvokeEx(obj, id, LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dp, &var, &ei, NULL);
1898     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1899     ok(V_VT(&var) == VT_DISPATCH, "V_VT(var)=%d\n", V_VT(&var));
1900     ok(V_DISPATCH(&var) != NULL, "V_DISPATCH(var) == NULL\n");
1901     disp = V_DISPATCH(&var);
1902
1903     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
1904     IDispatch_Release(disp);
1905     ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
1906
1907     /* FIXME: Test InvokeEx(DISPATCH_METHOD) */
1908
1909     memset(&dp, 0, sizeof(dp));
1910     memset(&ei, 0, sizeof(ei));
1911     VariantInit(&var);
1912     hres = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dp, &var, &ei, NULL);
1913     ok(hres == S_OK || broken(E_ACCESSDENIED), "InvokeEx failed: %08x\n", hres);
1914     if(SUCCEEDED(hres)) {
1915         ok(V_VT(&var) == VT_BSTR, "V_VT(var)=%d\n", V_VT(&var));
1916         ok(!strcmp_wa(V_BSTR(&var), "[object]"), "V_BSTR(var) = %s\n", wine_dbgstr_w(V_BSTR(&var)));
1917         VariantClear(&var);
1918     }
1919
1920     V_VT(&var) = VT_I4;
1921     V_I4(&var) = 100;
1922     hres = dispex_propput(obj, id, 0, &var, NULL);
1923     ok(hres == E_NOTIMPL, "InvokeEx failed: %08x\n", hres);
1924
1925     IDispatchEx_Release(dispex);
1926 }
1927
1928 static void test_nextdispid(IDispatchEx *dispex)
1929 {
1930     DISPID last_id = DISPID_STARTENUM, id, dyn_id;
1931     BSTR name;
1932     VARIANT var;
1933     HRESULT hres;
1934
1935     name = a2bstr("dynVal");
1936     hres = IDispatchEx_GetDispID(dispex, name, fdexNameCaseSensitive|fdexNameEnsure, &dyn_id);
1937     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
1938     SysFreeString(name);
1939
1940     V_VT(&var) = VT_EMPTY;
1941     hres = dispex_propput(dispex, dyn_id, 0, &var, NULL);
1942     ok(hres == S_OK, "dispex_propput failed: %08x\n", hres);
1943
1944     while(last_id != dyn_id) {
1945         hres = IDispatchEx_GetNextDispID(dispex, fdexEnumAll, last_id, &id);
1946         ok(hres == S_OK, "GetNextDispID returned: %08x\n", hres);
1947         ok(id != DISPID_STARTENUM, "id == DISPID_STARTENUM\n");
1948         ok(id != DISPID_IOMNAVIGATOR_TOSTRING, "id == DISPID_IOMNAVIGATOR_TOSTRING\n");
1949
1950         hres = IDispatchEx_GetMemberName(dispex, id, &name);
1951         ok(hres == S_OK, "GetMemberName failed: %08x\n", hres);
1952
1953         if(id == dyn_id)
1954             ok(!strcmp_wa(name, "dynVal"), "name = %s\n", wine_dbgstr_w(name));
1955         else if(id == DISPID_IOMNAVIGATOR_PLATFORM)
1956             ok(!strcmp_wa(name, "platform"), "name = %s\n", wine_dbgstr_w(name));
1957
1958         SysFreeString(name);
1959         last_id = id;
1960     }
1961
1962     hres = IDispatchEx_GetNextDispID(dispex, 0, id, &id);
1963     ok(hres == S_FALSE, "GetNextDispID returned: %08x\n", hres);
1964     ok(id == DISPID_STARTENUM, "id != DISPID_STARTENUM\n");
1965 }
1966
1967 static void test_global_id(void)
1968 {
1969     VARIANT var;
1970     DISPPARAMS dp;
1971     EXCEPINFO ei;
1972     BSTR tmp;
1973     DISPID id;
1974     HRESULT hres;
1975
1976     SET_EXPECT(GetScriptDispatch);
1977     SET_EXPECT(script_divid_d);
1978     tmp = a2bstr("divid");
1979     hres = IDispatchEx_GetDispID(window_dispex, tmp, fdexNameCaseSensitive, &id);
1980     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
1981     SysFreeString(tmp);
1982     CHECK_CALLED(GetScriptDispatch);
1983     CHECK_CALLED(script_divid_d);
1984
1985     VariantInit(&var);
1986     memset(&ei, 0, sizeof(ei));
1987     memset(&dp, 0, sizeof(dp));
1988     hres = IDispatchEx_InvokeEx(window_dispex, id, 0, DISPATCH_PROPERTYGET, &dp, &var, &ei, NULL);
1989     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1990     ok(V_VT(&var) == VT_DISPATCH, "V_VT(var) = %d\n", V_VT(&var));
1991     VariantClear(&var);
1992 }
1993
1994 static void test_arg_conv(IHTMLWindow2 *window)
1995 {
1996     IHTMLDocument2 *doc;
1997     IDispatchEx *dispex;
1998     IHTMLElement *elem;
1999     VARIANT v;
2000     HRESULT hres;
2001
2002     hres = IHTMLWindow2_get_document(window, &doc);
2003     ok(hres == S_OK, "get_document failed: %08x\n", hres);
2004
2005     hres = IHTMLDocument2_get_body(doc, &elem);
2006     IHTMLDocument2_Release(doc);
2007     ok(hres == S_OK, "get_body failed: %08x\n", hres);
2008
2009     hres = IHTMLElement_QueryInterface(elem, &IID_IDispatchEx, (void**)&dispex);
2010     IHTMLElement_Release(elem);
2011     ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
2012
2013     SET_EXPECT(QS_VariantConversion);
2014     SET_EXPECT(ChangeType);
2015     V_VT(&v) = VT_I4;
2016     V_I4(&v) = 0xf0f0f0;
2017     hres = dispex_propput(dispex, DISPID_IHTMLBODYELEMENT_BACKGROUND, 0, &v, &caller_sp);
2018     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2019     CHECK_CALLED(QS_VariantConversion);
2020     CHECK_CALLED(ChangeType);
2021
2022     V_VT(&v) = VT_EMPTY;
2023     hres = dispex_propget(dispex, DISPID_IHTMLBODYELEMENT_BGCOLOR, &v, &caller_sp);
2024     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2025     ok(V_VT(&v) == VT_BSTR, "V_VT(var)=%d\n", V_VT(&v));
2026     ok(!V_BSTR(&v), "V_BSTR(&var) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
2027
2028     IDispatchEx_Release(dispex);
2029 }
2030
2031 static void test_script_run(void)
2032 {
2033     IDispatchEx *document, *dispex;
2034     IHTMLWindow2 *window;
2035     IOmNavigator *navigator;
2036     IUnknown *unk;
2037     VARIANT var, arg;
2038     DISPPARAMS dp;
2039     EXCEPINFO ei;
2040     DISPID id;
2041     BSTR tmp;
2042     HRESULT hres;
2043
2044     static const WCHAR documentW[] = {'d','o','c','u','m','e','n','t',0};
2045     static const WCHAR testW[] = {'t','e','s','t',0};
2046     static const WCHAR funcW[] = {'f','u','n','c',0};
2047
2048     SET_EXPECT(GetScriptDispatch);
2049
2050     tmp = SysAllocString(documentW);
2051     hres = IDispatchEx_GetDispID(window_dispex, tmp, fdexNameCaseSensitive, &id);
2052     SysFreeString(tmp);
2053     ok(hres == S_OK, "GetDispID(document) failed: %08x\n", hres);
2054     ok(id == DISPID_IHTMLWINDOW2_DOCUMENT, "id=%x\n", id);
2055
2056     CHECK_CALLED(GetScriptDispatch);
2057
2058     VariantInit(&var);
2059     memset(&dp, 0, sizeof(dp));
2060     memset(&ei, 0, sizeof(ei));
2061
2062     hres = IDispatchEx_InvokeEx(window_dispex, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
2063     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2064     ok(V_VT(&var) == VT_DISPATCH, "V_VT(var)=%d\n", V_VT(&var));
2065     ok(V_DISPATCH(&var) != NULL, "V_DISPATCH(&var) == NULL\n");
2066
2067     hres = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IDispatchEx, (void**)&document);
2068     VariantClear(&var);
2069     ok(hres == S_OK, "Could not get DispatchEx: %08x\n", hres);
2070
2071     tmp = SysAllocString(testW);
2072     hres = IDispatchEx_GetDispID(document, tmp, fdexNameCaseSensitive, &id);
2073     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(document) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
2074     hres = IDispatchEx_GetDispID(document, tmp, fdexNameCaseSensitive | fdexNameImplicit, &id);
2075     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(document) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
2076     SysFreeString(tmp);
2077
2078     id = 0;
2079     tmp = SysAllocString(testW);
2080     hres = IDispatchEx_GetDispID(document, tmp, fdexNameCaseSensitive|fdexNameEnsure, &id);
2081     SysFreeString(tmp);
2082     ok(hres == S_OK, "GetDispID(document) failed: %08x\n", hres);
2083     ok(id, "id == 0\n");
2084
2085     V_VT(&var) = VT_I4;
2086     V_I4(&var) = 100;
2087     hres = dispex_propput(document, id, 0, &var, NULL);
2088     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2089
2090     tmp = SysAllocString(testW);
2091     hres = IDispatchEx_GetDispID(document, tmp, fdexNameCaseSensitive, &id);
2092     SysFreeString(tmp);
2093     ok(hres == S_OK, "GetDispID(document) failed: %08x\n", hres);
2094
2095     hres = IDispatchEx_DeleteMemberByDispID(document, id);
2096     ok(hres == E_NOTIMPL, "DeleteMemberByDispID failed = %08x\n", hres);
2097
2098     VariantInit(&var);
2099     memset(&dp, 0, sizeof(dp));
2100     memset(&ei, 0, sizeof(ei));
2101     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
2102     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2103     ok(V_VT(&var) == VT_I4, "V_VT(var)=%d\n", V_VT(&var));
2104     ok(V_I4(&var) == 100, "V_I4(&var) = %d\n", V_I4(&var));
2105
2106     V_VT(&var) = VT_I4;
2107     V_I4(&var) = 200;
2108     hres = dispex_propput(document, id, DISPATCH_PROPERTYPUTREF, &var, NULL);
2109     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2110
2111     VariantInit(&var);
2112     memset(&dp, 0, sizeof(dp));
2113     memset(&ei, 0, sizeof(ei));
2114     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
2115     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2116     ok(V_VT(&var) == VT_I4, "V_VT(var)=%d\n", V_VT(&var));
2117     ok(V_I4(&var) == 200, "V_I4(&var) = %d\n", V_I4(&var));
2118
2119     memset(&dp, 0, sizeof(dp));
2120     memset(&ei, 0, sizeof(ei));
2121     V_VT(&var) = VT_I4;
2122     V_I4(&var) = 300;
2123     dp.cArgs = 1;
2124     dp.rgvarg = &var;
2125     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYPUT, &dp, NULL, &ei, NULL);
2126     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2127
2128     VariantInit(&var);
2129     memset(&dp, 0, sizeof(dp));
2130     memset(&ei, 0, sizeof(ei));
2131     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
2132     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2133     ok(V_VT(&var) == VT_I4, "V_VT(var)=%d\n", V_VT(&var));
2134     ok(V_I4(&var) == 300, "V_I4(&var) = %d\n", V_I4(&var));
2135
2136     V_VT(&var) = VT_BSTR;
2137     V_BSTR(&var) = NULL;
2138     dispex_propput(document, id, 0, &var, NULL);
2139
2140     VariantInit(&var);
2141     memset(&dp, 0, sizeof(dp));
2142     memset(&ei, 0, sizeof(ei));
2143     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
2144     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2145     ok(V_VT(&var) == VT_BSTR, "V_VT(var)=%d\n", V_VT(&var));
2146     ok(!V_BSTR(&var), "V_BSTR(&var) = %s\n", wine_dbgstr_w(V_BSTR(&var)));
2147
2148     unk = (void*)0xdeadbeef;
2149     hres = IDispatchEx_GetNameSpaceParent(window_dispex, &unk);
2150     ok(hres == S_OK, "GetNameSpaceParent failed: %08x\n", hres);
2151     ok(!unk, "unk=%p, expected NULL\n", unk);
2152
2153     id = 0;
2154     tmp = SysAllocString(funcW);
2155     hres = IDispatchEx_GetDispID(document, tmp, fdexNameCaseSensitive|fdexNameEnsure, &id);
2156     SysFreeString(tmp);
2157     ok(hres == S_OK, "GetDispID(func) failed: %08x\n", hres);
2158     ok(id, "id == 0\n");
2159
2160     dp.cArgs = 1;
2161     dp.rgvarg = &var;
2162     dp.cNamedArgs = 0;
2163     dp.rgdispidNamedArgs = NULL;
2164     V_VT(&var) = VT_DISPATCH;
2165     V_DISPATCH(&var) = (IDispatch*)&funcDisp;
2166     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYPUT, &dp, NULL, &ei, NULL);
2167     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2168
2169     VariantInit(&var);
2170     memset(&dp, 0, sizeof(dp));
2171     memset(&ei, 0, sizeof(ei));
2172     V_VT(&arg) = VT_BOOL;
2173     V_BOOL(&arg) = VARIANT_TRUE;
2174     dp.cArgs = 1;
2175     dp.rgvarg = &arg;
2176
2177     SET_EXPECT(funcDisp);
2178     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_FUNC, &dp, &var, &ei, NULL);
2179     CHECK_CALLED(funcDisp);
2180
2181     ok(hres == S_OK, "InvokeEx(INVOKE_FUNC) failed: %08x\n", hres);
2182     ok(V_VT(&var) == VT_I4, "V_VT(var)=%d\n", V_VT(&var));
2183     ok(V_I4(&var) == 100, "V_I4(&var) == NULL\n");
2184
2185     IDispatchEx_Release(document);
2186
2187     hres = IDispatchEx_QueryInterface(window_dispex, &IID_IHTMLWindow2, (void**)&window);
2188     ok(hres == S_OK, "Could not get IHTMLWindow2 iface: %08x\n", hres);
2189
2190     hres = IHTMLWindow2_get_navigator(window, &navigator);
2191     ok(hres == S_OK, "get_navigator failed: %08x\n", hres);
2192
2193     hres = IOmNavigator_QueryInterface(navigator, &IID_IDispatchEx, (void**)&dispex);
2194     IOmNavigator_Release(navigator);
2195     ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
2196
2197     test_func(dispex);
2198     test_nextdispid(dispex);
2199
2200     test_arg_conv(window);
2201     IHTMLWindow2_Release(window);
2202
2203     tmp = a2bstr("test");
2204     hres = IDispatchEx_DeleteMemberByName(dispex, tmp, fdexNameCaseSensitive);
2205     ok(hres == E_NOTIMPL, "DeleteMemberByName failed: %08x\n", hres);
2206
2207     IDispatchEx_Release(dispex);
2208
2209     script_disp = (IDispatch*)&scriptDisp;
2210
2211     SET_EXPECT(GetScriptDispatch);
2212     SET_EXPECT(script_testprop_d);
2213     tmp = a2bstr("testProp");
2214     hres = IDispatchEx_GetDispID(window_dispex, tmp, fdexNameCaseSensitive, &id);
2215     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
2216     ok(id != DISPID_SCRIPT_TESTPROP, "id == DISPID_SCRIPT_TESTPROP\n");
2217     CHECK_CALLED(GetScriptDispatch);
2218     CHECK_CALLED(script_testprop_d);
2219     SysFreeString(tmp);
2220
2221     tmp = a2bstr("testProp");
2222     hres = IDispatchEx_GetDispID(window_dispex, tmp, fdexNameCaseSensitive, &id);
2223     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
2224     ok(id != DISPID_SCRIPT_TESTPROP, "id == DISPID_SCRIPT_TESTPROP\n");
2225     SysFreeString(tmp);
2226
2227     SET_EXPECT(GetScriptDispatch);
2228     SET_EXPECT(script_testprop_i);
2229     memset(&ei, 0, sizeof(ei));
2230     memset(&dp, 0, sizeof(dp));
2231     hres = IDispatchEx_InvokeEx(window_dispex, id, 0, DISPATCH_PROPERTYGET, &dp, &var, &ei, NULL);
2232     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2233     ok(V_VT(&var) == VT_NULL, "V_VT(var) = %d\n", V_VT(&var));
2234     CHECK_CALLED(GetScriptDispatch);
2235     CHECK_CALLED(script_testprop_i);
2236
2237     SET_EXPECT(GetScriptDispatch);
2238     SET_EXPECT(script_testprop2_d);
2239     tmp = a2bstr("testProp2");
2240     hres = IDispatchEx_GetDispID(window_dispex, tmp, fdexNameCaseSensitive|fdexNameEnsure, &id);
2241     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
2242     ok(id != DISPID_SCRIPT_TESTPROP2, "id == DISPID_SCRIPT_TESTPROP2\n");
2243     CHECK_CALLED(GetScriptDispatch);
2244     CHECK_CALLED(script_testprop2_d);
2245     SysFreeString(tmp);
2246
2247     tmp = a2bstr("test");
2248     hres = IDispatchEx_DeleteMemberByName(window_dispex, tmp, fdexNameCaseSensitive);
2249     ok(hres == E_NOTIMPL, "DeleteMemberByName failed: %08x\n", hres);
2250
2251     test_global_id();
2252
2253     test_security();
2254 }
2255
2256 static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *iface,
2257         LPCOLESTR pstrCode, LPCOLESTR pstrItemName, IUnknown *punkContext,
2258         LPCOLESTR pstrDelimiter, CTXARG_T dwSourceContextCookie, ULONG ulStartingLine,
2259         DWORD dwFlags, VARIANT *pvarResult, EXCEPINFO *pexcepinfo)
2260 {
2261     ok(pvarResult != NULL, "pvarResult == NULL\n");
2262     ok(pexcepinfo != NULL, "pexcepinfo == NULL\n");
2263
2264     if(!strcmp_wa(pstrCode, "execScript call")) {
2265         CHECK_EXPECT(ParseScriptText_execScript);
2266         ok(!pstrItemName, "pstrItemName = %s\n", wine_dbgstr_w(pstrItemName));
2267         ok(!strcmp_wa(pstrDelimiter, "\""), "pstrDelimiter = %s\n", wine_dbgstr_w(pstrDelimiter));
2268         ok(dwFlags == SCRIPTTEXT_ISVISIBLE, "dwFlags = %x\n", dwFlags);
2269
2270         V_VT(pvarResult) = VT_I4;
2271         V_I4(pvarResult) = 10;
2272         return S_OK;
2273     }else if(!strcmp_wa(pstrCode, "simple script")) {
2274         CHECK_EXPECT(ParseScriptText_script);
2275         ok(!strcmp_wa(pstrItemName, "window"), "pstrItemName = %s\n", wine_dbgstr_w(pstrItemName));
2276         ok(!strcmp_wa(pstrDelimiter, "</SCRIPT>"), "pstrDelimiter = %s\n", wine_dbgstr_w(pstrDelimiter));
2277         ok(dwFlags == (SCRIPTTEXT_ISVISIBLE|SCRIPTTEXT_HOSTMANAGESSOURCE), "dwFlags = %x\n", dwFlags);
2278
2279         test_script_run();
2280         return S_OK;
2281     }
2282
2283     ok(0, "unexpected script %s\n", wine_dbgstr_w(pstrCode));
2284     return E_FAIL;
2285 }
2286
2287 static const IActiveScriptParseVtbl ActiveScriptParseVtbl = {
2288     ActiveScriptParse_QueryInterface,
2289     ActiveScriptParse_AddRef,
2290     ActiveScriptParse_Release,
2291     ActiveScriptParse_InitNew,
2292     ActiveScriptParse_AddScriptlet,
2293     ActiveScriptParse_ParseScriptText
2294 };
2295
2296 static IActiveScriptParse ActiveScriptParse = { &ActiveScriptParseVtbl };
2297
2298 static HRESULT WINAPI ActiveScript_QueryInterface(IActiveScript *iface, REFIID riid, void **ppv)
2299 {
2300     *ppv = NULL;
2301
2302     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IActiveScript, riid)) {
2303         *ppv = iface;
2304         return S_OK;
2305     }
2306
2307     if(IsEqualGUID(&IID_IActiveScriptParse, riid)) {
2308         *ppv = &ActiveScriptParse;
2309         return S_OK;
2310     }
2311
2312     if(IsEqualGUID(&IID_IActiveScriptParseProcedure2, riid)) {
2313         *ppv = &ActiveScriptParseProcedure;
2314         return S_OK;
2315     }
2316
2317     if(IsEqualGUID(&IID_IActiveScriptProperty, riid)) {
2318         *ppv = &ActiveScriptProperty;
2319         return S_OK;
2320     }
2321
2322     if(IsEqualGUID(&IID_IObjectSafety, riid)) {
2323         *ppv = &ObjectSafety;
2324         return S_OK;
2325     }
2326
2327     if(IsEqualGUID(&IID_IActiveScriptDebug, riid))
2328         return E_NOINTERFACE;
2329
2330     trace("QI(%s)\n", debugstr_guid(riid));
2331     return E_NOINTERFACE;
2332 }
2333
2334 static ULONG WINAPI ActiveScript_AddRef(IActiveScript *iface)
2335 {
2336     return 2;
2337 }
2338
2339 static ULONG WINAPI ActiveScript_Release(IActiveScript *iface)
2340 {
2341     return 1;
2342 }
2343
2344 static HRESULT WINAPI ActiveScript_SetScriptSite(IActiveScript *iface, IActiveScriptSite *pass)
2345 {
2346     IActiveScriptSiteInterruptPoll *poll;
2347     IActiveScriptSiteDebug *debug;
2348     IServiceProvider *service;
2349     ICanHandleException *canexpection;
2350     LCID lcid;
2351     HRESULT hres;
2352
2353     CHECK_EXPECT(SetScriptSite);
2354
2355     ok(pass != NULL, "pass == NULL\n");
2356
2357     hres = IActiveScriptSite_QueryInterface(pass, &IID_IActiveScriptSiteInterruptPoll, (void**)&poll);
2358     ok(hres == S_OK, "Could not get IActiveScriptSiteInterruptPoll interface: %08x\n", hres);
2359     if(FAILED(hres))
2360         IActiveScriptSiteInterruptPoll_Release(poll);
2361
2362     hres = IActiveScriptSite_GetLCID(pass, &lcid);
2363     ok(hres == S_OK, "GetLCID failed: %08x\n", hres);
2364
2365     hres = IActiveScriptSite_OnStateChange(pass, (state = SCRIPTSTATE_INITIALIZED));
2366     ok(hres == S_OK, "OnStateChange failed: %08x\n", hres);
2367
2368     hres = IActiveScriptSite_QueryInterface(pass, &IID_IActiveScriptSiteDebug, (void**)&debug);
2369     ok(hres == S_OK, "Could not get IActiveScriptSiteDebug interface: %08x\n", hres);
2370     if(SUCCEEDED(hres))
2371         IActiveScriptSiteDebug_Release(debug);
2372
2373     hres = IActiveScriptSite_QueryInterface(pass, &IID_ICanHandleException, (void**)&canexpection);
2374     ok(hres == E_NOINTERFACE, "Could not get IID_ICanHandleException interface: %08x\n", hres);
2375
2376     hres = IActiveScriptSite_QueryInterface(pass, &IID_IServiceProvider, (void**)&service);
2377     ok(hres == S_OK, "Could not get IServiceProvider interface: %08x\n", hres);
2378     if(SUCCEEDED(hres))
2379         IServiceProvider_Release(service);
2380
2381     site = pass;
2382     IActiveScriptSite_AddRef(site);
2383     return S_OK;
2384 }
2385
2386 static HRESULT WINAPI ActiveScript_GetScriptSite(IActiveScript *iface, REFIID riid,
2387                                             void **ppvObject)
2388 {
2389     ok(0, "unexpected call\n");
2390     return E_NOTIMPL;
2391 }
2392
2393 static HRESULT WINAPI ActiveScript_SetScriptState(IActiveScript *iface, SCRIPTSTATE ss)
2394 {
2395     HRESULT hres;
2396
2397     switch(ss) {
2398     case SCRIPTSTATE_STARTED:
2399         CHECK_EXPECT(SetScriptState_STARTED);
2400         break;
2401     case SCRIPTSTATE_CONNECTED:
2402         CHECK_EXPECT(SetScriptState_CONNECTED);
2403         break;
2404     case SCRIPTSTATE_DISCONNECTED:
2405         CHECK_EXPECT(SetScriptState_DISCONNECTED);
2406         break;
2407     default:
2408         ok(0, "unexpected state %d\n", ss);
2409         return E_NOTIMPL;
2410     }
2411
2412     hres = IActiveScriptSite_OnStateChange(site, (state = ss));
2413     ok(hres == S_OK, "OnStateChange failed: %08x\n", hres);
2414
2415     return S_OK;
2416 }
2417
2418 static HRESULT WINAPI ActiveScript_GetScriptState(IActiveScript *iface, SCRIPTSTATE *pssState)
2419 {
2420     CHECK_EXPECT(GetScriptState);
2421
2422     *pssState = state;
2423     return S_OK;
2424 }
2425
2426 static HRESULT WINAPI ActiveScript_Close(IActiveScript *iface)
2427 {
2428     CHECK_EXPECT(Close);
2429     return E_NOTIMPL;
2430 }
2431
2432 static HRESULT WINAPI ActiveScript_AddNamedItem(IActiveScript *iface,
2433         LPCOLESTR pstrName, DWORD dwFlags)
2434 {
2435     IDispatch *disp;
2436     IUnknown *unk = NULL, *unk2;
2437     HRESULT hres;
2438
2439     static const WCHAR windowW[] = {'w','i','n','d','o','w',0};
2440
2441     static const IID unknown_iid = {0x719C3050,0xF9D3,0x11CF,{0xA4,0x93,0x00,0x40,0x05,0x23,0xA8,0xA0}};
2442
2443     CHECK_EXPECT(AddNamedItem);
2444
2445     ok(!lstrcmpW(pstrName, windowW), "pstrName=%s\n", wine_dbgstr_w(pstrName));
2446     ok(dwFlags == (SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS), "dwFlags=%x\n", dwFlags);
2447
2448     hres = IActiveScriptSite_GetItemInfo(site, windowW, SCRIPTINFO_IUNKNOWN, &unk, NULL);
2449     ok(hres == S_OK, "GetItemInfo failed: %08x\n", hres);
2450     ok(unk != NULL, "unk == NULL\n");
2451
2452     hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
2453     ok(hres == S_OK, "Could not get IDispatch interface: %08x\n", hres);
2454     if(SUCCEEDED(hres))
2455         IDispatch_Release(disp);
2456
2457     hres = IUnknown_QueryInterface(unk, &unknown_iid, (void**)&unk2);
2458     ok(hres == E_NOINTERFACE, "Got ?? interface: %p\n", unk2);
2459     if(SUCCEEDED(hres))
2460         IUnknown_Release(unk2);
2461
2462     hres = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&window_dispex);
2463     ok(hres == S_OK, "Could not get IDispatchEx interface: %08x\n", hres);
2464
2465     IUnknown_Release(unk);
2466     return S_OK;
2467 }
2468
2469 static HRESULT WINAPI ActiveScript_AddTypeLib(IActiveScript *iface, REFGUID rguidTypeLib,
2470                                          DWORD dwMajor, DWORD dwMinor, DWORD dwFlags)
2471 {
2472     ok(0, "unexpected call\n");
2473     return E_NOTIMPL;
2474 }
2475
2476 static HRESULT WINAPI ActiveScript_GetScriptDispatch(IActiveScript *iface, LPCOLESTR pstrItemName,
2477                                                 IDispatch **ppdisp)
2478 {
2479     CHECK_EXPECT(GetScriptDispatch);
2480
2481     ok(!strcmp_wa(pstrItemName, "window"), "pstrItemName = %s\n", wine_dbgstr_w(pstrItemName));
2482
2483     if(!script_disp)
2484         return E_NOTIMPL;
2485
2486     *ppdisp = script_disp;
2487     return S_OK;
2488 }
2489
2490 static HRESULT WINAPI ActiveScript_GetCurrentScriptThreadID(IActiveScript *iface,
2491                                                        SCRIPTTHREADID *pstridThread)
2492 {
2493     ok(0, "unexpected call\n");
2494     return E_NOTIMPL;
2495 }
2496
2497 static HRESULT WINAPI ActiveScript_GetScriptThreadID(IActiveScript *iface,
2498                                                 DWORD dwWin32ThreadId, SCRIPTTHREADID *pstidThread)
2499 {
2500     ok(0, "unexpected call\n");
2501     return E_NOTIMPL;
2502 }
2503
2504 static HRESULT WINAPI ActiveScript_GetScriptThreadState(IActiveScript *iface,
2505         SCRIPTTHREADID stidThread, SCRIPTTHREADSTATE *pstsState)
2506 {
2507     ok(0, "unexpected call\n");
2508     return E_NOTIMPL;
2509 }
2510
2511 static HRESULT WINAPI ActiveScript_InterruptScriptThread(IActiveScript *iface,
2512         SCRIPTTHREADID stidThread, const EXCEPINFO *pexcepinfo, DWORD dwFlags)
2513 {
2514     ok(0, "unexpected call\n");
2515     return E_NOTIMPL;
2516 }
2517
2518 static HRESULT WINAPI ActiveScript_Clone(IActiveScript *iface, IActiveScript **ppscript)
2519 {
2520     ok(0, "unexpected call\n");
2521     return E_NOTIMPL;
2522 }
2523
2524 static const IActiveScriptVtbl ActiveScriptVtbl = {
2525     ActiveScript_QueryInterface,
2526     ActiveScript_AddRef,
2527     ActiveScript_Release,
2528     ActiveScript_SetScriptSite,
2529     ActiveScript_GetScriptSite,
2530     ActiveScript_SetScriptState,
2531     ActiveScript_GetScriptState,
2532     ActiveScript_Close,
2533     ActiveScript_AddNamedItem,
2534     ActiveScript_AddTypeLib,
2535     ActiveScript_GetScriptDispatch,
2536     ActiveScript_GetCurrentScriptThreadID,
2537     ActiveScript_GetScriptThreadID,
2538     ActiveScript_GetScriptThreadState,
2539     ActiveScript_InterruptScriptThread,
2540     ActiveScript_Clone
2541 };
2542
2543 static IActiveScript ActiveScript = { &ActiveScriptVtbl };
2544
2545 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
2546 {
2547     *ppv = NULL;
2548
2549     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) {
2550         *ppv = iface;
2551         return S_OK;
2552     }
2553
2554     if(IsEqualGUID(&IID_IMarshal, riid))
2555         return E_NOINTERFACE;
2556     if(IsEqualGUID(&CLSID_IdentityUnmarshal, riid))
2557         return E_NOINTERFACE;
2558
2559     ok(0, "unexpected riid %s\n", debugstr_guid(riid));
2560     return E_NOTIMPL;
2561 }
2562
2563 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
2564 {
2565     return 2;
2566 }
2567
2568 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
2569 {
2570     return 1;
2571 }
2572
2573 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
2574 {
2575     CHECK_EXPECT(CreateInstance);
2576
2577     ok(!outer, "outer = %p\n", outer);
2578     ok(IsEqualGUID(&IID_IActiveScript, riid), "unexpected riid %s\n", debugstr_guid(riid));
2579     *ppv = &ActiveScript;
2580     return S_OK;
2581 }
2582
2583 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
2584 {
2585     ok(0, "unexpected call\n");
2586     return S_OK;
2587 }
2588
2589 static const IClassFactoryVtbl ClassFactoryVtbl = {
2590     ClassFactory_QueryInterface,
2591     ClassFactory_AddRef,
2592     ClassFactory_Release,
2593     ClassFactory_CreateInstance,
2594     ClassFactory_LockServer
2595 };
2596
2597 static IClassFactory script_cf = { &ClassFactoryVtbl };
2598
2599 static const char simple_script_str[] =
2600     "<html><head></head><body>"
2601     "<div id=\"divid\"></div>"
2602     "<script language=\"TestScript\">simple script</script>"
2603     "</body></html>";
2604
2605 static void test_exec_script(IHTMLDocument2 *doc, const char *codea, const char *langa)
2606 {
2607     IHTMLWindow2 *window;
2608     BSTR code, lang;
2609     VARIANT v;
2610     HRESULT hres;
2611
2612     hres = IHTMLDocument2_get_parentWindow(doc, &window);
2613     ok(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
2614
2615     code = a2bstr(codea);
2616     lang = a2bstr(langa);
2617
2618     SET_EXPECT(ParseScriptText_execScript);
2619     hres = IHTMLWindow2_execScript(window, code, lang, &v);
2620     ok(hres == S_OK, "execScript failed: %08x\n", hres);
2621     ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
2622     ok(V_I4(&v) == 10, "V_I4(v) = %d\n", V_I4(&v));
2623     CHECK_CALLED(ParseScriptText_execScript);
2624     SysFreeString(lang);
2625
2626     lang = a2bstr("invalid");
2627     V_VT(&v) = 100;
2628     hres = IHTMLWindow2_execScript(window, code, lang, &v);
2629     ok(hres == CO_E_CLASSSTRING, "execScript failed: %08x, expected CO_E_CLASSSTRING\n", hres);
2630     ok(V_VT(&v) == 100, "V_VT(v) = %d\n", V_VT(&v));
2631     SysFreeString(lang);
2632     SysFreeString(code);
2633
2634     IHTMLWindow2_Release(window);
2635 }
2636
2637 static void test_simple_script(void)
2638 {
2639     IHTMLDocument2 *doc;
2640
2641     doc = create_document();
2642     if(!doc)
2643         return;
2644
2645     SET_EXPECT(CreateInstance);
2646     SET_EXPECT(GetInterfaceSafetyOptions);
2647     SET_EXPECT(SetInterfaceSafetyOptions);
2648     SET_EXPECT(SetProperty_INVOKEVERSIONING); /* IE8 */
2649     SET_EXPECT(SetProperty_HACK_TRIDENTEVENTSINK);
2650     SET_EXPECT(InitNew);
2651     SET_EXPECT(SetScriptSite);
2652     SET_EXPECT(GetScriptState);
2653     SET_EXPECT(SetScriptState_STARTED);
2654     SET_EXPECT(AddNamedItem);
2655     SET_EXPECT(SetProperty_ABBREVIATE_GLOBALNAME_RESOLUTION); /* IE8 */
2656     SET_EXPECT(ParseScriptText_script);
2657     SET_EXPECT(SetScriptState_CONNECTED);
2658
2659     load_doc(doc, simple_script_str);
2660
2661     CHECK_CALLED(CreateInstance);
2662     CHECK_CALLED(GetInterfaceSafetyOptions);
2663     CHECK_CALLED(SetInterfaceSafetyOptions);
2664     CHECK_CALLED_BROKEN(SetProperty_INVOKEVERSIONING); /* IE8 */
2665     CHECK_CALLED(SetProperty_HACK_TRIDENTEVENTSINK);
2666     CHECK_CALLED(InitNew);
2667     CHECK_CALLED(SetScriptSite);
2668     CHECK_CALLED(GetScriptState);
2669     CHECK_CALLED(SetScriptState_STARTED);
2670     CHECK_CALLED(AddNamedItem);
2671     CHECK_CALLED_BROKEN(SetProperty_ABBREVIATE_GLOBALNAME_RESOLUTION); /* IE8 */
2672     CHECK_CALLED(ParseScriptText_script);
2673     CHECK_CALLED(SetScriptState_CONNECTED);
2674
2675     test_exec_script(doc, "execScript call", "TestScript");
2676
2677     if(site)
2678         IActiveScriptSite_Release(site);
2679     if(window_dispex)
2680         IDispatchEx_Release(window_dispex);
2681
2682     SET_EXPECT(SetScriptState_DISCONNECTED);
2683     SET_EXPECT(Close);
2684
2685     IHTMLDocument2_Release(doc);
2686
2687     CHECK_CALLED(SetScriptState_DISCONNECTED);
2688     CHECK_CALLED(Close);
2689 }
2690
2691 static void run_js_script(const char *test_name)
2692 {
2693     WCHAR url[INTERNET_MAX_URL_LENGTH];
2694     char urlA[INTERNET_MAX_URL_LENGTH];
2695     IPersistMoniker *persist;
2696     IHTMLDocument2 *doc;
2697     IMoniker *mon;
2698     MSG msg;
2699     HRESULT hres;
2700
2701     static const char res[] = "res://";
2702
2703     trace("running %s...\n", test_name);
2704
2705     doc = create_document();
2706     if(!doc)
2707         return;
2708
2709     set_client_site(doc, TRUE);
2710     do_advise(doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
2711
2712     lstrcpyA(urlA, res);
2713     GetModuleFileNameA(NULL, urlA + lstrlenA(res), sizeof(urlA) - lstrlenA(res));
2714     lstrcatA(urlA, "/");
2715     lstrcatA(urlA, test_name);
2716     MultiByteToWideChar(CP_ACP, 0, urlA, -1, url, sizeof(url)/sizeof(WCHAR));
2717
2718     hres = CreateURLMoniker(NULL, url, &mon);
2719     ok(hres == S_OK, "CreateURLMoniker failed: %08x\n", hres);
2720
2721     hres = IHTMLDocument2_QueryInterface(doc, &IID_IPersistMoniker, (void**)&persist);
2722     ok(hres == S_OK, "Could not get IPersistMoniker iface: %08x\n", hres);
2723
2724     hres = IPersistMoniker_Load(persist, FALSE, mon, NULL, 0);
2725     ok(hres == S_OK, "Load failed: %08x\n", hres);
2726
2727     IMoniker_Release(mon);
2728     IPersistMoniker_Release(persist);
2729
2730     SET_EXPECT(external_success);
2731
2732     while(!called_external_success && GetMessage(&msg, NULL, 0, 0)) {
2733         TranslateMessage(&msg);
2734         DispatchMessage(&msg);
2735     }
2736
2737     CHECK_CALLED(external_success);
2738
2739     set_client_site(doc, FALSE);
2740     IHTMLDocument2_Release(doc);
2741 }
2742
2743 static void run_js_tests(void)
2744 {
2745     run_js_script("jstest.html");
2746     run_js_script("exectest.html");
2747     run_js_script("vbtest.html");
2748     run_js_script("events.html");
2749 }
2750
2751 static BOOL init_registry(BOOL init)
2752 {
2753     return init_key("TestScript\\CLSID", TESTSCRIPT_CLSID, init)
2754         && init_key("CLSID\\"TESTSCRIPT_CLSID"\\Implemented Categories\\{F0B7A1A1-9847-11CF-8F20-00805F2CD064}",
2755                     NULL, init)
2756         && init_key("CLSID\\"TESTSCRIPT_CLSID"\\Implemented Categories\\{F0B7A1A2-9847-11CF-8F20-00805F2CD064}",
2757                     NULL, init);
2758 }
2759
2760 static BOOL register_script_engine(void)
2761 {
2762     DWORD regid;
2763     HRESULT hres;
2764
2765     if(!init_registry(TRUE)) {
2766         init_registry(FALSE);
2767         return FALSE;
2768     }
2769
2770     hres = CoRegisterClassObject(&CLSID_TestScript, (IUnknown *)&script_cf,
2771                                  CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &regid);
2772     ok(hres == S_OK, "Could not register script engine: %08x\n", hres);
2773
2774     return TRUE;
2775 }
2776
2777 static LRESULT WINAPI wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
2778 {
2779     return DefWindowProc(hwnd, msg, wParam, lParam);
2780 }
2781
2782 static HWND create_container_window(void)
2783 {
2784     static const CHAR szHTMLDocumentTest[] = "HTMLDocumentTest";
2785     static WNDCLASSEXA wndclass = {
2786         sizeof(WNDCLASSEXA),
2787         0,
2788         wnd_proc,
2789         0, 0, NULL, NULL, NULL, NULL, NULL,
2790         szHTMLDocumentTest,
2791         NULL
2792     };
2793
2794     RegisterClassExA(&wndclass);
2795     return CreateWindowA(szHTMLDocumentTest, szHTMLDocumentTest,
2796             WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
2797             300, 300, NULL, NULL, NULL, NULL);
2798 }
2799
2800 START_TEST(script)
2801 {
2802     CoInitialize(NULL);
2803     container_hwnd = create_container_window();
2804
2805     if(winetest_interactive || ! is_ie_hardened()) {
2806         if(register_script_engine()) {
2807             test_simple_script();
2808             init_registry(FALSE);
2809         }else {
2810             skip("Could not register TestScript engine\n");
2811         }
2812         run_js_tests();
2813     }else {
2814         skip("IE running in Enhanced Security Configuration\n");
2815     }
2816
2817     DestroyWindow(container_hwnd);
2818     CoUninitialize();
2819 }