jscript: Better handling of to_integer result in String.lastIndexOf.
[wine] / dlls / jscript / tests / run.c
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 static const CLSID CLSID_JScript =
31     {0xf414c260,0x6ac0,0x11cf,{0xb6,0xd1,0x00,0xaa,0x00,0xbb,0xbb,0x58}};
32 static const CLSID CLSID_JScriptEncode =
33     {0xf414c262,0x6ac0,0x11cf,{0xb6,0xd1,0x00,0xaa,0x00,0xbb,0xbb,0x58}};
34
35 #define DEFINE_EXPECT(func) \
36     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
37
38 #define SET_EXPECT(func) \
39     expect_ ## func = TRUE
40
41 #define CHECK_EXPECT2(func) \
42     do { \
43         ok(expect_ ##func, "unexpected call " #func "\n"); \
44         called_ ## func = TRUE; \
45     }while(0)
46
47 #define CHECK_EXPECT(func) \
48     do { \
49         CHECK_EXPECT2(func); \
50         expect_ ## func = FALSE; \
51     }while(0)
52
53 #define CHECK_CALLED(func) \
54     do { \
55         ok(called_ ## func, "expected " #func "\n"); \
56         expect_ ## func = called_ ## func = FALSE; \
57     }while(0)
58
59 DEFINE_EXPECT(global_propget_d);
60 DEFINE_EXPECT(global_propget_i);
61 DEFINE_EXPECT(global_propput_d);
62 DEFINE_EXPECT(global_propput_i);
63 DEFINE_EXPECT(global_propdelete_d);
64 DEFINE_EXPECT(global_success_d);
65 DEFINE_EXPECT(global_success_i);
66 DEFINE_EXPECT(global_notexists_d);
67 DEFINE_EXPECT(global_propargput_d);
68 DEFINE_EXPECT(global_propargput_i);
69 DEFINE_EXPECT(global_testargtypes_i);
70 DEFINE_EXPECT(puredisp_prop_d);
71 DEFINE_EXPECT(puredisp_noprop_d);
72 DEFINE_EXPECT(testobj_delete);
73 DEFINE_EXPECT(testobj_value);
74 DEFINE_EXPECT(testobj_prop_d);
75 DEFINE_EXPECT(testobj_noprop_d);
76 DEFINE_EXPECT(testobj_onlydispid_d);
77 DEFINE_EXPECT(testobj_onlydispid_i);
78 DEFINE_EXPECT(GetItemInfo_testVal);
79 DEFINE_EXPECT(ActiveScriptSite_OnScriptError);
80 DEFINE_EXPECT(invoke_func);
81 DEFINE_EXPECT(DeleteMemberByDispID);
82
83 #define DISPID_GLOBAL_TESTPROPGET   0x1000
84 #define DISPID_GLOBAL_TESTPROPPUT   0x1001
85 #define DISPID_GLOBAL_REPORTSUCCESS 0x1002
86 #define DISPID_GLOBAL_TRACE         0x1003
87 #define DISPID_GLOBAL_OK            0x1004
88 #define DISPID_GLOBAL_GETVT         0x1005
89 #define DISPID_GLOBAL_TESTOBJ       0x1006
90 #define DISPID_GLOBAL_GETNULLBSTR   0x1007
91 #define DISPID_GLOBAL_NULL_DISP     0x1008
92 #define DISPID_GLOBAL_TESTTHIS      0x1009
93 #define DISPID_GLOBAL_TESTTHIS2     0x100a
94 #define DISPID_GLOBAL_INVOKEVERSION 0x100b
95 #define DISPID_GLOBAL_CREATEARRAY   0x100c
96 #define DISPID_GLOBAL_PROPGETFUNC   0x100d
97 #define DISPID_GLOBAL_OBJECT_FLAG   0x100e
98 #define DISPID_GLOBAL_ISWIN64       0x100f
99 #define DISPID_GLOBAL_PUREDISP      0x1010
100 #define DISPID_GLOBAL_TESTPROPDELETE  0x1010
101 #define DISPID_GLOBAL_ISNULLBSTR    0x1011
102 #define DISPID_GLOBAL_PROPARGPUT    0x1012
103 #define DISPID_GLOBAL_SHORTPROP     0x1013
104 #define DISPID_GLOBAL_GETSHORT      0x1014
105 #define DISPID_GLOBAL_TESTARGTYPES  0x1015
106
107 #define DISPID_TESTOBJ_PROP         0x2000
108 #define DISPID_TESTOBJ_ONLYDISPID   0x2001
109
110 #define JS_E_INVALID_CHAR 0x800a03f6
111
112 static const WCHAR testW[] = {'t','e','s','t',0};
113 static const CHAR testA[] = "test";
114 static const WCHAR test_valW[] = {'t','e','s','t','V','a','l',0};
115 static const CHAR test_valA[] = "testVal";
116
117 static BOOL strict_dispid_check;
118 static const char *test_name = "(null)";
119 static IDispatch *script_disp;
120 static int invoke_version;
121 static IActiveScriptError *script_error;
122 static const CLSID *engine_clsid = &CLSID_JScript;
123
124 /* Returns true if the user interface is in English. Note that this does not
125  * presume of the formatting of dates, numbers, etc.
126  */
127 static BOOL is_lang_english(void)
128 {
129     static HMODULE hkernel32 = NULL;
130     static LANGID (WINAPI *pGetThreadUILanguage)(void) = NULL;
131     static LANGID (WINAPI *pGetUserDefaultUILanguage)(void) = NULL;
132
133     if (!hkernel32)
134     {
135         hkernel32 = GetModuleHandleA("kernel32.dll");
136         pGetThreadUILanguage = (void*)GetProcAddress(hkernel32, "GetThreadUILanguage");
137         pGetUserDefaultUILanguage = (void*)GetProcAddress(hkernel32, "GetUserDefaultUILanguage");
138     }
139     if (pGetThreadUILanguage)
140         return PRIMARYLANGID(pGetThreadUILanguage()) == LANG_ENGLISH;
141     if (pGetUserDefaultUILanguage)
142         return PRIMARYLANGID(pGetUserDefaultUILanguage()) == LANG_ENGLISH;
143
144     return PRIMARYLANGID(GetUserDefaultLangID()) == LANG_ENGLISH;
145 }
146
147 static BSTR a2bstr(const char *str)
148 {
149     BSTR ret;
150     int len;
151
152     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
153     ret = SysAllocStringLen(NULL, len-1);
154     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
155
156     return ret;
157 }
158
159 static int strcmp_wa(LPCWSTR strw, const char *stra)
160 {
161     CHAR buf[512];
162     WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), 0, 0);
163     return lstrcmpA(buf, stra);
164 }
165
166 #define test_grfdex(a,b) _test_grfdex(__LINE__,a,b)
167 static void _test_grfdex(unsigned line, DWORD grfdex, DWORD expect)
168 {
169     expect |= invoke_version << 28;
170     ok_(__FILE__,line)(grfdex == expect, "grfdex = %x, expected %x\n", grfdex, expect);
171 }
172
173 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
174 {
175     *ppv = NULL;
176
177     if(IsEqualGUID(riid, &IID_IUnknown)
178        || IsEqualGUID(riid, &IID_IDispatch)
179        || IsEqualGUID(riid, &IID_IDispatchEx))
180         *ppv = iface;
181     else
182         return E_NOINTERFACE;
183
184     return S_OK;
185 }
186
187 static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
188 {
189     return 2;
190 }
191
192 static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
193 {
194     return 1;
195 }
196
197 static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
198 {
199     ok(0, "unexpected call\n");
200     return E_NOTIMPL;
201 }
202
203 static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
204                                               LCID lcid, ITypeInfo **ppTInfo)
205 {
206     ok(0, "unexpected call\n");
207     return E_NOTIMPL;
208 }
209
210 static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
211                                                 LPOLESTR *rgszNames, UINT cNames,
212                                                 LCID lcid, DISPID *rgDispId)
213 {
214     ok(IsEqualGUID(riid, &IID_NULL), "Expected IID_NULL\n");
215     ok(cNames==1, "cNames = %d\n", cNames);
216
217     if(!strcmp_wa(*rgszNames, "prop")) {
218         CHECK_EXPECT(puredisp_prop_d);
219         *rgDispId = DISPID_TESTOBJ_PROP;
220         return S_OK;
221     } else if(!strcmp_wa(*rgszNames, "noprop")) {
222         CHECK_EXPECT(puredisp_noprop_d);
223         return DISP_E_UNKNOWNNAME;
224     }
225
226     ok(0, "unexpected call\n");
227     return E_NOTIMPL;
228 }
229
230 static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
231                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
232                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
233 {
234     ok(0, "unexpected call\n");
235     return E_NOTIMPL;
236 }
237
238 static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
239 {
240     ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
241     return E_NOTIMPL;
242 }
243
244 static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
245 {
246     ok(0, "unexpected call\n");
247     return E_NOTIMPL;
248 }
249
250 static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
251 {
252     ok(0, "unexpected call\n");
253     return E_NOTIMPL;
254 }
255
256 static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
257 {
258     ok(0, "unexpected call\n");
259     return E_NOTIMPL;
260 }
261
262 static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
263 {
264     ok(0, "unexpected call\n");
265     return E_NOTIMPL;
266 }
267
268 static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
269 {
270     ok(0, "unexpected call\n");
271     return E_NOTIMPL;
272 }
273
274 static HRESULT WINAPI testObj_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
275 {
276     if(!strcmp_wa(bstrName, "prop")) {
277         CHECK_EXPECT(testobj_prop_d);
278         test_grfdex(grfdex, fdexNameCaseSensitive);
279         *pid = DISPID_TESTOBJ_PROP;
280         return S_OK;
281     }
282     if(!strcmp_wa(bstrName, "noprop")) {
283         CHECK_EXPECT(testobj_noprop_d);
284         test_grfdex(grfdex, fdexNameCaseSensitive);
285         return DISP_E_UNKNOWNNAME;
286     }
287     if(!strcmp_wa(bstrName, "onlyDispID")) {
288         if(strict_dispid_check)
289             CHECK_EXPECT(testobj_onlydispid_d);
290         test_grfdex(grfdex, fdexNameCaseSensitive);
291         *pid = DISPID_TESTOBJ_ONLYDISPID;
292         return S_OK;
293     }
294
295     ok(0, "unexpected name %s\n", wine_dbgstr_w(bstrName));
296     return E_NOTIMPL;
297 }
298
299 static HRESULT WINAPI testObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
300         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
301 {
302     ok(pspCaller != NULL, "pspCaller = NULL\n");
303
304     switch(id) {
305     case DISPID_VALUE:
306         ok(pdp != NULL, "pdp == NULL\n");
307         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
308         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
309         ok(pvarRes != NULL, "pvarRes == NULL\n");
310         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
311         ok(pei != NULL, "pei == NULL\n");
312
313         switch(wFlags) {
314         case INVOKE_PROPERTYGET:
315             CHECK_EXPECT(testobj_value);
316             ok(!pdp->rgvarg, "rgvarg != NULL\n");
317             ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
318             break;
319         case INVOKE_FUNC:
320             ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
321             break;
322         case INVOKE_FUNC|INVOKE_PROPERTYGET:
323             ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
324             break;
325         default:
326             ok(0, "invalid flag (%x)\n", wFlags);
327         }
328
329         V_VT(pvarRes) = VT_I4;
330         V_I4(pvarRes) = 1;
331         return S_OK;
332     case DISPID_TESTOBJ_ONLYDISPID:
333         if(strict_dispid_check)
334             CHECK_EXPECT(testobj_onlydispid_i);
335         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
336         ok(pdp != NULL, "pdp == NULL\n");
337         ok(!pdp->rgvarg, "rgvarg != NULL\n");
338         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
339         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
340         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
341         ok(pvarRes != NULL, "pvarRes == NULL\n");
342         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
343         ok(pei != NULL, "pei == NULL\n");
344         return DISP_E_MEMBERNOTFOUND;
345     }
346
347     ok(0, "unexpected call %x\n", id);
348     return DISP_E_MEMBERNOTFOUND;
349 }
350
351 static HRESULT WINAPI testObj_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
352 {
353     CHECK_EXPECT(testobj_delete);
354
355     ok(!strcmp_wa(bstrName, "deleteTest"), "unexpected name %s\n", wine_dbgstr_w(bstrName));
356     test_grfdex(grfdex, fdexNameCaseSensitive);
357     return S_OK;
358 }
359
360 static IDispatchExVtbl testObjVtbl = {
361     DispatchEx_QueryInterface,
362     DispatchEx_AddRef,
363     DispatchEx_Release,
364     DispatchEx_GetTypeInfoCount,
365     DispatchEx_GetTypeInfo,
366     DispatchEx_GetIDsOfNames,
367     DispatchEx_Invoke,
368     testObj_GetDispID,
369     testObj_InvokeEx,
370     testObj_DeleteMemberByName,
371     DispatchEx_DeleteMemberByDispID,
372     DispatchEx_GetMemberProperties,
373     DispatchEx_GetMemberName,
374     DispatchEx_GetNextDispID,
375     DispatchEx_GetNameSpaceParent
376 };
377
378 static IDispatchEx testObj = { &testObjVtbl };
379
380 static HRESULT WINAPI pureDisp_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
381 {
382     if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDispatch)) {
383         *ppv = iface;
384         return S_OK;
385     }
386
387     *ppv = NULL;
388     return E_NOINTERFACE;
389 }
390
391 static IDispatchExVtbl pureDispVtbl = {
392     pureDisp_QueryInterface,
393     DispatchEx_AddRef,
394     DispatchEx_Release,
395     DispatchEx_GetTypeInfoCount,
396     DispatchEx_GetTypeInfo,
397     DispatchEx_GetIDsOfNames,
398     DispatchEx_Invoke
399 };
400
401 static IDispatchEx pureDisp = { &pureDispVtbl };
402
403 static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
404 {
405     if(!strcmp_wa(bstrName, "ok")) {
406         test_grfdex(grfdex, fdexNameCaseSensitive);
407         *pid = DISPID_GLOBAL_OK;
408         return S_OK;
409     }
410     if(!strcmp_wa(bstrName, "trace")) {
411         test_grfdex(grfdex, fdexNameCaseSensitive);
412         *pid = DISPID_GLOBAL_TRACE;
413         return S_OK;
414     }
415     if(!strcmp_wa(bstrName, "reportSuccess")) {
416         CHECK_EXPECT(global_success_d);
417         test_grfdex(grfdex, fdexNameCaseSensitive);
418         *pid = DISPID_GLOBAL_REPORTSUCCESS;
419         return S_OK;
420     }
421     if(!strcmp_wa(bstrName, "testPropGet")) {
422         CHECK_EXPECT(global_propget_d);
423         test_grfdex(grfdex, fdexNameCaseSensitive);
424         *pid = DISPID_GLOBAL_TESTPROPGET;
425         return S_OK;
426     }
427     if(!strcmp_wa(bstrName, "testPropPut")) {
428         CHECK_EXPECT(global_propput_d);
429         test_grfdex(grfdex, fdexNameCaseSensitive);
430         *pid = DISPID_GLOBAL_TESTPROPPUT;
431         return S_OK;
432     }
433     if(!strcmp_wa(bstrName, "testPropDelete")) {
434         CHECK_EXPECT(global_propdelete_d);
435         test_grfdex(grfdex, fdexNameCaseSensitive);
436         *pid = DISPID_GLOBAL_TESTPROPDELETE;
437         return S_OK;
438     }
439     if(!strcmp_wa(bstrName, "getVT")) {
440         test_grfdex(grfdex, fdexNameCaseSensitive);
441         *pid = DISPID_GLOBAL_GETVT;
442         return S_OK;
443     }
444     if(!strcmp_wa(bstrName, "testObj")) {
445         test_grfdex(grfdex, fdexNameCaseSensitive);
446         *pid = DISPID_GLOBAL_TESTOBJ;
447         return S_OK;
448     }
449     if(!strcmp_wa(bstrName, "getNullBSTR")) {
450         *pid = DISPID_GLOBAL_GETNULLBSTR;
451         return S_OK;
452     }
453     if(!strcmp_wa(bstrName, "isNullBSTR")) {
454         *pid = DISPID_GLOBAL_ISNULLBSTR;
455         return S_OK;
456     }
457     if(!strcmp_wa(bstrName, "nullDisp")) {
458         *pid = DISPID_GLOBAL_NULL_DISP;
459         return S_OK;
460     }
461     if(!strcmp_wa(bstrName, "notExists")) {
462         CHECK_EXPECT(global_notexists_d);
463         test_grfdex(grfdex, fdexNameCaseSensitive);
464         return DISP_E_UNKNOWNNAME;
465     }
466
467     if(!strcmp_wa(bstrName, "testThis")) {
468         test_grfdex(grfdex, fdexNameCaseSensitive);
469         *pid = DISPID_GLOBAL_TESTTHIS;
470         return S_OK;
471     }
472
473     if(!strcmp_wa(bstrName, "testThis2")) {
474         test_grfdex(grfdex, fdexNameCaseSensitive);
475         *pid = DISPID_GLOBAL_TESTTHIS2;
476         return S_OK;
477     }
478
479     if(!strcmp_wa(bstrName, "invokeVersion")) {
480         test_grfdex(grfdex, fdexNameCaseSensitive);
481         *pid = DISPID_GLOBAL_INVOKEVERSION;
482         return S_OK;
483     }
484     if(!strcmp_wa(bstrName, "createArray")) {
485         test_grfdex(grfdex, fdexNameCaseSensitive);
486         *pid = DISPID_GLOBAL_CREATEARRAY;
487         return S_OK;
488     }
489     if(!strcmp_wa(bstrName, "propGetFunc")) {
490         test_grfdex(grfdex, fdexNameCaseSensitive);
491         *pid = DISPID_GLOBAL_PROPGETFUNC;
492         return S_OK;
493     }
494     if(!strcmp_wa(bstrName, "objectFlag")) {
495         test_grfdex(grfdex, fdexNameCaseSensitive);
496         *pid = DISPID_GLOBAL_OBJECT_FLAG;
497         return S_OK;
498     }
499
500     if(!strcmp_wa(bstrName, "isWin64")) {
501         test_grfdex(grfdex, fdexNameCaseSensitive);
502         *pid = DISPID_GLOBAL_ISWIN64;
503         return S_OK;
504     }
505
506     if(!strcmp_wa(bstrName, "pureDisp")) {
507         test_grfdex(grfdex, fdexNameCaseSensitive);
508         *pid = DISPID_GLOBAL_PUREDISP;
509         return S_OK;
510     }
511
512     if(!strcmp_wa(bstrName, "propArgPutG")) {
513         CHECK_EXPECT(global_propargput_d);
514         test_grfdex(grfdex, fdexNameCaseSensitive);
515         *pid = DISPID_GLOBAL_PROPARGPUT;
516         return S_OK;
517     }
518
519     if(!strcmp_wa(bstrName, "propArgPutO")) {
520         CHECK_EXPECT(global_propargput_d);
521         test_grfdex(grfdex, fdexNameEnsure|fdexNameCaseSensitive);
522         *pid = DISPID_GLOBAL_PROPARGPUT;
523         return S_OK;
524     }
525
526     if(!strcmp_wa(bstrName, "shortProp")) {
527         *pid = DISPID_GLOBAL_SHORTPROP;
528         return S_OK;
529     }
530
531     if(!strcmp_wa(bstrName, "getShort")) {
532         *pid = DISPID_GLOBAL_GETSHORT;
533         return S_OK;
534     }
535
536     if(!strcmp_wa(bstrName, "testArgTypes")) {
537         *pid = DISPID_GLOBAL_TESTARGTYPES;
538         return S_OK;
539     }
540
541     if(strict_dispid_check && strcmp_wa(bstrName, "t"))
542         ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName));
543     return DISP_E_UNKNOWNNAME;
544 }
545
546 static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
547         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
548 {
549     ok(pspCaller != NULL, "pspCaller = NULL\n");
550
551     switch(id) {
552     case DISPID_GLOBAL_OK:
553         ok(wFlags == INVOKE_FUNC || wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
554         ok(pdp != NULL, "pdp == NULL\n");
555         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
556         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
557         ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
558         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
559         if(wFlags & INVOKE_PROPERTYGET)
560             ok(pvarRes != NULL, "pvarRes == NULL\n");
561         else
562             ok(!pvarRes, "pvarRes != NULL\n");
563         ok(pei != NULL, "pei == NULL\n");
564
565         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
566         ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(psp->rgvargs+1) = %d\n", V_VT(pdp->rgvarg));
567         ok(V_BOOL(pdp->rgvarg+1), "%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
568
569         return S_OK;
570
571      case DISPID_GLOBAL_TRACE:
572         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
573         ok(pdp != NULL, "pdp == NULL\n");
574         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
575         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
576         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
577         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
578         ok(!pvarRes, "pvarRes != NULL\n");
579         ok(pei != NULL, "pei == NULL\n");
580
581         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
582         if(V_VT(pdp->rgvarg) == VT_BSTR)
583             trace("%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
584
585         return S_OK;
586
587     case DISPID_GLOBAL_REPORTSUCCESS:
588         CHECK_EXPECT(global_success_i);
589
590         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
591         ok(pdp != NULL, "pdp == NULL\n");
592         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
593         ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
594         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
595         ok(!pvarRes, "pvarRes != NULL\n");
596         ok(pei != NULL, "pei == NULL\n");
597
598         return S_OK;
599
600      case DISPID_GLOBAL_TESTPROPGET:
601         CHECK_EXPECT(global_propget_i);
602
603         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
604         ok(pdp != NULL, "pdp == NULL\n");
605         ok(!pdp->rgvarg, "rgvarg != NULL\n");
606         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
607         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
608         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
609         ok(pvarRes != NULL, "pvarRes == NULL\n");
610         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
611         ok(pei != NULL, "pei == NULL\n");
612
613         V_VT(pvarRes) = VT_I4;
614         V_I4(pvarRes) = 1;
615
616         return S_OK;
617
618     case DISPID_GLOBAL_TESTPROPPUT:
619         CHECK_EXPECT(global_propput_i);
620
621         ok(wFlags == INVOKE_PROPERTYPUT, "wFlags = %x\n", wFlags);
622         ok(pdp != NULL, "pdp == NULL\n");
623         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
624         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
625         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
626         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
627         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
628         ok(!pvarRes, "pvarRes != NULL\n");
629
630         ok(V_VT(pdp->rgvarg) == VT_I4, "V_VT(pdp->rgvarg)=%d\n", V_VT(pdp->rgvarg));
631         ok(V_I4(pdp->rgvarg) == 1, "V_I4(pdp->rgvarg)=%d\n", V_I4(pdp->rgvarg));
632         return S_OK;
633
634      case DISPID_GLOBAL_GETVT:
635         ok(pdp != NULL, "pdp == NULL\n");
636         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
637         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
638         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
639         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
640         ok(pvarRes != NULL, "pvarRes == NULL\n");
641         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
642         ok(pei != NULL, "pei == NULL\n");
643
644         V_VT(pvarRes) = VT_BSTR;
645         switch(V_VT(pdp->rgvarg)) {
646         case VT_EMPTY:
647             V_BSTR(pvarRes) = a2bstr("VT_EMPTY");
648             break;
649         case VT_NULL:
650             V_BSTR(pvarRes) = a2bstr("VT_NULL");
651             break;
652         case VT_I4:
653             V_BSTR(pvarRes) = a2bstr("VT_I4");
654             break;
655         case VT_R8:
656             V_BSTR(pvarRes) = a2bstr("VT_R8");
657             break;
658         case VT_BSTR:
659             V_BSTR(pvarRes) = a2bstr("VT_BSTR");
660             break;
661         case VT_DISPATCH:
662             V_BSTR(pvarRes) = a2bstr("VT_DISPATCH");
663             break;
664         case VT_BOOL:
665             V_BSTR(pvarRes) = a2bstr("VT_BOOL");
666             break;
667         case VT_ARRAY|VT_VARIANT:
668             V_BSTR(pvarRes) = a2bstr("VT_ARRAY|VT_VARIANT");
669             break;
670         default:
671             ok(0, "unknown vt %d\n", V_VT(pdp->rgvarg));
672             return E_FAIL;
673         }
674
675         return S_OK;
676
677     case DISPID_GLOBAL_TESTOBJ:
678         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
679         ok(pdp != NULL, "pdp == NULL\n");
680         ok(!pdp->rgvarg, "rgvarg != NULL\n");
681         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
682         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
683         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
684         ok(pvarRes != NULL, "pvarRes == NULL\n");
685         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
686         ok(pei != NULL, "pei == NULL\n");
687
688         V_VT(pvarRes) = VT_DISPATCH;
689         V_DISPATCH(pvarRes) = (IDispatch*)&testObj;
690         return S_OK;
691
692     case DISPID_GLOBAL_PUREDISP:
693         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
694         ok(pdp != NULL, "pdp == NULL\n");
695         ok(!pdp->rgvarg, "rgvarg != NULL\n");
696         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
697         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
698         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
699         ok(pvarRes != NULL, "pvarRes == NULL\n");
700         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
701         ok(pei != NULL, "pei == NULL\n");
702
703         V_VT(pvarRes) = VT_DISPATCH;
704         V_DISPATCH(pvarRes) = (IDispatch*)&pureDisp;
705         return S_OK;
706
707     case DISPID_GLOBAL_GETNULLBSTR:
708         if(pvarRes) {
709             V_VT(pvarRes) = VT_BSTR;
710             V_BSTR(pvarRes) = NULL;
711         }
712         return S_OK;
713
714     case DISPID_GLOBAL_ISNULLBSTR:
715         ok(pdp != NULL, "pdp == NULL\n");
716         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
717         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
718         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
719         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
720         ok(pvarRes != NULL, "pvarRes == NULL\n");
721         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
722         ok(pei != NULL, "pei == NULL\n");
723         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
724
725         V_VT(pvarRes) = VT_BOOL;
726         V_BOOL(pvarRes) = V_BSTR(pdp->rgvarg) ? VARIANT_FALSE : VARIANT_TRUE;
727         return S_OK;
728
729     case DISPID_GLOBAL_ISWIN64:
730         if(pvarRes) {
731             V_VT(pvarRes) = VT_BOOL;
732             V_BOOL(pvarRes) = sizeof(void*) == 8 ? VARIANT_TRUE : VARIANT_FALSE;
733         }
734         return S_OK;
735
736     case DISPID_GLOBAL_NULL_DISP:
737         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
738         ok(pdp != NULL, "pdp == NULL\n");
739         ok(!pdp->rgvarg, "rgvarg != NULL\n");
740         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
741         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
742         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
743         ok(pvarRes != NULL, "pvarRes == NULL\n");
744         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
745         ok(pei != NULL, "pei == NULL\n");
746
747         V_VT(pvarRes) = VT_DISPATCH;
748         V_DISPATCH(pvarRes) = NULL;
749         return S_OK;
750
751     case DISPID_GLOBAL_TESTTHIS:
752         ok(pdp != NULL, "pdp == NULL\n");
753         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
754         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
755         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
756         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
757         ok(pvarRes == NULL, "pvarRes != NULL\n");
758         ok(pei != NULL, "pei == NULL\n");
759
760         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(arg) = %d\n", V_VT(pdp->rgvarg));
761         ok(V_DISPATCH(pdp->rgvarg) == (IDispatch*)iface, "disp != iface\n");
762
763         return S_OK;
764
765     case DISPID_GLOBAL_TESTTHIS2:
766         ok(pdp != NULL, "pdp == NULL\n");
767         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
768         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
769         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
770         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
771         ok(pvarRes == NULL, "pvarRes != NULL\n");
772         ok(pei != NULL, "pei == NULL\n");
773
774         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(arg) = %d\n", V_VT(pdp->rgvarg));
775         ok(V_DISPATCH(pdp->rgvarg) != (IDispatch*)iface, "disp == iface\n");
776         ok(V_DISPATCH(pdp->rgvarg) == script_disp, "disp != script_disp\n");
777
778         return S_OK;
779
780      case DISPID_GLOBAL_INVOKEVERSION:
781         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
782         ok(pdp != NULL, "pdp == NULL\n");
783         ok(!pdp->rgvarg, "rgvarg != NULL\n");
784         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
785         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
786         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
787         ok(pvarRes != NULL, "pvarRes == NULL\n");
788         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
789         ok(pei != NULL, "pei == NULL\n");
790
791         V_VT(pvarRes) = VT_I4;
792         V_I4(pvarRes) = invoke_version;
793
794         return S_OK;
795
796     case DISPID_GLOBAL_CREATEARRAY: {
797         SAFEARRAYBOUND bound[2];
798         VARIANT *data;
799         int i,j;
800
801         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
802         ok(pdp != NULL, "pdp == NULL\n");
803         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
804         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
805         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
806         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
807         ok(pvarRes != NULL, "pvarRes == NULL\n");
808         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
809         ok(pei != NULL, "pei == NULL\n");
810
811         bound[0].lLbound = 0;
812         bound[0].cElements = 5;
813         bound[1].lLbound = 2;
814         bound[1].cElements = 2;
815
816         V_VT(pvarRes) = VT_ARRAY|VT_VARIANT;
817         V_ARRAY(pvarRes) = SafeArrayCreate(VT_VARIANT, 2, bound);
818
819         SafeArrayAccessData(V_ARRAY(pvarRes), (void**)&data);
820         for(i=0; i<5; i++) {
821             for(j=2; j<4; j++) {
822                 V_VT(data) = VT_I4;
823                 V_I4(data) = i*10+j;
824                 data++;
825             }
826         }
827         SafeArrayUnaccessData(V_ARRAY(pvarRes));
828
829         return S_OK;
830     }
831
832     case DISPID_GLOBAL_PROPGETFUNC:
833         switch(wFlags) {
834         case INVOKE_FUNC:
835             CHECK_EXPECT(invoke_func);
836             break;
837         case INVOKE_FUNC|INVOKE_PROPERTYGET:
838             ok(pdp->cArgs != 0, "pdp->cArgs = %d\n", pdp->cArgs);
839             ok(pvarRes != NULL, "pdp->pvarRes == NULL\n");
840             break;
841         default:
842             ok(0, "invalid flag (%x)\n", wFlags);
843         }
844
845         ok(pdp != NULL, "pdp == NULL\n");
846         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
847         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
848         ok(pei != NULL, "pei == NULL\n");
849
850         if(pvarRes) {
851             ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
852             V_VT(pvarRes) = VT_I4;
853             V_I4(pvarRes) = pdp->cArgs;
854         }
855
856         return S_OK;
857
858     case DISPID_GLOBAL_PROPARGPUT:
859         CHECK_EXPECT(global_propargput_i);
860         ok(wFlags == INVOKE_PROPERTYPUT, "wFlags = %x\n", wFlags);
861         ok(pdp != NULL, "pdp == NULL\n");
862         ok(pdp->rgvarg != NULL, "rgvarg != NULL\n");
863         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
864         ok(pdp->cArgs == 3, "cArgs = %d\n", pdp->cArgs);
865         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
866         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
867         ok(!pvarRes, "pvarRes != NULL\n");
868         ok(pei != NULL, "pei == NULL\n");
869
870         ok(V_VT(pdp->rgvarg) == VT_I4, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
871         ok(V_I4(pdp->rgvarg) == 2, "V_I4(psp->rgvargs) = %d\n", V_I4(pdp->rgvarg));
872
873         ok(V_VT(pdp->rgvarg+1) == VT_I4, "V_VT(psp->rgvargs+1) = %d\n", V_VT(pdp->rgvarg+1));
874         ok(V_I4(pdp->rgvarg+1) == 1, "V_I4(psp->rgvargs+1) = %d\n", V_I4(pdp->rgvarg+1));
875
876         ok(V_VT(pdp->rgvarg+2) == VT_I4, "V_VT(psp->rgvargs+2) = %d\n", V_VT(pdp->rgvarg+2));
877         ok(V_I4(pdp->rgvarg+2) == 0, "V_I4(psp->rgvargs+2) = %d\n", V_I4(pdp->rgvarg+2));
878         return S_OK;
879
880     case DISPID_GLOBAL_OBJECT_FLAG: {
881         IDispatchEx *dispex;
882         BSTR str;
883         HRESULT hres;
884
885         hres = IDispatch_QueryInterface(script_disp, &IID_IDispatchEx, (void**)&dispex);
886         ok(hres == S_OK, "hres = %x\n", hres);
887
888         str = a2bstr("Object");
889         hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseSensitive, &id);
890         SysFreeString(str);
891         ok(hres == S_OK, "hres = %x\n", hres);
892
893         hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_METHOD, pdp, NULL, pei, pspCaller);
894         ok(hres == S_OK, "hres = %x\n", hres);
895
896         V_VT(pvarRes) = VT_EMPTY;
897         hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_METHOD, pdp, pvarRes, pei, pspCaller);
898         ok(hres == S_OK, "hres = %x\n", hres);
899         ok(V_VT(pvarRes) == VT_DISPATCH, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
900         VariantClear(pvarRes);
901
902         hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_METHOD|DISPATCH_PROPERTYGET, pdp, NULL, pei, pspCaller);
903         ok(hres == S_OK, "hres = %x\n", hres);
904
905         V_VT(pvarRes) = VT_EMPTY;
906         hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_CONSTRUCT, pdp, pvarRes, pei, pspCaller);
907         ok(hres == S_OK, "hres = %x\n", hres);
908         ok(V_VT(pvarRes) == VT_DISPATCH, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
909         VariantClear(pvarRes);
910
911         hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_CONSTRUCT, pdp, NULL, pei, pspCaller);
912         ok(hres == S_OK, "hres = %x\n", hres);
913
914         V_VT(pvarRes) = VT_EMPTY;
915         hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_CONSTRUCT|DISPATCH_PROPERTYGET, pdp, pvarRes, pei, pspCaller);
916         ok(hres == E_INVALIDARG, "hres = %x\n", hres);
917
918         V_VT(pvarRes) = VT_EMPTY;
919         hres = IDispatchEx_InvokeEx(dispex, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
920         ok(hres == S_OK, "hres = %x\n", hres);
921         ok(V_VT(pvarRes) == VT_DISPATCH, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
922         IDispatchEx_Release(dispex);
923         return S_OK;
924     }
925     case DISPID_GLOBAL_SHORTPROP:
926     case DISPID_GLOBAL_GETSHORT:
927         V_VT(pvarRes) = VT_I2;
928         V_I2(pvarRes) = 10;
929         return S_OK;
930
931     case DISPID_GLOBAL_TESTARGTYPES: {
932         VARIANT args[1];
933         DISPPARAMS dp = {args, NULL, 1, 0};
934         HRESULT hres;
935
936         CHECK_EXPECT(global_testargtypes_i);
937         ok(wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags);
938         ok(pdp != NULL, "pdp == NULL\n");
939         ok(pdp->rgvarg != NULL, "rgvarg != NULL\n");
940         ok(pdp->cArgs == 3, "cArgs = %d\n", pdp->cArgs);
941         ok(!pvarRes, "pvarRes != NULL\n");
942
943         ok(V_VT(pdp->rgvarg+1) == VT_I4, "V_VT(psp->rgvargs+1) = %d\n", V_VT(pdp->rgvarg));
944         ok(V_I4(pdp->rgvarg+1) == 10, "V_I4(psp->rgvargs+1) = %d\n", V_I4(pdp->rgvarg));
945
946         ok(V_VT(pdp->rgvarg+2) == VT_I4, "V_VT(psp->rgvargs+2) = %d\n", V_VT(pdp->rgvarg+1));
947         ok(V_I4(pdp->rgvarg+2) == 10, "V_I4(psp->rgvargs+2) = %d\n", V_I4(pdp->rgvarg+1));
948
949         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
950
951         V_VT(args) = VT_I2;
952         V_I2(args) = 2;
953         hres = IDispatch_Invoke(V_DISPATCH(pdp->rgvarg), DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, &dp, NULL, NULL, NULL);
954         ok(hres == S_OK, "Invoke failed: %08x\n", hres);
955
956         return S_OK;
957     }
958     }
959
960     ok(0, "unexpected call %x\n", id);
961     return DISP_E_MEMBERNOTFOUND;
962 }
963
964 static HRESULT WINAPI Global_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
965 {
966     CHECK_EXPECT(DeleteMemberByDispID);
967     ok(id == DISPID_GLOBAL_TESTPROPDELETE, "id = %d\n", id);
968     return S_OK;
969 }
970
971 static IDispatchExVtbl GlobalVtbl = {
972     DispatchEx_QueryInterface,
973     DispatchEx_AddRef,
974     DispatchEx_Release,
975     DispatchEx_GetTypeInfoCount,
976     DispatchEx_GetTypeInfo,
977     DispatchEx_GetIDsOfNames,
978     DispatchEx_Invoke,
979     Global_GetDispID,
980     Global_InvokeEx,
981     DispatchEx_DeleteMemberByName,
982     Global_DeleteMemberByDispID,
983     DispatchEx_GetMemberProperties,
984     DispatchEx_GetMemberName,
985     DispatchEx_GetNextDispID,
986     DispatchEx_GetNameSpaceParent
987 };
988
989 static IDispatchEx Global = { &GlobalVtbl };
990
991 static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
992 {
993     *ppv = NULL;
994
995     if(IsEqualGUID(&IID_IUnknown, riid))
996         *ppv = iface;
997     else if(IsEqualGUID(&IID_IActiveScriptSite, riid))
998         *ppv = iface;
999     else
1000         return E_NOINTERFACE;
1001
1002     IUnknown_AddRef((IUnknown*)*ppv);
1003     return S_OK;
1004 }
1005
1006 static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
1007 {
1008     return 2;
1009 }
1010
1011 static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
1012 {
1013     return 1;
1014 }
1015
1016 static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *plcid)
1017 {
1018     *plcid = GetUserDefaultLCID();
1019     return S_OK;
1020 }
1021
1022 static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR pstrName,
1023         DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti)
1024 {
1025     ok(dwReturnMask == SCRIPTINFO_IUNKNOWN, "unexpected dwReturnMask %x\n", dwReturnMask);
1026     ok(!ppti, "ppti != NULL\n");
1027
1028     if(!strcmp_wa(pstrName, test_valA))
1029         CHECK_EXPECT(GetItemInfo_testVal);
1030     else if(strcmp_wa(pstrName, testA))
1031         ok(0, "unexpected pstrName %s\n", wine_dbgstr_w(pstrName));
1032
1033     *ppiunkItem = (IUnknown*)&Global;
1034     return S_OK;
1035 }
1036
1037 static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *pbstrVersion)
1038 {
1039     return E_NOTIMPL;
1040 }
1041
1042 static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface,
1043         const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo)
1044 {
1045     return E_NOTIMPL;
1046 }
1047
1048 static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE ssScriptState)
1049 {
1050     return E_NOTIMPL;
1051 }
1052
1053 static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
1054 {
1055     return E_NOTIMPL;
1056 }
1057
1058 static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
1059 {
1060     return E_NOTIMPL;
1061 }
1062
1063 static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
1064 {
1065     return E_NOTIMPL;
1066 }
1067
1068 #undef ACTSCPSITE_THIS
1069
1070 static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
1071     ActiveScriptSite_QueryInterface,
1072     ActiveScriptSite_AddRef,
1073     ActiveScriptSite_Release,
1074     ActiveScriptSite_GetLCID,
1075     ActiveScriptSite_GetItemInfo,
1076     ActiveScriptSite_GetDocVersionString,
1077     ActiveScriptSite_OnScriptTerminate,
1078     ActiveScriptSite_OnStateChange,
1079     ActiveScriptSite_OnScriptError,
1080     ActiveScriptSite_OnEnterScript,
1081     ActiveScriptSite_OnLeaveScript
1082 };
1083
1084 static IActiveScriptSite ActiveScriptSite = { &ActiveScriptSiteVtbl };
1085
1086 static HRESULT WINAPI ActiveScriptSite_OnScriptError_CheckError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
1087 {
1088     ok(pscripterror != NULL, "ActiveScriptSite_OnScriptError -- expected pscripterror to be set, got NULL\n");
1089
1090     script_error = pscripterror;
1091     IUnknown_AddRef(script_error);
1092
1093     CHECK_EXPECT(ActiveScriptSite_OnScriptError);
1094
1095     return S_OK;
1096 }
1097
1098 static const IActiveScriptSiteVtbl ActiveScriptSite_CheckErrorVtbl = {
1099     ActiveScriptSite_QueryInterface,
1100     ActiveScriptSite_AddRef,
1101     ActiveScriptSite_Release,
1102     ActiveScriptSite_GetLCID,
1103     ActiveScriptSite_GetItemInfo,
1104     ActiveScriptSite_GetDocVersionString,
1105     ActiveScriptSite_OnScriptTerminate,
1106     ActiveScriptSite_OnStateChange,
1107     ActiveScriptSite_OnScriptError_CheckError,
1108     ActiveScriptSite_OnEnterScript,
1109     ActiveScriptSite_OnLeaveScript
1110 };
1111
1112 static IActiveScriptSite ActiveScriptSite_CheckError = { &ActiveScriptSite_CheckErrorVtbl };
1113
1114 static HRESULT set_script_prop(IActiveScript *engine, DWORD property, VARIANT *val)
1115 {
1116     IActiveScriptProperty *script_prop;
1117     HRESULT hres;
1118
1119     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptProperty,
1120             (void**)&script_prop);
1121     ok(hres == S_OK, "Could not get IActiveScriptProperty iface: %08x\n", hres);
1122
1123     hres = IActiveScriptProperty_SetProperty(script_prop, property, NULL, val);
1124     IActiveScriptProperty_Release(script_prop);
1125
1126     return hres;
1127 }
1128
1129 static IActiveScript *create_script(void)
1130 {
1131     IActiveScript *script;
1132     VARIANT v;
1133     HRESULT hres;
1134
1135     hres = CoCreateInstance(engine_clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1136             &IID_IActiveScript, (void**)&script);
1137     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
1138
1139     V_VT(&v) = VT_I4;
1140     V_I4(&v) = invoke_version;
1141     hres = set_script_prop(script, SCRIPTPROP_INVOKEVERSIONING, &v);
1142     ok(hres == S_OK || broken(hres == E_NOTIMPL), "SetProperty(SCRIPTPROP_INVOKEVERSIONING) failed: %08x\n", hres);
1143     if(invoke_version && FAILED(hres)) {
1144         IActiveScript_Release(script);
1145         return NULL;
1146     }
1147
1148     return script;
1149 }
1150
1151 static HRESULT parse_script(DWORD flags, BSTR script_str)
1152 {
1153     IActiveScriptParse *parser;
1154     IActiveScript *engine;
1155     HRESULT hres;
1156
1157     engine = create_script();
1158     if(!engine)
1159         return S_OK;
1160
1161     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
1162     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1163     if (FAILED(hres))
1164     {
1165         IActiveScript_Release(engine);
1166         return hres;
1167     }
1168
1169     hres = IActiveScriptParse64_InitNew(parser);
1170     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
1171
1172     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
1173     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
1174
1175     hres = IActiveScript_AddNamedItem(engine, testW,
1176             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|flags);
1177     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
1178
1179     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
1180     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
1181
1182     hres = IActiveScript_GetScriptDispatch(engine, NULL, &script_disp);
1183     ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres);
1184     ok(script_disp != NULL, "script_disp == NULL\n");
1185     ok(script_disp != (IDispatch*)&Global, "script_disp == Global\n");
1186
1187     hres = IActiveScriptParse64_ParseScriptText(parser, script_str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
1188
1189     IDispatch_Release(script_disp);
1190     IActiveScript_Release(engine);
1191     IUnknown_Release(parser);
1192
1193     return hres;
1194 }
1195
1196 static HRESULT parse_htmlscript(BSTR script_str)
1197 {
1198     IActiveScriptParse *parser;
1199     IActiveScript *engine;
1200     HRESULT hres;
1201     BSTR tmp = a2bstr("</SCRIPT>");
1202
1203     engine = create_script();
1204     if(!engine)
1205         return E_FAIL;
1206
1207     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
1208     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1209     if (FAILED(hres))
1210     {
1211         IActiveScript_Release(engine);
1212         return E_FAIL;
1213     }
1214
1215     hres = IActiveScriptParse64_InitNew(parser);
1216     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
1217
1218     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
1219     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
1220
1221     hres = IActiveScript_AddNamedItem(engine, testW,
1222             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
1223     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
1224
1225     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
1226     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
1227
1228     hres = IActiveScriptParse64_ParseScriptText(parser, script_str, NULL, NULL, tmp, 0, 0, 0, NULL, NULL);
1229
1230     IActiveScript_Release(engine);
1231     IUnknown_Release(parser);
1232     SysFreeString(tmp);
1233
1234     return hres;
1235 }
1236
1237 static void test_IActiveScriptError(IActiveScriptError *error, SCODE errorcode, ULONG line, LONG pos, BSTR script_source, BSTR description, BSTR line_text)
1238 {
1239     HRESULT hres;
1240     DWORD source_context;
1241     ULONG line_number;
1242     LONG char_position;
1243     BSTR linetext;
1244     EXCEPINFO excep;
1245
1246     /* IActiveScriptError_GetSourcePosition */
1247
1248     hres = IActiveScriptError_GetSourcePosition(error, NULL, NULL, NULL);
1249     ok(hres == S_OK, "IActiveScriptError_GetSourcePosition -- hres: expected S_OK, got 0x%08x\n", hres);
1250
1251     source_context = 0xdeadbeef;
1252     hres = IActiveScriptError_GetSourcePosition(error, &source_context, NULL, NULL);
1253     ok(hres == S_OK, "IActiveScriptError_GetSourcePosition -- hres: expected S_OK, got 0x%08x\n", hres);
1254     ok(source_context == 0, "IActiveScriptError_GetSourcePosition -- source_context: expected 0, got 0x%08x\n", source_context);
1255
1256     line_number = 0xdeadbeef;
1257     hres = IActiveScriptError_GetSourcePosition(error, NULL, &line_number, NULL);
1258     ok(hres == S_OK, "IActiveScriptError_GetSourcePosition -- hres: expected S_OK, got 0x%08x\n", hres);
1259     ok(line_number == line, "IActiveScriptError_GetSourcePosition -- line_number: expected %d, got %d\n", line, line_number);
1260
1261     char_position = 0xdeadbeef;
1262     hres = IActiveScriptError_GetSourcePosition(error, NULL, NULL, &char_position);
1263     ok(hres == S_OK, "IActiveScriptError_GetSourcePosition -- hres: expected S_OK, got 0x%08x\n", hres);
1264     ok(char_position == pos, "IActiveScriptError_GetSourcePosition -- char_position: expected %d, got %d\n", pos, char_position);
1265
1266     /* IActiveScriptError_GetSourceLineText */
1267
1268     hres = IActiveScriptError_GetSourceLineText(error, NULL);
1269     ok(hres == E_POINTER, "IActiveScriptError_GetSourceLineText -- hres: expected E_POINTER, got 0x%08x\n", hres);
1270
1271     linetext = NULL;
1272     hres = IActiveScriptError_GetSourceLineText(error, &linetext);
1273     if (line_text) {
1274         ok(hres == S_OK, "IActiveScriptError_GetSourceLineText -- hres: expected S_OK, got 0x%08x\n", hres);
1275         ok(linetext != NULL && !lstrcmpW(linetext, line_text),
1276            "IActiveScriptError_GetSourceLineText -- expected %s, got %s\n", wine_dbgstr_w(line_text), wine_dbgstr_w(linetext));
1277     } else {
1278         ok(hres == E_FAIL, "IActiveScriptError_GetSourceLineText -- hres: expected S_OK, got 0x%08x\n", hres);
1279         ok(linetext == NULL,
1280            "IActiveScriptError_GetSourceLineText -- expected NULL, got %s\n", wine_dbgstr_w(linetext));
1281     }
1282     SysFreeString(linetext);
1283
1284     /* IActiveScriptError_GetExceptionInfo */
1285
1286     hres = IActiveScriptError_GetExceptionInfo(error, NULL);
1287     ok(hres == E_POINTER, "IActiveScriptError_GetExceptionInfo -- hres: expected E_POINTER, got 0x%08x\n", hres);
1288
1289     excep.wCode = 0xdead;
1290     excep.wReserved = 0xdead;
1291     excep.bstrSource = (BSTR)0xdeadbeef;
1292     excep.bstrDescription = (BSTR)0xdeadbeef;
1293     excep.bstrHelpFile = (BSTR)0xdeadbeef;
1294     excep.dwHelpContext = 0xdeadbeef;
1295     excep.pvReserved = (void *)0xdeadbeef;
1296     excep.pfnDeferredFillIn = (void *)0xdeadbeef;
1297     excep.scode = 0xdeadbeef;
1298
1299     hres = IActiveScriptError_GetExceptionInfo(error, &excep);
1300     ok(hres == S_OK, "IActiveScriptError_GetExceptionInfo -- hres: expected S_OK, got 0x%08x\n", hres);
1301
1302     ok(excep.wCode == 0, "IActiveScriptError_GetExceptionInfo -- excep.wCode: expected 0, got 0x%08x\n", excep.wCode);
1303     ok(excep.wReserved == 0, "IActiveScriptError_GetExceptionInfo -- excep.wReserved: expected 0, got %d\n", excep.wReserved);
1304     if (!is_lang_english())
1305         skip("Non-english UI (test with hardcoded strings)\n");
1306     else {
1307         ok(excep.bstrSource != NULL && !lstrcmpW(excep.bstrSource, script_source),
1308            "IActiveScriptError_GetExceptionInfo -- excep.bstrSource is not valid: expected %s, got %s\n",
1309            wine_dbgstr_w(script_source), wine_dbgstr_w(excep.bstrSource));
1310         ok(excep.bstrDescription != NULL && !lstrcmpW(excep.bstrDescription, description),
1311            "IActiveScriptError_GetExceptionInfo -- excep.bstrDescription is not valid: got %s\n", wine_dbgstr_w(excep.bstrDescription));
1312     }
1313     ok(excep.bstrHelpFile == NULL,
1314        "IActiveScriptError_GetExceptionInfo -- excep.bstrHelpFile: expected NULL, got %s\n", wine_dbgstr_w(excep.bstrHelpFile));
1315     ok(excep.dwHelpContext == 0, "IActiveScriptError_GetExceptionInfo -- excep.dwHelpContext: expected 0, got %d\n", excep.dwHelpContext);
1316     ok(excep.pvReserved == NULL, "IActiveScriptError_GetExceptionInfo -- excep.pvReserved: expected NULL, got %p\n", excep.pvReserved);
1317     ok(excep.pfnDeferredFillIn == NULL, "IActiveScriptError_GetExceptionInfo -- excep.pfnDeferredFillIn: expected NULL, got %p\n", excep.pfnDeferredFillIn);
1318     ok(excep.scode == errorcode, "IActiveScriptError_GetExceptionInfo -- excep.scode: expected 0x%08x, got 0x%08x\n", errorcode, excep.scode);
1319
1320     SysFreeString(excep.bstrSource);
1321     SysFreeString(excep.bstrDescription);
1322     SysFreeString(excep.bstrHelpFile);
1323 }
1324
1325 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)
1326 {
1327     IActiveScriptParse *parser;
1328     IActiveScript *engine;
1329     HRESULT hres;
1330
1331     engine = create_script();
1332     if(!engine)
1333         return;
1334
1335     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
1336     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1337     if (FAILED(hres))
1338     {
1339         IActiveScript_Release(engine);
1340         return;
1341     }
1342
1343     hres = IActiveScriptParse64_InitNew(parser);
1344     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
1345
1346     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite_CheckError);
1347     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
1348
1349     hres = IActiveScript_AddNamedItem(engine, testW,
1350             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|flags);
1351     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
1352
1353     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
1354     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
1355
1356     hres = IActiveScript_GetScriptDispatch(engine, NULL, &script_disp);
1357     ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres);
1358     ok(script_disp != NULL, "script_disp == NULL\n");
1359     ok(script_disp != (IDispatch*)&Global, "script_disp == Global\n");
1360
1361     script_error = NULL;
1362     SET_EXPECT(ActiveScriptSite_OnScriptError);
1363     hres = IActiveScriptParse64_ParseScriptText(parser, script_str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
1364     todo_wine ok(hres == 0x80020101, "parse_script_with_error should have returned 0x80020101, got: 0x%08x\n", hres);
1365     todo_wine CHECK_CALLED(ActiveScriptSite_OnScriptError);
1366
1367     if (script_error)
1368     {
1369         test_IActiveScriptError(script_error, errorcode, line, pos, script_source, description, line_text);
1370
1371         IUnknown_Release(script_error);
1372     }
1373
1374     IDispatch_Release(script_disp);
1375     IActiveScript_Release(engine);
1376     IUnknown_Release(parser);
1377 }
1378
1379 static void parse_script_af(DWORD flags, const char *src)
1380 {
1381     BSTR tmp;
1382     HRESULT hres;
1383
1384     tmp = a2bstr(src);
1385     hres = parse_script(flags, tmp);
1386     SysFreeString(tmp);
1387     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
1388 }
1389
1390 static void parse_script_a(const char *src)
1391 {
1392     parse_script_af(SCRIPTITEM_GLOBALMEMBERS, src);
1393 }
1394
1395 static void parse_script_with_error_a(const char *src, SCODE errorcode, ULONG line, LONG pos, LPCSTR source, LPCSTR desc, LPCSTR linetext)
1396 {
1397     BSTR tmp, script_source, description, line_text;
1398
1399     tmp = a2bstr(src);
1400     script_source = a2bstr(source);
1401     description = a2bstr(desc);
1402     line_text = a2bstr(linetext);
1403
1404     parse_script_with_error(SCRIPTITEM_GLOBALMEMBERS, tmp, errorcode, line, pos, script_source, description, line_text);
1405
1406     SysFreeString(line_text);
1407     SysFreeString(description);
1408     SysFreeString(script_source);
1409     SysFreeString(tmp);
1410 }
1411
1412 static HRESULT parse_htmlscript_a(const char *src)
1413 {
1414     HRESULT hres;
1415     BSTR tmp = a2bstr(src);
1416     hres = parse_htmlscript(tmp);
1417     SysFreeString(tmp);
1418
1419     return hres;
1420 }
1421
1422 static BSTR get_script_from_file(const char *filename)
1423 {
1424     DWORD size, len;
1425     HANDLE file, map;
1426     const char *file_map;
1427     BSTR ret;
1428
1429     file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
1430     if(file == INVALID_HANDLE_VALUE) {
1431         trace("Could not open file: %u\n", GetLastError());
1432         return NULL;
1433     }
1434
1435     size = GetFileSize(file, NULL);
1436
1437     map = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
1438     CloseHandle(file);
1439     if(map == INVALID_HANDLE_VALUE) {
1440         trace("Could not create file mapping: %u\n", GetLastError());
1441         return NULL;
1442     }
1443
1444     file_map = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
1445     CloseHandle(map);
1446     if(!file_map) {
1447         trace("MapViewOfFile failed: %u\n", GetLastError());
1448         return NULL;
1449     }
1450
1451     len = MultiByteToWideChar(CP_ACP, 0, file_map, size, NULL, 0);
1452     ret = SysAllocStringLen(NULL, len);
1453     MultiByteToWideChar(CP_ACP, 0, file_map, size, ret, len);
1454
1455     UnmapViewOfFile(file_map);
1456
1457     return ret;
1458 }
1459
1460 static void run_from_file(const char *filename)
1461 {
1462     BSTR script_str;
1463     HRESULT hres;
1464
1465     script_str = get_script_from_file(filename);
1466     if(!script_str)
1467         return;
1468
1469     strict_dispid_check = FALSE;
1470     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, script_str);
1471     SysFreeString(script_str);
1472     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
1473 }
1474
1475 static void run_from_res(const char *name)
1476 {
1477     const char *data;
1478     DWORD size, len;
1479     BSTR str;
1480     HRSRC src;
1481     HRESULT hres;
1482
1483     strict_dispid_check = FALSE;
1484     test_name = name;
1485
1486     src = FindResourceA(NULL, name, (LPCSTR)40);
1487     ok(src != NULL, "Could not find resource %s\n", name);
1488
1489     size = SizeofResource(NULL, src);
1490     data = LoadResource(NULL, src);
1491
1492     len = MultiByteToWideChar(CP_ACP, 0, data, size, NULL, 0);
1493     str = SysAllocStringLen(NULL, len);
1494     MultiByteToWideChar(CP_ACP, 0, data, size, str, len);
1495
1496     SET_EXPECT(global_success_d);
1497     SET_EXPECT(global_success_i);
1498     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, str);
1499     CHECK_CALLED(global_success_d);
1500     CHECK_CALLED(global_success_i);
1501
1502     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
1503     SysFreeString(str);
1504 }
1505
1506 static void test_isvisible(BOOL global_members)
1507 {
1508     IActiveScriptParse *parser;
1509     IActiveScript *engine;
1510     HRESULT hres;
1511
1512     static const WCHAR script_textW[] =
1513         {'v','a','r',' ','v',' ','=',' ','t','e','s','t','V','a','l',';',0};
1514
1515     engine = create_script();
1516     if(!engine)
1517         return;
1518
1519     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
1520     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1521     if (FAILED(hres))
1522     {
1523         IActiveScript_Release(engine);
1524         return;
1525     }
1526
1527     hres = IActiveScriptParse64_InitNew(parser);
1528     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
1529
1530     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
1531     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
1532
1533     if(global_members)
1534         SET_EXPECT(GetItemInfo_testVal);
1535     hres = IActiveScript_AddNamedItem(engine, test_valW,
1536             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|
1537             (global_members ? SCRIPTITEM_GLOBALMEMBERS : 0));
1538     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
1539     if(global_members)
1540         CHECK_CALLED(GetItemInfo_testVal);
1541
1542     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
1543     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
1544
1545     if(!global_members)
1546         SET_EXPECT(GetItemInfo_testVal);
1547     hres = IActiveScriptParse64_ParseScriptText(parser, script_textW, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
1548     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
1549     if(!global_members)
1550         CHECK_CALLED(GetItemInfo_testVal);
1551
1552     hres = IActiveScriptParse64_ParseScriptText(parser, script_textW, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
1553     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
1554
1555     IActiveScript_Release(engine);
1556     IUnknown_Release(parser);
1557 }
1558
1559 static BOOL run_tests(void)
1560 {
1561     HRESULT hres;
1562
1563     if(invoke_version) {
1564         IActiveScript *script;
1565
1566         script = create_script();
1567         if(!script) {
1568             win_skip("Could not create script\n");
1569             return FALSE;
1570         }
1571         IActiveScript_Release(script);
1572     }
1573
1574     strict_dispid_check = TRUE;
1575
1576     parse_script_a("");
1577     parse_script_a("/* empty */ ;");
1578
1579     SET_EXPECT(global_propget_d);
1580     SET_EXPECT(global_propget_i);
1581     parse_script_a("testPropGet;");
1582     CHECK_CALLED(global_propget_d);
1583     CHECK_CALLED(global_propget_i);
1584
1585     SET_EXPECT(global_propput_d);
1586     SET_EXPECT(global_propput_i);
1587     parse_script_a("testPropPut = 1;");
1588     CHECK_CALLED(global_propput_d);
1589     CHECK_CALLED(global_propput_i);
1590
1591     SET_EXPECT(global_success_d);
1592     SET_EXPECT(global_success_i);
1593     parse_script_a("reportSuccess();");
1594     CHECK_CALLED(global_success_d);
1595     CHECK_CALLED(global_success_i);
1596
1597     SET_EXPECT(testobj_delete);
1598     parse_script_a("delete testObj.deleteTest;");
1599     CHECK_CALLED(testobj_delete);
1600
1601     SET_EXPECT(global_propdelete_d);
1602     SET_EXPECT(DeleteMemberByDispID);
1603     parse_script_a("delete testPropDelete;");
1604     CHECK_CALLED(global_propdelete_d);
1605     CHECK_CALLED(DeleteMemberByDispID);
1606
1607     parse_script_a("(function reportSuccess() {})()");
1608
1609     parse_script_a("ok(typeof(test) === 'object', \"typeof(test) != 'object'\");");
1610
1611     parse_script_a("function reportSuccess() {}; reportSuccess();");
1612
1613     SET_EXPECT(global_propget_d);
1614     parse_script_a("var testPropGet");
1615     CHECK_CALLED(global_propget_d);
1616
1617     SET_EXPECT(global_propget_d);
1618     parse_script_a("eval('var testPropGet;');");
1619     CHECK_CALLED(global_propget_d);
1620
1621     SET_EXPECT(global_notexists_d);
1622     parse_script_a("var notExists; notExists = 1;");
1623     CHECK_CALLED(global_notexists_d);
1624
1625     parse_script_a("function f() { var testPropGet; }");
1626     parse_script_a("(function () { var testPropGet; })();");
1627     parse_script_a("(function () { eval('var testPropGet;'); })();");
1628
1629     SET_EXPECT(invoke_func);
1630     parse_script_a("ok(propGetFunc() == 0, \"Incorrect propGetFunc value\");");
1631     CHECK_CALLED(invoke_func);
1632     parse_script_a("ok(propGetFunc(1) == 1, \"Incorrect propGetFunc value\");");
1633     parse_script_a("ok(propGetFunc(1, 2) == 2, \"Incorrect propGetFunc value\");");
1634     SET_EXPECT(invoke_func);
1635     parse_script_a("ok(propGetFunc().toString() == 0, \"Incorrect propGetFunc value\");");
1636     CHECK_CALLED(invoke_func);
1637     parse_script_a("ok(propGetFunc(1).toString() == 1, \"Incorrect propGetFunc value\");");
1638     SET_EXPECT(invoke_func);
1639     parse_script_a("propGetFunc(1);");
1640     CHECK_CALLED(invoke_func);
1641
1642     parse_script_a("objectFlag(1).toString();");
1643
1644     parse_script_a("(function() { var tmp = (function () { return testObj; })()(1);})();");
1645     parse_script_a("(function() { var tmp = (function () { return testObj; })()();})();");
1646
1647     parse_script_a("ok((testObj instanceof Object) === false, 'testObj is instance of Object');");
1648
1649     SET_EXPECT(testobj_prop_d);
1650     parse_script_a("ok(('prop' in testObj) === true, 'prop is not in testObj');");
1651     CHECK_CALLED(testobj_prop_d);
1652
1653     SET_EXPECT(testobj_noprop_d);
1654     parse_script_a("ok(('noprop' in testObj) === false, 'noprop is in testObj');");
1655     CHECK_CALLED(testobj_noprop_d);
1656
1657     SET_EXPECT(testobj_prop_d);
1658     parse_script_a("ok(Object.prototype.hasOwnProperty.call(testObj, 'prop') === true, 'hasOwnProperty(\\\"prop\\\") returned false');");
1659     CHECK_CALLED(testobj_prop_d);
1660
1661     SET_EXPECT(testobj_noprop_d);
1662     parse_script_a("ok(Object.prototype.hasOwnProperty.call(testObj, 'noprop') === false, 'hasOwnProperty(\\\"noprop\\\") returned true');");
1663     CHECK_CALLED(testobj_noprop_d);
1664
1665     SET_EXPECT(puredisp_prop_d);
1666     parse_script_a("ok(Object.prototype.hasOwnProperty.call(pureDisp, 'prop') === true, 'hasOwnProperty(\\\"noprop\\\") returned false');");
1667     CHECK_CALLED(puredisp_prop_d);
1668
1669     SET_EXPECT(puredisp_noprop_d);
1670     parse_script_a("ok(Object.prototype.hasOwnProperty.call(pureDisp, 'noprop') === false, 'hasOwnProperty(\\\"noprop\\\") returned true');");
1671     CHECK_CALLED(puredisp_noprop_d);
1672
1673     SET_EXPECT(testobj_value);
1674     parse_script_a("ok(String(testObj) === '1', 'wrong testObj value');");
1675     CHECK_CALLED(testobj_value);
1676
1677     SET_EXPECT(testobj_value);
1678     parse_script_a("ok(String.prototype.concat.call(testObj, ' OK') === '1 OK', 'wrong concat result');");
1679     CHECK_CALLED(testobj_value);
1680
1681     SET_EXPECT(global_propget_d);
1682     SET_EXPECT(global_propget_i);
1683     parse_script_a("this.testPropGet;");
1684     CHECK_CALLED(global_propget_d);
1685     CHECK_CALLED(global_propget_i);
1686
1687     SET_EXPECT(global_propget_d);
1688     SET_EXPECT(global_propget_i);
1689     parse_script_a("(function () { this.testPropGet; })();");
1690     CHECK_CALLED(global_propget_d);
1691     CHECK_CALLED(global_propget_i);
1692
1693     parse_script_a("testThis(this);");
1694     parse_script_a("(function () { testThis(this); })();");
1695
1696     SET_EXPECT(testobj_onlydispid_d);
1697     SET_EXPECT(testobj_onlydispid_i);
1698     parse_script_a("ok(typeof(testObj.onlyDispID) === 'unknown', 'unexpected typeof(testObj.onlyDispID)');");
1699     CHECK_CALLED(testobj_onlydispid_d);
1700     CHECK_CALLED(testobj_onlydispid_i);
1701
1702     SET_EXPECT(global_propargput_d);
1703     SET_EXPECT(global_propargput_i);
1704     parse_script_a("var t=0; propArgPutG(t++, t++) = t++;");
1705     CHECK_CALLED(global_propargput_d);
1706     CHECK_CALLED(global_propargput_i);
1707
1708     SET_EXPECT(global_propargput_d);
1709     SET_EXPECT(global_propargput_i);
1710     parse_script_a("var t=0; test.propArgPutO(t++, t++) = t++;");
1711     CHECK_CALLED(global_propargput_d);
1712     CHECK_CALLED(global_propargput_i);
1713
1714     SET_EXPECT(global_testargtypes_i);
1715     parse_script_a("testArgTypes(getShort(), shortProp, function(s) {ok(getVT(s) === 'VT_I4', 'not VT_I4');});");
1716     CHECK_CALLED(global_testargtypes_i);
1717
1718     run_from_res("lang.js");
1719     run_from_res("api.js");
1720     run_from_res("regexp.js");
1721     run_from_res("cc.js");
1722
1723     test_isvisible(FALSE);
1724     test_isvisible(TRUE);
1725
1726     parse_script_af(0, "test.testThis2(this);");
1727     parse_script_af(0, "(function () { test.testThis2(this); })();");
1728
1729     hres = parse_htmlscript_a("<!--");
1730     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
1731     hres = parse_htmlscript_a("-->");
1732     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
1733     hres = parse_htmlscript_a("<!--\nvar a=1;\n-->\n");
1734     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
1735     hres = parse_htmlscript_a("<!--\n<!-- ignore this\n-->\n");
1736     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
1737     hres = parse_htmlscript_a("var a=1;\nif(a-->0) a=5;\n");
1738     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
1739     hres = parse_htmlscript_a("var a=1;\nif(a\n-->0) a=5;\n");
1740     ok(hres != S_OK, "ParseScriptText have not failed\n");
1741
1742     parse_script_with_error_a(
1743         "?",
1744         0x800a03ea, 0, 0,
1745         "Microsoft JScript compilation error",
1746         "Syntax error",
1747         "?");
1748
1749     parse_script_with_error_a(
1750         "var a=1;\nif(a\n-->0) a=5;\n",
1751         0x800a03ee, 2, 0,
1752         "Microsoft JScript compilation error",
1753         "Expected ')'",
1754         "-->0) a=5;");
1755
1756     parse_script_with_error_a(
1757         "new 3;",
1758         0x800a01bd, 0, 0,
1759         "Microsoft JScript runtime error",
1760         "Object doesn't support this action",
1761         NULL);
1762
1763     parse_script_with_error_a(
1764         "new null;",
1765         0x800a138f, 0, 0,
1766         "Microsoft JScript runtime error",
1767         "Object expected",
1768         NULL);
1769
1770     parse_script_with_error_a(
1771         "var a;\nnew null;",
1772         0x800a138f, 1, 0,
1773         "Microsoft JScript runtime error",
1774         "Object expected",
1775         NULL);
1776
1777     parse_script_with_error_a(
1778         "var a; new null;",
1779         0x800a138f, 0, 7,
1780         "Microsoft JScript runtime error",
1781         "Object expected",
1782         NULL);
1783
1784     return TRUE;
1785 }
1786
1787 static void run_encoded_tests(void)
1788 {
1789     BSTR src;
1790     HRESULT hres;
1791
1792     engine_clsid = &CLSID_JScriptEncode;
1793
1794     SET_EXPECT(global_success_d);
1795     SET_EXPECT(global_success_i);
1796     /*             |reportSuccess();                           | */
1797     parse_script_a("#@~^EAAAAA==.\x7fwGMYUEm1+kd`*iAQYAAA==^#~@");
1798     CHECK_CALLED(global_success_d);
1799     CHECK_CALLED(global_success_i);
1800
1801     SET_EXPECT(global_success_d);
1802     SET_EXPECT(global_success_i);
1803     parse_script_a("reportSuccess();");
1804     CHECK_CALLED(global_success_d);
1805     CHECK_CALLED(global_success_i);
1806
1807     SET_EXPECT(global_success_d);
1808     SET_EXPECT(global_success_i);
1809     /*                   |Success                         | */
1810     parse_script_a("report#@~^BwAAAA==j!m^\x7f/k2QIAAA==^#~@();");
1811     CHECK_CALLED(global_success_d);
1812     CHECK_CALLED(global_success_i);
1813
1814     SET_EXPECT(global_success_d);
1815     SET_EXPECT(global_success_i);
1816     /*             |\r\n\treportSuccess();\r\n                        | */
1817     parse_script_a("#@~^GQAAAA==@#@&d.\x7fwKDYUE1^+k/c#p@#@&OAYAAA==^#~@");
1818     CHECK_CALLED(global_success_d);
1819     CHECK_CALLED(global_success_i);
1820
1821     /*                   v                                   */
1822     src = a2bstr("#@~^EAA*AA==.\x7fwGMYUEm1+kd`*iAQYAAA==^#~@");
1823     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
1824     SysFreeString(src);
1825     ok(hres == JS_E_INVALID_CHAR, "parse_script failed %08x\n", hres);
1826
1827     /*                      vv                                 */
1828     src = a2bstr("#@~^EAAAAAAA==.\x7fwGMYUEm1+kd`*iAQYAAA==^#~@");
1829     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
1830     SysFreeString(src);
1831     ok(hres == JS_E_INVALID_CHAR, "parse_script failed %08x\n", hres);
1832
1833     /*                      v                                */
1834     src = a2bstr("#@~^EAAAAA^=.\x7fwGMYUEm1+kd`*iAQYAAA==^#~@");
1835     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
1836     SysFreeString(src);
1837     ok(hres == JS_E_INVALID_CHAR, "parse_script failed %08x\n", hres);
1838
1839     /*                                     v                 */
1840     src = a2bstr("#@~^EAAAAA==.\x7fwGMYUEm1ekd`*iAQYAAA==^#~@");
1841     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
1842     SysFreeString(src);
1843     ok(hres == JS_E_INVALID_CHAR, "parse_script failed %08x\n", hres);
1844
1845     /*                                                    vv  */
1846     src = a2bstr("#@~^EAAAAA==.\x7fwGMYUEm1+kd`*iAQYAAA==^~#@");
1847     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
1848     SysFreeString(src);
1849     ok(hres == JS_E_INVALID_CHAR, "parse_script failed %08x\n", hres);
1850 }
1851
1852 static BOOL check_jscript(void)
1853 {
1854     IActiveScriptProperty *script_prop;
1855     BSTR str;
1856     HRESULT hres;
1857
1858     hres = CoCreateInstance(&CLSID_JScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1859             &IID_IActiveScriptProperty, (void**)&script_prop);
1860     if(FAILED(hres))
1861         return FALSE;
1862     IActiveScriptProperty_Release(script_prop);
1863
1864     str = a2bstr("if(!('localeCompare' in String.prototype)) throw 1;");
1865     hres = parse_script(0, str);
1866     SysFreeString(str);
1867
1868     return hres == S_OK;
1869 }
1870
1871 START_TEST(run)
1872 {
1873     int argc;
1874     char **argv;
1875
1876     argc = winetest_get_mainargs(&argv);
1877
1878     CoInitialize(NULL);
1879
1880     if(!check_jscript()) {
1881         win_skip("Broken engine, probably too old\n");
1882     }else if(argc > 2) {
1883         invoke_version = 2;
1884         run_from_file(argv[2]);
1885     }else {
1886         trace("invoke version 0\n");
1887         invoke_version = 0;
1888         run_tests();
1889
1890         trace("invoke version 2\n");
1891         invoke_version = 2;
1892         if(run_tests()) {
1893             trace("JSctipt.Encode tests...\n");
1894             run_encoded_tests();
1895         }
1896     }
1897
1898     CoUninitialize();
1899 }