rsaenh: Fix padding bytes check for 0-byte payload.
[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 "dispex.h"
30 #include "mshtml.h"
31 #include "initguid.h"
32 #include "activscp.h"
33 #include "activdbg.h"
34 #include "objsafe.h"
35 #include "mshtmdid.h"
36 #include "mshtml_test.h"
37
38 DEFINE_GUID(CLSID_IdentityUnmarshal,0x0000001b,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
39
40 /* Defined as extern in urlmon.idl, but not exported by uuid.lib */
41 const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY =
42     {0x10200490,0xfa38,0x11d0,{0xac,0x0e,0x00,0xa0,0xc9,0xf,0xff,0xc0}};
43
44 #ifdef _WIN64
45
46 #define CTXARG_T DWORDLONG
47 #define IActiveScriptParseVtbl IActiveScriptParse64Vtbl
48 #define IActiveScriptParseProcedure2Vtbl IActiveScriptParseProcedure2_64Vtbl
49
50 #else
51
52 #define CTXARG_T DWORD
53 #define IActiveScriptParseVtbl IActiveScriptParse32Vtbl
54 #define IActiveScriptParseProcedure2Vtbl IActiveScriptParseProcedure2_32Vtbl
55
56 #endif
57
58 #define DEFINE_EXPECT(func) \
59     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
60
61 #define SET_EXPECT(func) \
62     do { called_ ## func = FALSE; expect_ ## func = TRUE; } while(0)
63
64 #define CHECK_EXPECT2(func) \
65     do { \
66         ok(expect_ ##func, "unexpected call " #func "\n"); \
67         called_ ## func = TRUE; \
68     }while(0)
69
70 #define CHECK_EXPECT(func) \
71     do { \
72         CHECK_EXPECT2(func); \
73         expect_ ## func = FALSE; \
74     }while(0)
75
76 #define CHECK_CALLED(func) \
77     do { \
78         ok(called_ ## func, "expected " #func "\n"); \
79         expect_ ## func = called_ ## func = FALSE; \
80     }while(0)
81
82 #define CHECK_CALLED_BROKEN(func) \
83     do { \
84         ok(called_ ## func || broken(!called_ ## func), "expected " #func "\n"); \
85         expect_ ## func = called_ ## func = FALSE; \
86     }while(0)
87
88 #define CHECK_NOT_CALLED(func) \
89     do { \
90         ok(!called_ ## func, "unexpected " #func "\n"); \
91         expect_ ## func = called_ ## func = FALSE; \
92     }while(0)
93
94 #define CLEAR_CALLED(func) \
95     expect_ ## func = called_ ## func = FALSE
96
97
98 DEFINE_EXPECT(CreateInstance);
99 DEFINE_EXPECT(GetInterfaceSafetyOptions);
100 DEFINE_EXPECT(SetInterfaceSafetyOptions);
101 DEFINE_EXPECT(InitNew);
102 DEFINE_EXPECT(Close);
103 DEFINE_EXPECT(SetProperty_HACK_TRIDENTEVENTSINK);
104 DEFINE_EXPECT(SetProperty_INVOKEVERSIONING);
105 DEFINE_EXPECT(SetProperty_ABBREVIATE_GLOBALNAME_RESOLUTION);
106 DEFINE_EXPECT(SetScriptSite);
107 DEFINE_EXPECT(GetScriptState);
108 DEFINE_EXPECT(SetScriptState_STARTED);
109 DEFINE_EXPECT(SetScriptState_CONNECTED);
110 DEFINE_EXPECT(SetScriptState_DISCONNECTED);
111 DEFINE_EXPECT(AddNamedItem);
112 DEFINE_EXPECT(ParseScriptText);
113 DEFINE_EXPECT(GetScriptDispatch);
114 DEFINE_EXPECT(funcDisp);
115 DEFINE_EXPECT(script_divid_d);
116 DEFINE_EXPECT(script_testprop_d);
117 DEFINE_EXPECT(script_testprop_i);
118 DEFINE_EXPECT(AXQueryInterface_IActiveScript);
119 DEFINE_EXPECT(AXQueryInterface_IObjectSafety);
120 DEFINE_EXPECT(AXGetInterfaceSafetyOptions);
121 DEFINE_EXPECT(AXSetInterfaceSafetyOptions);
122
123 #define TESTSCRIPT_CLSID "{178fc163-f585-4e24-9c13-4bb7faf80746}"
124 #define TESTACTIVEX_CLSID "{178fc163-f585-4e24-9c13-4bb7faf80646}"
125
126 #define DISPID_SCRIPT_TESTPROP   0x100000
127
128 static const GUID CLSID_TestScript =
129     {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x07,0x46}};
130 static const GUID CLSID_TestActiveX =
131     {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x06,0x46}};
132
133 static IHTMLDocument2 *notif_doc;
134 static IDispatchEx *window_dispex;
135 static BOOL doc_complete;
136 static IDispatch *script_disp;
137 static BOOL ax_objsafe;
138
139 static const char *debugstr_guid(REFIID riid)
140 {
141     static char buf[50];
142
143     sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
144             riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
145             riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
146             riid->Data4[5], riid->Data4[6], riid->Data4[7]);
147
148     return buf;
149 }
150
151 static int strcmp_wa(LPCWSTR strw, const char *stra)
152 {
153     CHAR buf[512];
154     WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL);
155     return lstrcmpA(stra, buf);
156 }
157
158 static BSTR a2bstr(const char *str)
159 {
160     BSTR ret;
161     int len;
162
163     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
164     ret = SysAllocStringLen(NULL, len);
165     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
166
167     return ret;
168 }
169
170 static BOOL init_key(const char *key_name, const char *def_value, BOOL init)
171 {
172     HKEY hkey;
173     DWORD res;
174
175     if(!init) {
176         RegDeleteKey(HKEY_CLASSES_ROOT, key_name);
177         return TRUE;
178     }
179
180     res = RegCreateKeyA(HKEY_CLASSES_ROOT, key_name, &hkey);
181     if(res != ERROR_SUCCESS)
182         return FALSE;
183
184     if(def_value)
185         res = RegSetValueA(hkey, NULL, REG_SZ, def_value, strlen(def_value));
186
187     RegCloseKey(hkey);
188
189     return res == ERROR_SUCCESS;
190 }
191
192 static HRESULT WINAPI PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface,
193         REFIID riid, void**ppv)
194 {
195     if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) {
196         *ppv = iface;
197         return S_OK;
198     }
199
200     return E_NOINTERFACE;
201 }
202
203 static ULONG WINAPI PropertyNotifySink_AddRef(IPropertyNotifySink *iface)
204 {
205     return 2;
206 }
207
208 static ULONG WINAPI PropertyNotifySink_Release(IPropertyNotifySink *iface)
209 {
210     return 1;
211 }
212
213 static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID)
214 {
215     if(dispID == DISPID_READYSTATE){
216         BSTR state;
217         HRESULT hres;
218
219         static const WCHAR completeW[] = {'c','o','m','p','l','e','t','e',0};
220
221         hres = IHTMLDocument2_get_readyState(notif_doc, &state);
222         ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
223
224         if(!lstrcmpW(state, completeW))
225             doc_complete = TRUE;
226
227         SysFreeString(state);
228     }
229
230     return S_OK;
231 }
232
233 static HRESULT WINAPI PropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID)
234 {
235     ok(0, "unexpected call\n");
236     return E_NOTIMPL;
237 }
238
239 static IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = {
240     PropertyNotifySink_QueryInterface,
241     PropertyNotifySink_AddRef,
242     PropertyNotifySink_Release,
243     PropertyNotifySink_OnChanged,
244     PropertyNotifySink_OnRequestEdit
245 };
246
247 static IPropertyNotifySink PropertyNotifySink = { &PropertyNotifySinkVtbl };
248
249 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
250 {
251     *ppv = NULL;
252
253     if(IsEqualGUID(riid, &IID_IUnknown)
254        || IsEqualGUID(riid, &IID_IDispatch)
255        || IsEqualGUID(riid, &IID_IDispatchEx))
256         *ppv = iface;
257     else
258         return E_NOINTERFACE;
259
260     return S_OK;
261 }
262
263 static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
264 {
265     return 2;
266 }
267
268 static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
269 {
270     return 1;
271 }
272
273 static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
274 {
275     ok(0, "unexpected call\n");
276     return E_NOTIMPL;
277 }
278
279 static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
280                                               LCID lcid, ITypeInfo **ppTInfo)
281 {
282     ok(0, "unexpected call\n");
283     return E_NOTIMPL;
284 }
285
286 static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
287                                                 LPOLESTR *rgszNames, UINT cNames,
288                                                 LCID lcid, DISPID *rgDispId)
289 {
290     ok(0, "unexpected call\n");
291     return E_NOTIMPL;
292 }
293
294 static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
295                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
296                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
297 {
298     ok(0, "unexpected call\n");
299     return E_NOTIMPL;
300 }
301
302 static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
303 {
304     ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
305     return E_NOTIMPL;
306 }
307
308 static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
309 {
310     ok(0, "unexpected call\n");
311     return E_NOTIMPL;
312 }
313
314 static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
315 {
316     ok(0, "unexpected call\n");
317     return E_NOTIMPL;
318 }
319
320 static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
321 {
322     ok(0, "unexpected call\n");
323     return E_NOTIMPL;
324 }
325
326 static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
327 {
328     ok(0, "unexpected call\n");
329     return E_NOTIMPL;
330 }
331
332 static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
333 {
334     ok(0, "unexpected call\n");
335     return E_NOTIMPL;
336 }
337
338 static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
339 {
340     ok(0, "unexpected call\n");
341     return E_NOTIMPL;
342 }
343
344 static HRESULT WINAPI funcDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
345         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
346 {
347     CHECK_EXPECT(funcDisp);
348
349     ok(id == DISPID_VALUE, "id = %d\n", id);
350     ok(lcid == 0, "lcid = %x\n", lcid);
351     ok(wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags);
352     ok(pdp != NULL, "pdp == NULL\n");
353     ok(pdp->cArgs == 2, "pdp->cArgs = %d\n", pdp->cArgs);
354     ok(pdp->cNamedArgs == 1, "pdp->cNamedArgs = %d\n", pdp->cNamedArgs);
355     ok(pdp->rgdispidNamedArgs[0] == DISPID_THIS, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
356     ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(rgvarg) = %d\n", V_VT(pdp->rgvarg));
357     ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(rgvarg[1]) = %d\n", V_VT(pdp->rgvarg));
358     ok(V_BOOL(pdp->rgvarg+1) == VARIANT_TRUE, "V_BOOL(rgvarg[1]) = %x\n", V_BOOL(pdp->rgvarg));
359     ok(pvarRes != NULL, "pvarRes == NULL\n");
360     ok(pei != NULL, "pei == NULL\n");
361     ok(!pspCaller, "pspCaller != NULL\n");
362
363     V_VT(pvarRes) = VT_I4;
364     V_I4(pvarRes) = 100;
365     return S_OK;
366 }
367
368 static IDispatchExVtbl testObjVtbl = {
369     DispatchEx_QueryInterface,
370     DispatchEx_AddRef,
371     DispatchEx_Release,
372     DispatchEx_GetTypeInfoCount,
373     DispatchEx_GetTypeInfo,
374     DispatchEx_GetIDsOfNames,
375     DispatchEx_Invoke,
376     DispatchEx_GetDispID,
377     funcDisp_InvokeEx,
378     DispatchEx_DeleteMemberByName,
379     DispatchEx_DeleteMemberByDispID,
380     DispatchEx_GetMemberProperties,
381     DispatchEx_GetMemberName,
382     DispatchEx_GetNextDispID,
383     DispatchEx_GetNameSpaceParent
384 };
385
386 static IDispatchEx funcDisp = { &testObjVtbl };
387
388 static HRESULT WINAPI scriptDisp_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
389 {
390     if(!strcmp_wa(bstrName, "testProp")) {
391         CHECK_EXPECT(script_testprop_d);
392         ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
393         *pid = DISPID_SCRIPT_TESTPROP;
394         return S_OK;
395     }
396
397     if(!strcmp_wa(bstrName, "divid")) {
398         CHECK_EXPECT(script_divid_d);
399         ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
400         return E_FAIL;
401     }
402
403     ok(0, "unexpected call\n");
404     return E_NOTIMPL;
405 }
406
407 static HRESULT WINAPI scriptDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
408         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
409 {
410     switch(id) {
411     case DISPID_SCRIPT_TESTPROP:
412         CHECK_EXPECT(script_testprop_i);
413
414         ok(lcid == 0, "lcid = %x\n", lcid);
415         ok(wFlags == DISPATCH_PROPERTYGET, "wFlags = %x\n", wFlags);
416         ok(pdp != NULL, "pdp == NULL\n");
417         ok(pdp->cArgs == 0, "pdp->cArgs = %d\n", pdp->cArgs);
418         ok(pdp->cNamedArgs == 0, "pdp->cNamedArgs = %d\n", pdp->cNamedArgs);
419         ok(!pdp->rgdispidNamedArgs, "pdp->rgdispidNamedArgs != NULL\n");
420         ok(!pdp->rgvarg, "rgvarg != NULL\n");
421         ok(pvarRes != NULL, "pvarRes == NULL\n");
422         ok(pei != NULL, "pei == NULL\n");
423         ok(!pspCaller, "pspCaller != NULL\n");
424
425         V_VT(pvarRes) = VT_NULL;
426         break;
427     default:
428         ok(0, "unexpected call\n");
429         return E_NOTIMPL;
430     }
431
432     return S_OK;
433 }
434
435 static IDispatchExVtbl scriptDispVtbl = {
436     DispatchEx_QueryInterface,
437     DispatchEx_AddRef,
438     DispatchEx_Release,
439     DispatchEx_GetTypeInfoCount,
440     DispatchEx_GetTypeInfo,
441     DispatchEx_GetIDsOfNames,
442     DispatchEx_Invoke,
443     scriptDisp_GetDispID,
444     scriptDisp_InvokeEx,
445     DispatchEx_DeleteMemberByName,
446     DispatchEx_DeleteMemberByDispID,
447     DispatchEx_GetMemberProperties,
448     DispatchEx_GetMemberName,
449     DispatchEx_GetNextDispID,
450     DispatchEx_GetNameSpaceParent
451 };
452
453 static IDispatchEx scriptDisp = { &scriptDispVtbl };
454
455 static IHTMLDocument2 *create_document(void)
456 {
457     IHTMLDocument2 *doc;
458     HRESULT hres;
459
460     hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
461             &IID_IHTMLDocument2, (void**)&doc);
462     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
463
464     return doc;
465 }
466
467 static IHTMLDocument2 *create_doc_with_string(const char *str)
468 {
469     IPersistStreamInit *init;
470     IStream *stream;
471     IHTMLDocument2 *doc;
472     HGLOBAL mem;
473     SIZE_T len;
474
475     notif_doc = doc = create_document();
476     if(!doc)
477         return NULL;
478
479     doc_complete = FALSE;
480     len = strlen(str);
481     mem = GlobalAlloc(0, len);
482     memcpy(mem, str, len);
483     CreateStreamOnHGlobal(mem, TRUE, &stream);
484
485     IHTMLDocument2_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&init);
486
487     IPersistStreamInit_Load(init, stream);
488     IPersistStreamInit_Release(init);
489     IStream_Release(stream);
490
491     return doc;
492 }
493
494 static void do_advise(IUnknown *unk, REFIID riid, IUnknown *unk_advise)
495 {
496     IConnectionPointContainer *container;
497     IConnectionPoint *cp;
498     DWORD cookie;
499     HRESULT hres;
500
501     hres = IUnknown_QueryInterface(unk, &IID_IConnectionPointContainer, (void**)&container);
502     ok(hres == S_OK, "QueryInterface(IID_IConnectionPointContainer) failed: %08x\n", hres);
503
504     hres = IConnectionPointContainer_FindConnectionPoint(container, riid, &cp);
505     IConnectionPointContainer_Release(container);
506     ok(hres == S_OK, "FindConnectionPoint failed: %08x\n", hres);
507
508     hres = IConnectionPoint_Advise(cp, unk_advise, &cookie);
509     IConnectionPoint_Release(cp);
510     ok(hres == S_OK, "Advise failed: %08x\n", hres);
511 }
512
513 typedef void (*domtest_t)(IHTMLDocument2*);
514
515 static IHTMLDocument2 *create_and_load_doc(const char *str)
516 {
517     IHTMLDocument2 *doc;
518     IHTMLElement *body = NULL;
519     MSG msg;
520     HRESULT hres;
521     static const WCHAR ucPtr[] = {'b','a','c','k','g','r','o','u','n','d',0};
522     DISPID dispID = -1;
523     OLECHAR *name;
524
525
526     doc = create_doc_with_string(str);
527     do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
528
529     while(!doc_complete && GetMessage(&msg, NULL, 0, 0)) {
530         TranslateMessage(&msg);
531         DispatchMessage(&msg);
532     }
533
534     hres = IHTMLDocument2_get_body(doc, &body);
535     ok(hres == S_OK, "get_body failed: %08x\n", hres);
536
537     /* Check we can query for function on the IHTMLElementBody interface */
538     name = (WCHAR*)ucPtr;
539     hres = IHTMLElement_GetIDsOfNames(body, &IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &dispID);
540     ok(hres == S_OK, "GetIDsOfNames(background) failed %08x\n", hres);
541     ok(dispID == DISPID_IHTMLBODYELEMENT_BACKGROUND, "Incorrect dispID got (%d)\n", dispID);
542
543     IHTMLElement_Release(body);
544     return doc;
545 }
546
547 static IActiveScriptSite *site;
548 static SCRIPTSTATE state;
549
550 static HRESULT WINAPI ObjectSafety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
551 {
552     *ppv = NULL;
553     ok(0, "unexpected call %s\n", debugstr_guid(riid));
554     return E_NOINTERFACE;
555 }
556
557 static ULONG WINAPI ObjectSafety_AddRef(IObjectSafety *iface)
558 {
559     return 2;
560 }
561
562 static ULONG WINAPI ObjectSafety_Release(IObjectSafety *iface)
563 {
564     return 1;
565 }
566
567 static HRESULT WINAPI ObjectSafety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
568         DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
569 {
570     CHECK_EXPECT(GetInterfaceSafetyOptions);
571
572     ok(IsEqualGUID(&IID_IActiveScriptParse, riid), "unexpected riid %s\n", debugstr_guid(riid));
573     ok(pdwSupportedOptions != NULL, "pdwSupportedOptions == NULL\n");
574     ok(pdwEnabledOptions != NULL, "pdwEnabledOptions == NULL\n");
575
576     *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER;
577     *pdwEnabledOptions = INTERFACE_USES_DISPEX;
578
579     return S_OK;
580 }
581
582 static HRESULT WINAPI ObjectSafety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
583         DWORD dwOptionSetMask, DWORD dwEnabledOptions)
584 {
585     CHECK_EXPECT(SetInterfaceSafetyOptions);
586
587     ok(IsEqualGUID(&IID_IActiveScriptParse, riid), "unexpected riid %s\n", debugstr_guid(riid));
588
589     ok(dwOptionSetMask == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
590        "dwOptionSetMask=%x\n", dwOptionSetMask);
591     ok(dwEnabledOptions == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
592        "dwEnabledOptions=%x\n", dwOptionSetMask);
593
594     return S_OK;
595 }
596
597 static const IObjectSafetyVtbl ObjectSafetyVtbl = {
598     ObjectSafety_QueryInterface,
599     ObjectSafety_AddRef,
600     ObjectSafety_Release,
601     ObjectSafety_GetInterfaceSafetyOptions,
602     ObjectSafety_SetInterfaceSafetyOptions
603 };
604
605 static IObjectSafety ObjectSafety = { &ObjectSafetyVtbl };
606
607 static HRESULT WINAPI AXObjectSafety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
608 {
609     *ppv = NULL;
610
611     if(IsEqualGUID(&IID_IActiveScript, riid)) {
612         CHECK_EXPECT(AXQueryInterface_IActiveScript);
613         return E_NOINTERFACE;
614     }
615
616     if(IsEqualGUID(&IID_IObjectSafety, riid)) {
617         CHECK_EXPECT(AXQueryInterface_IObjectSafety);
618         if(!ax_objsafe)
619             return E_NOINTERFACE;
620         *ppv = iface;
621         return S_OK;
622     }
623
624     ok(0, "unexpected call %s\n", debugstr_guid(riid));
625     return E_NOINTERFACE;
626 }
627
628 static HRESULT WINAPI AXObjectSafety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
629         DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
630 {
631     CHECK_EXPECT(AXGetInterfaceSafetyOptions);
632
633     ok(IsEqualGUID(&IID_IDispatchEx, riid), "unexpected riid %s\n", debugstr_guid(riid));
634     ok(pdwSupportedOptions != NULL, "pdwSupportedOptions == NULL\n");
635     ok(pdwEnabledOptions != NULL, "pdwEnabledOptions == NULL\n");
636
637     *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER;
638     *pdwEnabledOptions = INTERFACE_USES_DISPEX;
639
640     return S_OK;
641 }
642
643 static HRESULT WINAPI AXObjectSafety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
644         DWORD dwOptionSetMask, DWORD dwEnabledOptions)
645 {
646     CHECK_EXPECT(AXSetInterfaceSafetyOptions);
647
648     ok(IsEqualGUID(&IID_IDispatchEx, riid), "unexpected riid %s\n", debugstr_guid(riid));
649
650     ok(dwOptionSetMask == (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACE_USES_SECURITY_MANAGER),
651        "dwOptionSetMask=%x\n", dwOptionSetMask);
652     ok(dwEnabledOptions == (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACE_USES_SECURITY_MANAGER),
653        "dwEnabledOptions=%x\n", dwOptionSetMask);
654
655     return S_OK;
656 }
657
658 static const IObjectSafetyVtbl AXObjectSafetyVtbl = {
659     AXObjectSafety_QueryInterface,
660     ObjectSafety_AddRef,
661     ObjectSafety_Release,
662     AXObjectSafety_GetInterfaceSafetyOptions,
663     AXObjectSafety_SetInterfaceSafetyOptions
664 };
665
666 static IObjectSafety AXObjectSafety = { &AXObjectSafetyVtbl };
667
668 static BOOL set_safe_reg(BOOL init)
669 {
670     return init_key("CLSID\\"TESTACTIVEX_CLSID"\\Implemented Categories\\{7dd95801-9882-11cf-9fa9-00aa006c42c4}",
671                     NULL, init);
672 }
673
674 static void test_security(void)
675 {
676     IInternetHostSecurityManager *sec_mgr;
677     IServiceProvider *sp;
678     DWORD policy, policy_size;
679     struct CONFIRMSAFETY cs;
680     BYTE *ppolicy;
681     HRESULT hres;
682
683     hres = IActiveScriptSite_QueryInterface(site, &IID_IServiceProvider, (void**)&sp);
684     ok(hres == S_OK, "Could not get IServiceProvider iface: %08x\n", hres);
685
686     hres = IServiceProvider_QueryService(sp, &SID_SInternetHostSecurityManager,
687             &IID_IInternetHostSecurityManager, (void**)&sec_mgr);
688     IServiceProvider_Release(sp);
689     ok(hres == S_OK, "QueryService failed: %08x\n", hres);
690
691     hres = IInternetHostSecurityManager_ProcessUrlAction(sec_mgr, URLACTION_ACTIVEX_RUN, (BYTE*)&policy, sizeof(policy),
692                                                          (BYTE*)&CLSID_TestActiveX, sizeof(CLSID), 0, 0);
693     ok(hres == S_OK, "ProcessUrlAction failed: %08x\n", hres);
694     ok(policy == URLPOLICY_ALLOW, "policy = %x\n", policy);
695
696     cs.clsid = CLSID_TestActiveX;
697     cs.pUnk = (IUnknown*)&AXObjectSafety;
698     cs.dwFlags = 0;
699
700     ax_objsafe = TRUE;
701     SET_EXPECT(AXQueryInterface_IActiveScript);
702     SET_EXPECT(AXQueryInterface_IObjectSafety);
703     SET_EXPECT(AXGetInterfaceSafetyOptions);
704     SET_EXPECT(AXSetInterfaceSafetyOptions);
705     hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
706             &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
707     CHECK_CALLED(AXQueryInterface_IActiveScript);
708     CHECK_CALLED(AXQueryInterface_IObjectSafety);
709     CHECK_CALLED(AXGetInterfaceSafetyOptions);
710     CHECK_CALLED(AXSetInterfaceSafetyOptions);
711
712     ok(hres == S_OK, "QueryCusromPolicy failed: %08x\n", hres);
713     ok(policy_size == sizeof(DWORD), "policy_size = %d\n", policy_size);
714     ok(*(DWORD*)ppolicy == URLPOLICY_ALLOW, "policy = %x\n", *(DWORD*)ppolicy);
715     CoTaskMemFree(ppolicy);
716
717     ax_objsafe = FALSE;
718     SET_EXPECT(AXQueryInterface_IActiveScript);
719     SET_EXPECT(AXQueryInterface_IObjectSafety);
720     hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
721             &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
722     CHECK_CALLED(AXQueryInterface_IActiveScript);
723     CHECK_CALLED(AXQueryInterface_IObjectSafety);
724
725     ok(hres == S_OK, "QueryCusromPolicy failed: %08x\n", hres);
726     ok(policy_size == sizeof(DWORD), "policy_size = %d\n", policy_size);
727     ok(*(DWORD*)ppolicy == URLPOLICY_DISALLOW, "policy = %x\n", *(DWORD*)ppolicy);
728     CoTaskMemFree(ppolicy);
729
730     if(set_safe_reg(TRUE)) {
731         ax_objsafe = FALSE;
732         SET_EXPECT(AXQueryInterface_IActiveScript);
733         SET_EXPECT(AXQueryInterface_IObjectSafety);
734         hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
735                  &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
736         CHECK_CALLED(AXQueryInterface_IActiveScript);
737         CHECK_CALLED(AXQueryInterface_IObjectSafety);
738
739         ok(hres == S_OK, "QueryCusromPolicy failed: %08x\n", hres);
740         ok(policy_size == sizeof(DWORD), "policy_size = %d\n", policy_size);
741         ok(*(DWORD*)ppolicy == URLPOLICY_ALLOW, "policy = %x\n", *(DWORD*)ppolicy);
742         CoTaskMemFree(ppolicy);
743
744         ax_objsafe = TRUE;
745         SET_EXPECT(AXQueryInterface_IActiveScript);
746         SET_EXPECT(AXQueryInterface_IObjectSafety);
747         SET_EXPECT(AXGetInterfaceSafetyOptions);
748         SET_EXPECT(AXSetInterfaceSafetyOptions);
749         hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
750                 &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
751         CHECK_CALLED(AXQueryInterface_IActiveScript);
752         CHECK_CALLED(AXQueryInterface_IObjectSafety);
753         CHECK_CALLED(AXGetInterfaceSafetyOptions);
754         CHECK_CALLED(AXSetInterfaceSafetyOptions);
755
756         ok(hres == S_OK, "QueryCusromPolicy failed: %08x\n", hres);
757         ok(policy_size == sizeof(DWORD), "policy_size = %d\n", policy_size);
758         ok(*(DWORD*)ppolicy == URLPOLICY_ALLOW, "policy = %x\n", *(DWORD*)ppolicy);
759         CoTaskMemFree(ppolicy);
760
761         set_safe_reg(FALSE);
762     }else {
763         skip("Could not set safety registry\n");
764     }
765
766     IInternetHostSecurityManager_Release(sec_mgr);
767 }
768
769 static HRESULT WINAPI ActiveScriptProperty_QueryInterface(IActiveScriptProperty *iface, REFIID riid, void **ppv)
770 {
771     *ppv = NULL;
772     ok(0, "unexpected call\n");
773     return E_NOINTERFACE;
774 }
775
776 static ULONG WINAPI ActiveScriptProperty_AddRef(IActiveScriptProperty *iface)
777 {
778     return 2;
779 }
780
781 static ULONG WINAPI ActiveScriptProperty_Release(IActiveScriptProperty *iface)
782 {
783     return 1;
784 }
785
786 static HRESULT WINAPI ActiveScriptProperty_GetProperty(IActiveScriptProperty *iface, DWORD dwProperty,
787         VARIANT *pvarIndex, VARIANT *pvarValue)
788 {
789     ok(0, "unexpected call\n");
790     return E_NOTIMPL;
791 }
792
793 static HRESULT WINAPI ActiveScriptProperty_SetProperty(IActiveScriptProperty *iface, DWORD dwProperty,
794         VARIANT *pvarIndex, VARIANT *pvarValue)
795 {
796     switch(dwProperty) {
797     case SCRIPTPROP_HACK_TRIDENTEVENTSINK:
798         CHECK_EXPECT(SetProperty_HACK_TRIDENTEVENTSINK);
799         ok(V_VT(pvarValue) == VT_BOOL, "V_VT(pvarValue)=%d\n", V_VT(pvarValue));
800         ok(V_BOOL(pvarValue) == VARIANT_TRUE, "V_BOOL(pvarValue)=%x\n", V_BOOL(pvarValue));
801         break;
802     case SCRIPTPROP_INVOKEVERSIONING:
803         CHECK_EXPECT(SetProperty_INVOKEVERSIONING);
804         ok(V_VT(pvarValue) == VT_I4, "V_VT(pvarValue)=%d\n", V_VT(pvarValue));
805         ok(V_I4(pvarValue) == 1, "V_I4(pvarValue)=%d\n", V_I4(pvarValue));
806         break;
807     case SCRIPTPROP_ABBREVIATE_GLOBALNAME_RESOLUTION:
808         CHECK_EXPECT(SetProperty_ABBREVIATE_GLOBALNAME_RESOLUTION);
809         ok(V_VT(pvarValue) == VT_BOOL, "V_VT(pvarValue)=%d\n", V_VT(pvarValue));
810         ok(V_BOOL(pvarValue) == VARIANT_TRUE, "V_BOOL(pvarValue)=%x\n", V_BOOL(pvarValue));
811         break;
812     default:
813         ok(0, "unexpected property %x\n", dwProperty);
814         return E_NOTIMPL;
815     }
816
817     ok(!pvarIndex, "pvarIndex != NULL\n");
818     ok(pvarValue != NULL, "pvarValue == NULL\n");
819
820     return S_OK;
821 }
822
823 static const IActiveScriptPropertyVtbl ActiveScriptPropertyVtbl = {
824     ActiveScriptProperty_QueryInterface,
825     ActiveScriptProperty_AddRef,
826     ActiveScriptProperty_Release,
827     ActiveScriptProperty_GetProperty,
828     ActiveScriptProperty_SetProperty
829 };
830
831 static IActiveScriptProperty ActiveScriptProperty = { &ActiveScriptPropertyVtbl };
832
833 static HRESULT WINAPI ActiveScriptParseProcedure_QueryInterface(IActiveScriptParseProcedure2 *iface, REFIID riid, void **ppv)
834 {
835     *ppv = NULL;
836     ok(0, "unexpected call\n");
837     return E_NOINTERFACE;
838 }
839
840 static ULONG WINAPI ActiveScriptParseProcedure_AddRef(IActiveScriptParseProcedure2 *iface)
841 {
842     return 2;
843 }
844
845 static ULONG WINAPI ActiveScriptParseProcedure_Release(IActiveScriptParseProcedure2 *iface)
846 {
847     return 1;
848 }
849
850 static HRESULT WINAPI ActiveScriptParseProcedure_ParseProcedureText(IActiveScriptParseProcedure2 *iface,
851         LPCOLESTR pstrCode, LPCOLESTR pstrFormalParams, LPCOLESTR pstrProcedureName,
852         LPCOLESTR pstrItemName, IUnknown *punkContext, LPCOLESTR pstrDelimiter,
853         CTXARG_T dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags, IDispatch **ppdisp)
854 {
855     ok(0, "unexpected call\n");
856     return E_NOTIMPL;
857 }
858
859 static const IActiveScriptParseProcedure2Vtbl ActiveScriptParseProcedureVtbl = {
860     ActiveScriptParseProcedure_QueryInterface,
861     ActiveScriptParseProcedure_AddRef,
862     ActiveScriptParseProcedure_Release,
863     ActiveScriptParseProcedure_ParseProcedureText
864 };
865
866 static IActiveScriptParseProcedure2 ActiveScriptParseProcedure = { &ActiveScriptParseProcedureVtbl };
867
868 static HRESULT WINAPI ActiveScriptParse_QueryInterface(IActiveScriptParse *iface, REFIID riid, void **ppv)
869 {
870     *ppv = NULL;
871     ok(0, "unexpected call\n");
872     return E_NOINTERFACE;
873 }
874
875 static ULONG WINAPI ActiveScriptParse_AddRef(IActiveScriptParse *iface)
876 {
877     return 2;
878 }
879
880 static ULONG WINAPI ActiveScriptParse_Release(IActiveScriptParse *iface)
881 {
882     return 1;
883 }
884
885 static HRESULT WINAPI ActiveScriptParse_InitNew(IActiveScriptParse *iface)
886 {
887     CHECK_EXPECT(InitNew);
888     return S_OK;
889 }
890
891 static HRESULT WINAPI ActiveScriptParse_AddScriptlet(IActiveScriptParse *iface,
892         LPCOLESTR pstrDefaultName, LPCOLESTR pstrCode, LPCOLESTR pstrItemName,
893         LPCOLESTR pstrSubItemName, LPCOLESTR pstrEventName, LPCOLESTR pstrDelimiter,
894         CTXARG_T dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags,
895         BSTR *pbstrName, EXCEPINFO *pexcepinfo)
896 {
897     ok(0, "unexpected call\n");
898     return E_NOTIMPL;
899 }
900
901 static HRESULT dispex_propput(IDispatchEx *obj, DISPID id, DWORD flags, VARIANT *var)
902 {
903     DISPID propput_arg = DISPID_PROPERTYPUT;
904     DISPPARAMS dp = {var, &propput_arg, 1, 1};
905     EXCEPINFO ei = {0};
906
907     return IDispatchEx_InvokeEx(obj, id, LOCALE_NEUTRAL, DISPATCH_PROPERTYPUT|flags, &dp, NULL, &ei, NULL);
908 }
909
910 static void test_func(IDispatchEx *obj)
911 {
912     DISPID id;
913     IDispatchEx *dispex;
914     IDispatch *disp;
915     EXCEPINFO ei;
916     DISPPARAMS dp;
917     BSTR str;
918     VARIANT var;
919     HRESULT hres;
920
921     str = a2bstr("toString");
922     hres = IDispatchEx_GetDispID(obj, str, fdexNameCaseSensitive, &id);
923     SysFreeString(str);
924     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
925     ok(id == DISPID_IOMNAVIGATOR_TOSTRING, "id = %x\n", id);
926
927     memset(&dp, 0, sizeof(dp));
928     memset(&ei, 0, sizeof(ei));
929     VariantInit(&var);
930     hres = IDispatchEx_InvokeEx(obj, id, LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dp, &var, &ei, NULL);
931     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
932     ok(V_VT(&var) == VT_DISPATCH, "V_VT(var)=%d\n", V_VT(&var));
933     ok(V_DISPATCH(&var) != NULL, "V_DISPATCH(var) == NULL\n");
934     disp = V_DISPATCH(&var);
935
936     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
937     IDispatch_Release(disp);
938     ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
939
940     /* FIXME: Test InvokeEx(DISPATCH_METHOD) */
941
942     memset(&dp, 0, sizeof(dp));
943     memset(&ei, 0, sizeof(ei));
944     VariantInit(&var);
945     hres = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dp, &var, &ei, NULL);
946     ok(hres == S_OK || broken(E_ACCESSDENIED), "InvokeEx failed: %08x\n", hres);
947     if(SUCCEEDED(hres)) {
948         ok(V_VT(&var) == VT_BSTR, "V_VT(var)=%d\n", V_VT(&var));
949         ok(!strcmp_wa(V_BSTR(&var), "[object]"), "V_BSTR(var) = %s\n", wine_dbgstr_w(V_BSTR(&var)));
950         VariantClear(&var);
951     }
952
953     V_VT(&var) = VT_I4;
954     V_I4(&var) = 100;
955     hres = dispex_propput(obj, id, 0, &var);
956     ok(hres == E_NOTIMPL, "InvokeEx failed: %08x\n", hres);
957
958     IDispatchEx_Release(dispex);
959 }
960
961 static void test_nextdispid(IDispatchEx *dispex)
962 {
963     DISPID last_id = DISPID_STARTENUM, id, dyn_id;
964     BSTR name;
965     VARIANT var;
966     HRESULT hres;
967
968     name = a2bstr("dynVal");
969     hres = IDispatchEx_GetDispID(dispex, name, fdexNameCaseSensitive|fdexNameEnsure, &dyn_id);
970     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
971     SysFreeString(name);
972
973     V_VT(&var) = VT_EMPTY;
974     hres = dispex_propput(dispex, dyn_id, 0, &var);
975
976     while(last_id != dyn_id) {
977         hres = IDispatchEx_GetNextDispID(dispex, fdexEnumAll, last_id, &id);
978         ok(hres == S_OK, "GetNextDispID returned: %08x\n", hres);
979         ok(id != DISPID_STARTENUM, "id == DISPID_STARTENUM\n");
980         ok(id != DISPID_IOMNAVIGATOR_TOSTRING, "id == DISPID_IOMNAVIGATOR_TOSTRING\n");
981
982         hres = IDispatchEx_GetMemberName(dispex, id, &name);
983         ok(hres == S_OK, "GetMemberName failed: %08x\n", hres);
984
985         if(id == dyn_id)
986             ok(!strcmp_wa(name, "dynVal"), "name = %s\n", wine_dbgstr_w(name));
987         else if(id == DISPID_IOMNAVIGATOR_PLATFORM)
988             ok(!strcmp_wa(name, "platform"), "name = %s\n", wine_dbgstr_w(name));
989
990         SysFreeString(name);
991         last_id = id;
992     }
993
994     hres = IDispatchEx_GetNextDispID(dispex, 0, id, &id);
995     ok(hres == S_FALSE, "GetNextDispID returned: %08x\n", hres);
996     ok(id == DISPID_STARTENUM, "id != DISPID_STARTENUM\n");
997 }
998
999 static void test_global_id(void)
1000 {
1001     VARIANT var;
1002     DISPPARAMS dp;
1003     EXCEPINFO ei;
1004     BSTR tmp;
1005     DISPID id;
1006     HRESULT hres;
1007
1008     SET_EXPECT(GetScriptDispatch);
1009     SET_EXPECT(script_divid_d);
1010     tmp = a2bstr("divid");
1011     hres = IDispatchEx_GetDispID(window_dispex, tmp, fdexNameCaseSensitive, &id);
1012     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
1013     SysFreeString(tmp);
1014     CHECK_CALLED(GetScriptDispatch);
1015     CHECK_CALLED(script_divid_d);
1016
1017     VariantInit(&var);
1018     memset(&ei, 0, sizeof(ei));
1019     memset(&dp, 0, sizeof(dp));
1020     hres = IDispatchEx_InvokeEx(window_dispex, id, 0, DISPATCH_PROPERTYGET, &dp, &var, &ei, NULL);
1021     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1022     ok(V_VT(&var) == VT_DISPATCH, "V_VT(var) = %d\n", V_VT(&var));
1023     VariantClear(&var);
1024 }
1025
1026 static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *iface,
1027         LPCOLESTR pstrCode, LPCOLESTR pstrItemName, IUnknown *punkContext,
1028         LPCOLESTR pstrDelimiter, CTXARG_T dwSourceContextCookie, ULONG ulStartingLine,
1029         DWORD dwFlags, VARIANT *pvarResult, EXCEPINFO *pexcepinfo)
1030 {
1031     IDispatchEx *document, *dispex;
1032     IHTMLWindow2 *window;
1033     IOmNavigator *navigator;
1034     IUnknown *unk;
1035     VARIANT var, arg;
1036     DISPPARAMS dp;
1037     EXCEPINFO ei;
1038     DISPID id;
1039     BSTR tmp;
1040     HRESULT hres;
1041
1042     static const WCHAR documentW[] = {'d','o','c','u','m','e','n','t',0};
1043     static const WCHAR testW[] = {'t','e','s','t',0};
1044     static const WCHAR funcW[] = {'f','u','n','c',0};
1045
1046     CHECK_EXPECT(ParseScriptText);
1047
1048     SET_EXPECT(GetScriptDispatch);
1049
1050     tmp = SysAllocString(documentW);
1051     hres = IDispatchEx_GetDispID(window_dispex, tmp, fdexNameCaseSensitive, &id);
1052     SysFreeString(tmp);
1053     ok(hres == S_OK, "GetDispID(document) failed: %08x\n", hres);
1054     ok(id == DISPID_IHTMLWINDOW2_DOCUMENT, "id=%x\n", id);
1055
1056     CHECK_CALLED(GetScriptDispatch);
1057
1058     VariantInit(&var);
1059     memset(&dp, 0, sizeof(dp));
1060     memset(&ei, 0, sizeof(ei));
1061
1062     hres = IDispatchEx_InvokeEx(window_dispex, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
1063     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1064     ok(V_VT(&var) == VT_DISPATCH, "V_VT(var)=%d\n", V_VT(&var));
1065     ok(V_DISPATCH(&var) != NULL, "V_DISPATCH(&var) == NULL\n");
1066
1067     hres = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IDispatchEx, (void**)&document);
1068     VariantClear(&var);
1069     ok(hres == S_OK, "Could not get DispatchEx: %08x\n", hres);
1070
1071     tmp = SysAllocString(testW);
1072     hres = IDispatchEx_GetDispID(document, tmp, fdexNameCaseSensitive, &id);
1073     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(document) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
1074     hres = IDispatchEx_GetDispID(document, tmp, fdexNameCaseSensitive | fdexNameImplicit, &id);
1075     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(document) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
1076     SysFreeString(tmp);
1077
1078     id = 0;
1079     tmp = SysAllocString(testW);
1080     hres = IDispatchEx_GetDispID(document, tmp, fdexNameCaseSensitive|fdexNameEnsure, &id);
1081     SysFreeString(tmp);
1082     ok(hres == S_OK, "GetDispID(document) failed: %08x\n", hres);
1083     ok(id, "id == 0\n");
1084
1085     V_VT(&var) = VT_I4;
1086     V_I4(&var) = 100;
1087     hres = dispex_propput(document, id, 0, &var);
1088     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1089
1090     tmp = SysAllocString(testW);
1091     hres = IDispatchEx_GetDispID(document, tmp, fdexNameCaseSensitive, &id);
1092     SysFreeString(tmp);
1093     ok(hres == S_OK, "GetDispID(document) failed: %08x\n", hres);
1094
1095     VariantInit(&var);
1096     memset(&dp, 0, sizeof(dp));
1097     memset(&ei, 0, sizeof(ei));
1098     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
1099     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1100     ok(V_VT(&var) == VT_I4, "V_VT(var)=%d\n", V_VT(&var));
1101     ok(V_I4(&var) == 100, "V_I4(&var) = %d\n", V_I4(&var));
1102
1103     V_VT(&var) = VT_I4;
1104     V_I4(&var) = 200;
1105     hres = dispex_propput(document, id, DISPATCH_PROPERTYPUTREF, &var);
1106     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1107
1108     VariantInit(&var);
1109     memset(&dp, 0, sizeof(dp));
1110     memset(&ei, 0, sizeof(ei));
1111     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
1112     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1113     ok(V_VT(&var) == VT_I4, "V_VT(var)=%d\n", V_VT(&var));
1114     ok(V_I4(&var) == 200, "V_I4(&var) = %d\n", V_I4(&var));
1115
1116     memset(&dp, 0, sizeof(dp));
1117     memset(&ei, 0, sizeof(ei));
1118     V_VT(&var) = VT_I4;
1119     V_I4(&var) = 300;
1120     dp.cArgs = 1;
1121     dp.rgvarg = &var;
1122     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYPUT, &dp, NULL, &ei, NULL);
1123     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1124
1125     VariantInit(&var);
1126     memset(&dp, 0, sizeof(dp));
1127     memset(&ei, 0, sizeof(ei));
1128     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
1129     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1130     ok(V_VT(&var) == VT_I4, "V_VT(var)=%d\n", V_VT(&var));
1131     ok(V_I4(&var) == 300, "V_I4(&var) = %d\n", V_I4(&var));
1132
1133     unk = (void*)0xdeadbeef;
1134     hres = IDispatchEx_GetNameSpaceParent(window_dispex, &unk);
1135     ok(hres == S_OK, "GetNameSpaceParent failed: %08x\n", hres);
1136     ok(!unk, "unk=%p, expected NULL\n", unk);
1137
1138     id = 0;
1139     tmp = SysAllocString(funcW);
1140     hres = IDispatchEx_GetDispID(document, tmp, fdexNameCaseSensitive|fdexNameEnsure, &id);
1141     SysFreeString(tmp);
1142     ok(hres == S_OK, "GetDispID(func) failed: %08x\n", hres);
1143     ok(id, "id == 0\n");
1144
1145     dp.cArgs = 1;
1146     dp.rgvarg = &var;
1147     dp.cNamedArgs = 0;
1148     dp.rgdispidNamedArgs = NULL;
1149     V_VT(&var) = VT_DISPATCH;
1150     V_DISPATCH(&var) = (IDispatch*)&funcDisp;
1151     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYPUT, &dp, NULL, &ei, NULL);
1152     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1153
1154     VariantInit(&var);
1155     memset(&dp, 0, sizeof(dp));
1156     memset(&ei, 0, sizeof(ei));
1157     V_VT(&arg) = VT_BOOL;
1158     V_BOOL(&arg) = VARIANT_TRUE;
1159     dp.cArgs = 1;
1160     dp.rgvarg = &arg;
1161
1162     SET_EXPECT(funcDisp);
1163     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_FUNC, &dp, &var, &ei, NULL);
1164     CHECK_CALLED(funcDisp);
1165
1166     ok(hres == S_OK, "InvokeEx(INVOKE_FUNC) failed: %08x\n", hres);
1167     ok(V_VT(&var) == VT_I4, "V_VT(var)=%d\n", V_VT(&var));
1168     ok(V_I4(&var) == 100, "V_I4(&var) == NULL\n");
1169
1170     IDispatchEx_Release(document);
1171
1172     hres = IDispatchEx_QueryInterface(window_dispex, &IID_IHTMLWindow2, (void**)&window);
1173     ok(hres == S_OK, "Could not get IHTMLWindow2 iface: %08x\n", hres);
1174
1175     hres = IHTMLWindow2_get_navigator(window, &navigator);
1176     IHTMLWindow2_Release(window);
1177     ok(hres == S_OK, "get_navigator failed: %08x\n", hres);
1178
1179     hres = IOmNavigator_QueryInterface(navigator, &IID_IDispatchEx, (void**)&dispex);
1180     IOmNavigator_Release(navigator);
1181     ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
1182
1183     test_func(dispex);
1184     test_nextdispid(dispex);
1185     IDispatchEx_Release(dispex);
1186
1187     script_disp = (IDispatch*)&scriptDisp;
1188
1189     SET_EXPECT(GetScriptDispatch);
1190     SET_EXPECT(script_testprop_d);
1191     tmp = a2bstr("testProp");
1192     hres = IDispatchEx_GetDispID(window_dispex, tmp, fdexNameCaseSensitive, &id);
1193     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
1194     ok(id != DISPID_SCRIPT_TESTPROP, "id == DISPID_SCRIPT_TESTPROP\n");
1195     CHECK_CALLED(GetScriptDispatch);
1196     CHECK_CALLED(script_testprop_d);
1197     SysFreeString(tmp);
1198
1199     tmp = a2bstr("testProp");
1200     hres = IDispatchEx_GetDispID(window_dispex, tmp, fdexNameCaseSensitive, &id);
1201     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
1202     ok(id != DISPID_SCRIPT_TESTPROP, "id == DISPID_SCRIPT_TESTPROP\n");
1203     SysFreeString(tmp);
1204
1205     SET_EXPECT(GetScriptDispatch);
1206     SET_EXPECT(script_testprop_i);
1207     memset(&ei, 0, sizeof(ei));
1208     memset(&dp, 0, sizeof(dp));
1209     hres = IDispatchEx_InvokeEx(window_dispex, id, 0, DISPATCH_PROPERTYGET, &dp, &var, &ei, NULL);
1210     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1211     ok(V_VT(&var) == VT_NULL, "V_VT(var) = %d\n", V_VT(&var));
1212     CHECK_CALLED(GetScriptDispatch);
1213     CHECK_CALLED(script_testprop_i);
1214
1215     test_global_id();
1216
1217     test_security();
1218
1219     return S_OK;
1220 }
1221
1222 static const IActiveScriptParseVtbl ActiveScriptParseVtbl = {
1223     ActiveScriptParse_QueryInterface,
1224     ActiveScriptParse_AddRef,
1225     ActiveScriptParse_Release,
1226     ActiveScriptParse_InitNew,
1227     ActiveScriptParse_AddScriptlet,
1228     ActiveScriptParse_ParseScriptText
1229 };
1230
1231 static IActiveScriptParse ActiveScriptParse = { &ActiveScriptParseVtbl };
1232
1233 static HRESULT WINAPI ActiveScript_QueryInterface(IActiveScript *iface, REFIID riid, void **ppv)
1234 {
1235     *ppv = NULL;
1236
1237     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IActiveScript, riid)) {
1238         *ppv = iface;
1239         return S_OK;
1240     }
1241
1242     if(IsEqualGUID(&IID_IActiveScriptParse, riid)) {
1243         *ppv = &ActiveScriptParse;
1244         return S_OK;
1245     }
1246
1247     if(IsEqualGUID(&IID_IActiveScriptParseProcedure2, riid)) {
1248         *ppv = &ActiveScriptParseProcedure;
1249         return S_OK;
1250     }
1251
1252     if(IsEqualGUID(&IID_IActiveScriptProperty, riid)) {
1253         *ppv = &ActiveScriptProperty;
1254         return S_OK;
1255     }
1256
1257     if(IsEqualGUID(&IID_IObjectSafety, riid)) {
1258         *ppv = &ObjectSafety;
1259         return S_OK;
1260     }
1261
1262     if(IsEqualGUID(&IID_IActiveScriptDebug, riid))
1263         return E_NOINTERFACE;
1264
1265     ok(0, "unexpected riid %s\n", debugstr_guid(riid));
1266     return E_NOINTERFACE;
1267 }
1268
1269 static ULONG WINAPI ActiveScript_AddRef(IActiveScript *iface)
1270 {
1271     return 2;
1272 }
1273
1274 static ULONG WINAPI ActiveScript_Release(IActiveScript *iface)
1275 {
1276     return 1;
1277 }
1278
1279 static HRESULT WINAPI ActiveScript_SetScriptSite(IActiveScript *iface, IActiveScriptSite *pass)
1280 {
1281     IActiveScriptSiteInterruptPoll *poll;
1282     IActiveScriptSiteDebug *debug;
1283     IServiceProvider *service;
1284     ICanHandleException *canexpection;
1285     LCID lcid;
1286     HRESULT hres;
1287
1288     CHECK_EXPECT(SetScriptSite);
1289
1290     ok(pass != NULL, "pass == NULL\n");
1291
1292     hres = IActiveScriptSite_QueryInterface(pass, &IID_IActiveScriptSiteInterruptPoll, (void**)&poll);
1293     ok(hres == S_OK, "Could not get IActiveScriptSiteInterruptPoll interface: %08x\n", hres);
1294     if(FAILED(hres))
1295         IActiveScriptSiteInterruptPoll_Release(poll);
1296
1297     hres = IActiveScriptSite_GetLCID(pass, &lcid);
1298     ok(hres == S_OK, "GetLCID failed: %08x\n", hres);
1299
1300     hres = IActiveScriptSite_OnStateChange(pass, (state = SCRIPTSTATE_INITIALIZED));
1301     ok(hres == S_OK, "OnStateChange failed: %08x\n", hres);
1302
1303     hres = IActiveScriptSite_QueryInterface(pass, &IID_IActiveScriptSiteDebug, (void**)&debug);
1304     ok(hres == S_OK, "Could not get IActiveScriptSiteDebug interface: %08x\n", hres);
1305     if(SUCCEEDED(hres))
1306         IActiveScriptSiteDebug32_Release(debug);
1307
1308     hres = IActiveScriptSite_QueryInterface(pass, &IID_ICanHandleException, (void**)&canexpection);
1309     ok(hres == E_NOINTERFACE, "Could not get IID_ICanHandleException interface: %08x\n", hres);
1310
1311     hres = IActiveScriptSite_QueryInterface(pass, &IID_IServiceProvider, (void**)&service);
1312     ok(hres == S_OK, "Could not get IServiceProvider interface: %08x\n", hres);
1313     if(SUCCEEDED(hres))
1314         IServiceProvider_Release(service);
1315
1316     site = pass;
1317     IActiveScriptSite_AddRef(site);
1318     return S_OK;
1319 }
1320
1321 static HRESULT WINAPI ActiveScript_GetScriptSite(IActiveScript *iface, REFIID riid,
1322                                             void **ppvObject)
1323 {
1324     ok(0, "unexpected call\n");
1325     return E_NOTIMPL;
1326 }
1327
1328 static HRESULT WINAPI ActiveScript_SetScriptState(IActiveScript *iface, SCRIPTSTATE ss)
1329 {
1330     HRESULT hres;
1331
1332     switch(ss) {
1333     case SCRIPTSTATE_STARTED:
1334         CHECK_EXPECT(SetScriptState_STARTED);
1335         break;
1336     case SCRIPTSTATE_CONNECTED:
1337         CHECK_EXPECT(SetScriptState_CONNECTED);
1338         break;
1339     case SCRIPTSTATE_DISCONNECTED:
1340         CHECK_EXPECT(SetScriptState_DISCONNECTED);
1341         break;
1342     default:
1343         ok(0, "unexpected state %d\n", ss);
1344         return E_NOTIMPL;
1345     }
1346
1347     hres = IActiveScriptSite_OnStateChange(site, (state = ss));
1348     return S_OK;
1349 }
1350
1351 static HRESULT WINAPI ActiveScript_GetScriptState(IActiveScript *iface, SCRIPTSTATE *pssState)
1352 {
1353     CHECK_EXPECT(GetScriptState);
1354
1355     *pssState = state;
1356     return S_OK;
1357 }
1358
1359 static HRESULT WINAPI ActiveScript_Close(IActiveScript *iface)
1360 {
1361     CHECK_EXPECT(Close);
1362     return E_NOTIMPL;
1363 }
1364
1365 static HRESULT WINAPI ActiveScript_AddNamedItem(IActiveScript *iface,
1366         LPCOLESTR pstrName, DWORD dwFlags)
1367 {
1368     IDispatch *disp;
1369     IUnknown *unk = NULL, *unk2;
1370     HRESULT hres;
1371
1372     static const WCHAR windowW[] = {'w','i','n','d','o','w',0};
1373
1374     static const IID unknown_iid = {0x719C3050,0xF9D3,0x11CF,{0xA4,0x93,0x00,0x40,0x05,0x23,0xA8,0xA0}};
1375
1376     CHECK_EXPECT(AddNamedItem);
1377
1378     ok(!lstrcmpW(pstrName, windowW), "pstrName=%s\n", wine_dbgstr_w(pstrName));
1379     ok(dwFlags == (SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS), "dwFlags=%x\n", dwFlags);
1380
1381     hres = IActiveScriptSite_GetItemInfo(site, windowW, SCRIPTINFO_IUNKNOWN, &unk, NULL);
1382     ok(hres == S_OK, "GetItemInfo failed: %08x\n", hres);
1383     ok(unk != NULL, "unk == NULL\n");
1384
1385     hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
1386     ok(hres == S_OK, "Could not get IDispatch interface: %08x\n", hres);
1387     if(SUCCEEDED(hres))
1388         IDispatch_Release(disp);
1389
1390     hres = IUnknown_QueryInterface(unk, &unknown_iid, (void**)&unk2);
1391     ok(hres == E_NOINTERFACE, "Got ?? interface: %p\n", unk2);
1392     if(SUCCEEDED(hres))
1393         IUnknown_Release(unk2);
1394
1395     hres = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&window_dispex);
1396     ok(hres == S_OK, "Could not get IDispatchEx interface: %08x\n", hres);
1397
1398     IUnknown_Release(unk);
1399     return S_OK;
1400 }
1401
1402 static HRESULT WINAPI ActiveScript_AddTypeLib(IActiveScript *iface, REFGUID rguidTypeLib,
1403                                          DWORD dwMajor, DWORD dwMinor, DWORD dwFlags)
1404 {
1405     ok(0, "unexpected call\n");
1406     return E_NOTIMPL;
1407 }
1408
1409 static HRESULT WINAPI ActiveScript_GetScriptDispatch(IActiveScript *iface, LPCOLESTR pstrItemName,
1410                                                 IDispatch **ppdisp)
1411 {
1412     CHECK_EXPECT(GetScriptDispatch);
1413
1414     ok(!strcmp_wa(pstrItemName, "window"), "pstrItemName = %s\n", wine_dbgstr_w(pstrItemName));
1415
1416     if(!script_disp)
1417         return E_NOTIMPL;
1418
1419     *ppdisp = script_disp;
1420     return S_OK;
1421 }
1422
1423 static HRESULT WINAPI ActiveScript_GetCurrentScriptThreadID(IActiveScript *iface,
1424                                                        SCRIPTTHREADID *pstridThread)
1425 {
1426     ok(0, "unexpected call\n");
1427     return E_NOTIMPL;
1428 }
1429
1430 static HRESULT WINAPI ActiveScript_GetScriptThreadID(IActiveScript *iface,
1431                                                 DWORD dwWin32ThreadId, SCRIPTTHREADID *pstidThread)
1432 {
1433     ok(0, "unexpected call\n");
1434     return E_NOTIMPL;
1435 }
1436
1437 static HRESULT WINAPI ActiveScript_GetScriptThreadState(IActiveScript *iface,
1438         SCRIPTTHREADID stidThread, SCRIPTTHREADSTATE *pstsState)
1439 {
1440     ok(0, "unexpected call\n");
1441     return E_NOTIMPL;
1442 }
1443
1444 static HRESULT WINAPI ActiveScript_InterruptScriptThread(IActiveScript *iface,
1445         SCRIPTTHREADID stidThread, const EXCEPINFO *pexcepinfo, DWORD dwFlags)
1446 {
1447     ok(0, "unexpected call\n");
1448     return E_NOTIMPL;
1449 }
1450
1451 static HRESULT WINAPI ActiveScript_Clone(IActiveScript *iface, IActiveScript **ppscript)
1452 {
1453     ok(0, "unexpected call\n");
1454     return E_NOTIMPL;
1455 }
1456
1457 static const IActiveScriptVtbl ActiveScriptVtbl = {
1458     ActiveScript_QueryInterface,
1459     ActiveScript_AddRef,
1460     ActiveScript_Release,
1461     ActiveScript_SetScriptSite,
1462     ActiveScript_GetScriptSite,
1463     ActiveScript_SetScriptState,
1464     ActiveScript_GetScriptState,
1465     ActiveScript_Close,
1466     ActiveScript_AddNamedItem,
1467     ActiveScript_AddTypeLib,
1468     ActiveScript_GetScriptDispatch,
1469     ActiveScript_GetCurrentScriptThreadID,
1470     ActiveScript_GetScriptThreadID,
1471     ActiveScript_GetScriptThreadState,
1472     ActiveScript_InterruptScriptThread,
1473     ActiveScript_Clone
1474 };
1475
1476 static IActiveScript ActiveScript = { &ActiveScriptVtbl };
1477
1478 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
1479 {
1480     *ppv = NULL;
1481
1482     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) {
1483         *ppv = iface;
1484         return S_OK;
1485     }
1486
1487     if(IsEqualGUID(&IID_IMarshal, riid))
1488         return E_NOINTERFACE;
1489     if(IsEqualGUID(&CLSID_IdentityUnmarshal, riid))
1490         return E_NOINTERFACE;
1491
1492     ok(0, "unexpected riid %s\n", debugstr_guid(riid));
1493     return E_NOTIMPL;
1494 }
1495
1496 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
1497 {
1498     return 2;
1499 }
1500
1501 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
1502 {
1503     return 1;
1504 }
1505
1506 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
1507 {
1508     CHECK_EXPECT(CreateInstance);
1509
1510     ok(!outer, "outer = %p\n", outer);
1511     ok(IsEqualGUID(&IID_IActiveScript, riid), "unexpected riid %s\n", debugstr_guid(riid));
1512     *ppv = &ActiveScript;
1513     return S_OK;
1514 }
1515
1516 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
1517 {
1518     ok(0, "unexpected call\n");
1519     return S_OK;
1520 }
1521
1522 static const IClassFactoryVtbl ClassFactoryVtbl = {
1523     ClassFactory_QueryInterface,
1524     ClassFactory_AddRef,
1525     ClassFactory_Release,
1526     ClassFactory_CreateInstance,
1527     ClassFactory_LockServer
1528 };
1529
1530 static IClassFactory script_cf = { &ClassFactoryVtbl };
1531
1532 static const char simple_script_str[] =
1533     "<html><head></head><body>"
1534     "<div id=\"divid\"></div>"
1535     "<script language=\"TestScript\">simple script</script>"
1536     "</body></html>";
1537
1538 static void test_simple_script(void)
1539 {
1540     IHTMLDocument2 *doc;
1541
1542     SET_EXPECT(CreateInstance);
1543     SET_EXPECT(GetInterfaceSafetyOptions);
1544     SET_EXPECT(SetInterfaceSafetyOptions);
1545     SET_EXPECT(SetProperty_INVOKEVERSIONING); /* IE8 */
1546     SET_EXPECT(SetProperty_HACK_TRIDENTEVENTSINK);
1547     SET_EXPECT(InitNew);
1548     SET_EXPECT(SetScriptSite);
1549     SET_EXPECT(GetScriptState);
1550     SET_EXPECT(SetScriptState_STARTED);
1551     SET_EXPECT(AddNamedItem);
1552     SET_EXPECT(SetProperty_ABBREVIATE_GLOBALNAME_RESOLUTION); /* IE8 */
1553     SET_EXPECT(ParseScriptText);
1554     SET_EXPECT(SetScriptState_CONNECTED);
1555
1556     doc = create_and_load_doc(simple_script_str);
1557     if(!doc) return;
1558
1559     CHECK_CALLED(CreateInstance);
1560     CHECK_CALLED(GetInterfaceSafetyOptions);
1561     CHECK_CALLED(SetInterfaceSafetyOptions);
1562     CHECK_CALLED_BROKEN(SetProperty_INVOKEVERSIONING); /* IE8 */
1563     CHECK_CALLED(SetProperty_HACK_TRIDENTEVENTSINK);
1564     CHECK_CALLED(InitNew);
1565     CHECK_CALLED(SetScriptSite);
1566     CHECK_CALLED(GetScriptState);
1567     CHECK_CALLED(SetScriptState_STARTED);
1568     CHECK_CALLED(AddNamedItem);
1569     CHECK_CALLED_BROKEN(SetProperty_ABBREVIATE_GLOBALNAME_RESOLUTION); /* IE8 */
1570     CHECK_CALLED(ParseScriptText);
1571     CHECK_CALLED(SetScriptState_CONNECTED);
1572
1573     if(site)
1574         IActiveScriptSite_Release(site);
1575     if(window_dispex)
1576         IDispatchEx_Release(window_dispex);
1577
1578     SET_EXPECT(SetScriptState_DISCONNECTED);
1579     SET_EXPECT(Close);
1580
1581     IHTMLDocument2_Release(doc);
1582
1583     CHECK_CALLED(SetScriptState_DISCONNECTED);
1584     CHECK_CALLED(Close);
1585 }
1586
1587 static BOOL init_registry(BOOL init)
1588 {
1589     return init_key("TestScript\\CLSID", TESTSCRIPT_CLSID, init)
1590         && init_key("CLSID\\"TESTSCRIPT_CLSID"\\Implemented Categories\\{F0B7A1A1-9847-11CF-8F20-00805F2CD064}",
1591                     NULL, init)
1592         && init_key("CLSID\\"TESTSCRIPT_CLSID"\\Implemented Categories\\{F0B7A1A2-9847-11CF-8F20-00805F2CD064}",
1593                     NULL, init);
1594 }
1595
1596 static BOOL register_script_engine(void)
1597 {
1598     DWORD regid;
1599     HRESULT hres;
1600
1601     if(!init_registry(TRUE)) {
1602         init_registry(FALSE);
1603         return FALSE;
1604     }
1605
1606     hres = CoRegisterClassObject(&CLSID_TestScript, (IUnknown *)&script_cf,
1607                                  CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &regid);
1608     ok(hres == S_OK, "Could not register screipt engine: %08x\n", hres);
1609
1610     return TRUE;
1611 }
1612
1613 START_TEST(script)
1614 {
1615     CoInitialize(NULL);
1616
1617     if(winetest_interactive || ! is_ie_hardened()) {
1618         if(register_script_engine()) {
1619             test_simple_script();
1620             init_registry(FALSE);
1621         }else {
1622             skip("Could not register TestScript engine\n");
1623         }
1624     }else {
1625         skip("IE running in Enhanced Security Configuration\n");
1626     }
1627
1628     CoUninitialize();
1629 }