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