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