1 /*
2  * Copyright 2008 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 #include <stdio.h>
20 
21 #define COBJMACROS
22 #define CONST_VTABLE
23 
24 #include <ole2.h>
25 #include <dispex.h>
26 #include <activscp.h>
27 
28 #include "wine/test.h"
29 
30 #ifdef _WIN64
31 
32 #define IActiveScriptParse_QueryInterface IActiveScriptParse64_QueryInterface
33 #define IActiveScriptParse_Release IActiveScriptParse64_Release
34 #define IActiveScriptParse_InitNew IActiveScriptParse64_InitNew
35 #define IActiveScriptParse_ParseScriptText IActiveScriptParse64_ParseScriptText
36 #define IActiveScriptParseProcedure2_Release IActiveScriptParseProcedure2_64_Release
37 #define IActiveScriptParseProcedure2_ParseProcedureText IActiveScriptParseProcedure2_64_ParseProcedureText
38 
39 #else
40 
41 #define IActiveScriptParse_QueryInterface IActiveScriptParse32_QueryInterface
42 #define IActiveScriptParse_Release IActiveScriptParse32_Release
43 #define IActiveScriptParse_InitNew IActiveScriptParse32_InitNew
44 #define IActiveScriptParse_ParseScriptText IActiveScriptParse32_ParseScriptText
45 #define IActiveScriptParseProcedure2_Release IActiveScriptParseProcedure2_32_Release
46 #define IActiveScriptParseProcedure2_ParseProcedureText IActiveScriptParseProcedure2_32_ParseProcedureText
47 
48 #endif
49 
50 static const CLSID CLSID_JScript =
51     {0xf414c260,0x6ac0,0x11cf,{0xb6,0xd1,0x00,0xaa,0x00,0xbb,0xbb,0x58}};
52 static const CLSID CLSID_JScriptEncode =
53     {0xf414c262,0x6ac0,0x11cf,{0xb6,0xd1,0x00,0xaa,0x00,0xbb,0xbb,0x58}};
54 
55 #define DEFINE_EXPECT(func) \
56     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
57 
58 #define SET_EXPECT(func) \
59     expect_ ## func = TRUE
60 
61 #define CHECK_EXPECT2(func) \
62     do { \
63         ok(expect_ ##func, "unexpected call " #func "\n"); \
64         called_ ## func = TRUE; \
65     }while(0)
66 
67 #define CHECK_EXPECT(func) \
68     do { \
69         CHECK_EXPECT2(func); \
70         expect_ ## func = FALSE; \
71     }while(0)
72 
73 #define CHECK_CALLED(func) \
74     do { \
75         ok(called_ ## func, "expected " #func "\n"); \
76         expect_ ## func = called_ ## func = FALSE; \
77     }while(0)
78 
79 DEFINE_EXPECT(global_propget_d);
80 DEFINE_EXPECT(global_propget_i);
81 DEFINE_EXPECT(global_propput_d);
82 DEFINE_EXPECT(global_propput_i);
83 DEFINE_EXPECT(global_propputref_d);
84 DEFINE_EXPECT(global_propputref_i);
85 DEFINE_EXPECT(global_propdelete_d);
86 DEFINE_EXPECT(global_nopropdelete_d);
87 DEFINE_EXPECT(global_propdeleteerror_d);
88 DEFINE_EXPECT(global_success_d);
89 DEFINE_EXPECT(global_success_i);
90 DEFINE_EXPECT(global_notexists_d);
91 DEFINE_EXPECT(global_propargput_d);
92 DEFINE_EXPECT(global_propargput_i);
93 DEFINE_EXPECT(global_testargtypes_i);
94 DEFINE_EXPECT(puredisp_prop_d);
95 DEFINE_EXPECT(puredisp_noprop_d);
96 DEFINE_EXPECT(puredisp_value);
97 DEFINE_EXPECT(dispexfunc_value);
98 DEFINE_EXPECT(testobj_delete_test);
99 DEFINE_EXPECT(testobj_delete_nodelete);
100 DEFINE_EXPECT(testobj_value);
101 DEFINE_EXPECT(testobj_construct);
102 DEFINE_EXPECT(testobj_prop_d);
103 DEFINE_EXPECT(testobj_withprop_d);
104 DEFINE_EXPECT(testobj_withprop_i);
105 DEFINE_EXPECT(testobj_noprop_d);
106 DEFINE_EXPECT(testobj_onlydispid_d);
107 DEFINE_EXPECT(testobj_onlydispid_i);
108 DEFINE_EXPECT(testobj_notexists_d);
109 DEFINE_EXPECT(GetItemInfo_testVal);
110 DEFINE_EXPECT(ActiveScriptSite_OnScriptError);
111 DEFINE_EXPECT(invoke_func);
112 DEFINE_EXPECT(DeleteMemberByDispID);
113 DEFINE_EXPECT(DeleteMemberByDispID_false);
114 DEFINE_EXPECT(DeleteMemberByDispID_error);
115 DEFINE_EXPECT(BindHandler);
116 
117 #define DISPID_GLOBAL_TESTPROPGET   0x1000
118 #define DISPID_GLOBAL_TESTPROPPUT   0x1001
119 #define DISPID_GLOBAL_REPORTSUCCESS 0x1002
120 #define DISPID_GLOBAL_TRACE         0x1003
121 #define DISPID_GLOBAL_OK            0x1004
122 #define DISPID_GLOBAL_GETVT         0x1005
123 #define DISPID_GLOBAL_TESTOBJ       0x1006
124 #define DISPID_GLOBAL_GETNULLBSTR   0x1007
125 #define DISPID_GLOBAL_NULL_DISP     0x1008
126 #define DISPID_GLOBAL_TESTTHIS      0x1009
127 #define DISPID_GLOBAL_TESTTHIS2     0x100a
128 #define DISPID_GLOBAL_INVOKEVERSION 0x100b
129 #define DISPID_GLOBAL_CREATEARRAY   0x100c
130 #define DISPID_GLOBAL_PROPGETFUNC   0x100d
131 #define DISPID_GLOBAL_OBJECT_FLAG   0x100e
132 #define DISPID_GLOBAL_ISWIN64       0x100f
133 #define DISPID_GLOBAL_PUREDISP      0x1010
134 #define DISPID_GLOBAL_ISNULLBSTR    0x1011
135 #define DISPID_GLOBAL_PROPARGPUT    0x1012
136 #define DISPID_GLOBAL_SHORTPROP     0x1013
137 #define DISPID_GLOBAL_GETSHORT      0x1014
138 #define DISPID_GLOBAL_TESTARGTYPES  0x1015
139 #define DISPID_GLOBAL_INTPROP       0x1016
140 #define DISPID_GLOBAL_DISPUNK       0x1017
141 #define DISPID_GLOBAL_TESTRES       0x1018
142 #define DISPID_GLOBAL_TESTNORES     0x1019
143 #define DISPID_GLOBAL_DISPEXFUNC    0x101a
144 #define DISPID_GLOBAL_TESTPROPPUTREF 0x101b
145 #define DISPID_GLOBAL_GETSCRIPTSTATE 0x101c
146 #define DISPID_GLOBAL_BINDEVENTHANDLER 0x101d
147 
148 #define DISPID_GLOBAL_TESTPROPDELETE      0x2000
149 #define DISPID_GLOBAL_TESTNOPROPDELETE    0x2001
150 #define DISPID_GLOBAL_TESTPROPDELETEERROR 0x2002
151 
152 #define DISPID_TESTOBJ_PROP         0x2000
153 #define DISPID_TESTOBJ_ONLYDISPID   0x2001
154 #define DISPID_TESTOBJ_WITHPROP     0x2002
155 
156 #define JS_E_OUT_OF_MEMORY 0x800a03ec
157 #define JS_E_INVALID_CHAR 0x800a03f6
158 
159 static const WCHAR testW[] = {'t','e','s','t',0};
160 static const CHAR testA[] = "test";
161 static const WCHAR test_valW[] = {'t','e','s','t','V','a','l',0};
162 static const CHAR test_valA[] = "testVal";
163 static const WCHAR emptyW[] = {0};
164 
165 static BOOL strict_dispid_check, testing_expr;
166 static const char *test_name = "(null)";
167 static IDispatch *script_disp;
168 static int invoke_version;
169 static IActiveScriptError *script_error;
170 static IActiveScript *script_engine;
171 static const CLSID *engine_clsid = &CLSID_JScript;
172 
173 /* Returns true if the user interface is in English. Note that this does not
174  * presume of the formatting of dates, numbers, etc.
175  */
176 static BOOL is_lang_english(void)
177 {
178     static HMODULE hkernel32 = NULL;
179     static LANGID (WINAPI *pGetThreadUILanguage)(void) = NULL;
180     static LANGID (WINAPI *pGetUserDefaultUILanguage)(void) = NULL;
181 
182     if (!hkernel32)
183     {
184         hkernel32 = GetModuleHandleA("kernel32.dll");
185         pGetThreadUILanguage = (void*)GetProcAddress(hkernel32, "GetThreadUILanguage");
186         pGetUserDefaultUILanguage = (void*)GetProcAddress(hkernel32, "GetUserDefaultUILanguage");
187     }
188     if (pGetThreadUILanguage)
189         return PRIMARYLANGID(pGetThreadUILanguage()) == LANG_ENGLISH;
190     if (pGetUserDefaultUILanguage)
191         return PRIMARYLANGID(pGetUserDefaultUILanguage()) == LANG_ENGLISH;
192 
193     return PRIMARYLANGID(GetUserDefaultLangID()) == LANG_ENGLISH;
194 }
195 
196 static BSTR a2bstr(const char *str)
197 {
198     BSTR ret;
199     int len;
200 
201     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
202     ret = SysAllocStringLen(NULL, len-1);
203     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
204 
205     return ret;
206 }
207 
208 static int strcmp_wa(LPCWSTR strw, const char *stra)
209 {
210     CHAR buf[512];
211     WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), 0, 0);
212     return lstrcmpA(buf, stra);
213 }
214 
215 #define test_grfdex(a,b) _test_grfdex(__LINE__,a,b)
216 static void _test_grfdex(unsigned line, DWORD grfdex, DWORD expect)
217 {
218     expect |= invoke_version << 28;
219     ok_(__FILE__,line)(grfdex == expect, "grfdex = %x, expected %x\n", grfdex, expect);
220 }
221 
222 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
223 {
224     *ppv = NULL;
225 
226     if(IsEqualGUID(riid, &IID_IUnknown)
227        || IsEqualGUID(riid, &IID_IDispatch)
228        || IsEqualGUID(riid, &IID_IDispatchEx))
229         *ppv = iface;
230     else
231         return E_NOINTERFACE;
232 
233     return S_OK;
234 }
235 
236 static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
237 {
238     return 2;
239 }
240 
241 static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
242 {
243     return 1;
244 }
245 
246 static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
247 {
248     ok(0, "unexpected call\n");
249     return E_NOTIMPL;
250 }
251 
252 static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
253                                               LCID lcid, ITypeInfo **ppTInfo)
254 {
255     ok(0, "unexpected call\n");
256     return E_NOTIMPL;
257 }
258 
259 static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
260                                                 LPOLESTR *rgszNames, UINT cNames,
261                                                 LCID lcid, DISPID *rgDispId)
262 {
263     ok(0, "unexpected call\n");
264     return E_NOTIMPL;
265 }
266 
267 static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
268                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
269                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
270 {
271     ok(0, "unexpected call\n");
272     return E_NOTIMPL;
273 }
274 
275 static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
276 {
277     ok(0, "unexpected call\n");
278     return E_NOTIMPL;
279 }
280 
281 static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
282         VARIANT *res, EXCEPINFO *pei, IServiceProvider *pspCaller)
283 {
284     ok(0, "unexpected call\n");
285     return E_NOTIMPL;
286 }
287 
288 static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
289 {
290     ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
291     return E_NOTIMPL;
292 }
293 
294 static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
295 {
296     ok(0, "unexpected call\n");
297     return E_NOTIMPL;
298 }
299 
300 static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
301 {
302     ok(0, "unexpected call\n");
303     return E_NOTIMPL;
304 }
305 
306 static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
307 {
308     ok(0, "unexpected call\n");
309     return E_NOTIMPL;
310 }
311 
312 static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
313 {
314     ok(0, "unexpected call\n");
315     return E_NOTIMPL;
316 }
317 
318 static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
319 {
320     ok(0, "unexpected call\n");
321     return E_NOTIMPL;
322 }
323 
324 static HRESULT WINAPI testObj_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
325 {
326     if(!strcmp_wa(bstrName, "prop")) {
327         CHECK_EXPECT(testobj_prop_d);
328         test_grfdex(grfdex, fdexNameCaseSensitive);
329         *pid = DISPID_TESTOBJ_PROP;
330         return S_OK;
331     }
332     if(!strcmp_wa(bstrName, "withProp")) {
333         CHECK_EXPECT(testobj_withprop_d);
334         test_grfdex(grfdex, fdexNameCaseSensitive|fdexNameImplicit);
335         *pid = DISPID_TESTOBJ_WITHPROP;
336         return S_OK;
337     }
338     if(!strcmp_wa(bstrName, "noprop")) {
339         CHECK_EXPECT(testobj_noprop_d);
340         test_grfdex(grfdex, fdexNameCaseSensitive);
341         return DISP_E_UNKNOWNNAME;
342     }
343     if(!strcmp_wa(bstrName, "onlyDispID")) {
344         if(strict_dispid_check)
345             CHECK_EXPECT(testobj_onlydispid_d);
346         test_grfdex(grfdex, fdexNameCaseSensitive);
347         *pid = DISPID_TESTOBJ_ONLYDISPID;
348         return S_OK;
349     }
350     if(!strcmp_wa(bstrName, "notExists")) {
351         CHECK_EXPECT(testobj_notexists_d);
352         test_grfdex(grfdex, fdexNameCaseSensitive);
353         return DISP_E_UNKNOWNNAME;
354     }
355 
356     ok(0, "unexpected name %s\n", wine_dbgstr_w(bstrName));
357     return E_NOTIMPL;
358 }
359 
360 static HRESULT WINAPI testObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
361         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
362 {
363     ok(pspCaller != NULL, "pspCaller = NULL\n");
364 
365     switch(id) {
366     case DISPID_VALUE:
367         ok(pdp != NULL, "pdp == NULL\n");
368         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
369         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
370         ok(pvarRes != NULL, "pvarRes == NULL\n");
371         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
372         ok(pei != NULL, "pei == NULL\n");
373 
374         switch(wFlags) {
375         case INVOKE_PROPERTYGET:
376             CHECK_EXPECT(testobj_value);
377             ok(!pdp->rgvarg, "rgvarg != NULL\n");
378             ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
379             break;
380         case INVOKE_FUNC:
381             ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
382             break;
383         case INVOKE_FUNC|INVOKE_PROPERTYGET:
384             ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
385             break;
386         case DISPATCH_CONSTRUCT:
387             CHECK_EXPECT(testobj_construct);
388             ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
389             break;
390         default:
391             ok(0, "invalid flag (%x)\n", wFlags);
392         }
393 
394         V_VT(pvarRes) = VT_I4;
395         V_I4(pvarRes) = 1;
396         return S_OK;
397     case DISPID_TESTOBJ_ONLYDISPID:
398         if(strict_dispid_check)
399             CHECK_EXPECT(testobj_onlydispid_i);
400         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
401         ok(pdp != NULL, "pdp == NULL\n");
402         ok(!pdp->rgvarg, "rgvarg != NULL\n");
403         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
404         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
405         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
406         ok(pvarRes != NULL, "pvarRes == NULL\n");
407         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
408         ok(pei != NULL, "pei == NULL\n");
409         return DISP_E_MEMBERNOTFOUND;
410      case DISPID_TESTOBJ_WITHPROP:
411         CHECK_EXPECT(testobj_withprop_i);
412 
413         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
414         ok(pdp != NULL, "pdp == NULL\n");
415         ok(!pdp->rgvarg, "rgvarg != NULL\n");
416         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
417         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
418         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
419         ok(pvarRes != NULL, "pvarRes == NULL\n");
420         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
421         ok(pei != NULL, "pei == NULL\n");
422 
423         V_VT(pvarRes) = VT_I4;
424         V_I4(pvarRes) = 1;
425 
426         return S_OK;
427     }
428 
429     ok(0, "unexpected call %x\n", id);
430     return DISP_E_MEMBERNOTFOUND;
431 }
432 
433 static HRESULT WINAPI testObj_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
434 {
435     if(!strcmp_wa(bstrName, "deleteTest")) {
436         CHECK_EXPECT(testobj_delete_test);
437         test_grfdex(grfdex, fdexNameCaseSensitive);
438         return S_OK;
439     }
440     if(!strcmp_wa(bstrName, "noDeleteTest")) {
441         CHECK_EXPECT(testobj_delete_nodelete);
442         test_grfdex(grfdex, fdexNameCaseSensitive);
443         return S_FALSE;
444     }
445 
446     ok(0, "unexpected name %s\n", wine_dbgstr_w(bstrName));
447     return E_FAIL;
448 }
449 
450 static IDispatchExVtbl testObjVtbl = {
451     DispatchEx_QueryInterface,
452     DispatchEx_AddRef,
453     DispatchEx_Release,
454     DispatchEx_GetTypeInfoCount,
455     DispatchEx_GetTypeInfo,
456     DispatchEx_GetIDsOfNames,
457     DispatchEx_Invoke,
458     testObj_GetDispID,
459     testObj_InvokeEx,
460     testObj_DeleteMemberByName,
461     DispatchEx_DeleteMemberByDispID,
462     DispatchEx_GetMemberProperties,
463     DispatchEx_GetMemberName,
464     DispatchEx_GetNextDispID,
465     DispatchEx_GetNameSpaceParent
466 };
467 
468 static IDispatchEx testObj = { &testObjVtbl };
469 
470 static HRESULT WINAPI dispexFunc_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
471         VARIANT *res, EXCEPINFO *pei, IServiceProvider *pspCaller)
472 {
473     ok(pspCaller != NULL, "pspCaller = NULL\n");
474 
475     switch(id) {
476     case DISPID_VALUE:
477         CHECK_EXPECT(dispexfunc_value);
478 
479         ok(pdp != NULL, "pdp == NULL\n");
480         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
481         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs != NULL\n");
482         ok(*pdp->rgdispidNamedArgs == DISPID_THIS, "*rgdispidNamedArgs = %d\n", *pdp->rgdispidNamedArgs);
483         ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
484         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
485         ok(res != NULL, "res == NULL\n");
486         ok(pei != NULL, "pei == NULL\n");
487 
488         ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(pdp->rgvarg+1) = %d\n", V_VT(pdp->rgvarg+1));
489 
490         if(V_BOOL(pdp->rgvarg+1))
491             /* NOTE: If called by Function.apply(), native doesn't set DISPATCH_PROPERTYGET flag. */
492             todo_wine ok(wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags);
493         else
494             ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
495 
496         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
497         ok(V_DISPATCH(pdp->rgvarg) != NULL, "V_DISPATCH(pdp->rgvarg) == NULL\n");
498 
499         if(res)
500             V_VT(res) = VT_NULL;
501         return S_OK;
502     default:
503         ok(0, "unexpected call %x\n", id);
504         return DISP_E_MEMBERNOTFOUND;
505     }
506 }
507 
508 static IDispatchExVtbl dispexFuncVtbl = {
509     DispatchEx_QueryInterface,
510     DispatchEx_AddRef,
511     DispatchEx_Release,
512     DispatchEx_GetTypeInfoCount,
513     DispatchEx_GetTypeInfo,
514     DispatchEx_GetIDsOfNames,
515     DispatchEx_Invoke,
516     DispatchEx_GetDispID,
517     dispexFunc_InvokeEx,
518     DispatchEx_DeleteMemberByName,
519     DispatchEx_DeleteMemberByDispID,
520     DispatchEx_GetMemberProperties,
521     DispatchEx_GetMemberName,
522     DispatchEx_GetNextDispID,
523     DispatchEx_GetNameSpaceParent
524 };
525 
526 static IDispatchEx dispexFunc = { &dispexFuncVtbl };
527 
528 static HRESULT WINAPI pureDisp_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
529 {
530     if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDispatch)) {
531         *ppv = iface;
532         return S_OK;
533     }
534 
535     *ppv = NULL;
536     return E_NOINTERFACE;
537 }
538 
539 static HRESULT WINAPI pureDisp_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
540                                                 LPOLESTR *rgszNames, UINT cNames,
541                                                 LCID lcid, DISPID *rgDispId)
542 {
543     ok(IsEqualGUID(riid, &IID_NULL), "Expected IID_NULL\n");
544     ok(cNames==1, "cNames = %d\n", cNames);
545 
546     if(!strcmp_wa(*rgszNames, "prop")) {
547         CHECK_EXPECT(puredisp_prop_d);
548         *rgDispId = DISPID_TESTOBJ_PROP;
549         return S_OK;
550     } else if(!strcmp_wa(*rgszNames, "noprop")) {
551         CHECK_EXPECT(puredisp_noprop_d);
552         return DISP_E_UNKNOWNNAME;
553     }
554 
555     ok(0, "unexpected call\n");
556     return E_NOTIMPL;
557 }
558 
559 static HRESULT WINAPI pureDisp_Invoke(IDispatchEx *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
560         WORD wFlags, DISPPARAMS *pdp, VARIANT *res, EXCEPINFO *ei, UINT *puArgErr)
561 {
562     ok(IsEqualGUID(&IID_NULL, riid), "unexpected riid\n");
563 
564     switch(dispIdMember) {
565     case DISPID_VALUE:
566         CHECK_EXPECT(puredisp_value);
567 
568         ok(pdp != NULL, "pdp == NULL\n");
569         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
570         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
571         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
572         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
573         ok(res != NULL, "res == NULL\n");
574         ok(ei != NULL, "ei == NULL\n");
575         ok(puArgErr != NULL, "puArgErr == NULL\n");
576 
577         ok(V_VT(pdp->rgvarg) == VT_BOOL, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
578 
579         if(V_BOOL(pdp->rgvarg))
580             todo_wine ok(wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags);
581         else
582             ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
583 
584         if(res)
585             V_VT(res) = VT_NULL;
586         return S_OK;
587     default:
588         ok(0, "unexpected call\n");
589         return E_NOTIMPL;
590     }
591 }
592 
593 static IDispatchExVtbl pureDispVtbl = {
594     pureDisp_QueryInterface,
595     DispatchEx_AddRef,
596     DispatchEx_Release,
597     DispatchEx_GetTypeInfoCount,
598     DispatchEx_GetTypeInfo,
599     pureDisp_GetIDsOfNames,
600     pureDisp_Invoke
601 };
602 
603 static IDispatchEx pureDisp = { &pureDispVtbl };
604 
605 static HRESULT WINAPI BindEventHandler_QueryInterface(IBindEventHandler *iface, REFIID riid, void **ppv)
606 {
607     ok(0, "unexpected call\n");
608     return E_NOINTERFACE;
609 }
610 
611 static ULONG WINAPI BindEventHandler_AddRef(IBindEventHandler *iface)
612 {
613     return 2;
614 }
615 
616 static ULONG WINAPI BindEventHandler_Release(IBindEventHandler *iface)
617 {
618     return 1;
619 }
620 
621 static HRESULT WINAPI BindEventHandler_BindHandler(IBindEventHandler *iface, const WCHAR *event, IDispatch *disp)
622 {
623     CHECK_EXPECT(BindHandler);
624     ok(!strcmp_wa(event, "eventName"), "event = %s\n", wine_dbgstr_w(event));
625     ok(disp != NULL, "disp = NULL\n");
626     return S_OK;
627 }
628 
629 static const IBindEventHandlerVtbl BindEventHandlerVtbl = {
630     BindEventHandler_QueryInterface,
631     BindEventHandler_AddRef,
632     BindEventHandler_Release,
633     BindEventHandler_BindHandler
634 };
635 
636 static IBindEventHandler BindEventHandler = { &BindEventHandlerVtbl };
637 
638 static HRESULT WINAPI bindEventHandlerDisp_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
639 {
640     if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDispatch) || IsEqualGUID(riid, &IID_IDispatchEx)) {
641         *ppv = iface;
642         return S_OK;
643     }
644 
645     if(IsEqualGUID(riid, &IID_IBindEventHandler)) {
646         *ppv = &BindEventHandler;
647         return S_OK;
648     }
649 
650     *ppv = NULL;
651     return E_NOINTERFACE;
652 }
653 
654 static IDispatchExVtbl bindEventHandlerDispVtbl = {
655     bindEventHandlerDisp_QueryInterface,
656     DispatchEx_AddRef,
657     DispatchEx_Release,
658     DispatchEx_GetTypeInfoCount,
659     DispatchEx_GetTypeInfo,
660     DispatchEx_GetIDsOfNames,
661     DispatchEx_Invoke,
662     DispatchEx_GetDispID,
663     DispatchEx_InvokeEx,
664     DispatchEx_DeleteMemberByName,
665     DispatchEx_DeleteMemberByDispID,
666     DispatchEx_GetMemberProperties,
667     DispatchEx_GetMemberName,
668     DispatchEx_GetNextDispID,
669     DispatchEx_GetNameSpaceParent
670 };
671 
672 static IDispatchEx bindEventHandlerDisp = { &bindEventHandlerDispVtbl };
673 
674 static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
675 {
676     if(!strcmp_wa(bstrName, "ok")) {
677         test_grfdex(grfdex, fdexNameCaseSensitive);
678         *pid = DISPID_GLOBAL_OK;
679         return S_OK;
680     }
681     if(!strcmp_wa(bstrName, "trace")) {
682         test_grfdex(grfdex, fdexNameCaseSensitive);
683         *pid = DISPID_GLOBAL_TRACE;
684         return S_OK;
685     }
686     if(!strcmp_wa(bstrName, "reportSuccess")) {
687         CHECK_EXPECT(global_success_d);
688         test_grfdex(grfdex, fdexNameCaseSensitive);
689         *pid = DISPID_GLOBAL_REPORTSUCCESS;
690         return S_OK;
691     }
692     if(!strcmp_wa(bstrName, "testPropGet")) {
693         CHECK_EXPECT(global_propget_d);
694         test_grfdex(grfdex, fdexNameCaseSensitive);
695         *pid = DISPID_GLOBAL_TESTPROPGET;
696         return S_OK;
697     }
698     if(!strcmp_wa(bstrName, "testPropPut")) {
699         CHECK_EXPECT(global_propput_d);
700         test_grfdex(grfdex, fdexNameCaseSensitive);
701         *pid = DISPID_GLOBAL_TESTPROPPUT;
702         return S_OK;
703     }
704     if(!strcmp_wa(bstrName, "testPropPutRef")) {
705         CHECK_EXPECT(global_propputref_d);
706         test_grfdex(grfdex, fdexNameCaseSensitive);
707         *pid = DISPID_GLOBAL_TESTPROPPUTREF;
708         return S_OK;
709     }
710     if(!strcmp_wa(bstrName, "testPropDelete")) {
711         CHECK_EXPECT(global_propdelete_d);
712         test_grfdex(grfdex, fdexNameCaseSensitive);
713         *pid = DISPID_GLOBAL_TESTPROPDELETE;
714         return S_OK;
715     }
716     if(!strcmp_wa(bstrName, "testNoPropDelete")) {
717         CHECK_EXPECT(global_nopropdelete_d);
718         test_grfdex(grfdex, fdexNameCaseSensitive);
719         *pid = DISPID_GLOBAL_TESTNOPROPDELETE;
720         return S_OK;
721     }
722     if(!strcmp_wa(bstrName, "testPropDeleteError")) {
723         CHECK_EXPECT(global_propdeleteerror_d);
724         test_grfdex(grfdex, fdexNameCaseSensitive);
725         *pid = DISPID_GLOBAL_TESTPROPDELETEERROR;
726         return S_OK;
727     }
728     if(!strcmp_wa(bstrName, "getVT")) {
729         test_grfdex(grfdex, fdexNameCaseSensitive);
730         *pid = DISPID_GLOBAL_GETVT;
731         return S_OK;
732     }
733     if(!strcmp_wa(bstrName, "testObj")) {
734         test_grfdex(grfdex, fdexNameCaseSensitive);
735         *pid = DISPID_GLOBAL_TESTOBJ;
736         return S_OK;
737     }
738     if(!strcmp_wa(bstrName, "getNullBSTR")) {
739         *pid = DISPID_GLOBAL_GETNULLBSTR;
740         return S_OK;
741     }
742     if(!strcmp_wa(bstrName, "isNullBSTR")) {
743         *pid = DISPID_GLOBAL_ISNULLBSTR;
744         return S_OK;
745     }
746     if(!strcmp_wa(bstrName, "nullDisp")) {
747         *pid = DISPID_GLOBAL_NULL_DISP;
748         return S_OK;
749     }
750     if(!strcmp_wa(bstrName, "notExists")) {
751         CHECK_EXPECT(global_notexists_d);
752         test_grfdex(grfdex, fdexNameCaseSensitive);
753         return DISP_E_UNKNOWNNAME;
754     }
755 
756     if(!strcmp_wa(bstrName, "testThis")) {
757         test_grfdex(grfdex, fdexNameCaseSensitive);
758         *pid = DISPID_GLOBAL_TESTTHIS;
759         return S_OK;
760     }
761 
762     if(!strcmp_wa(bstrName, "testThis2")) {
763         test_grfdex(grfdex, fdexNameCaseSensitive);
764         *pid = DISPID_GLOBAL_TESTTHIS2;
765         return S_OK;
766     }
767 
768     if(!strcmp_wa(bstrName, "invokeVersion")) {
769         test_grfdex(grfdex, fdexNameCaseSensitive);
770         *pid = DISPID_GLOBAL_INVOKEVERSION;
771         return S_OK;
772     }
773     if(!strcmp_wa(bstrName, "createArray")) {
774         test_grfdex(grfdex, fdexNameCaseSensitive);
775         *pid = DISPID_GLOBAL_CREATEARRAY;
776         return S_OK;
777     }
778     if(!strcmp_wa(bstrName, "propGetFunc")) {
779         test_grfdex(grfdex, fdexNameCaseSensitive);
780         *pid = DISPID_GLOBAL_PROPGETFUNC;
781         return S_OK;
782     }
783     if(!strcmp_wa(bstrName, "objectFlag")) {
784         test_grfdex(grfdex, fdexNameCaseSensitive);
785         *pid = DISPID_GLOBAL_OBJECT_FLAG;
786         return S_OK;
787     }
788 
789     if(!strcmp_wa(bstrName, "isWin64")) {
790         test_grfdex(grfdex, fdexNameCaseSensitive);
791         *pid = DISPID_GLOBAL_ISWIN64;
792         return S_OK;
793     }
794 
795     if(!strcmp_wa(bstrName, "pureDisp")) {
796         test_grfdex(grfdex, fdexNameCaseSensitive);
797         *pid = DISPID_GLOBAL_PUREDISP;
798         return S_OK;
799     }
800 
801     if(!strcmp_wa(bstrName, "propArgPutG")) {
802         CHECK_EXPECT(global_propargput_d);
803         test_grfdex(grfdex, fdexNameCaseSensitive);
804         *pid = DISPID_GLOBAL_PROPARGPUT;
805         return S_OK;
806     }
807 
808     if(!strcmp_wa(bstrName, "propArgPutO")) {
809         CHECK_EXPECT(global_propargput_d);
810         test_grfdex(grfdex, fdexNameEnsure|fdexNameCaseSensitive);
811         *pid = DISPID_GLOBAL_PROPARGPUT;
812         return S_OK;
813     }
814 
815     if(!strcmp_wa(bstrName, "shortProp")) {
816         *pid = DISPID_GLOBAL_SHORTPROP;
817         return S_OK;
818     }
819 
820     if(!strcmp_wa(bstrName, "getShort")) {
821         *pid = DISPID_GLOBAL_GETSHORT;
822         return S_OK;
823     }
824 
825     if(!strcmp_wa(bstrName, "testArgTypes")) {
826         *pid = DISPID_GLOBAL_TESTARGTYPES;
827         return S_OK;
828     }
829 
830     if(!strcmp_wa(bstrName, "intProp")) {
831         *pid = DISPID_GLOBAL_INTPROP;
832         return S_OK;
833     }
834 
835     if(!strcmp_wa(bstrName, "dispUnk")) {
836         *pid = DISPID_GLOBAL_DISPUNK;
837         return S_OK;
838     }
839 
840     if(!strcmp_wa(bstrName, "testRes")) {
841         *pid = DISPID_GLOBAL_TESTRES;
842         return S_OK;
843     }
844 
845     if(!strcmp_wa(bstrName, "testNoRes")) {
846         *pid = DISPID_GLOBAL_TESTNORES;
847         return S_OK;
848     }
849 
850     if(!strcmp_wa(bstrName, "dispexFunc")) {
851         *pid = DISPID_GLOBAL_DISPEXFUNC;
852         return S_OK;
853     }
854 
855     if(!strcmp_wa(bstrName, "getScriptState")) {
856         *pid = DISPID_GLOBAL_GETSCRIPTSTATE;
857         return S_OK;
858     }
859 
860     if(!strcmp_wa(bstrName, "bindEventHandler")) {
861         *pid = DISPID_GLOBAL_BINDEVENTHANDLER;
862         return S_OK;
863     }
864 
865     if(strict_dispid_check && strcmp_wa(bstrName, "t"))
866         ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName));
867     return DISP_E_UNKNOWNNAME;
868 }
869 
870 static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
871         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
872 {
873     ok(pspCaller != NULL, "pspCaller = NULL\n");
874 
875     switch(id) {
876     case DISPID_GLOBAL_OK:
877         ok(wFlags == INVOKE_FUNC || wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
878         ok(pdp != NULL, "pdp == NULL\n");
879         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
880         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
881         ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
882         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
883         if(wFlags & INVOKE_PROPERTYGET)
884             ok(pvarRes != NULL, "pvarRes == NULL\n");
885         else
886             ok(!pvarRes, "pvarRes != NULL\n");
887         ok(pei != NULL, "pei == NULL\n");
888 
889         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
890         ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(pdp->rgvarg+1) = %d\n", V_VT(pdp->rgvarg+1));
891         ok(V_BOOL(pdp->rgvarg+1), "%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
892 
893         return S_OK;
894 
895      case DISPID_GLOBAL_TRACE:
896         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
897         ok(pdp != NULL, "pdp == NULL\n");
898         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
899         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
900         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
901         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
902         ok(!pvarRes, "pvarRes != NULL\n");
903         ok(pei != NULL, "pei == NULL\n");
904 
905         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
906         if(V_VT(pdp->rgvarg) == VT_BSTR)
907             trace("%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
908 
909         return S_OK;
910 
911     case DISPID_GLOBAL_REPORTSUCCESS:
912         CHECK_EXPECT(global_success_i);
913 
914         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
915         ok(pdp != NULL, "pdp == NULL\n");
916         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
917         ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
918         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
919         if(!testing_expr)
920             ok(!pvarRes, "pvarRes != NULL\n");
921         ok(pei != NULL, "pei == NULL\n");
922 
923         return S_OK;
924 
925      case DISPID_GLOBAL_TESTPROPGET:
926         CHECK_EXPECT(global_propget_i);
927 
928         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
929         ok(pdp != NULL, "pdp == NULL\n");
930         ok(!pdp->rgvarg, "rgvarg != NULL\n");
931         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
932         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
933         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
934         ok(pvarRes != NULL, "pvarRes == NULL\n");
935         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
936         ok(pei != NULL, "pei == NULL\n");
937 
938         V_VT(pvarRes) = VT_I4;
939         V_I4(pvarRes) = 1;
940 
941         return S_OK;
942 
943     case DISPID_GLOBAL_TESTPROPPUT:
944         CHECK_EXPECT(global_propput_i);
945 
946         ok(wFlags == INVOKE_PROPERTYPUT, "wFlags = %x\n", wFlags);
947         ok(pdp != NULL, "pdp == NULL\n");
948         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
949         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
950         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
951         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
952         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
953         ok(!pvarRes, "pvarRes != NULL\n");
954 
955         ok(V_VT(pdp->rgvarg) == VT_I4, "V_VT(pdp->rgvarg)=%d\n", V_VT(pdp->rgvarg));
956         ok(V_I4(pdp->rgvarg) == 1, "V_I4(pdp->rgvarg)=%d\n", V_I4(pdp->rgvarg));
957         return S_OK;
958 
959     case DISPID_GLOBAL_TESTPROPPUTREF:
960         CHECK_EXPECT(global_propputref_i);
961 
962         ok(wFlags == (INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF), "wFlags = %x\n", wFlags);
963         ok(pdp != NULL, "pdp == NULL\n");
964         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
965         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
966         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
967         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
968         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
969         ok(!pvarRes, "pvarRes != NULL\n");
970 
971         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(pdp->rgvarg)=%d\n", V_VT(pdp->rgvarg));
972         return S_OK;
973 
974      case DISPID_GLOBAL_GETVT:
975         ok(pdp != NULL, "pdp == NULL\n");
976         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
977         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
978         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
979         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
980         ok(pvarRes != NULL, "pvarRes == NULL\n");
981         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
982         ok(pei != NULL, "pei == NULL\n");
983 
984         V_VT(pvarRes) = VT_BSTR;
985         switch(V_VT(pdp->rgvarg)) {
986         case VT_EMPTY:
987             V_BSTR(pvarRes) = a2bstr("VT_EMPTY");
988             break;
989         case VT_NULL:
990             V_BSTR(pvarRes) = a2bstr("VT_NULL");
991             break;
992         case VT_I4:
993             V_BSTR(pvarRes) = a2bstr("VT_I4");
994             break;
995         case VT_R8:
996             V_BSTR(pvarRes) = a2bstr("VT_R8");
997             break;
998         case VT_BSTR:
999             V_BSTR(pvarRes) = a2bstr("VT_BSTR");
1000             break;
1001         case VT_DISPATCH:
1002             V_BSTR(pvarRes) = a2bstr("VT_DISPATCH");
1003             break;
1004         case VT_BOOL:
1005             V_BSTR(pvarRes) = a2bstr("VT_BOOL");
1006             break;
1007         case VT_ARRAY|VT_VARIANT:
1008             V_BSTR(pvarRes) = a2bstr("VT_ARRAY|VT_VARIANT");
1009             break;
1010         default:
1011             ok(0, "unknown vt %d\n", V_VT(pdp->rgvarg));
1012             return E_FAIL;
1013         }
1014 
1015         return S_OK;
1016 
1017     case DISPID_GLOBAL_TESTRES:
1018         ok(pvarRes != NULL, "pvarRes = NULL\n");
1019         if(pvarRes) {
1020             V_VT(pvarRes) = VT_BOOL;
1021             V_BOOL(pvarRes) = VARIANT_TRUE;
1022         }
1023         return S_OK;
1024 
1025     case DISPID_GLOBAL_TESTNORES:
1026         ok(!pvarRes, "pvarRes != NULL\n");
1027         if(pvarRes)
1028             V_VT(pvarRes) = VT_NULL;
1029         return S_OK;
1030 
1031     case DISPID_GLOBAL_TESTOBJ:
1032         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
1033         ok(pdp != NULL, "pdp == NULL\n");
1034         ok(!pdp->rgvarg, "rgvarg != NULL\n");
1035         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1036         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
1037         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1038         ok(pvarRes != NULL, "pvarRes == NULL\n");
1039         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1040         ok(pei != NULL, "pei == NULL\n");
1041 
1042         V_VT(pvarRes) = VT_DISPATCH;
1043         V_DISPATCH(pvarRes) = (IDispatch*)&testObj;
1044         return S_OK;
1045 
1046     case DISPID_GLOBAL_PUREDISP:
1047         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
1048         ok(pdp != NULL, "pdp == NULL\n");
1049         ok(!pdp->rgvarg, "rgvarg != NULL\n");
1050         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1051         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
1052         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1053         ok(pvarRes != NULL, "pvarRes == NULL\n");
1054         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1055         ok(pei != NULL, "pei == NULL\n");
1056 
1057         V_VT(pvarRes) = VT_DISPATCH;
1058         V_DISPATCH(pvarRes) = (IDispatch*)&pureDisp;
1059         return S_OK;
1060 
1061     case DISPID_GLOBAL_DISPEXFUNC:
1062         V_VT(pvarRes) = VT_DISPATCH;
1063         V_DISPATCH(pvarRes) = (IDispatch*)&dispexFunc;
1064         return S_OK;
1065 
1066     case DISPID_GLOBAL_GETNULLBSTR:
1067         if(pvarRes) {
1068             V_VT(pvarRes) = VT_BSTR;
1069             V_BSTR(pvarRes) = NULL;
1070         }
1071         return S_OK;
1072 
1073     case DISPID_GLOBAL_ISNULLBSTR:
1074         ok(pdp != NULL, "pdp == NULL\n");
1075         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1076         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1077         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1078         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1079         ok(pvarRes != NULL, "pvarRes == NULL\n");
1080         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1081         ok(pei != NULL, "pei == NULL\n");
1082         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
1083 
1084         V_VT(pvarRes) = VT_BOOL;
1085         V_BOOL(pvarRes) = V_BSTR(pdp->rgvarg) ? VARIANT_FALSE : VARIANT_TRUE;
1086         return S_OK;
1087 
1088     case DISPID_GLOBAL_ISWIN64:
1089         if(pvarRes) {
1090             V_VT(pvarRes) = VT_BOOL;
1091             V_BOOL(pvarRes) = sizeof(void*) == 8 ? VARIANT_TRUE : VARIANT_FALSE;
1092         }
1093         return S_OK;
1094 
1095     case DISPID_GLOBAL_NULL_DISP:
1096         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
1097         ok(pdp != NULL, "pdp == NULL\n");
1098         ok(!pdp->rgvarg, "rgvarg != NULL\n");
1099         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1100         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
1101         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1102         ok(pvarRes != NULL, "pvarRes == NULL\n");
1103         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1104         ok(pei != NULL, "pei == NULL\n");
1105 
1106         V_VT(pvarRes) = VT_DISPATCH;
1107         V_DISPATCH(pvarRes) = NULL;
1108         return S_OK;
1109 
1110     case DISPID_GLOBAL_TESTTHIS:
1111         ok(pdp != NULL, "pdp == NULL\n");
1112         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1113         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1114         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1115         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1116         ok(pvarRes == NULL, "pvarRes != NULL\n");
1117         ok(pei != NULL, "pei == NULL\n");
1118 
1119         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
1120         ok(V_DISPATCH(pdp->rgvarg) == (IDispatch*)iface, "disp != iface\n");
1121 
1122         return S_OK;
1123 
1124     case DISPID_GLOBAL_TESTTHIS2:
1125         ok(pdp != NULL, "pdp == NULL\n");
1126         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1127         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1128         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1129         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1130         ok(pvarRes == NULL, "pvarRes != NULL\n");
1131         ok(pei != NULL, "pei == NULL\n");
1132 
1133         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(arg) = %d\n", V_VT(pdp->rgvarg));
1134         ok(V_DISPATCH(pdp->rgvarg) != (IDispatch*)iface, "disp == iface\n");
1135         ok(V_DISPATCH(pdp->rgvarg) == script_disp, "disp != script_disp\n");
1136 
1137         return S_OK;
1138 
1139      case DISPID_GLOBAL_INVOKEVERSION:
1140         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
1141         ok(pdp != NULL, "pdp == NULL\n");
1142         ok(!pdp->rgvarg, "rgvarg != NULL\n");
1143         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1144         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
1145         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1146         ok(pvarRes != NULL, "pvarRes == NULL\n");
1147         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1148         ok(pei != NULL, "pei == NULL\n");
1149 
1150         V_VT(pvarRes) = VT_I4;
1151         V_I4(pvarRes) = invoke_version;
1152 
1153         return S_OK;
1154 
1155     case DISPID_GLOBAL_CREATEARRAY: {
1156         SAFEARRAYBOUND bound[2];
1157         VARIANT *data;
1158         int i,j;
1159 
1160         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
1161         ok(pdp != NULL, "pdp == NULL\n");
1162         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1163         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1164         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
1165         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1166         ok(pvarRes != NULL, "pvarRes == NULL\n");
1167         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1168         ok(pei != NULL, "pei == NULL\n");
1169 
1170         bound[0].lLbound = 0;
1171         bound[0].cElements = 5;
1172         bound[1].lLbound = 2;
1173         bound[1].cElements = 2;
1174 
1175         V_VT(pvarRes) = VT_ARRAY|VT_VARIANT;
1176         V_ARRAY(pvarRes) = SafeArrayCreate(VT_VARIANT, 2, bound);
1177 
1178         SafeArrayAccessData(V_ARRAY(pvarRes), (void**)&data);
1179         for(i=0; i<5; i++) {
1180             for(j=2; j<4; j++) {
1181                 V_VT(data) = VT_I4;
1182                 V_I4(data) = i*10+j;
1183                 data++;
1184             }
1185         }
1186         SafeArrayUnaccessData(V_ARRAY(pvarRes));
1187 
1188         return S_OK;
1189     }
1190 
1191     case DISPID_GLOBAL_PROPGETFUNC:
1192         switch(wFlags) {
1193         case INVOKE_FUNC:
1194             CHECK_EXPECT(invoke_func);
1195             break;
1196         case INVOKE_FUNC|INVOKE_PROPERTYGET:
1197             ok(pdp->cArgs != 0, "pdp->cArgs = %d\n", pdp->cArgs);
1198             ok(pvarRes != NULL, "pdp->pvarRes == NULL\n");
1199             break;
1200         default:
1201             ok(0, "invalid flag (%x)\n", wFlags);
1202         }
1203 
1204         ok(pdp != NULL, "pdp == NULL\n");
1205         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1206         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1207         ok(pei != NULL, "pei == NULL\n");
1208 
1209         if(pvarRes) {
1210             ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1211             V_VT(pvarRes) = VT_I4;
1212             V_I4(pvarRes) = pdp->cArgs;
1213         }
1214 
1215         return S_OK;
1216 
1217     case DISPID_GLOBAL_GETSCRIPTSTATE: {
1218         SCRIPTSTATE state;
1219         HRESULT hres;
1220 
1221         hres = IActiveScript_GetScriptState(script_engine, &state);
1222         ok(hres == S_OK, "GetScriptState failed: %08x\n", hres);
1223 
1224         V_VT(pvarRes) = VT_I4;
1225         V_I4(pvarRes) = state;
1226         return S_OK;
1227     }
1228 
1229     case DISPID_GLOBAL_BINDEVENTHANDLER:
1230         V_VT(pvarRes) = VT_DISPATCH;
1231         V_DISPATCH(pvarRes) = (IDispatch*)&bindEventHandlerDisp;
1232         return S_OK;
1233 
1234     case DISPID_GLOBAL_PROPARGPUT:
1235         CHECK_EXPECT(global_propargput_i);
1236         ok(wFlags == INVOKE_PROPERTYPUT, "wFlags = %x\n", wFlags);
1237         ok(pdp != NULL, "pdp == NULL\n");
1238         ok(pdp->rgvarg != NULL, "rgvarg != NULL\n");
1239         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
1240         ok(pdp->cArgs == 3, "cArgs = %d\n", pdp->cArgs);
1241         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
1242         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
1243         ok(!pvarRes, "pvarRes != NULL\n");
1244         ok(pei != NULL, "pei == NULL\n");
1245 
1246         ok(V_VT(pdp->rgvarg) == VT_I4, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
1247         ok(V_I4(pdp->rgvarg) == 2, "V_I4(pdp->rgvarg) = %d\n", V_I4(pdp->rgvarg));
1248 
1249         ok(V_VT(pdp->rgvarg+1) == VT_I4, "V_VT(pdp->rgvarg+1) = %d\n", V_VT(pdp->rgvarg+1));
1250         ok(V_I4(pdp->rgvarg+1) == 1, "V_I4(pdp->rgvarg+1) = %d\n", V_I4(pdp->rgvarg+1));
1251 
1252         ok(V_VT(pdp->rgvarg+2) == VT_I4, "V_VT(pdp->rgvarg+2) = %d\n", V_VT(pdp->rgvarg+2));
1253         ok(V_I4(pdp->rgvarg+2) == 0, "V_I4(pdp->rgvarg+2) = %d\n", V_I4(pdp->rgvarg+2));
1254         return S_OK;
1255 
1256     case DISPID_GLOBAL_OBJECT_FLAG: {
1257         IDispatchEx *dispex;
1258         BSTR str;
1259         HRESULT hres;
1260 
1261         hres = IDispatch_QueryInterface(script_disp, &IID_IDispatchEx, (void**)&dispex);
1262         ok(hres == S_OK, "hres = %x\n", hres);
1263 
1264         str = a2bstr("Object");
1265         hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseSensitive, &id);
1266         SysFreeString(str);
1267         ok(hres == S_OK, "hres = %x\n", hres);
1268 
1269         hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_METHOD, pdp, NULL, pei, pspCaller);
1270         ok(hres == S_OK, "hres = %x\n", hres);
1271 
1272         V_VT(pvarRes) = VT_EMPTY;
1273         hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_METHOD, pdp, pvarRes, pei, pspCaller);
1274         ok(hres == S_OK, "hres = %x\n", hres);
1275         ok(V_VT(pvarRes) == VT_DISPATCH, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1276         VariantClear(pvarRes);
1277 
1278         hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_METHOD|DISPATCH_PROPERTYGET, pdp, NULL, pei, pspCaller);
1279         ok(hres == S_OK, "hres = %x\n", hres);
1280 
1281         V_VT(pvarRes) = VT_EMPTY;
1282         hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_CONSTRUCT, pdp, pvarRes, pei, pspCaller);
1283         ok(hres == S_OK, "hres = %x\n", hres);
1284         ok(V_VT(pvarRes) == VT_DISPATCH, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1285         VariantClear(pvarRes);
1286 
1287         hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_CONSTRUCT, pdp, NULL, pei, pspCaller);
1288         ok(hres == S_OK, "hres = %x\n", hres);
1289 
1290         V_VT(pvarRes) = VT_EMPTY;
1291         hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_CONSTRUCT|DISPATCH_PROPERTYGET, pdp, pvarRes, pei, pspCaller);
1292         ok(hres == E_INVALIDARG, "hres = %x\n", hres);
1293 
1294         V_VT(pvarRes) = VT_EMPTY;
1295         hres = IDispatchEx_InvokeEx(dispex, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
1296         ok(hres == S_OK, "hres = %x\n", hres);
1297         ok(V_VT(pvarRes) == VT_DISPATCH, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1298         IDispatchEx_Release(dispex);
1299         return S_OK;
1300     }
1301     case DISPID_GLOBAL_SHORTPROP:
1302     case DISPID_GLOBAL_GETSHORT:
1303         V_VT(pvarRes) = VT_I2;
1304         V_I2(pvarRes) = 10;
1305         return S_OK;
1306 
1307     case DISPID_GLOBAL_INTPROP:
1308         V_VT(pvarRes) = VT_INT;
1309         V_INT(pvarRes) = 22;
1310         return S_OK;
1311 
1312     case DISPID_GLOBAL_DISPUNK:
1313         V_VT(pvarRes) = VT_UNKNOWN;
1314         V_UNKNOWN(pvarRes) = (IUnknown*)&testObj;
1315         return S_OK;
1316 
1317     case DISPID_GLOBAL_TESTARGTYPES: {
1318         VARIANT args[8], v;
1319         DISPPARAMS dp = {args, NULL, ARRAY_SIZE(args), 0};
1320         HRESULT hres;
1321 
1322         CHECK_EXPECT(global_testargtypes_i);
1323         ok(wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags);
1324         ok(pdp != NULL, "pdp == NULL\n");
1325         ok(pdp->rgvarg != NULL, "rgvarg != NULL\n");
1326         ok(pdp->cArgs == 6, "cArgs = %d\n", pdp->cArgs);
1327         ok(!pvarRes, "pvarRes != NULL\n");
1328 
1329         ok(V_VT(pdp->rgvarg+1) == VT_I4, "V_VT(pdp->rgvarg+1) = %d\n", V_VT(pdp->rgvarg+1));
1330         ok(V_I4(pdp->rgvarg+1) == 10, "V_I4(pdp->rgvarg+1) = %d\n", V_I4(pdp->rgvarg+1));
1331 
1332         ok(V_VT(pdp->rgvarg+2) == VT_I4, "V_VT(pdp->rgvarg+2) = %d\n", V_VT(pdp->rgvarg+2));
1333         ok(V_I4(pdp->rgvarg+2) == 10, "V_I4(pdp->rgvarg+2) = %d\n", V_I4(pdp->rgvarg+2));
1334 
1335         ok(V_VT(pdp->rgvarg+3) == VT_I4, "V_VT(pdp->rgvarg+3) = %d\n", V_VT(pdp->rgvarg+3));
1336         ok(V_I4(pdp->rgvarg+3) == 22, "V_I4(pdp->rgvarg+3) = %d\n", V_I4(pdp->rgvarg+3));
1337 
1338         ok(V_VT(pdp->rgvarg+4) == VT_I4, "V_VT(pdp->rgvarg+4) = %d\n", V_VT(pdp->rgvarg+4));
1339         ok(V_I4(pdp->rgvarg+4) == 22, "V_I4(pdp->rgvarg+4) = %d\n", V_I4(pdp->rgvarg+4));
1340 
1341         ok(V_VT(pdp->rgvarg+5) == VT_DISPATCH, "V_VT(pdp->rgvarg+5) = %d\n", V_VT(pdp->rgvarg+5));
1342         ok(V_DISPATCH(pdp->rgvarg+5) == (IDispatch*)&testObj, "V_DISPATCH(pdp->rgvarg+5) != testObj\n");
1343 
1344         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
1345 
1346         V_VT(args) = VT_I2;
1347         V_I2(args) = 2;
1348         V_VT(args+1) = VT_INT;
1349         V_INT(args+1) = 22;
1350         V_VT(args+2) = VT_UNKNOWN;
1351         V_UNKNOWN(args+2) = (IUnknown*)&testObj;
1352         V_VT(args+3) = VT_UNKNOWN;
1353         V_UNKNOWN(args+3) = NULL;
1354         V_VT(args+4) = VT_UI4;
1355         V_UI4(args+4) = 0xffffffff;
1356         V_VT(args+5) = VT_BYREF|VT_VARIANT;
1357         V_VARIANTREF(args+5) = &v;
1358         V_VT(args+6) = VT_R4;
1359         V_R4(args+6) = 0.5;
1360         V_VT(args+7) = VT_UI2;
1361         V_R4(args+7) = 3;
1362         V_VT(&v) = VT_I4;
1363         V_I4(&v) = 2;
1364         hres = IDispatch_Invoke(V_DISPATCH(pdp->rgvarg), DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dp, NULL, NULL, NULL);
1365         ok(hres == S_OK, "Invoke failed: %08x\n", hres);
1366 
1367         return S_OK;
1368     }
1369     }
1370 
1371     ok(0, "unexpected call %x\n", id);
1372     return DISP_E_MEMBERNOTFOUND;
1373 }
1374 
1375 static HRESULT WINAPI Global_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
1376 {
1377     switch(id) {
1378     case DISPID_GLOBAL_TESTPROPDELETE:
1379         CHECK_EXPECT(DeleteMemberByDispID);
1380         return S_OK;
1381     case DISPID_GLOBAL_TESTNOPROPDELETE:
1382         CHECK_EXPECT(DeleteMemberByDispID_false);
1383         return S_FALSE;
1384     case DISPID_GLOBAL_TESTPROPDELETEERROR:
1385         CHECK_EXPECT(DeleteMemberByDispID_error);
1386         return E_FAIL;
1387     default:
1388         ok(0, "id = %d\n", id);
1389     }
1390 
1391     return E_FAIL;
1392 }
1393 
1394 static IDispatchExVtbl GlobalVtbl = {
1395     DispatchEx_QueryInterface,
1396     DispatchEx_AddRef,
1397     DispatchEx_Release,
1398     DispatchEx_GetTypeInfoCount,
1399     DispatchEx_GetTypeInfo,
1400     DispatchEx_GetIDsOfNames,
1401     DispatchEx_Invoke,
1402     Global_GetDispID,
1403     Global_InvokeEx,
1404     DispatchEx_DeleteMemberByName,
1405     Global_DeleteMemberByDispID,
1406     DispatchEx_GetMemberProperties,
1407     DispatchEx_GetMemberName,
1408     DispatchEx_GetNextDispID,
1409     DispatchEx_GetNameSpaceParent
1410 };
1411 
1412 static IDispatchEx Global = { &GlobalVtbl };
1413 
1414 static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
1415 {
1416     *ppv = NULL;
1417 
1418     if(IsEqualGUID(&IID_IUnknown, riid))
1419         *ppv = iface;
1420     else if(IsEqualGUID(&IID_IActiveScriptSite, riid))
1421         *ppv = iface;
1422     else
1423         return E_NOINTERFACE;
1424 
1425     IUnknown_AddRef((IUnknown*)*ppv);
1426     return S_OK;
1427 }
1428 
1429 static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
1430 {
1431     return 2;
1432 }
1433 
1434 static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
1435 {
1436     return 1;
1437 }
1438 
1439 static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *plcid)
1440 {
1441     *plcid = GetUserDefaultLCID();
1442     return S_OK;
1443 }
1444 
1445 static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR pstrName,
1446         DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti)
1447 {
1448     ok(dwReturnMask == SCRIPTINFO_IUNKNOWN, "unexpected dwReturnMask %x\n", dwReturnMask);
1449     ok(!ppti, "ppti != NULL\n");
1450 
1451     if(!strcmp_wa(pstrName, test_valA))
1452         CHECK_EXPECT(GetItemInfo_testVal);
1453     else if(strcmp_wa(pstrName, testA))
1454         ok(0, "unexpected pstrName %s\n", wine_dbgstr_w(pstrName));
1455 
1456     *ppiunkItem = (IUnknown*)&Global;
1457     return S_OK;
1458 }
1459 
1460 static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *pbstrVersion)
1461 {
1462     return E_NOTIMPL;
1463 }
1464 
1465 static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface,
1466         const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo)
1467 {
1468     return E_NOTIMPL;
1469 }
1470 
1471 static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE ssScriptState)
1472 {
1473     return E_NOTIMPL;
1474 }
1475 
1476 static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
1477 {
1478     return E_NOTIMPL;
1479 }
1480 
1481 static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
1482 {
1483     return E_NOTIMPL;
1484 }
1485 
1486 static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
1487 {
1488     return E_NOTIMPL;
1489 }
1490 
1491 #undef ACTSCPSITE_THIS
1492 
1493 static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
1494     ActiveScriptSite_QueryInterface,
1495     ActiveScriptSite_AddRef,
1496     ActiveScriptSite_Release,
1497     ActiveScriptSite_GetLCID,
1498     ActiveScriptSite_GetItemInfo,
1499     ActiveScriptSite_GetDocVersionString,
1500     ActiveScriptSite_OnScriptTerminate,
1501     ActiveScriptSite_OnStateChange,
1502     ActiveScriptSite_OnScriptError,
1503     ActiveScriptSite_OnEnterScript,
1504     ActiveScriptSite_OnLeaveScript
1505 };
1506 
1507 static IActiveScriptSite ActiveScriptSite = { &ActiveScriptSiteVtbl };
1508 
1509 static HRESULT WINAPI ActiveScriptSite_OnScriptError_CheckError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
1510 {
1511     ok(pscripterror != NULL, "ActiveScriptSite_OnScriptError -- expected pscripterror to be set, got NULL\n");
1512 
1513     script_error = pscripterror;
1514     IActiveScriptError_AddRef(script_error);
1515 
1516     CHECK_EXPECT(ActiveScriptSite_OnScriptError);
1517 
1518     return S_OK;
1519 }
1520 
1521 static const IActiveScriptSiteVtbl ActiveScriptSite_CheckErrorVtbl = {
1522     ActiveScriptSite_QueryInterface,
1523     ActiveScriptSite_AddRef,
1524     ActiveScriptSite_Release,
1525     ActiveScriptSite_GetLCID,
1526     ActiveScriptSite_GetItemInfo,
1527     ActiveScriptSite_GetDocVersionString,
1528     ActiveScriptSite_OnScriptTerminate,
1529     ActiveScriptSite_OnStateChange,
1530     ActiveScriptSite_OnScriptError_CheckError,
1531     ActiveScriptSite_OnEnterScript,
1532     ActiveScriptSite_OnLeaveScript
1533 };
1534 
1535 static IActiveScriptSite ActiveScriptSite_CheckError = { &ActiveScriptSite_CheckErrorVtbl };
1536 
1537 static HRESULT set_script_prop(IActiveScript *engine, DWORD property, VARIANT *val)
1538 {
1539     IActiveScriptProperty *script_prop;
1540     HRESULT hres;
1541 
1542     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptProperty,
1543             (void**)&script_prop);
1544     ok(hres == S_OK, "Could not get IActiveScriptProperty iface: %08x\n", hres);
1545 
1546     hres = IActiveScriptProperty_SetProperty(script_prop, property, NULL, val);
1547     IActiveScriptProperty_Release(script_prop);
1548 
1549     return hres;
1550 }
1551 
1552 static IActiveScript *create_script(void)
1553 {
1554     IActiveScript *script;
1555     VARIANT v;
1556     HRESULT hres;
1557 
1558     hres = CoCreateInstance(engine_clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1559             &IID_IActiveScript, (void**)&script);
1560     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
1561 
1562     V_VT(&v) = VT_I4;
1563     V_I4(&v) = invoke_version;
1564     hres = set_script_prop(script, SCRIPTPROP_INVOKEVERSIONING, &v);
1565     ok(hres == S_OK || broken(hres == E_NOTIMPL), "SetProperty(SCRIPTPROP_INVOKEVERSIONING) failed: %08x\n", hres);
1566     if(invoke_version && FAILED(hres)) {
1567         IActiveScript_Release(script);
1568         return NULL;
1569     }
1570 
1571     return script;
1572 }
1573 
1574 static HRESULT parse_script(DWORD flags, BSTR script_str)
1575 {
1576     IActiveScriptParse *parser;
1577     IActiveScript *engine;
1578     HRESULT hres;
1579 
1580     engine = create_script();
1581     if(!engine)
1582         return S_OK;
1583 
1584     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
1585     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1586     if (FAILED(hres))
1587     {
1588         IActiveScript_Release(engine);
1589         return hres;
1590     }
1591 
1592     hres = IActiveScriptParse_InitNew(parser);
1593     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
1594 
1595     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
1596     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
1597 
1598     hres = IActiveScript_AddNamedItem(engine, testW,
1599             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|flags);
1600     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
1601 
1602     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
1603     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
1604 
1605     hres = IActiveScript_GetScriptDispatch(engine, NULL, &script_disp);
1606     ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres);
1607     ok(script_disp != NULL, "script_disp == NULL\n");
1608     ok(script_disp != (IDispatch*)&Global, "script_disp == Global\n");
1609 
1610     hres = IActiveScriptParse_ParseScriptText(parser, script_str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
1611 
1612     IDispatch_Release(script_disp);
1613     IActiveScript_Release(engine);
1614     IActiveScriptParse_Release(parser);
1615 
1616     return hres;
1617 }
1618 
1619 static HRESULT invoke_procedure(const char *argsa, const char *sourcea, DISPPARAMS *dp)
1620 {
1621     IActiveScriptParseProcedure2 *parse_proc;
1622     IActiveScriptParse *parser;
1623     IActiveScript *engine;
1624     IDispatchEx *dispex;
1625     EXCEPINFO ei = {0};
1626     BSTR source, args;
1627     IDispatch *disp;
1628     VARIANT res;
1629     HRESULT hres;
1630 
1631     engine = create_script();
1632     if(!engine)
1633         return S_OK;
1634 
1635     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
1636     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1637 
1638     hres = IActiveScriptParse_InitNew(parser);
1639     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
1640 
1641     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
1642     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
1643 
1644     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
1645     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
1646 
1647     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParseProcedure2, (void**)&parse_proc);
1648     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1649 
1650     source = a2bstr(sourcea);
1651     args = argsa ? a2bstr(argsa) : NULL;
1652     hres = IActiveScriptParseProcedure2_ParseProcedureText(parse_proc, source, args, emptyW, NULL, NULL, NULL, 0, 0,
1653         SCRIPTPROC_HOSTMANAGESSOURCE|SCRIPTPROC_IMPLICIT_THIS|SCRIPTPROC_IMPLICIT_PARENTS, &disp);
1654     ok(hres == S_OK, "ParseProcedureText failed: %08x\n", hres);
1655     SysFreeString(source);
1656     SysFreeString(args);
1657 
1658     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
1659     ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
1660     IDispatch_Release(disp);
1661 
1662     V_VT(&res) = VT_EMPTY;
1663     hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, 0, DISPATCH_METHOD, dp, &res, &ei, NULL);
1664     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1665     ok(V_VT(&res) == VT_BOOL && V_BOOL(&res), "InvokeEx returned vt %d (%x)\n", V_VT(&res), V_I4(&res));
1666     IDispatchEx_Release(dispex);
1667 
1668     IActiveScriptParseProcedure2_Release(parse_proc);
1669     IActiveScript_Release(engine);
1670     IActiveScriptParse_Release(parser);
1671 
1672     return hres;
1673 }
1674 
1675 static HRESULT parse_htmlscript(BSTR script_str)
1676 {
1677     IActiveScriptParse *parser;
1678     IActiveScript *engine;
1679     HRESULT hres;
1680     BSTR tmp = a2bstr("</SCRIPT>");
1681 
1682     engine = create_script();
1683     if(!engine)
1684         return E_FAIL;
1685 
1686     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
1687     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1688     if (FAILED(hres))
1689     {
1690         IActiveScript_Release(engine);
1691         return E_FAIL;
1692     }
1693 
1694     hres = IActiveScriptParse_InitNew(parser);
1695     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
1696 
1697     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
1698     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
1699 
1700     hres = IActiveScript_AddNamedItem(engine, testW,
1701             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
1702     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
1703 
1704     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
1705     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
1706 
1707     hres = IActiveScriptParse_ParseScriptText(parser, script_str, NULL, NULL, tmp, 0, 0, 0, NULL, NULL);
1708 
1709     IActiveScript_Release(engine);
1710     IActiveScriptParse_Release(parser);
1711     SysFreeString(tmp);
1712 
1713     return hres;
1714 }
1715 
1716 static void test_IActiveScriptError(IActiveScriptError *error, SCODE errorcode, ULONG line, LONG pos, BSTR script_source, BSTR description, BSTR line_text)
1717 {
1718     HRESULT hres;
1719     DWORD source_context;
1720     ULONG line_number;
1721     LONG char_position;
1722     BSTR linetext;
1723     EXCEPINFO excep;
1724 
1725     /* IActiveScriptError_GetSourcePosition */
1726 
1727     hres = IActiveScriptError_GetSourcePosition(error, NULL, NULL, NULL);
1728     ok(hres == S_OK, "IActiveScriptError_GetSourcePosition -- hres: expected S_OK, got 0x%08x\n", hres);
1729 
1730     source_context = 0xdeadbeef;
1731     hres = IActiveScriptError_GetSourcePosition(error, &source_context, NULL, NULL);
1732     ok(hres == S_OK, "IActiveScriptError_GetSourcePosition -- hres: expected S_OK, got 0x%08x\n", hres);
1733     ok(source_context == 0, "IActiveScriptError_GetSourcePosition -- source_context: expected 0, got 0x%08x\n", source_context);
1734 
1735     line_number = 0xdeadbeef;
1736     hres = IActiveScriptError_GetSourcePosition(error, NULL, &line_number, NULL);
1737     ok(hres == S_OK, "IActiveScriptError_GetSourcePosition -- hres: expected S_OK, got 0x%08x\n", hres);
1738     ok(line_number == line, "IActiveScriptError_GetSourcePosition -- line_number: expected %d, got %d\n", line, line_number);
1739 
1740     char_position = 0xdeadbeef;
1741     hres = IActiveScriptError_GetSourcePosition(error, NULL, NULL, &char_position);
1742     ok(hres == S_OK, "IActiveScriptError_GetSourcePosition -- hres: expected S_OK, got 0x%08x\n", hres);
1743     ok(char_position == pos, "IActiveScriptError_GetSourcePosition -- char_position: expected %d, got %d\n", pos, char_position);
1744 
1745     /* IActiveScriptError_GetSourceLineText */
1746 
1747     hres = IActiveScriptError_GetSourceLineText(error, NULL);
1748     ok(hres == E_POINTER, "IActiveScriptError_GetSourceLineText -- hres: expected E_POINTER, got 0x%08x\n", hres);
1749 
1750     linetext = NULL;
1751     hres = IActiveScriptError_GetSourceLineText(error, &linetext);
1752     if (line_text) {
1753         ok(hres == S_OK, "IActiveScriptError_GetSourceLineText -- hres: expected S_OK, got 0x%08x\n", hres);
1754         ok(linetext != NULL && !lstrcmpW(linetext, line_text),
1755            "IActiveScriptError_GetSourceLineText -- expected %s, got %s\n", wine_dbgstr_w(line_text), wine_dbgstr_w(linetext));
1756     } else {
1757         ok(hres == E_FAIL, "IActiveScriptError_GetSourceLineText -- hres: expected S_OK, got 0x%08x\n", hres);
1758         ok(linetext == NULL,
1759            "IActiveScriptError_GetSourceLineText -- expected NULL, got %s\n", wine_dbgstr_w(linetext));
1760     }
1761     SysFreeString(linetext);
1762 
1763     /* IActiveScriptError_GetExceptionInfo */
1764 
1765     hres = IActiveScriptError_GetExceptionInfo(error, NULL);
1766     ok(hres == E_POINTER, "IActiveScriptError_GetExceptionInfo -- hres: expected E_POINTER, got 0x%08x\n", hres);
1767 
1768     excep.wCode = 0xdead;
1769     excep.wReserved = 0xdead;
1770     excep.bstrSource = (BSTR)0xdeadbeef;
1771     excep.bstrDescription = (BSTR)0xdeadbeef;
1772     excep.bstrHelpFile = (BSTR)0xdeadbeef;
1773     excep.dwHelpContext = 0xdeadbeef;
1774     excep.pvReserved = (void *)0xdeadbeef;
1775     excep.pfnDeferredFillIn = (void *)0xdeadbeef;
1776     excep.scode = 0xdeadbeef;
1777 
1778     hres = IActiveScriptError_GetExceptionInfo(error, &excep);
1779     ok(hres == S_OK, "IActiveScriptError_GetExceptionInfo -- hres: expected S_OK, got 0x%08x\n", hres);
1780 
1781     ok(excep.wCode == 0, "IActiveScriptError_GetExceptionInfo -- excep.wCode: expected 0, got 0x%08x\n", excep.wCode);
1782     ok(excep.wReserved == 0, "IActiveScriptError_GetExceptionInfo -- excep.wReserved: expected 0, got %d\n", excep.wReserved);
1783     if (!is_lang_english())
1784         skip("Non-english UI (test with hardcoded strings)\n");
1785     else {
1786         ok(excep.bstrSource != NULL && !lstrcmpW(excep.bstrSource, script_source),
1787            "IActiveScriptError_GetExceptionInfo -- excep.bstrSource is not valid: expected %s, got %s\n",
1788            wine_dbgstr_w(script_source), wine_dbgstr_w(excep.bstrSource));
1789         ok(excep.bstrDescription != NULL && !lstrcmpW(excep.bstrDescription, description),
1790            "IActiveScriptError_GetExceptionInfo -- excep.bstrDescription is not valid: got %s\n", wine_dbgstr_w(excep.bstrDescription));
1791     }
1792     ok(excep.bstrHelpFile == NULL,
1793        "IActiveScriptError_GetExceptionInfo -- excep.bstrHelpFile: expected NULL, got %s\n", wine_dbgstr_w(excep.bstrHelpFile));
1794     ok(excep.dwHelpContext == 0, "IActiveScriptError_GetExceptionInfo -- excep.dwHelpContext: expected 0, got %d\n", excep.dwHelpContext);
1795     ok(excep.pvReserved == NULL, "IActiveScriptError_GetExceptionInfo -- excep.pvReserved: expected NULL, got %p\n", excep.pvReserved);
1796     ok(excep.pfnDeferredFillIn == NULL, "IActiveScriptError_GetExceptionInfo -- excep.pfnDeferredFillIn: expected NULL, got %p\n", excep.pfnDeferredFillIn);
1797     ok(excep.scode == errorcode, "IActiveScriptError_GetExceptionInfo -- excep.scode: expected 0x%08x, got 0x%08x\n", errorcode, excep.scode);
1798 
1799     SysFreeString(excep.bstrSource);
1800     SysFreeString(excep.bstrDescription);
1801     SysFreeString(excep.bstrHelpFile);
1802 }
1803 
1804 static void parse_script_with_error(DWORD flags, BSTR script_str, SCODE errorcode, ULONG line, LONG pos, BSTR script_source, BSTR description, BSTR line_text)
1805 {
1806     IActiveScriptParse *parser;
1807     IActiveScript *engine;
1808     HRESULT hres;
1809 
1810     engine = create_script();
1811     if(!engine)
1812         return;
1813 
1814     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
1815     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1816     if (FAILED(hres))
1817     {
1818         IActiveScript_Release(engine);
1819         return;
1820     }
1821 
1822     hres = IActiveScriptParse_InitNew(parser);
1823     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
1824 
1825     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite_CheckError);
1826     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
1827 
1828     hres = IActiveScript_AddNamedItem(engine, testW,
1829             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|flags);
1830     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
1831 
1832     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
1833     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
1834 
1835     hres = IActiveScript_GetScriptDispatch(engine, NULL, &script_disp);
1836     ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres);
1837     ok(script_disp != NULL, "script_disp == NULL\n");
1838     ok(script_disp != (IDispatch*)&Global, "script_disp == Global\n");
1839 
1840     script_error = NULL;
1841     SET_EXPECT(ActiveScriptSite_OnScriptError);
1842     hres = IActiveScriptParse_ParseScriptText(parser, script_str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
1843     todo_wine ok(hres == 0x80020101, "parse_script_with_error should have returned 0x80020101, got: 0x%08x\n", hres);
1844     todo_wine CHECK_CALLED(ActiveScriptSite_OnScriptError);
1845 
1846     if (script_error)
1847     {
1848         test_IActiveScriptError(script_error, errorcode, line, pos, script_source, description, line_text);
1849 
1850         IActiveScriptError_Release(script_error);
1851     }
1852 
1853     IDispatch_Release(script_disp);
1854     IActiveScript_Release(engine);
1855     IActiveScriptParse_Release(parser);
1856 }
1857 
1858 static void parse_script_af(DWORD flags, const char *src)
1859 {
1860     BSTR tmp;
1861     HRESULT hres;
1862 
1863     tmp = a2bstr(src);
1864     hres = parse_script(flags, tmp);
1865     SysFreeString(tmp);
1866     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
1867 }
1868 
1869 static void parse_script_a(const char *src)
1870 {
1871     parse_script_af(SCRIPTITEM_GLOBALMEMBERS, src);
1872 }
1873 
1874 static void parse_script_ae(const char *src, HRESULT exhres)
1875 {
1876     BSTR tmp;
1877     HRESULT hres;
1878 
1879     tmp = a2bstr(src);
1880     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, tmp);
1881     SysFreeString(tmp);
1882     ok(hres == exhres, "parse_script failed: %08x, expected %08x\n", hres, exhres);
1883 }
1884 
1885 static void parse_script_with_error_a(const char *src, SCODE errorcode, ULONG line, LONG pos, LPCSTR source, LPCSTR desc, LPCSTR linetext)
1886 {
1887     BSTR tmp, script_source, description, line_text;
1888 
1889     tmp = a2bstr(src);
1890     script_source = a2bstr(source);
1891     description = a2bstr(desc);
1892     line_text = a2bstr(linetext);
1893 
1894     parse_script_with_error(SCRIPTITEM_GLOBALMEMBERS, tmp, errorcode, line, pos, script_source, description, line_text);
1895 
1896     SysFreeString(line_text);
1897     SysFreeString(description);
1898     SysFreeString(script_source);
1899     SysFreeString(tmp);
1900 }
1901 
1902 static HRESULT parse_htmlscript_a(const char *src)
1903 {
1904     HRESULT hres;
1905     BSTR tmp = a2bstr(src);
1906     hres = parse_htmlscript(tmp);
1907     SysFreeString(tmp);
1908 
1909     return hres;
1910 }
1911 
1912 static BSTR get_script_from_file(const char *filename)
1913 {
1914     DWORD size, len;
1915     HANDLE file, map;
1916     const char *file_map;
1917     BSTR ret;
1918 
1919     file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
1920     if(file == INVALID_HANDLE_VALUE) {
1921         trace("Could not open file: %u\n", GetLastError());
1922         return NULL;
1923     }
1924 
1925     size = GetFileSize(file, NULL);
1926 
1927     map = CreateFileMappingW(file, NULL, PAGE_READONLY, 0, 0, NULL);
1928     CloseHandle(file);
1929     if(map == INVALID_HANDLE_VALUE) {
1930         trace("Could not create file mapping: %u\n", GetLastError());
1931         return NULL;
1932     }
1933 
1934     file_map = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
1935     CloseHandle(map);
1936     if(!file_map) {
1937         trace("MapViewOfFile failed: %u\n", GetLastError());
1938         return NULL;
1939     }
1940 
1941     len = MultiByteToWideChar(CP_ACP, 0, file_map, size, NULL, 0);
1942     ret = SysAllocStringLen(NULL, len);
1943     MultiByteToWideChar(CP_ACP, 0, file_map, size, ret, len);
1944 
1945     UnmapViewOfFile(file_map);
1946 
1947     return ret;
1948 }
1949 
1950 static void run_from_file(const char *filename)
1951 {
1952     BSTR script_str;
1953     HRESULT hres;
1954 
1955     script_str = get_script_from_file(filename);
1956     if(!script_str)
1957         return;
1958 
1959     strict_dispid_check = FALSE;
1960     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, script_str);
1961     SysFreeString(script_str);
1962     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
1963 }
1964 
1965 static BSTR load_res(const char *name)
1966 {
1967     const char *data;
1968     DWORD size, len;
1969     BSTR str;
1970     HRSRC src;
1971 
1972     strict_dispid_check = FALSE;
1973     test_name = name;
1974 
1975     src = FindResourceA(NULL, name, (LPCSTR)40);
1976     ok(src != NULL, "Could not find resource %s\n", name);
1977 
1978     size = SizeofResource(NULL, src);
1979     data = LoadResource(NULL, src);
1980 
1981     len = MultiByteToWideChar(CP_ACP, 0, data, size, NULL, 0);
1982     str = SysAllocStringLen(NULL, len);
1983     MultiByteToWideChar(CP_ACP, 0, data, size, str, len);
1984 
1985     return str;
1986 }
1987 
1988 static void run_from_res(const char *name)
1989 {
1990     BSTR str;
1991     HRESULT hres;
1992 
1993     str = load_res(name);
1994 
1995     SET_EXPECT(global_success_d);
1996     SET_EXPECT(global_success_i);
1997     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, str);
1998     CHECK_CALLED(global_success_d);
1999     CHECK_CALLED(global_success_i);
2000 
2001     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
2002     SysFreeString(str);
2003 }
2004 
2005 static void test_isvisible(BOOL global_members)
2006 {
2007     IActiveScriptParse *parser;
2008     IActiveScript *engine;
2009     HRESULT hres;
2010 
2011     static const WCHAR script_textW[] =
2012         {'v','a','r',' ','v',' ','=',' ','t','e','s','t','V','a','l',';',0};
2013 
2014     engine = create_script();
2015     if(!engine)
2016         return;
2017 
2018     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
2019     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
2020     if (FAILED(hres))
2021     {
2022         IActiveScript_Release(engine);
2023         return;
2024     }
2025 
2026     hres = IActiveScriptParse_InitNew(parser);
2027     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
2028 
2029     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
2030     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
2031 
2032     if(global_members)
2033         SET_EXPECT(GetItemInfo_testVal);
2034     hres = IActiveScript_AddNamedItem(engine, test_valW,
2035             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|
2036             (global_members ? SCRIPTITEM_GLOBALMEMBERS : 0));
2037     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
2038     if(global_members)
2039         CHECK_CALLED(GetItemInfo_testVal);
2040 
2041     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
2042     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
2043 
2044     if(!global_members)
2045         SET_EXPECT(GetItemInfo_testVal);
2046     hres = IActiveScriptParse_ParseScriptText(parser, script_textW, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
2047     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2048     if(!global_members)
2049         CHECK_CALLED(GetItemInfo_testVal);
2050 
2051     hres = IActiveScriptParse_ParseScriptText(parser, script_textW, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
2052     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2053 
2054     IActiveScript_Release(engine);
2055     IActiveScriptParse_Release(parser);
2056 }
2057 
2058 static void test_start(void)
2059 {
2060     IActiveScriptParse *parser;
2061     IActiveScript *engine;
2062     BSTR str;
2063     HRESULT hres;
2064 
2065     script_engine = engine = create_script();
2066     if(!engine)
2067         return;
2068 
2069     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
2070     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
2071 
2072     hres = IActiveScriptParse_InitNew(parser);
2073     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
2074 
2075     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
2076     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
2077 
2078     hres = IActiveScript_AddNamedItem(engine, testW, SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
2079     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
2080 
2081     str = a2bstr("ok(getScriptState() === 5, \"getScriptState = \" + getScriptState());\n"
2082                  "reportSuccess();");
2083     hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
2084     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2085     SysFreeString(str);
2086 
2087     SET_EXPECT(global_success_d);
2088     SET_EXPECT(global_success_i);
2089     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
2090     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
2091     CHECK_CALLED(global_success_d);
2092     CHECK_CALLED(global_success_i);
2093 
2094     IActiveScript_Release(engine);
2095     IActiveScriptParse_Release(parser);
2096     script_engine = NULL;
2097 }
2098 
2099 static void test_automagic(void)
2100 {
2101     IActiveScriptParse *parser;
2102     IActiveScript *engine;
2103     BSTR str;
2104     HRESULT hres;
2105 
2106     script_engine = engine = create_script();
2107     if(!engine)
2108         return;
2109 
2110     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
2111     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
2112 
2113     hres = IActiveScriptParse_InitNew(parser);
2114     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
2115 
2116     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
2117     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
2118 
2119     hres = IActiveScript_AddNamedItem(engine, testW, SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
2120     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
2121 
2122     str = a2bstr("function bindEventHandler::eventName() {}\n"
2123                  "reportSuccess();");
2124     hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
2125     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2126     SysFreeString(str);
2127 
2128     SET_EXPECT(BindHandler);
2129     SET_EXPECT(global_success_d);
2130     SET_EXPECT(global_success_i);
2131     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
2132     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
2133     CHECK_CALLED(BindHandler);
2134     CHECK_CALLED(global_success_d);
2135     CHECK_CALLED(global_success_i);
2136 
2137     IActiveScript_Release(engine);
2138     IActiveScriptParse_Release(parser);
2139     script_engine = NULL;
2140 }
2141 
2142 static HRESULT parse_script_expr(const char *expr, VARIANT *res, IActiveScript **engine_ret)
2143 {
2144     IActiveScriptParse *parser;
2145     IActiveScript *engine;
2146     BSTR str;
2147     HRESULT hres;
2148 
2149     engine = create_script();
2150     if(!engine)
2151         return E_FAIL;
2152 
2153     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
2154     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
2155 
2156     hres = IActiveScriptParse_InitNew(parser);
2157     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
2158 
2159     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
2160     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
2161 
2162     SET_EXPECT(GetItemInfo_testVal);
2163     hres = IActiveScript_AddNamedItem(engine, test_valW,
2164             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
2165     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
2166     CHECK_CALLED(GetItemInfo_testVal);
2167 
2168     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
2169     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
2170 
2171     str = a2bstr(expr);
2172     hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, res, NULL);
2173     SysFreeString(str);
2174 
2175     IActiveScriptParse_Release(parser);
2176 
2177     if(engine_ret) {
2178         *engine_ret = engine;
2179     }else {
2180         IActiveScript_Close(engine);
2181         IActiveScript_Release(engine);
2182     }
2183     return hres;
2184 }
2185 
2186 static void test_retval(void)
2187 {
2188     BSTR str = a2bstr("reportSuccess(), true");
2189     IActiveScriptParse *parser;
2190     IActiveScript *engine;
2191     SCRIPTSTATE state;
2192     VARIANT res;
2193     HRESULT hres;
2194 
2195     engine = create_script();
2196     if(!engine)
2197         return;
2198 
2199     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
2200     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
2201 
2202     hres = IActiveScriptParse_InitNew(parser);
2203     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
2204 
2205     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
2206     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
2207 
2208     SET_EXPECT(GetItemInfo_testVal);
2209     hres = IActiveScript_AddNamedItem(engine, test_valW,
2210             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
2211     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
2212     CHECK_CALLED(GetItemInfo_testVal);
2213 
2214     V_VT(&res) = VT_NULL;
2215     SET_EXPECT(global_success_d);
2216     SET_EXPECT(global_success_i);
2217     hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, &res, NULL);
2218     CHECK_CALLED(global_success_d);
2219     CHECK_CALLED(global_success_i);
2220     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2221     ok(V_VT(&res) == VT_EMPTY, "V_VT(&res) = %d\n", V_VT(&res));
2222 
2223     hres = IActiveScript_GetScriptState(engine, &state);
2224     ok(hres == S_OK, "GetScriptState failed: %08x\n", hres);
2225     ok(state == SCRIPTSTATE_INITIALIZED, "state = %d\n", state);
2226 
2227     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
2228     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
2229 
2230     hres = IActiveScript_Close(engine);
2231     ok(hres == S_OK, "Close failed: %08x\n", hres);
2232 
2233     IActiveScriptParse_Release(parser);
2234     IActiveScript_Release(engine);
2235     SysFreeString(str);
2236 }
2237 
2238 static void test_default_value(void)
2239 {
2240     DISPPARAMS dp = {0};
2241     IDispatch *disp;
2242     VARIANT v;
2243     HRESULT hres;
2244 
2245     hres = parse_script_expr("new Date()", &v, NULL);
2246     ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
2247     ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v));
2248     disp = V_DISPATCH(&v);
2249 
2250     V_VT(&v) = VT_EMPTY;
2251     hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL);
2252     ok(hres == S_OK || broken(hres == 0x8000ffff), "Invoke failed: %08x\n", hres);
2253     if(hres == S_OK)
2254     {
2255         ok(V_VT(&v) == VT_BSTR, "V_VT(v) = %d\n", V_VT(&v));
2256     }
2257 
2258     VariantClear(&v);
2259     IDispatch_Release(disp);
2260 }
2261 
2262 static void test_script_exprs(void)
2263 {
2264     VARIANT v;
2265     HRESULT hres;
2266 
2267     testing_expr = TRUE;
2268 
2269     hres = parse_script_expr("true", &v, NULL);
2270     ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
2271     ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
2272     ok(V_BOOL(&v) == VARIANT_TRUE, "V_BOOL(v) = %x\n", V_BOOL(&v));
2273 
2274     hres = parse_script_expr("false, true", &v, NULL);
2275     ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
2276     ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
2277     ok(V_BOOL(&v) == VARIANT_TRUE, "V_BOOL(v) = %x\n", V_BOOL(&v));
2278 
2279     SET_EXPECT(global_success_d);
2280     SET_EXPECT(global_success_i);
2281     hres = parse_script_expr("reportSuccess(); true", &v, NULL);
2282     ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
2283     ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
2284     ok(V_BOOL(&v) == VARIANT_TRUE, "V_BOOL(v) = %x\n", V_BOOL(&v));
2285     CHECK_CALLED(global_success_d);
2286     CHECK_CALLED(global_success_i);
2287 
2288     hres = parse_script_expr("if(false) true", &v, NULL);
2289     ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
2290     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
2291 
2292     hres = parse_script_expr("return testPropGet", &v, NULL);
2293     ok(hres == 0x800a03fa, "parse_script_expr failed: %08x\n", hres);
2294 
2295     hres = parse_script_expr("reportSuccess(); return true", &v, NULL);
2296     ok(hres == 0x800a03fa, "parse_script_expr failed: %08x\n", hres);
2297 
2298     SET_EXPECT(global_success_d);
2299     SET_EXPECT(global_success_i);
2300     hres = parse_script_expr("reportSuccess(); true", NULL, NULL);
2301     ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
2302     CHECK_CALLED(global_success_d);
2303     CHECK_CALLED(global_success_i);
2304 
2305     test_default_value();
2306     test_retval();
2307 
2308     testing_expr = FALSE;
2309 }
2310 
2311 static void test_invokeex(void)
2312 {
2313     DISPID func_id, prop_id;
2314     DISPPARAMS dp = {NULL};
2315     IActiveScript *script;
2316     IDispatchEx *dispex;
2317     VARIANT v;
2318     BSTR str;
2319     HRESULT hres;
2320 
2321     hres = parse_script_expr("var o = {func: function() {return 3;}, prop: 6}; o", &v, &script);
2322     ok(hres == S_OK, "parse_script_expr failed: %08x\n", hres);
2323     ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v));
2324 
2325     hres = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IDispatchEx, (void**)&dispex);
2326     ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
2327     VariantClear(&v);
2328 
2329     str = a2bstr("func");
2330     hres = IDispatchEx_GetDispID(dispex, str, 0, &func_id);
2331     SysFreeString(str);
2332     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
2333 
2334     str = a2bstr("prop");
2335     hres = IDispatchEx_GetDispID(dispex, str, 0, &prop_id);
2336     SysFreeString(str);
2337     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
2338 
2339     hres = IDispatchEx_InvokeEx(dispex, func_id, 0, DISPATCH_METHOD, &dp, &v, NULL, NULL);
2340     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2341     ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
2342     ok(V_I4(&v) == 3, "V_I4(v) = %d\n", V_I4(&v));
2343 
2344     hres = IDispatchEx_InvokeEx(dispex, prop_id, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL);
2345     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2346     ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
2347     ok(V_I4(&v) == 6, "V_I4(v) = %d\n", V_I4(&v));
2348 
2349     hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_UNINITIALIZED);
2350     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
2351 
2352     str = a2bstr("func");
2353     hres = IDispatchEx_GetDispID(dispex, str, 0, &func_id);
2354     SysFreeString(str);
2355     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
2356 
2357     hres = IDispatchEx_InvokeEx(dispex, func_id, 0, DISPATCH_METHOD, &dp, &v, NULL, NULL);
2358     ok(hres == E_UNEXPECTED || broken(hres == 0x800a1393), "InvokeEx failed: %08x\n", hres);
2359 
2360     hres = IDispatchEx_InvokeEx(dispex, prop_id, 0, DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL);
2361     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2362     ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
2363     ok(V_I4(&v) == 6, "V_I4(v) = %d\n", V_I4(&v));
2364 
2365     IDispatchEx_Release(dispex);
2366     IActiveScript_Release(script);
2367 }
2368 
2369 struct bom_test
2370 {
2371     WCHAR str[1024];
2372     HRESULT hres;
2373 };
2374 
2375 static void run_bom_tests(void)
2376 {
2377     BSTR src;
2378     int i;
2379     HRESULT hres;
2380     struct bom_test bom_tests[] = {
2381         {{'v','a','r',' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',')',';','\0'}, S_OK},
2382         {{0xFEFF,'v','a','r',' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',')',';','\0'}, S_OK},
2383         {{'v',0xFEFF,'a','r',' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',')',';','\0'}, JS_E_OUT_OF_MEMORY},
2384         {{'v','a','r',0xFEFF,' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',')',';','\0'}, S_OK},
2385         {{'v','a','r',' ','a',' ','=',' ','1',';',' ',0xFEFF,'r','e','p','o','r','t','S','u','c','c','e','s','s','(',')',';','\0'}, S_OK},
2386         {{'v','a','r',' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t',0xFEFF,'S','u','c','c','e','s','s','(',')',';','\0'}, JS_E_OUT_OF_MEMORY},
2387         {{'v','a','r',' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s',0xFEFF,'(',')',';','\0'}, S_OK},
2388         {{'v','a','r',' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',0xFEFF,')',';','\0'}, S_OK},
2389         {{'v','a','r',' ','a',' ','=',0xFEFF,' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',0xFEFF,')',';','\0'}, S_OK},
2390         {{0xFEFF,'v','a','r',' ','a',' ','=',0xFEFF,0xFEFF,' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',0xFEFF,')',';','\0'}, S_OK},
2391         {{0}}
2392     };
2393 
2394     engine_clsid = &CLSID_JScript;
2395 
2396     for (i = 0; bom_tests[i].str[0]; i++)
2397     {
2398         if(bom_tests[i].hres == S_OK)
2399         {
2400              SET_EXPECT(global_success_d);
2401              SET_EXPECT(global_success_i);
2402              src = SysAllocString(bom_tests[i].str);
2403              hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
2404              ok(hres == S_OK, "test %s failed with %08x\n", wine_dbgstr_w(src), hres);
2405              SysFreeString(src);
2406              CHECK_CALLED(global_success_d);
2407              CHECK_CALLED(global_success_i);
2408         }
2409         else
2410         {
2411              src = SysAllocString(bom_tests[i].str);
2412              hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
2413              todo_wine ok(hres == bom_tests[i].hres, "test %s returned with %08x\n", wine_dbgstr_w(src), hres);
2414              SysFreeString(src);
2415         }
2416     }
2417 }
2418 
2419 static BOOL run_tests(void)
2420 {
2421     HRESULT hres;
2422 
2423     if(invoke_version) {
2424         IActiveScript *script;
2425 
2426         script = create_script();
2427         if(!script) {
2428             win_skip("Could not create script\n");
2429             return FALSE;
2430         }
2431         IActiveScript_Release(script);
2432     }
2433 
2434     strict_dispid_check = TRUE;
2435 
2436     parse_script_a("");
2437     parse_script_a("/* empty */ ;");
2438 
2439     SET_EXPECT(global_propget_d);
2440     SET_EXPECT(global_propget_i);
2441     parse_script_a("testPropGet;");
2442     CHECK_CALLED(global_propget_d);
2443     CHECK_CALLED(global_propget_i);
2444 
2445     SET_EXPECT(global_propput_d);
2446     SET_EXPECT(global_propput_i);
2447     parse_script_a("testPropPut = 1;");
2448     CHECK_CALLED(global_propput_d);
2449     CHECK_CALLED(global_propput_i);
2450 
2451     SET_EXPECT(global_propputref_d);
2452     SET_EXPECT(global_propputref_i);
2453     parse_script_a("testPropPutRef = new Object();");
2454     CHECK_CALLED(global_propputref_d);
2455     CHECK_CALLED(global_propputref_i);
2456 
2457     SET_EXPECT(global_propputref_d);
2458     SET_EXPECT(global_propputref_i);
2459     parse_script_a("testPropPutRef = testObj;");
2460     CHECK_CALLED(global_propputref_d);
2461     CHECK_CALLED(global_propputref_i);
2462 
2463     SET_EXPECT(global_success_d);
2464     SET_EXPECT(global_success_i);
2465     parse_script_a("reportSuccess();");
2466     CHECK_CALLED(global_success_d);
2467     CHECK_CALLED(global_success_i);
2468 
2469     SET_EXPECT(testobj_delete_test);
2470     parse_script_a("ok((delete testObj.deleteTest) === true, 'delete testObj.deleteTest did not return true');");
2471     CHECK_CALLED(testobj_delete_test);
2472 
2473     SET_EXPECT(testobj_delete_nodelete);
2474     parse_script_a("ok((delete testObj.noDeleteTest) === false, 'delete testObj.noDeleteTest did not return false');");
2475     CHECK_CALLED(testobj_delete_nodelete);
2476 
2477     SET_EXPECT(global_propdelete_d);
2478     SET_EXPECT(DeleteMemberByDispID);
2479     parse_script_a("ok((delete testPropDelete) === true, 'delete testPropDelete did not return true');");
2480     CHECK_CALLED(global_propdelete_d);
2481     CHECK_CALLED(DeleteMemberByDispID);
2482 
2483     SET_EXPECT(global_nopropdelete_d);
2484     SET_EXPECT(DeleteMemberByDispID_false);
2485     parse_script_a("ok((delete testNoPropDelete) === false, 'delete testPropDelete did not return false');");
2486     CHECK_CALLED(global_nopropdelete_d);
2487     CHECK_CALLED(DeleteMemberByDispID_false);
2488 
2489     SET_EXPECT(global_propdeleteerror_d);
2490     SET_EXPECT(DeleteMemberByDispID_error);
2491     parse_script_ae("delete testPropDeleteError;", E_FAIL);
2492     CHECK_CALLED(global_propdeleteerror_d);
2493     CHECK_CALLED(DeleteMemberByDispID_error);
2494 
2495     SET_EXPECT(puredisp_prop_d);
2496     parse_script_a("ok((delete pureDisp.prop) === false, 'delete pureDisp.prop did not return true');");
2497     CHECK_CALLED(puredisp_prop_d);
2498 
2499     SET_EXPECT(puredisp_noprop_d);
2500     parse_script_a("ok((delete pureDisp.noprop) === true, 'delete pureDisp.noprop did not return false');");
2501     CHECK_CALLED(puredisp_noprop_d);
2502 
2503     SET_EXPECT(puredisp_value);
2504     parse_script_a("var t=pureDisp; t=t(false);");
2505     CHECK_CALLED(puredisp_value);
2506 
2507     SET_EXPECT(puredisp_value);
2508     parse_script_a("var t = {func: pureDisp}; t = t.func(false);");
2509     CHECK_CALLED(puredisp_value);
2510 
2511     SET_EXPECT(dispexfunc_value);
2512     parse_script_a("var t = dispexFunc; t = t(false);");
2513     CHECK_CALLED(dispexfunc_value);
2514 
2515     SET_EXPECT(dispexfunc_value);
2516     parse_script_a("var t = {func: dispexFunc}; t = t.func(false);");
2517     CHECK_CALLED(dispexfunc_value);
2518 
2519     SET_EXPECT(dispexfunc_value);
2520     parse_script_a("Function.prototype.apply.call(dispexFunc, testObj, [true]);");
2521     CHECK_CALLED(dispexfunc_value);
2522 
2523     SET_EXPECT(puredisp_value);
2524     parse_script_a("Function.prototype.apply.call(pureDisp, testObj, [true]);");
2525     CHECK_CALLED(puredisp_value);
2526 
2527     parse_script_a("(function reportSuccess() {})()");
2528 
2529     parse_script_a("ok(typeof(test) === 'object', \"typeof(test) != 'object'\");");
2530 
2531     parse_script_a("function reportSuccess() {}; reportSuccess();");
2532 
2533     SET_EXPECT(global_propget_d);
2534     parse_script_a("var testPropGet");
2535     CHECK_CALLED(global_propget_d);
2536 
2537     SET_EXPECT(global_propget_d);
2538     parse_script_a("eval('var testPropGet;');");
2539     CHECK_CALLED(global_propget_d);
2540 
2541     parse_script_a("var testPropGet; function testPropGet() {}");
2542 
2543     SET_EXPECT(global_notexists_d);
2544     parse_script_a("var notExists; notExists = 1;");
2545     CHECK_CALLED(global_notexists_d);
2546 
2547     SET_EXPECT(testobj_notexists_d);
2548     parse_script_a("testObj.notExists;");
2549     CHECK_CALLED(testobj_notexists_d);
2550 
2551     parse_script_a("function f() { var testPropGet; }");
2552     parse_script_a("(function () { var testPropGet; })();");
2553     parse_script_a("(function () { eval('var testPropGet;'); })();");
2554 
2555     SET_EXPECT(invoke_func);
2556     parse_script_a("ok(propGetFunc() == 0, \"Incorrect propGetFunc value\");");
2557     CHECK_CALLED(invoke_func);
2558     parse_script_a("ok(propGetFunc(1) == 1, \"Incorrect propGetFunc value\");");
2559     parse_script_a("ok(propGetFunc(1, 2) == 2, \"Incorrect propGetFunc value\");");
2560     SET_EXPECT(invoke_func);
2561     parse_script_a("ok(propGetFunc().toString() == 0, \"Incorrect propGetFunc value\");");
2562     CHECK_CALLED(invoke_func);
2563     parse_script_a("ok(propGetFunc(1).toString() == 1, \"Incorrect propGetFunc value\");");
2564     SET_EXPECT(invoke_func);
2565     parse_script_a("propGetFunc(1);");
2566     CHECK_CALLED(invoke_func);
2567 
2568     parse_script_a("objectFlag(1).toString();");
2569 
2570     parse_script_a("(function() { var tmp = (function () { return testObj; })()(1);})();");
2571     parse_script_a("(function() { var tmp = (function () { return testObj; })()();})();");
2572 
2573     parse_script_a("ok((testObj instanceof Object) === false, 'testObj is instance of Object');");
2574 
2575     SET_EXPECT(testobj_prop_d);
2576     parse_script_a("ok(('prop' in testObj) === true, 'prop is not in testObj');");
2577     CHECK_CALLED(testobj_prop_d);
2578 
2579     SET_EXPECT(testobj_noprop_d);
2580     parse_script_a("ok(('noprop' in testObj) === false, 'noprop is in testObj');");
2581     CHECK_CALLED(testobj_noprop_d);
2582 
2583     SET_EXPECT(testobj_prop_d);
2584     parse_script_a("ok(Object.prototype.hasOwnProperty.call(testObj, 'prop') === true, 'hasOwnProperty(\\\"prop\\\") returned false');");
2585     CHECK_CALLED(testobj_prop_d);
2586 
2587     SET_EXPECT(testobj_noprop_d);
2588     parse_script_a("ok(Object.prototype.hasOwnProperty.call(testObj, 'noprop') === false, 'hasOwnProperty(\\\"noprop\\\") returned true');");
2589     CHECK_CALLED(testobj_noprop_d);
2590 
2591     SET_EXPECT(puredisp_prop_d);
2592     parse_script_a("ok(Object.prototype.hasOwnProperty.call(pureDisp, 'prop') === true, 'hasOwnProperty(\\\"noprop\\\") returned false');");
2593     CHECK_CALLED(puredisp_prop_d);
2594 
2595     SET_EXPECT(puredisp_noprop_d);
2596     parse_script_a("ok(Object.prototype.hasOwnProperty.call(pureDisp, 'noprop') === false, 'hasOwnProperty(\\\"noprop\\\") returned true');");
2597     CHECK_CALLED(puredisp_noprop_d);
2598 
2599     SET_EXPECT(testobj_value);
2600     parse_script_a("ok(String(testObj) === '1', 'wrong testObj value');");
2601     CHECK_CALLED(testobj_value);
2602 
2603     SET_EXPECT(testobj_value);
2604     parse_script_a("ok(String.prototype.concat.call(testObj, ' OK') === '1 OK', 'wrong concat result');");
2605     CHECK_CALLED(testobj_value);
2606 
2607     SET_EXPECT(testobj_construct);
2608     parse_script_a("var t = new testObj(1);");
2609     CHECK_CALLED(testobj_construct);
2610 
2611     SET_EXPECT(global_propget_d);
2612     SET_EXPECT(global_propget_i);
2613     parse_script_a("this.testPropGet;");
2614     CHECK_CALLED(global_propget_d);
2615     CHECK_CALLED(global_propget_i);
2616 
2617     SET_EXPECT(global_propputref_d);
2618     SET_EXPECT(global_propputref_i);
2619     parse_script_a("testPropPutRef = nullDisp;");
2620     CHECK_CALLED(global_propputref_d);
2621     CHECK_CALLED(global_propputref_i);
2622 
2623     SET_EXPECT(global_propget_d);
2624     SET_EXPECT(global_propget_i);
2625     parse_script_a("(function () { this.testPropGet; })();");
2626     CHECK_CALLED(global_propget_d);
2627     CHECK_CALLED(global_propget_i);
2628 
2629     parse_script_a("testThis(this);");
2630     parse_script_a("(function () { testThis(this); })();");
2631     parse_script_a("function x() { testThis(this); }; x();");
2632     parse_script_a("var t = {func: function () { ok(this === t, 'this !== t'); }}; with(t) { func(); }");
2633     parse_script_a("function x() { testThis(this); }; with({y: 1}) { x(); }");
2634     parse_script_a("(function () { function x() { testThis(this);} x(); })();");
2635 
2636     SET_EXPECT(testobj_onlydispid_d);
2637     SET_EXPECT(testobj_onlydispid_i);
2638     parse_script_a("ok(typeof(testObj.onlyDispID) === 'unknown', 'unexpected typeof(testObj.onlyDispID)');");
2639     CHECK_CALLED(testobj_onlydispid_d);
2640     CHECK_CALLED(testobj_onlydispid_i);
2641 
2642     SET_EXPECT(global_propargput_d);
2643     SET_EXPECT(global_propargput_i);
2644     parse_script_a("var t=0; propArgPutG(t++, t++) = t++;");
2645     CHECK_CALLED(global_propargput_d);
2646     CHECK_CALLED(global_propargput_i);
2647 
2648     SET_EXPECT(global_propargput_d);
2649     SET_EXPECT(global_propargput_i);
2650     parse_script_a("var t=0; test.propArgPutO(t++, t++) = t++;");
2651     CHECK_CALLED(global_propargput_d);
2652     CHECK_CALLED(global_propargput_i);
2653 
2654     SET_EXPECT(global_testargtypes_i);
2655     parse_script_a("testArgTypes(dispUnk, intProp(), intProp, getShort(), shortProp,"
2656                    "function(ui2,r4,i4ref,ui4,nullunk,d,i,s) {"
2657                    "    ok(getVT(i) === 'VT_I4', 'getVT(i) = ' + getVT(i));"
2658                    "    ok(getVT(s) === 'VT_I4', 'getVT(s) = ' + getVT(s));"
2659                    "    ok(getVT(d) === 'VT_DISPATCH', 'getVT(d) = ' + getVT(d));"
2660                    "    ok(getVT(nullunk) === 'VT_DISPATCH', 'getVT(nullunk) = ' + getVT(nullunk));"
2661                    "    ok(nullunk === null, 'nullunk !== null');"
2662                    "    ok(getVT(ui4) === 'VT_R8', 'getVT(ui4) = ' + getVT(ui4));"
2663                    "    ok(ui4 > 0, 'ui4 = ' + ui4);"
2664                    "    ok(getVT(i4ref) === 'VT_I4', 'getVT(i4ref) = ' + getVT(i4ref));"
2665                    "    ok(i4ref === 2, 'i4ref = ' + i4ref);"
2666                    "    ok(r4 === 0.5, 'r4 = ' + r4);"
2667                    "    ok(getVT(r4) === 'VT_R8', 'getVT(r4) = ' + getVT(r4));"
2668                    "    ok(getVT(ui2) === 'VT_I4', 'getVT(ui2) = ' + getVT(ui2));"
2669                    "});");
2670     CHECK_CALLED(global_testargtypes_i);
2671 
2672     SET_EXPECT(testobj_withprop_d);
2673     SET_EXPECT(testobj_withprop_i);
2674     parse_script_a("var t = (function () { with(testObj) { return withProp; }})(); ok(t === 1, 't = ' + t);");
2675     CHECK_CALLED(testobj_withprop_d);
2676     CHECK_CALLED(testobj_withprop_i);
2677 
2678     parse_script_a("@set @t=2\nok(@t === 2, '@t = ' + @t);");
2679 
2680     SET_EXPECT(global_success_d);
2681     SET_EXPECT(global_success_i);
2682     parse_script_a("@if(true)\nif(@_jscript) reportSuccess();\n@end");
2683     CHECK_CALLED(global_success_d);
2684     CHECK_CALLED(global_success_i);
2685 
2686     run_from_res("lang.js");
2687     run_from_res("api.js");
2688     run_from_res("regexp.js");
2689     run_from_res("cc.js");
2690 
2691     test_isvisible(FALSE);
2692     test_isvisible(TRUE);
2693     test_start();
2694     test_automagic();
2695 
2696     parse_script_af(0, "test.testThis2(this);");
2697     parse_script_af(0, "(function () { test.testThis2(this); })();");
2698 
2699     hres = parse_htmlscript_a("<!--");
2700     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2701     hres = parse_htmlscript_a("-->");
2702     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2703     hres = parse_htmlscript_a("<!--\nvar a=1;\n-->\n");
2704     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2705     hres = parse_htmlscript_a("<!--\n<!-- ignore this\n-->\n");
2706     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2707     hres = parse_htmlscript_a("var a=1;\nif(a-->0) a=5;\n");
2708     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2709     hres = parse_htmlscript_a("var a=1;\nif(a\n-->0) a=5;\n");
2710     ok(hres != S_OK, "ParseScriptText have not failed\n");
2711 
2712     test_script_exprs();
2713     test_invokeex();
2714 
2715     parse_script_with_error_a(
2716         "?",
2717         0x800a03ea, 0, 0,
2718         "Microsoft JScript compilation error",
2719         "Syntax error",
2720         "?");
2721 
2722     parse_script_with_error_a(
2723         "var a=1;\nif(a\n-->0) a=5;\n",
2724         0x800a03ee, 2, 0,
2725         "Microsoft JScript compilation error",
2726         "Expected ')'",
2727         "-->0) a=5;");
2728 
2729     parse_script_with_error_a(
2730         "new 3;",
2731         0x800a01bd, 0, 0,
2732         "Microsoft JScript runtime error",
2733         "Object doesn't support this action",
2734         NULL);
2735 
2736     parse_script_with_error_a(
2737         "new null;",
2738         0x800a138f, 0, 0,
2739         "Microsoft JScript runtime error",
2740         "Object expected",
2741         NULL);
2742 
2743     parse_script_with_error_a(
2744         "var a;\nnew null;",
2745         0x800a138f, 1, 0,
2746         "Microsoft JScript runtime error",
2747         "Object expected",
2748         NULL);
2749 
2750     parse_script_with_error_a(
2751         "var a; new null;",
2752         0x800a138f, 0, 7,
2753         "Microsoft JScript runtime error",
2754         "Object expected",
2755         NULL);
2756 
2757     run_bom_tests();
2758 
2759     return TRUE;
2760 }
2761 
2762 static void test_parse_proc(void)
2763 {
2764     VARIANT args[2];
2765     DISPPARAMS dp = {args};
2766 
2767     dp.cArgs = 0;
2768     invoke_procedure(NULL, "return true;", &dp);
2769 
2770     dp.cArgs = 1;
2771     V_VT(args) = VT_EMPTY;
2772     invoke_procedure(NULL, "return arguments.length == 1;", &dp);
2773 
2774     V_VT(args) = VT_BOOL;
2775     V_BOOL(args) = VARIANT_TRUE;
2776     invoke_procedure(" x ", "return x;", &dp);
2777 
2778     dp.cArgs = 2;
2779     V_VT(args) = VT_I4;
2780     V_I4(args) = 2;
2781     V_VT(args+1) = VT_I4;
2782     V_I4(args+1) = 1;
2783     invoke_procedure(" _x1 , y_2", "return _x1 === 1 && y_2 === 2;", &dp);
2784 }
2785 
2786 static void run_encoded_tests(void)
2787 {
2788     BSTR src;
2789     HRESULT hres;
2790 
2791     engine_clsid = &CLSID_JScriptEncode;
2792 
2793     SET_EXPECT(global_success_d);
2794     SET_EXPECT(global_success_i);
2795     /*             |reportSuccess();                           | */
2796     parse_script_a("#@~^EAAAAA==.\x7fwGMYUEm1+kd`*iAQYAAA==^#~@");
2797     CHECK_CALLED(global_success_d);
2798     CHECK_CALLED(global_success_i);
2799 
2800     SET_EXPECT(global_success_d);
2801     SET_EXPECT(global_success_i);
2802     parse_script_a("reportSuccess();");
2803     CHECK_CALLED(global_success_d);
2804     CHECK_CALLED(global_success_i);
2805 
2806     SET_EXPECT(global_success_d);
2807     SET_EXPECT(global_success_i);
2808     /*                   |Success                         | */
2809     parse_script_a("report#@~^BwAAAA==j!m^\x7f/k2QIAAA==^#~@();");
2810     CHECK_CALLED(global_success_d);
2811     CHECK_CALLED(global_success_i);
2812 
2813     SET_EXPECT(global_success_d);
2814     SET_EXPECT(global_success_i);
2815     /*             |\r\n\treportSuccess();\r\n                        | */
2816     parse_script_a("#@~^GQAAAA==@#@&d.\x7fwKDYUE1^+k/c#p@#@&OAYAAA==^#~@");
2817     CHECK_CALLED(global_success_d);
2818     CHECK_CALLED(global_success_i);
2819 
2820     /*                   v                                   */
2821     src = a2bstr("#@~^EAA*AA==.\x7fwGMYUEm1+kd`*iAQYAAA==^#~@");
2822     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
2823     SysFreeString(src);
2824     ok(hres == JS_E_INVALID_CHAR, "parse_script failed %08x\n", hres);
2825 
2826     /*                      vv                                 */
2827     src = a2bstr("#@~^EAAAAAAA==.\x7fwGMYUEm1+kd`*iAQYAAA==^#~@");
2828     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
2829     SysFreeString(src);
2830     ok(hres == JS_E_INVALID_CHAR, "parse_script failed %08x\n", hres);
2831 
2832     /*                      v                                */
2833     src = a2bstr("#@~^EAAAAA^=.\x7fwGMYUEm1+kd`*iAQYAAA==^#~@");
2834     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
2835     SysFreeString(src);
2836     ok(hres == JS_E_INVALID_CHAR, "parse_script failed %08x\n", hres);
2837 
2838     /*                                     v                 */
2839     src = a2bstr("#@~^EAAAAA==.\x7fwGMYUEm1ekd`*iAQYAAA==^#~@");
2840     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
2841     SysFreeString(src);
2842     ok(hres == JS_E_INVALID_CHAR, "parse_script failed %08x\n", hres);
2843 
2844     /*                                                    vv  */
2845     src = a2bstr("#@~^EAAAAA==.\x7fwGMYUEm1+kd`*iAQYAAA==^~#@");
2846     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
2847     SysFreeString(src);
2848     ok(hres == JS_E_INVALID_CHAR, "parse_script failed %08x\n", hres);
2849 }
2850 
2851 static void run_benchmark(const char *script_name)
2852 {
2853     IActiveScriptParse *parser;
2854     IActiveScript *engine;
2855     ULONG start, end;
2856     BSTR src;
2857     HRESULT hres;
2858 
2859     engine = create_script();
2860     if(!engine)
2861         return;
2862 
2863     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
2864     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
2865     if (FAILED(hres)) {
2866         IActiveScript_Release(engine);
2867         return;
2868     }
2869 
2870     hres = IActiveScriptParse_InitNew(parser);
2871     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
2872 
2873     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
2874     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
2875 
2876     hres = IActiveScript_AddNamedItem(engine, testW,
2877             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE);
2878     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
2879 
2880     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
2881     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
2882 
2883     src = load_res(script_name);
2884 
2885     start = GetTickCount();
2886     hres = IActiveScriptParse_ParseScriptText(parser, src, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
2887     end = GetTickCount();
2888     ok(hres == S_OK, "%s: ParseScriptText failed: %08x\n", script_name, hres);
2889 
2890     trace("%s ran in %u ms\n", script_name, end-start);
2891 
2892     IActiveScript_Release(engine);
2893     IActiveScriptParse_Release(parser);
2894     SysFreeString(src);
2895 }
2896 
2897 static void run_benchmarks(void)
2898 {
2899     trace("Running benchmarks...\n");
2900 
2901     run_benchmark("dna.js");
2902     run_benchmark("base64.js");
2903     run_benchmark("validateinput.js");
2904 }
2905 
2906 static BOOL check_jscript(void)
2907 {
2908     IActiveScriptProperty *script_prop;
2909     BSTR str;
2910     HRESULT hres;
2911 
2912     hres = CoCreateInstance(&CLSID_JScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2913             &IID_IActiveScriptProperty, (void**)&script_prop);
2914     if(FAILED(hres))
2915         return FALSE;
2916     IActiveScriptProperty_Release(script_prop);
2917 
2918     str = a2bstr("if(!('localeCompare' in String.prototype)) throw 1;");
2919     hres = parse_script(0, str);
2920     SysFreeString(str);
2921 
2922     return hres == S_OK;
2923 }
2924 
2925 START_TEST(run)
2926 {
2927     int argc;
2928     char **argv;
2929 
2930     argc = winetest_get_mainargs(&argv);
2931 
2932     CoInitialize(NULL);
2933 
2934     if(!check_jscript()) {
2935         win_skip("Broken engine, probably too old\n");
2936     }else if(argc > 2) {
2937         invoke_version = 2;
2938         run_from_file(argv[2]);
2939     }else {
2940         trace("invoke version 0\n");
2941         invoke_version = 0;
2942         run_tests();
2943 
2944         trace("invoke version 2\n");
2945         invoke_version = 2;
2946         if(run_tests()) {
2947             trace("JSctipt.Encode tests...\n");
2948             run_encoded_tests();
2949             trace("ParseProcedureText tests...\n");
2950             test_parse_proc();
2951         }
2952 
2953         if(winetest_interactive)
2954             run_benchmarks();
2955     }
2956 
2957     CoUninitialize();
2958 }
2959