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