atl80: Added AtlComModuleRegisterServer implementation (based on AtlModuleRegisterSer...
[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 #define test_elem_disabled(a,b) _test_elem_disabled(__LINE__,a,b)
2032 static void _test_elem_disabled(unsigned line, IHTMLElement *elem, VARIANT_BOOL exb)
2033 {
2034     IHTMLElement3 *elem3;
2035     VARIANT_BOOL b = 100;
2036     HRESULT hres;
2037
2038     hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLElement3, (void**)&elem3);
2039     ok_(__FILE__,line)(hres == S_OK, "Could not get IHTMLElement3 iface: %08x\n", hres);
2040
2041     hres = IHTMLElement3_get_disabled(elem3, &b);
2042     ok_(__FILE__,line)(hres == S_OK, "get_disabled failed: %08x\n", hres);
2043     ok_(__FILE__,line)(b == exb, "disabled = %x, expected %x\n", b, exb);
2044
2045     IHTMLElement3_Release(elem3);
2046 }
2047
2048 static void test_default_arg_conv(IHTMLWindow2 *window)
2049 {
2050     IHTMLDocument2 *doc;
2051     IDispatchEx *dispex;
2052     IHTMLElement *elem;
2053     VARIANT v;
2054     HRESULT hres;
2055
2056     hres = IHTMLWindow2_get_document(window, &doc);
2057     ok(hres == S_OK, "get_document failed: %08x\n", hres);
2058
2059     hres = IHTMLDocument2_get_body(doc, &elem);
2060     IHTMLDocument2_Release(doc);
2061     ok(hres == S_OK, "get_body failed: %08x\n", hres);
2062
2063     hres = IHTMLElement_QueryInterface(elem, &IID_IDispatchEx, (void**)&dispex);
2064     ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
2065
2066     test_elem_disabled(elem, VARIANT_FALSE);
2067
2068     V_VT(&v) = VT_BSTR;
2069     V_BSTR(&v) = a2bstr("test");
2070     hres = dispex_propput(dispex, DISPID_IHTMLELEMENT3_DISABLED, 0, &v, NULL);
2071     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2072     SysFreeString(V_BSTR(&v));
2073
2074     test_elem_disabled(elem, VARIANT_TRUE);
2075
2076     V_VT(&v) = VT_I4;
2077     V_BSTR(&v) = 0;
2078     hres = dispex_propput(dispex, DISPID_IHTMLELEMENT3_DISABLED, 0, &v, NULL);
2079     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2080
2081     test_elem_disabled(elem, VARIANT_FALSE);
2082
2083     IHTMLElement_Release(elem);
2084     IDispatchEx_Release(dispex);
2085 }
2086
2087 static void test_ui(void)
2088 {
2089     IActiveScriptSiteUIControl *ui_control;
2090     SCRIPTUICHANDLING uic_handling = 10;
2091     HRESULT hres;
2092
2093     hres = IActiveScriptSite_QueryInterface(site, &IID_IActiveScriptSiteUIControl, (void**)&ui_control);
2094     if(hres == E_NOINTERFACE) {
2095         win_skip("IActiveScriptSiteUIControl not supported\n");
2096         return;
2097     }
2098     ok(hres == S_OK, "Could not get IActiveScriptSiteUIControl: %08x\n", hres);
2099
2100     hres = IActiveScriptSiteUIControl_GetUIBehavior(ui_control, SCRIPTUICITEM_MSGBOX, &uic_handling);
2101     ok(hres == S_OK, "GetUIBehavior failed: %08x\n", hres);
2102     ok(uic_handling == SCRIPTUICHANDLING_ALLOW, "uic_handling = %d\n", uic_handling);
2103
2104     IActiveScriptSiteUIControl_Release(ui_control);
2105 }
2106
2107 static void test_sp(void)
2108 {
2109     IServiceProvider *sp;
2110     IUnknown *unk;
2111     HRESULT hres;
2112
2113     hres = IActiveScriptSite_QueryInterface(site, &IID_IServiceProvider, (void**)&sp);
2114     ok(hres == S_OK, "Could not get IServiceProvider iface: %08x\n", hres);
2115
2116     hres = IServiceProvider_QueryService(sp, &SID_SContainerDispatch, &IID_IHTMLDocument, (void**)&unk);
2117     ok(hres == S_OK, "Could not get SID_SContainerDispatch service: %08x\n", hres);
2118     IUnknown_Release(unk);
2119
2120     IServiceProvider_Release(sp);
2121 }
2122
2123 static void test_script_run(void)
2124 {
2125     IDispatchEx *document, *dispex;
2126     IHTMLWindow2 *window;
2127     IOmNavigator *navigator;
2128     IUnknown *unk;
2129     VARIANT var, arg;
2130     DISPPARAMS dp;
2131     EXCEPINFO ei;
2132     DISPID id;
2133     BSTR tmp;
2134     HRESULT hres;
2135
2136     static const WCHAR documentW[] = {'d','o','c','u','m','e','n','t',0};
2137     static const WCHAR testW[] = {'t','e','s','t',0};
2138     static const WCHAR funcW[] = {'f','u','n','c',0};
2139
2140     SET_EXPECT(GetScriptDispatch);
2141
2142     tmp = SysAllocString(documentW);
2143     hres = IDispatchEx_GetDispID(window_dispex, tmp, fdexNameCaseSensitive, &id);
2144     SysFreeString(tmp);
2145     ok(hres == S_OK, "GetDispID(document) failed: %08x\n", hres);
2146     ok(id == DISPID_IHTMLWINDOW2_DOCUMENT, "id=%x\n", id);
2147
2148     CHECK_CALLED(GetScriptDispatch);
2149
2150     VariantInit(&var);
2151     memset(&dp, 0, sizeof(dp));
2152     memset(&ei, 0, sizeof(ei));
2153
2154     hres = IDispatchEx_InvokeEx(window_dispex, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
2155     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2156     ok(V_VT(&var) == VT_DISPATCH, "V_VT(var)=%d\n", V_VT(&var));
2157     ok(V_DISPATCH(&var) != NULL, "V_DISPATCH(&var) == NULL\n");
2158
2159     hres = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IDispatchEx, (void**)&document);
2160     VariantClear(&var);
2161     ok(hres == S_OK, "Could not get DispatchEx: %08x\n", hres);
2162
2163     tmp = SysAllocString(testW);
2164     hres = IDispatchEx_GetDispID(document, tmp, fdexNameCaseSensitive, &id);
2165     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(document) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
2166     hres = IDispatchEx_GetDispID(document, tmp, fdexNameCaseSensitive | fdexNameImplicit, &id);
2167     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(document) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
2168     SysFreeString(tmp);
2169
2170     id = 0;
2171     tmp = SysAllocString(testW);
2172     hres = IDispatchEx_GetDispID(document, tmp, fdexNameCaseSensitive|fdexNameEnsure, &id);
2173     SysFreeString(tmp);
2174     ok(hres == S_OK, "GetDispID(document) failed: %08x\n", hres);
2175     ok(id, "id == 0\n");
2176
2177     V_VT(&var) = VT_I4;
2178     V_I4(&var) = 100;
2179     hres = dispex_propput(document, id, 0, &var, NULL);
2180     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2181
2182     tmp = SysAllocString(testW);
2183     hres = IDispatchEx_GetDispID(document, tmp, fdexNameCaseSensitive, &id);
2184     SysFreeString(tmp);
2185     ok(hres == S_OK, "GetDispID(document) failed: %08x\n", hres);
2186
2187     hres = IDispatchEx_DeleteMemberByDispID(document, id);
2188     ok(hres == E_NOTIMPL, "DeleteMemberByDispID failed = %08x\n", hres);
2189
2190     VariantInit(&var);
2191     memset(&dp, 0, sizeof(dp));
2192     memset(&ei, 0, sizeof(ei));
2193     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
2194     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2195     ok(V_VT(&var) == VT_I4, "V_VT(var)=%d\n", V_VT(&var));
2196     ok(V_I4(&var) == 100, "V_I4(&var) = %d\n", V_I4(&var));
2197
2198     V_VT(&var) = VT_I4;
2199     V_I4(&var) = 200;
2200     hres = dispex_propput(document, id, DISPATCH_PROPERTYPUTREF, &var, NULL);
2201     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2202
2203     VariantInit(&var);
2204     memset(&dp, 0, sizeof(dp));
2205     memset(&ei, 0, sizeof(ei));
2206     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
2207     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2208     ok(V_VT(&var) == VT_I4, "V_VT(var)=%d\n", V_VT(&var));
2209     ok(V_I4(&var) == 200, "V_I4(&var) = %d\n", V_I4(&var));
2210
2211     memset(&dp, 0, sizeof(dp));
2212     memset(&ei, 0, sizeof(ei));
2213     V_VT(&var) = VT_I4;
2214     V_I4(&var) = 300;
2215     dp.cArgs = 1;
2216     dp.rgvarg = &var;
2217     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYPUT, &dp, NULL, &ei, NULL);
2218     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2219
2220     VariantInit(&var);
2221     memset(&dp, 0, sizeof(dp));
2222     memset(&ei, 0, sizeof(ei));
2223     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
2224     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2225     ok(V_VT(&var) == VT_I4, "V_VT(var)=%d\n", V_VT(&var));
2226     ok(V_I4(&var) == 300, "V_I4(&var) = %d\n", V_I4(&var));
2227
2228     V_VT(&var) = VT_BSTR;
2229     V_BSTR(&var) = NULL;
2230     dispex_propput(document, id, 0, &var, NULL);
2231
2232     VariantInit(&var);
2233     memset(&dp, 0, sizeof(dp));
2234     memset(&ei, 0, sizeof(ei));
2235     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
2236     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2237     ok(V_VT(&var) == VT_BSTR, "V_VT(var)=%d\n", V_VT(&var));
2238     ok(!V_BSTR(&var), "V_BSTR(&var) = %s\n", wine_dbgstr_w(V_BSTR(&var)));
2239
2240     unk = (void*)0xdeadbeef;
2241     hres = IDispatchEx_GetNameSpaceParent(window_dispex, &unk);
2242     ok(hres == S_OK, "GetNameSpaceParent failed: %08x\n", hres);
2243     ok(!unk, "unk=%p, expected NULL\n", unk);
2244
2245     id = 0;
2246     tmp = SysAllocString(funcW);
2247     hres = IDispatchEx_GetDispID(document, tmp, fdexNameCaseSensitive|fdexNameEnsure, &id);
2248     SysFreeString(tmp);
2249     ok(hres == S_OK, "GetDispID(func) failed: %08x\n", hres);
2250     ok(id, "id == 0\n");
2251
2252     dp.cArgs = 1;
2253     dp.rgvarg = &var;
2254     dp.cNamedArgs = 0;
2255     dp.rgdispidNamedArgs = NULL;
2256     V_VT(&var) = VT_DISPATCH;
2257     V_DISPATCH(&var) = (IDispatch*)&funcDisp;
2258     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYPUT, &dp, NULL, &ei, NULL);
2259     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2260
2261     VariantInit(&var);
2262     memset(&dp, 0, sizeof(dp));
2263     memset(&ei, 0, sizeof(ei));
2264     V_VT(&arg) = VT_BOOL;
2265     V_BOOL(&arg) = VARIANT_TRUE;
2266     dp.cArgs = 1;
2267     dp.rgvarg = &arg;
2268
2269     SET_EXPECT(funcDisp);
2270     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_FUNC, &dp, &var, &ei, NULL);
2271     CHECK_CALLED(funcDisp);
2272
2273     ok(hres == S_OK, "InvokeEx(INVOKE_FUNC) failed: %08x\n", hres);
2274     ok(V_VT(&var) == VT_I4, "V_VT(var)=%d\n", V_VT(&var));
2275     ok(V_I4(&var) == 100, "V_I4(&var) == NULL\n");
2276
2277     IDispatchEx_Release(document);
2278
2279     hres = IDispatchEx_QueryInterface(window_dispex, &IID_IHTMLWindow2, (void**)&window);
2280     ok(hres == S_OK, "Could not get IHTMLWindow2 iface: %08x\n", hres);
2281
2282     hres = IHTMLWindow2_get_navigator(window, &navigator);
2283     ok(hres == S_OK, "get_navigator failed: %08x\n", hres);
2284
2285     hres = IOmNavigator_QueryInterface(navigator, &IID_IDispatchEx, (void**)&dispex);
2286     IOmNavigator_Release(navigator);
2287     ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
2288
2289     test_func(dispex);
2290     test_nextdispid(dispex);
2291
2292     test_arg_conv(window);
2293     test_default_arg_conv(window);
2294     IHTMLWindow2_Release(window);
2295
2296     tmp = a2bstr("test");
2297     hres = IDispatchEx_DeleteMemberByName(dispex, tmp, fdexNameCaseSensitive);
2298     ok(hres == E_NOTIMPL, "DeleteMemberByName failed: %08x\n", hres);
2299
2300     IDispatchEx_Release(dispex);
2301
2302     script_disp = (IDispatch*)&scriptDisp;
2303
2304     SET_EXPECT(GetScriptDispatch);
2305     SET_EXPECT(script_testprop_d);
2306     tmp = a2bstr("testProp");
2307     hres = IDispatchEx_GetDispID(window_dispex, tmp, fdexNameCaseSensitive, &id);
2308     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
2309     ok(id != DISPID_SCRIPT_TESTPROP, "id == DISPID_SCRIPT_TESTPROP\n");
2310     CHECK_CALLED(GetScriptDispatch);
2311     CHECK_CALLED(script_testprop_d);
2312     SysFreeString(tmp);
2313
2314     tmp = a2bstr("testProp");
2315     hres = IDispatchEx_GetDispID(window_dispex, tmp, fdexNameCaseSensitive, &id);
2316     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
2317     ok(id != DISPID_SCRIPT_TESTPROP, "id == DISPID_SCRIPT_TESTPROP\n");
2318     SysFreeString(tmp);
2319
2320     SET_EXPECT(GetScriptDispatch);
2321     SET_EXPECT(script_testprop_i);
2322     memset(&ei, 0, sizeof(ei));
2323     memset(&dp, 0, sizeof(dp));
2324     hres = IDispatchEx_InvokeEx(window_dispex, id, 0, DISPATCH_PROPERTYGET, &dp, &var, &ei, NULL);
2325     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2326     ok(V_VT(&var) == VT_NULL, "V_VT(var) = %d\n", V_VT(&var));
2327     CHECK_CALLED(GetScriptDispatch);
2328     CHECK_CALLED(script_testprop_i);
2329
2330     SET_EXPECT(GetScriptDispatch);
2331     SET_EXPECT(script_testprop2_d);
2332     tmp = a2bstr("testProp2");
2333     hres = IDispatchEx_GetDispID(window_dispex, tmp, fdexNameCaseSensitive|fdexNameEnsure, &id);
2334     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
2335     ok(id != DISPID_SCRIPT_TESTPROP2, "id == DISPID_SCRIPT_TESTPROP2\n");
2336     CHECK_CALLED(GetScriptDispatch);
2337     CHECK_CALLED(script_testprop2_d);
2338     SysFreeString(tmp);
2339
2340     tmp = a2bstr("test");
2341     hres = IDispatchEx_DeleteMemberByName(window_dispex, tmp, fdexNameCaseSensitive);
2342     ok(hres == E_NOTIMPL, "DeleteMemberByName failed: %08x\n", hres);
2343
2344     test_global_id();
2345
2346     test_security();
2347     test_ui();
2348     test_sp();
2349 }
2350
2351 static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *iface,
2352         LPCOLESTR pstrCode, LPCOLESTR pstrItemName, IUnknown *punkContext,
2353         LPCOLESTR pstrDelimiter, CTXARG_T dwSourceContextCookie, ULONG ulStartingLine,
2354         DWORD dwFlags, VARIANT *pvarResult, EXCEPINFO *pexcepinfo)
2355 {
2356     ok(pvarResult != NULL, "pvarResult == NULL\n");
2357     ok(pexcepinfo != NULL, "pexcepinfo == NULL\n");
2358
2359     if(!strcmp_wa(pstrCode, "execScript call")) {
2360         CHECK_EXPECT(ParseScriptText_execScript);
2361         ok(!pstrItemName, "pstrItemName = %s\n", wine_dbgstr_w(pstrItemName));
2362         ok(!strcmp_wa(pstrDelimiter, "\""), "pstrDelimiter = %s\n", wine_dbgstr_w(pstrDelimiter));
2363         ok(dwFlags == SCRIPTTEXT_ISVISIBLE, "dwFlags = %x\n", dwFlags);
2364
2365         V_VT(pvarResult) = VT_I4;
2366         V_I4(pvarResult) = 10;
2367         return S_OK;
2368     }else if(!strcmp_wa(pstrCode, "simple script")) {
2369         CHECK_EXPECT(ParseScriptText_script);
2370         ok(!strcmp_wa(pstrItemName, "window"), "pstrItemName = %s\n", wine_dbgstr_w(pstrItemName));
2371         ok(!strcmp_wa(pstrDelimiter, "</SCRIPT>"), "pstrDelimiter = %s\n", wine_dbgstr_w(pstrDelimiter));
2372         ok(dwFlags == (SCRIPTTEXT_ISVISIBLE|SCRIPTTEXT_HOSTMANAGESSOURCE), "dwFlags = %x\n", dwFlags);
2373
2374         test_script_run();
2375         return S_OK;
2376     }
2377
2378     ok(0, "unexpected script %s\n", wine_dbgstr_w(pstrCode));
2379     return E_FAIL;
2380 }
2381
2382 static const IActiveScriptParseVtbl ActiveScriptParseVtbl = {
2383     ActiveScriptParse_QueryInterface,
2384     ActiveScriptParse_AddRef,
2385     ActiveScriptParse_Release,
2386     ActiveScriptParse_InitNew,
2387     ActiveScriptParse_AddScriptlet,
2388     ActiveScriptParse_ParseScriptText
2389 };
2390
2391 static IActiveScriptParse ActiveScriptParse = { &ActiveScriptParseVtbl };
2392
2393 static HRESULT WINAPI ActiveScript_QueryInterface(IActiveScript *iface, REFIID riid, void **ppv)
2394 {
2395     *ppv = NULL;
2396
2397     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IActiveScript, riid)) {
2398         *ppv = iface;
2399         return S_OK;
2400     }
2401
2402     if(IsEqualGUID(&IID_IActiveScriptParse, riid)) {
2403         *ppv = &ActiveScriptParse;
2404         return S_OK;
2405     }
2406
2407     if(IsEqualGUID(&IID_IActiveScriptParseProcedure2, riid)) {
2408         *ppv = &ActiveScriptParseProcedure;
2409         return S_OK;
2410     }
2411
2412     if(IsEqualGUID(&IID_IActiveScriptProperty, riid)) {
2413         *ppv = &ActiveScriptProperty;
2414         return S_OK;
2415     }
2416
2417     if(IsEqualGUID(&IID_IObjectSafety, riid)) {
2418         *ppv = &ObjectSafety;
2419         return S_OK;
2420     }
2421
2422     if(IsEqualGUID(&IID_IActiveScriptDebug, riid))
2423         return E_NOINTERFACE;
2424
2425     trace("QI(%s)\n", debugstr_guid(riid));
2426     return E_NOINTERFACE;
2427 }
2428
2429 static ULONG WINAPI ActiveScript_AddRef(IActiveScript *iface)
2430 {
2431     return 2;
2432 }
2433
2434 static ULONG WINAPI ActiveScript_Release(IActiveScript *iface)
2435 {
2436     return 1;
2437 }
2438
2439 static HRESULT WINAPI ActiveScript_SetScriptSite(IActiveScript *iface, IActiveScriptSite *pass)
2440 {
2441     IActiveScriptSiteInterruptPoll *poll;
2442     IActiveScriptSiteDebug *debug;
2443     IServiceProvider *service;
2444     ICanHandleException *canexpection;
2445     LCID lcid;
2446     HRESULT hres;
2447
2448     CHECK_EXPECT(SetScriptSite);
2449
2450     ok(pass != NULL, "pass == NULL\n");
2451
2452     hres = IActiveScriptSite_QueryInterface(pass, &IID_IActiveScriptSiteInterruptPoll, (void**)&poll);
2453     ok(hres == S_OK, "Could not get IActiveScriptSiteInterruptPoll interface: %08x\n", hres);
2454     if(FAILED(hres))
2455         IActiveScriptSiteInterruptPoll_Release(poll);
2456
2457     hres = IActiveScriptSite_GetLCID(pass, &lcid);
2458     ok(hres == S_OK, "GetLCID failed: %08x\n", hres);
2459
2460     hres = IActiveScriptSite_OnStateChange(pass, (state = SCRIPTSTATE_INITIALIZED));
2461     ok(hres == S_OK, "OnStateChange failed: %08x\n", hres);
2462
2463     hres = IActiveScriptSite_QueryInterface(pass, &IID_IActiveScriptSiteDebug, (void**)&debug);
2464     ok(hres == S_OK, "Could not get IActiveScriptSiteDebug interface: %08x\n", hres);
2465     if(SUCCEEDED(hres))
2466         IActiveScriptSiteDebug_Release(debug);
2467
2468     hres = IActiveScriptSite_QueryInterface(pass, &IID_ICanHandleException, (void**)&canexpection);
2469     ok(hres == E_NOINTERFACE, "Could not get IID_ICanHandleException interface: %08x\n", hres);
2470
2471     hres = IActiveScriptSite_QueryInterface(pass, &IID_IServiceProvider, (void**)&service);
2472     ok(hres == S_OK, "Could not get IServiceProvider interface: %08x\n", hres);
2473     if(SUCCEEDED(hres))
2474         IServiceProvider_Release(service);
2475
2476     site = pass;
2477     IActiveScriptSite_AddRef(site);
2478     return S_OK;
2479 }
2480
2481 static HRESULT WINAPI ActiveScript_GetScriptSite(IActiveScript *iface, REFIID riid,
2482                                             void **ppvObject)
2483 {
2484     ok(0, "unexpected call\n");
2485     return E_NOTIMPL;
2486 }
2487
2488 static HRESULT WINAPI ActiveScript_SetScriptState(IActiveScript *iface, SCRIPTSTATE ss)
2489 {
2490     HRESULT hres;
2491
2492     switch(ss) {
2493     case SCRIPTSTATE_STARTED:
2494         CHECK_EXPECT(SetScriptState_STARTED);
2495         break;
2496     case SCRIPTSTATE_CONNECTED:
2497         CHECK_EXPECT(SetScriptState_CONNECTED);
2498         break;
2499     case SCRIPTSTATE_DISCONNECTED:
2500         CHECK_EXPECT(SetScriptState_DISCONNECTED);
2501         break;
2502     default:
2503         ok(0, "unexpected state %d\n", ss);
2504         return E_NOTIMPL;
2505     }
2506
2507     hres = IActiveScriptSite_OnStateChange(site, (state = ss));
2508     ok(hres == S_OK, "OnStateChange failed: %08x\n", hres);
2509
2510     return S_OK;
2511 }
2512
2513 static HRESULT WINAPI ActiveScript_GetScriptState(IActiveScript *iface, SCRIPTSTATE *pssState)
2514 {
2515     CHECK_EXPECT(GetScriptState);
2516
2517     *pssState = state;
2518     return S_OK;
2519 }
2520
2521 static HRESULT WINAPI ActiveScript_Close(IActiveScript *iface)
2522 {
2523     CHECK_EXPECT(Close);
2524     return E_NOTIMPL;
2525 }
2526
2527 static HRESULT WINAPI ActiveScript_AddNamedItem(IActiveScript *iface,
2528         LPCOLESTR pstrName, DWORD dwFlags)
2529 {
2530     IDispatch *disp;
2531     IUnknown *unk = NULL, *unk2;
2532     HRESULT hres;
2533
2534     static const WCHAR windowW[] = {'w','i','n','d','o','w',0};
2535
2536     static const IID unknown_iid = {0x719C3050,0xF9D3,0x11CF,{0xA4,0x93,0x00,0x40,0x05,0x23,0xA8,0xA0}};
2537
2538     CHECK_EXPECT(AddNamedItem);
2539
2540     ok(!lstrcmpW(pstrName, windowW), "pstrName=%s\n", wine_dbgstr_w(pstrName));
2541     ok(dwFlags == (SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS), "dwFlags=%x\n", dwFlags);
2542
2543     hres = IActiveScriptSite_GetItemInfo(site, windowW, SCRIPTINFO_IUNKNOWN, &unk, NULL);
2544     ok(hres == S_OK, "GetItemInfo failed: %08x\n", hres);
2545     ok(unk != NULL, "unk == NULL\n");
2546
2547     hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
2548     ok(hres == S_OK, "Could not get IDispatch interface: %08x\n", hres);
2549     if(SUCCEEDED(hres))
2550         IDispatch_Release(disp);
2551
2552     hres = IUnknown_QueryInterface(unk, &unknown_iid, (void**)&unk2);
2553     ok(hres == E_NOINTERFACE, "Got ?? interface: %p\n", unk2);
2554     if(SUCCEEDED(hres))
2555         IUnknown_Release(unk2);
2556
2557     hres = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&window_dispex);
2558     ok(hres == S_OK, "Could not get IDispatchEx interface: %08x\n", hres);
2559
2560     IUnknown_Release(unk);
2561     return S_OK;
2562 }
2563
2564 static HRESULT WINAPI ActiveScript_AddTypeLib(IActiveScript *iface, REFGUID rguidTypeLib,
2565                                          DWORD dwMajor, DWORD dwMinor, DWORD dwFlags)
2566 {
2567     ok(0, "unexpected call\n");
2568     return E_NOTIMPL;
2569 }
2570
2571 static HRESULT WINAPI ActiveScript_GetScriptDispatch(IActiveScript *iface, LPCOLESTR pstrItemName,
2572                                                 IDispatch **ppdisp)
2573 {
2574     CHECK_EXPECT(GetScriptDispatch);
2575
2576     ok(!strcmp_wa(pstrItemName, "window"), "pstrItemName = %s\n", wine_dbgstr_w(pstrItemName));
2577
2578     if(!script_disp)
2579         return E_NOTIMPL;
2580
2581     *ppdisp = script_disp;
2582     return S_OK;
2583 }
2584
2585 static HRESULT WINAPI ActiveScript_GetCurrentScriptThreadID(IActiveScript *iface,
2586                                                        SCRIPTTHREADID *pstridThread)
2587 {
2588     ok(0, "unexpected call\n");
2589     return E_NOTIMPL;
2590 }
2591
2592 static HRESULT WINAPI ActiveScript_GetScriptThreadID(IActiveScript *iface,
2593                                                 DWORD dwWin32ThreadId, SCRIPTTHREADID *pstidThread)
2594 {
2595     ok(0, "unexpected call\n");
2596     return E_NOTIMPL;
2597 }
2598
2599 static HRESULT WINAPI ActiveScript_GetScriptThreadState(IActiveScript *iface,
2600         SCRIPTTHREADID stidThread, SCRIPTTHREADSTATE *pstsState)
2601 {
2602     ok(0, "unexpected call\n");
2603     return E_NOTIMPL;
2604 }
2605
2606 static HRESULT WINAPI ActiveScript_InterruptScriptThread(IActiveScript *iface,
2607         SCRIPTTHREADID stidThread, const EXCEPINFO *pexcepinfo, DWORD dwFlags)
2608 {
2609     ok(0, "unexpected call\n");
2610     return E_NOTIMPL;
2611 }
2612
2613 static HRESULT WINAPI ActiveScript_Clone(IActiveScript *iface, IActiveScript **ppscript)
2614 {
2615     ok(0, "unexpected call\n");
2616     return E_NOTIMPL;
2617 }
2618
2619 static const IActiveScriptVtbl ActiveScriptVtbl = {
2620     ActiveScript_QueryInterface,
2621     ActiveScript_AddRef,
2622     ActiveScript_Release,
2623     ActiveScript_SetScriptSite,
2624     ActiveScript_GetScriptSite,
2625     ActiveScript_SetScriptState,
2626     ActiveScript_GetScriptState,
2627     ActiveScript_Close,
2628     ActiveScript_AddNamedItem,
2629     ActiveScript_AddTypeLib,
2630     ActiveScript_GetScriptDispatch,
2631     ActiveScript_GetCurrentScriptThreadID,
2632     ActiveScript_GetScriptThreadID,
2633     ActiveScript_GetScriptThreadState,
2634     ActiveScript_InterruptScriptThread,
2635     ActiveScript_Clone
2636 };
2637
2638 static IActiveScript ActiveScript = { &ActiveScriptVtbl };
2639
2640 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
2641 {
2642     *ppv = NULL;
2643
2644     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) {
2645         *ppv = iface;
2646         return S_OK;
2647     }
2648
2649     if(IsEqualGUID(&IID_IMarshal, riid))
2650         return E_NOINTERFACE;
2651     if(IsEqualGUID(&CLSID_IdentityUnmarshal, riid))
2652         return E_NOINTERFACE;
2653
2654     ok(0, "unexpected riid %s\n", debugstr_guid(riid));
2655     return E_NOTIMPL;
2656 }
2657
2658 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
2659 {
2660     return 2;
2661 }
2662
2663 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
2664 {
2665     return 1;
2666 }
2667
2668 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
2669 {
2670     CHECK_EXPECT(CreateInstance);
2671
2672     ok(!outer, "outer = %p\n", outer);
2673     ok(IsEqualGUID(&IID_IActiveScript, riid), "unexpected riid %s\n", debugstr_guid(riid));
2674     *ppv = &ActiveScript;
2675     return S_OK;
2676 }
2677
2678 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
2679 {
2680     ok(0, "unexpected call\n");
2681     return S_OK;
2682 }
2683
2684 static const IClassFactoryVtbl ClassFactoryVtbl = {
2685     ClassFactory_QueryInterface,
2686     ClassFactory_AddRef,
2687     ClassFactory_Release,
2688     ClassFactory_CreateInstance,
2689     ClassFactory_LockServer
2690 };
2691
2692 static IClassFactory script_cf = { &ClassFactoryVtbl };
2693
2694 static const char simple_script_str[] =
2695     "<html><head></head><body>"
2696     "<div id=\"divid\"></div>"
2697     "<script language=\"TestScript\">simple script</script>"
2698     "</body></html>";
2699
2700 static void test_exec_script(IHTMLDocument2 *doc, const char *codea, const char *langa)
2701 {
2702     IHTMLWindow2 *window;
2703     BSTR code, lang;
2704     VARIANT v;
2705     HRESULT hres;
2706
2707     hres = IHTMLDocument2_get_parentWindow(doc, &window);
2708     ok(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
2709
2710     code = a2bstr(codea);
2711     lang = a2bstr(langa);
2712
2713     SET_EXPECT(ParseScriptText_execScript);
2714     hres = IHTMLWindow2_execScript(window, code, lang, &v);
2715     ok(hres == S_OK, "execScript failed: %08x\n", hres);
2716     ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
2717     ok(V_I4(&v) == 10, "V_I4(v) = %d\n", V_I4(&v));
2718     CHECK_CALLED(ParseScriptText_execScript);
2719     SysFreeString(lang);
2720
2721     lang = a2bstr("invalid");
2722     V_VT(&v) = 100;
2723     hres = IHTMLWindow2_execScript(window, code, lang, &v);
2724     ok(hres == CO_E_CLASSSTRING, "execScript failed: %08x, expected CO_E_CLASSSTRING\n", hres);
2725     ok(V_VT(&v) == 100, "V_VT(v) = %d\n", V_VT(&v));
2726     SysFreeString(lang);
2727     SysFreeString(code);
2728
2729     IHTMLWindow2_Release(window);
2730 }
2731
2732 static void test_simple_script(void)
2733 {
2734     IHTMLDocument2 *doc;
2735
2736     doc = create_document();
2737     if(!doc)
2738         return;
2739
2740     SET_EXPECT(CreateInstance);
2741     SET_EXPECT(GetInterfaceSafetyOptions);
2742     SET_EXPECT(SetInterfaceSafetyOptions);
2743     SET_EXPECT(SetProperty_INVOKEVERSIONING); /* IE8 */
2744     SET_EXPECT(SetProperty_HACK_TRIDENTEVENTSINK);
2745     SET_EXPECT(InitNew);
2746     SET_EXPECT(SetScriptSite);
2747     SET_EXPECT(GetScriptState);
2748     SET_EXPECT(SetScriptState_STARTED);
2749     SET_EXPECT(AddNamedItem);
2750     SET_EXPECT(SetProperty_ABBREVIATE_GLOBALNAME_RESOLUTION); /* IE8 */
2751     SET_EXPECT(ParseScriptText_script);
2752     SET_EXPECT(SetScriptState_CONNECTED);
2753
2754     load_doc(doc, simple_script_str);
2755
2756     CHECK_CALLED(CreateInstance);
2757     CHECK_CALLED(GetInterfaceSafetyOptions);
2758     CHECK_CALLED(SetInterfaceSafetyOptions);
2759     CHECK_CALLED_BROKEN(SetProperty_INVOKEVERSIONING); /* IE8 */
2760     CHECK_CALLED(SetProperty_HACK_TRIDENTEVENTSINK);
2761     CHECK_CALLED(InitNew);
2762     CHECK_CALLED(SetScriptSite);
2763     CHECK_CALLED(GetScriptState);
2764     CHECK_CALLED(SetScriptState_STARTED);
2765     CHECK_CALLED(AddNamedItem);
2766     CHECK_CALLED_BROKEN(SetProperty_ABBREVIATE_GLOBALNAME_RESOLUTION); /* IE8 */
2767     CHECK_CALLED(ParseScriptText_script);
2768     CHECK_CALLED(SetScriptState_CONNECTED);
2769
2770     test_exec_script(doc, "execScript call", "TestScript");
2771
2772     if(site)
2773         IActiveScriptSite_Release(site);
2774     if(window_dispex)
2775         IDispatchEx_Release(window_dispex);
2776
2777     SET_EXPECT(SetScriptState_DISCONNECTED);
2778     SET_EXPECT(Close);
2779
2780     IHTMLDocument2_Release(doc);
2781
2782     CHECK_CALLED(SetScriptState_DISCONNECTED);
2783     CHECK_CALLED(Close);
2784 }
2785
2786 static void run_js_script(const char *test_name)
2787 {
2788     WCHAR url[INTERNET_MAX_URL_LENGTH];
2789     char urlA[INTERNET_MAX_URL_LENGTH];
2790     IPersistMoniker *persist;
2791     IHTMLDocument2 *doc;
2792     IMoniker *mon;
2793     MSG msg;
2794     HRESULT hres;
2795
2796     static const char res[] = "res://";
2797
2798     trace("running %s...\n", test_name);
2799
2800     doc = create_document();
2801     if(!doc)
2802         return;
2803
2804     set_client_site(doc, TRUE);
2805     do_advise(doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
2806
2807     lstrcpyA(urlA, res);
2808     GetModuleFileNameA(NULL, urlA + lstrlenA(res), sizeof(urlA) - lstrlenA(res));
2809     lstrcatA(urlA, "/");
2810     lstrcatA(urlA, test_name);
2811     MultiByteToWideChar(CP_ACP, 0, urlA, -1, url, sizeof(url)/sizeof(WCHAR));
2812
2813     hres = CreateURLMoniker(NULL, url, &mon);
2814     ok(hres == S_OK, "CreateURLMoniker failed: %08x\n", hres);
2815
2816     hres = IHTMLDocument2_QueryInterface(doc, &IID_IPersistMoniker, (void**)&persist);
2817     ok(hres == S_OK, "Could not get IPersistMoniker iface: %08x\n", hres);
2818
2819     hres = IPersistMoniker_Load(persist, FALSE, mon, NULL, 0);
2820     ok(hres == S_OK, "Load failed: %08x\n", hres);
2821
2822     IMoniker_Release(mon);
2823     IPersistMoniker_Release(persist);
2824
2825     SET_EXPECT(external_success);
2826
2827     while(!called_external_success && GetMessage(&msg, NULL, 0, 0)) {
2828         TranslateMessage(&msg);
2829         DispatchMessage(&msg);
2830     }
2831
2832     CHECK_CALLED(external_success);
2833
2834     set_client_site(doc, FALSE);
2835     IHTMLDocument2_Release(doc);
2836 }
2837
2838 static void run_js_tests(void)
2839 {
2840     run_js_script("jstest.html");
2841     run_js_script("exectest.html");
2842     run_js_script("vbtest.html");
2843     run_js_script("events.html");
2844 }
2845
2846 static BOOL init_registry(BOOL init)
2847 {
2848     return init_key("TestScript\\CLSID", TESTSCRIPT_CLSID, init)
2849         && init_key("CLSID\\"TESTSCRIPT_CLSID"\\Implemented Categories\\{F0B7A1A1-9847-11CF-8F20-00805F2CD064}",
2850                     NULL, init)
2851         && init_key("CLSID\\"TESTSCRIPT_CLSID"\\Implemented Categories\\{F0B7A1A2-9847-11CF-8F20-00805F2CD064}",
2852                     NULL, init);
2853 }
2854
2855 static BOOL register_script_engine(void)
2856 {
2857     DWORD regid;
2858     HRESULT hres;
2859
2860     if(!init_registry(TRUE)) {
2861         init_registry(FALSE);
2862         return FALSE;
2863     }
2864
2865     hres = CoRegisterClassObject(&CLSID_TestScript, (IUnknown *)&script_cf,
2866                                  CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &regid);
2867     ok(hres == S_OK, "Could not register script engine: %08x\n", hres);
2868
2869     return TRUE;
2870 }
2871
2872 static LRESULT WINAPI wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
2873 {
2874     return DefWindowProc(hwnd, msg, wParam, lParam);
2875 }
2876
2877 static HWND create_container_window(void)
2878 {
2879     static const CHAR szHTMLDocumentTest[] = "HTMLDocumentTest";
2880     static WNDCLASSEXA wndclass = {
2881         sizeof(WNDCLASSEXA),
2882         0,
2883         wnd_proc,
2884         0, 0, NULL, NULL, NULL, NULL, NULL,
2885         szHTMLDocumentTest,
2886         NULL
2887     };
2888
2889     RegisterClassExA(&wndclass);
2890     return CreateWindowA(szHTMLDocumentTest, szHTMLDocumentTest,
2891             WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
2892             300, 300, NULL, NULL, NULL, NULL);
2893 }
2894
2895 START_TEST(script)
2896 {
2897     CoInitialize(NULL);
2898     container_hwnd = create_container_window();
2899
2900     if(winetest_interactive || ! is_ie_hardened()) {
2901         if(register_script_engine()) {
2902             test_simple_script();
2903             init_registry(FALSE);
2904         }else {
2905             skip("Could not register TestScript engine\n");
2906         }
2907         run_js_tests();
2908     }else {
2909         skip("IE running in Enhanced Security Configuration\n");
2910     }
2911
2912     DestroyWindow(container_hwnd);
2913     CoUninitialize();
2914 }