vbscript: Use default object value for objets in stack_pop_val.
[wine] / dlls / vbscript / tests / run.c
1 /*
2  * Copyright 2011 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 extern const CLSID CLSID_VBScript;
31
32 #define DEFINE_EXPECT(func) \
33     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
34
35 #define SET_EXPECT(func) \
36     expect_ ## func = TRUE
37
38 #define SET_CALLED(func) \
39     called_ ## 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_success_d);
60 DEFINE_EXPECT(global_success_i);
61 DEFINE_EXPECT(global_vbvar_d);
62 DEFINE_EXPECT(global_vbvar_i);
63 DEFINE_EXPECT(testobj_propget_d);
64 DEFINE_EXPECT(testobj_propget_i);
65 DEFINE_EXPECT(testobj_propput_d);
66 DEFINE_EXPECT(testobj_propput_i);
67
68 #define DISPID_GLOBAL_REPORTSUCCESS 1000
69 #define DISPID_GLOBAL_TRACE         1001
70 #define DISPID_GLOBAL_OK            1002
71 #define DISPID_GLOBAL_GETVT         1003
72 #define DISPID_GLOBAL_ISENGLANG     1004
73 #define DISPID_GLOBAL_VBVAR         1005
74 #define DISPID_GLOBAL_TESTOBJ       1006
75 #define DISPID_GLOBAL_ISNULLDISP    1007
76 #define DISPID_GLOBAL_TESTDISP      1008
77
78 #define DISPID_TESTOBJ_PROPGET      2000
79 #define DISPID_TESTOBJ_PROPPUT      2001
80
81 static const WCHAR testW[] = {'t','e','s','t',0};
82
83 static BOOL strict_dispid_check;
84 static const char *test_name = "(null)";
85
86 static BSTR a2bstr(const char *str)
87 {
88     BSTR ret;
89     int len;
90
91     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
92     ret = SysAllocStringLen(NULL, len-1);
93     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
94
95     return ret;
96 }
97
98 static int strcmp_wa(LPCWSTR strw, const char *stra)
99 {
100     CHAR buf[512];
101     WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), 0, 0);
102     return lstrcmpA(buf, stra);
103 }
104
105 static const char *vt2a(VARIANT *v)
106 {
107     if(V_VT(v) == (VT_BYREF|VT_VARIANT)) {
108         static char buf[64];
109         sprintf(buf, "%s*", vt2a(V_BYREF(v)));
110         return buf;
111     }
112
113     switch(V_VT(v)) {
114     case VT_EMPTY:
115         return "VT_EMPTY";
116     case VT_NULL:
117         return "VT_NULL";
118     case VT_I2:
119         return "VT_I2";
120     case VT_I4:
121         return "VT_I4";
122     case VT_R8:
123         return "VT_R8";
124     case VT_BSTR:
125         return "VT_BSTR";
126     case VT_DISPATCH:
127         return "VT_DISPATCH";
128     case VT_BOOL:
129         return "VT_BOOL";
130     case VT_ARRAY|VT_VARIANT:
131         return "VT_ARRAY|VT_VARIANT";
132     default:
133         ok(0, "unknown vt %d\n", V_VT(v));
134         return NULL;
135     }
136 }
137
138 /* Returns true if the user interface is in English. Note that this does not
139  * presume of the formatting of dates, numbers, etc.
140  */
141 static BOOL is_lang_english(void)
142 {
143     static HMODULE hkernel32 = NULL;
144     static LANGID (WINAPI *pGetThreadUILanguage)(void) = NULL;
145     static LANGID (WINAPI *pGetUserDefaultUILanguage)(void) = NULL;
146
147     if (!hkernel32)
148     {
149         hkernel32 = GetModuleHandleA("kernel32.dll");
150         pGetThreadUILanguage = (void*)GetProcAddress(hkernel32, "GetThreadUILanguage");
151         pGetUserDefaultUILanguage = (void*)GetProcAddress(hkernel32, "GetUserDefaultUILanguage");
152     }
153     if (pGetThreadUILanguage)
154         return PRIMARYLANGID(pGetThreadUILanguage()) == LANG_ENGLISH;
155     if (pGetUserDefaultUILanguage)
156         return PRIMARYLANGID(pGetUserDefaultUILanguage()) == LANG_ENGLISH;
157
158     return PRIMARYLANGID(GetUserDefaultLangID()) == LANG_ENGLISH;
159 }
160
161 static void test_disp(IDispatch *disp)
162 {
163     DISPID id, public_prop_id, public_prop2_id, public_func_id, public_sub_id;
164     DISPID named_args[5] = {DISPID_PROPERTYPUT};
165     VARIANT v, args[5];
166     DISPPARAMS dp = {args, named_args};
167     IDispatchEx *dispex;
168     EXCEPINFO ei = {0};
169     BSTR str;
170     HRESULT hres;
171
172     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
173     ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
174
175     str = a2bstr("publicProp");
176     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_prop_id);
177     SysFreeString(str);
178     ok(hres == S_OK, "GetDispID(publicProp) failed: %08x\n", hres);
179
180     str = a2bstr("PUBLICPROP");
181     hres = IDispatchEx_GetDispID(dispex, str, 0, &id);
182     SysFreeString(str);
183     ok(hres == S_OK, "GetDispID(PUBLICPROP) failed: %08x\n", hres);
184     ok(public_prop_id == id, "id = %d\n", public_prop_id);
185
186     str = a2bstr("publicPROP2");
187     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_prop2_id);
188     SysFreeString(str);
189     ok(hres == S_OK, "GetDispID(publicProp2) failed: %08x\n", hres);
190
191     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
192     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
193     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
194
195     V_VT(args) = VT_BOOL;
196     V_BOOL(args) = VARIANT_TRUE;
197     dp.cArgs = dp.cNamedArgs = 1;
198     V_VT(&v) = VT_BOOL;
199     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUT, &dp, &v, &ei, NULL);
200     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
201     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
202
203     dp.cArgs = dp.cNamedArgs = 0;
204     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
205    ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
206     ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
207     ok(V_BOOL(&v), "V_BOOL(v) = %x\n", V_BOOL(&v));
208
209     dp.cArgs = 1;
210     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
211     ok(hres == DISP_E_MEMBERNOTFOUND, "InvokeEx failed: %08x, expected DISP_E_MEMBERNOTFOUND\n", hres);
212     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
213
214     V_VT(args) = VT_BOOL;
215     V_BOOL(args) = VARIANT_FALSE;
216     dp.cArgs = 1;
217     V_VT(&v) = VT_BOOL;
218     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL);
219     ok(hres == DISP_E_PARAMNOTOPTIONAL, "InvokeEx failed: %08x, expected DISP_E_PARAMNOTOPTIONAL\n", hres);
220
221     str = a2bstr("publicFunction");
222     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_func_id);
223     SysFreeString(str);
224     ok(hres == S_OK, "GetDispID(publicFunction) failed: %08x\n", hres);
225     ok(public_func_id != -1, "public_func_id = -1\n");
226
227     str = a2bstr("publicSub");
228     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_sub_id);
229     SysFreeString(str);
230     ok(hres == S_OK, "GetDispID(publicSub) failed: %08x\n", hres);
231     ok(public_sub_id != -1, "public_func_id = -1\n");
232
233     dp.cArgs = dp.cNamedArgs = 0;
234     hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
235     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
236     ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
237     ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
238
239     dp.cArgs = dp.cNamedArgs = 0;
240     hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
241     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
242     ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
243     ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
244
245     dp.cArgs = dp.cNamedArgs = 0;
246     hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
247     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
248     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
249
250     dp.cArgs = dp.cNamedArgs = 0;
251     hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
252     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
253     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
254
255     str = a2bstr("privateSub");
256     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id);
257     SysFreeString(str);
258     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateSub) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
259     ok(id == -1, "id = %d\n", id);
260
261     str = a2bstr("dynprop");
262     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive|fdexNameEnsure, &id);
263     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateProp) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
264     ok(id == -1, "id = %d\n", id);
265     hres = IDispatchEx_GetDispID(dispex, str, fdexNameEnsure, &id);
266     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateProp) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
267     ok(id == -1, "id = %d\n", id);
268     SysFreeString(str);
269
270     IDispatchEx_Release(dispex);
271 }
272
273 #define test_grfdex(a,b) _test_grfdex(__LINE__,a,b)
274 static void _test_grfdex(unsigned line, DWORD grfdex, DWORD expect)
275 {
276     ok_(__FILE__,line)(grfdex == expect, "grfdex = %x, expected %x\n", grfdex, expect);
277 }
278
279 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
280 {
281     *ppv = NULL;
282
283     if(IsEqualGUID(riid, &IID_IUnknown)
284        || IsEqualGUID(riid, &IID_IDispatch)
285        || IsEqualGUID(riid, &IID_IDispatchEx))
286         *ppv = iface;
287     else
288         return E_NOINTERFACE;
289
290     return S_OK;
291 }
292
293 static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
294 {
295     return 2;
296 }
297
298 static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
299 {
300     return 1;
301 }
302
303 static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
304 {
305     ok(0, "unexpected call\n");
306     return E_NOTIMPL;
307 }
308
309 static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
310                                               LCID lcid, ITypeInfo **ppTInfo)
311 {
312     ok(0, "unexpected call\n");
313     return E_NOTIMPL;
314 }
315
316 static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
317                                                 LPOLESTR *rgszNames, UINT cNames,
318                                                 LCID lcid, DISPID *rgDispId)
319 {
320     ok(0, "unexpected call\n");
321     return E_NOTIMPL;
322 }
323
324 static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
325                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
326                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
327 {
328     ok(0, "unexpected call\n");
329     return E_NOTIMPL;
330 }
331
332 static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
333 {
334     ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
335     return E_NOTIMPL;
336 }
337
338 static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
339 {
340     ok(0, "unexpected call\n");
341     return E_NOTIMPL;
342 }
343
344 static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
345 {
346     ok(0, "unexpected call\n");
347     return E_NOTIMPL;
348 }
349
350 static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
351 {
352     ok(0, "unexpected call\n");
353     return E_NOTIMPL;
354 }
355
356 static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
357 {
358     ok(0, "unexpected call\n");
359     return E_NOTIMPL;
360 }
361
362 static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
363 {
364     ok(0, "unexpected call\n");
365     return E_NOTIMPL;
366 }
367
368 static HRESULT WINAPI testObj_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
369 {
370     if(!strcmp_wa(bstrName, "propget")) {
371         CHECK_EXPECT(testobj_propget_d);
372         test_grfdex(grfdex, fdexNameCaseInsensitive);
373         *pid = DISPID_TESTOBJ_PROPGET;
374         return S_OK;
375     }
376     if(!strcmp_wa(bstrName, "propput")) {
377         CHECK_EXPECT(testobj_propput_d);
378         test_grfdex(grfdex, fdexNameCaseInsensitive);
379         *pid = DISPID_TESTOBJ_PROPPUT;
380         return S_OK;
381     }
382
383     ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName));
384     return DISP_E_UNKNOWNNAME;
385 }
386
387 static HRESULT WINAPI testObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
388         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
389 {
390     switch(id) {
391     case DISPID_TESTOBJ_PROPGET:
392         CHECK_EXPECT(testobj_propget_i);
393
394         ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
395         ok(pdp != NULL, "pdp == NULL\n");
396         ok(!pdp->rgvarg, "rgvarg == NULL\n");
397         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
398         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
399         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
400         ok(pvarRes != NULL, "pvarRes == NULL\n");
401         ok(pei != NULL, "pei == NULL\n");
402
403         V_VT(pvarRes) = VT_I2;
404         V_I2(pvarRes) = 10;
405         return S_OK;
406     case DISPID_TESTOBJ_PROPPUT:
407         CHECK_EXPECT(testobj_propput_i);
408
409         ok(wFlags == DISPATCH_PROPERTYPUT, "wFlags = %x\n", wFlags);
410         ok(pdp != NULL, "pdp == NULL\n");
411         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
412         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
413         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
414         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
415         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
416         ok(!pvarRes, "pvarRes != NULL\n");
417         ok(pei != NULL, "pei == NULL\n");
418
419         ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
420         ok(V_I2(pdp->rgvarg) == 1, "V_I2(psp->rgvargs) = %d\n", V_I2(pdp->rgvarg));
421         return S_OK;
422     }
423
424     ok(0, "unexpected call %d\n", id);
425     return E_FAIL;
426 }
427
428 static IDispatchExVtbl testObjVtbl = {
429     DispatchEx_QueryInterface,
430     DispatchEx_AddRef,
431     DispatchEx_Release,
432     DispatchEx_GetTypeInfoCount,
433     DispatchEx_GetTypeInfo,
434     DispatchEx_GetIDsOfNames,
435     DispatchEx_Invoke,
436     testObj_GetDispID,
437     testObj_InvokeEx,
438     DispatchEx_DeleteMemberByName,
439     DispatchEx_DeleteMemberByDispID,
440     DispatchEx_GetMemberProperties,
441     DispatchEx_GetMemberName,
442     DispatchEx_GetNextDispID,
443     DispatchEx_GetNameSpaceParent
444 };
445
446 static IDispatchEx testObj = { &testObjVtbl };
447
448 static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
449 {
450     if(!strcmp_wa(bstrName, "ok")) {
451         test_grfdex(grfdex, fdexNameCaseInsensitive);
452         *pid = DISPID_GLOBAL_OK;
453         return S_OK;
454     }
455     if(!strcmp_wa(bstrName, "trace")) {
456         test_grfdex(grfdex, fdexNameCaseInsensitive);
457         *pid = DISPID_GLOBAL_TRACE;
458         return S_OK;
459     }
460     if(!strcmp_wa(bstrName, "reportSuccess")) {
461         CHECK_EXPECT(global_success_d);
462         test_grfdex(grfdex, fdexNameCaseInsensitive);
463         *pid = DISPID_GLOBAL_REPORTSUCCESS;
464         return S_OK;
465     }
466     if(!strcmp_wa(bstrName, "getVT")) {
467         test_grfdex(grfdex, fdexNameCaseInsensitive);
468         *pid = DISPID_GLOBAL_GETVT;
469         return S_OK;
470     }
471     if(!strcmp_wa(bstrName, "isEnglishLang")) {
472         test_grfdex(grfdex, fdexNameCaseInsensitive);
473         *pid = DISPID_GLOBAL_ISENGLANG;
474         return S_OK;
475     }
476     if(!strcmp_wa(bstrName, "testObj")) {
477         test_grfdex(grfdex, fdexNameCaseInsensitive);
478         *pid = DISPID_GLOBAL_TESTOBJ;
479         return S_OK;
480     }
481     if(!strcmp_wa(bstrName, "vbvar")) {
482         CHECK_EXPECT(global_vbvar_d);
483         test_grfdex(grfdex, fdexNameCaseInsensitive);
484         *pid = DISPID_GLOBAL_VBVAR;
485         return S_OK;
486     }
487     if(!strcmp_wa(bstrName, "isNullDisp")) {
488         test_grfdex(grfdex, fdexNameCaseInsensitive);
489         *pid = DISPID_GLOBAL_ISNULLDISP;
490         return S_OK;
491     }
492     if(!strcmp_wa(bstrName, "testDisp")) {
493         test_grfdex(grfdex, fdexNameCaseInsensitive);
494         *pid = DISPID_GLOBAL_TESTDISP;
495         return S_OK;
496     }
497
498     if(strict_dispid_check && strcmp_wa(bstrName, "x"))
499         ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
500     return DISP_E_UNKNOWNNAME;
501 }
502
503 static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
504         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
505 {
506     switch(id) {
507     case DISPID_GLOBAL_OK: {
508         VARIANT *b;
509
510         ok(wFlags == INVOKE_FUNC || wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
511         ok(pdp != NULL, "pdp == NULL\n");
512         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
513         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
514         ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
515         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
516         if(wFlags & INVOKE_PROPERTYGET)
517             ok(pvarRes != NULL, "pvarRes == NULL\n");
518         else
519             ok(!pvarRes, "pvarRes != NULL\n");
520         ok(pei != NULL, "pei == NULL\n");
521
522         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
523
524         b = pdp->rgvarg+1;
525         if(V_VT(b) == (VT_BYREF|VT_VARIANT))
526             b = V_BYREF(b);
527
528         ok(V_VT(b) == VT_BOOL, "V_VT(b) = %d\n", V_VT(b));
529
530         ok(V_BOOL(b), "%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
531         return S_OK;
532     }
533
534      case DISPID_GLOBAL_TRACE:
535         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
536         ok(pdp != NULL, "pdp == NULL\n");
537         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
538         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
539         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
540         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
541         ok(!pvarRes, "pvarRes != NULL\n");
542         ok(pei != NULL, "pei == NULL\n");
543
544         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
545         if(V_VT(pdp->rgvarg) == VT_BSTR)
546             trace("%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
547
548         return S_OK;
549
550     case DISPID_GLOBAL_REPORTSUCCESS:
551         CHECK_EXPECT(global_success_i);
552
553         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
554         ok(pdp != NULL, "pdp == NULL\n");
555         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
556         ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
557         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
558         ok(!pvarRes, "pvarRes != NULL\n");
559         ok(pei != NULL, "pei == NULL\n");
560
561         return S_OK;
562
563     case DISPID_GLOBAL_GETVT:
564         ok(pdp != NULL, "pdp == NULL\n");
565         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
566         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
567         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
568         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
569         ok(pvarRes != NULL, "pvarRes == NULL\n");
570         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
571         ok(pei != NULL, "pei == NULL\n");
572
573         V_VT(pvarRes) = VT_BSTR;
574         V_BSTR(pvarRes) = a2bstr(vt2a(pdp->rgvarg));
575         return S_OK;
576
577     case DISPID_GLOBAL_ISENGLANG:
578         ok(wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
579         ok(pdp != NULL, "pdp == NULL\n");
580         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
581         ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
582         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
583         ok(pvarRes != NULL, "pvarRes == NULL\n");
584         ok(pei != NULL, "pei == NULL\n");
585
586         V_VT(pvarRes) = VT_BOOL;
587         if(is_lang_english()) {
588             V_BOOL(pvarRes) = VARIANT_TRUE;
589         }else {
590             skip("Skipping some tests in non-English UIs\n");
591             V_BOOL(pvarRes) = VARIANT_FALSE;
592         }
593         return S_OK;
594
595     case DISPID_GLOBAL_VBVAR:
596         CHECK_EXPECT(global_vbvar_i);
597
598         ok(wFlags == DISPATCH_PROPERTYPUT, "wFlags = %x\n", wFlags);
599         ok(pdp != NULL, "pdp == NULL\n");
600         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
601         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
602         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
603         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
604         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
605         ok(!pvarRes, "pvarRes != NULL\n");
606         ok(pei != NULL, "pei == NULL\n");
607
608         ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
609         ok(V_I2(pdp->rgvarg) == 3, "V_I2(psp->rgvargs) = %d\n", V_I2(pdp->rgvarg));
610         return S_OK;
611
612     case DISPID_GLOBAL_TESTOBJ:
613         ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
614
615         ok(pdp != NULL, "pdp == NULL\n");
616         ok(!pdp->rgvarg, "rgvarg == NULL\n");
617         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
618         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
619         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
620         ok(pvarRes != NULL, "pvarRes == NULL\n");
621         ok(pei != NULL, "pei == NULL\n");
622
623         V_VT(pvarRes) = VT_DISPATCH;
624         V_DISPATCH(pvarRes) = (IDispatch*)&testObj;
625         return S_OK;
626
627     case DISPID_GLOBAL_ISNULLDISP: {
628         VARIANT *v;
629
630         ok(wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
631         ok(pdp != NULL, "pdp == NULL\n");
632         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
633         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
634         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
635         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
636         ok(pvarRes != NULL, "pvarRes == NULL\n");
637         ok(pei != NULL, "pei == NULL\n");
638
639         v = pdp->rgvarg;
640         if(V_VT(v) == (VT_VARIANT|VT_BYREF))
641             v = V_VARIANTREF(v);
642
643         ok(V_VT(v) == VT_DISPATCH, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
644         V_VT(pvarRes) = VT_BOOL;
645         V_BOOL(pvarRes) = V_DISPATCH(v) ? VARIANT_FALSE : VARIANT_TRUE;
646         return S_OK;
647     }
648
649     case DISPID_GLOBAL_TESTDISP:
650         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
651         ok(pdp != NULL, "pdp == NULL\n");
652         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
653         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
654         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
655         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
656         ok(!pvarRes, "pvarRes != NULL\n");
657         ok(pei != NULL, "pei == NULL\n");
658
659         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
660         test_disp(V_DISPATCH(pdp->rgvarg));
661         return S_OK;
662     }
663
664     ok(0, "unexpected call %d\n", id);
665     return DISP_E_MEMBERNOTFOUND;
666 }
667
668 static IDispatchExVtbl GlobalVtbl = {
669     DispatchEx_QueryInterface,
670     DispatchEx_AddRef,
671     DispatchEx_Release,
672     DispatchEx_GetTypeInfoCount,
673     DispatchEx_GetTypeInfo,
674     DispatchEx_GetIDsOfNames,
675     DispatchEx_Invoke,
676     Global_GetDispID,
677     Global_InvokeEx,
678     DispatchEx_DeleteMemberByName,
679     DispatchEx_DeleteMemberByDispID,
680     DispatchEx_GetMemberProperties,
681     DispatchEx_GetMemberName,
682     DispatchEx_GetNextDispID,
683     DispatchEx_GetNameSpaceParent
684 };
685
686 static IDispatchEx Global = { &GlobalVtbl };
687
688 static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
689 {
690     *ppv = NULL;
691
692     if(IsEqualGUID(&IID_IUnknown, riid))
693         *ppv = iface;
694     else if(IsEqualGUID(&IID_IActiveScriptSite, riid))
695         *ppv = iface;
696     else
697         return E_NOINTERFACE;
698
699     IUnknown_AddRef((IUnknown*)*ppv);
700     return S_OK;
701 }
702
703 static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
704 {
705     return 2;
706 }
707
708 static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
709 {
710     return 1;
711 }
712
713 static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *plcid)
714 {
715     *plcid = GetUserDefaultLCID();
716     return S_OK;
717 }
718
719 static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR pstrName,
720         DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti)
721 {
722     ok(dwReturnMask == SCRIPTINFO_IUNKNOWN, "unexpected dwReturnMask %x\n", dwReturnMask);
723     ok(!ppti, "ppti != NULL\n");
724
725     if(strcmp_wa(pstrName, "test"))
726         ok(0, "unexpected pstrName %s\n", wine_dbgstr_w(pstrName));
727
728     *ppiunkItem = (IUnknown*)&Global;
729     return S_OK;
730 }
731
732 static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *pbstrVersion)
733 {
734     return E_NOTIMPL;
735 }
736
737 static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface,
738         const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo)
739 {
740     return E_NOTIMPL;
741 }
742
743 static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE ssScriptState)
744 {
745     return E_NOTIMPL;
746 }
747
748 static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
749 {
750     return E_NOTIMPL;
751 }
752
753 static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
754 {
755     return E_NOTIMPL;
756 }
757
758 static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
759 {
760     return E_NOTIMPL;
761 }
762
763 #undef ACTSCPSITE_THIS
764
765 static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
766     ActiveScriptSite_QueryInterface,
767     ActiveScriptSite_AddRef,
768     ActiveScriptSite_Release,
769     ActiveScriptSite_GetLCID,
770     ActiveScriptSite_GetItemInfo,
771     ActiveScriptSite_GetDocVersionString,
772     ActiveScriptSite_OnScriptTerminate,
773     ActiveScriptSite_OnStateChange,
774     ActiveScriptSite_OnScriptError,
775     ActiveScriptSite_OnEnterScript,
776     ActiveScriptSite_OnLeaveScript
777 };
778
779 static IActiveScriptSite ActiveScriptSite = { &ActiveScriptSiteVtbl };
780
781 static IActiveScript *create_script(void)
782 {
783     IActiveScript *script;
784     HRESULT hres;
785
786     hres = CoCreateInstance(&CLSID_VBScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
787             &IID_IActiveScript, (void**)&script);
788     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
789
790     return script;
791 }
792
793 static HRESULT parse_script(DWORD flags, BSTR script_str)
794 {
795     IActiveScriptParse *parser;
796     IActiveScript *engine;
797     IDispatch *script_disp;
798     HRESULT hres;
799
800     engine = create_script();
801     if(!engine)
802         return S_OK;
803
804     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
805     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
806     if (FAILED(hres))
807     {
808         IActiveScript_Release(engine);
809         return hres;
810     }
811
812     hres = IActiveScriptParse64_InitNew(parser);
813     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
814
815     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
816     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
817
818     hres = IActiveScript_AddNamedItem(engine, testW,
819             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|flags);
820     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
821
822     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
823     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
824
825     hres = IActiveScript_GetScriptDispatch(engine, NULL, &script_disp);
826     ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres);
827     ok(script_disp != NULL, "script_disp == NULL\n");
828     ok(script_disp != (IDispatch*)&Global, "script_disp == Global\n");
829
830     hres = IActiveScriptParse64_ParseScriptText(parser, script_str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
831
832     IDispatch_Release(script_disp);
833     IActiveScript_Release(engine);
834     IUnknown_Release(parser);
835
836     return hres;
837 }
838
839 static void parse_script_af(DWORD flags, const char *src)
840 {
841     BSTR tmp;
842     HRESULT hres;
843
844     tmp = a2bstr(src);
845     hres = parse_script(flags, tmp);
846     SysFreeString(tmp);
847     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
848 }
849
850 static void parse_script_a(const char *src)
851 {
852     parse_script_af(SCRIPTITEM_GLOBALMEMBERS, src);
853 }
854
855 static BSTR get_script_from_file(const char *filename)
856 {
857     DWORD size, len;
858     HANDLE file, map;
859     const char *file_map;
860     BSTR ret;
861
862     file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
863     if(file == INVALID_HANDLE_VALUE) {
864         trace("Could not open file: %u\n", GetLastError());
865         return NULL;
866     }
867
868     size = GetFileSize(file, NULL);
869
870     map = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
871     CloseHandle(file);
872     if(map == INVALID_HANDLE_VALUE) {
873         trace("Could not create file mapping: %u\n", GetLastError());
874         return NULL;
875     }
876
877     file_map = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
878     CloseHandle(map);
879     if(!file_map) {
880         trace("MapViewOfFile failed: %u\n", GetLastError());
881         return NULL;
882     }
883
884     len = MultiByteToWideChar(CP_ACP, 0, file_map, size, NULL, 0);
885     ret = SysAllocStringLen(NULL, len);
886     MultiByteToWideChar(CP_ACP, 0, file_map, size, ret, len);
887
888     UnmapViewOfFile(file_map);
889
890     return ret;
891 }
892
893 static void run_from_file(const char *filename)
894 {
895     BSTR script_str;
896     HRESULT hres;
897
898     script_str = get_script_from_file(filename);
899     if(!script_str)
900         return;
901
902     strict_dispid_check = FALSE;
903     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, script_str);
904     SysFreeString(script_str);
905     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
906 }
907
908 static void run_from_res(const char *name)
909 {
910     const char *data;
911     DWORD size, len;
912     BSTR str;
913     HRSRC src;
914     HRESULT hres;
915
916     strict_dispid_check = FALSE;
917     test_name = name;
918
919     src = FindResourceA(NULL, name, (LPCSTR)40);
920     ok(src != NULL, "Could not find resource %s\n", name);
921
922     size = SizeofResource(NULL, src);
923     data = LoadResource(NULL, src);
924
925     len = MultiByteToWideChar(CP_ACP, 0, data, size, NULL, 0);
926     str = SysAllocStringLen(NULL, len);
927     MultiByteToWideChar(CP_ACP, 0, data, size, str, len);
928
929     SET_EXPECT(global_success_d);
930     SET_EXPECT(global_success_i);
931     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, str);
932     CHECK_CALLED(global_success_d);
933     CHECK_CALLED(global_success_i);
934
935     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
936     SysFreeString(str);
937 }
938
939 static void run_tests(void)
940 {
941     strict_dispid_check = TRUE;
942
943     parse_script_a("");
944     parse_script_a("' empty ;");
945
946     SET_EXPECT(global_success_d);
947     SET_EXPECT(global_success_i);
948     parse_script_a("reportSuccess");
949     CHECK_CALLED(global_success_d);
950     CHECK_CALLED(global_success_i);
951
952     SET_EXPECT(global_success_d);
953     SET_EXPECT(global_success_i);
954     parse_script_a("reportSuccess()");
955     CHECK_CALLED(global_success_d);
956     CHECK_CALLED(global_success_i);
957
958     SET_EXPECT(global_success_d);
959     SET_EXPECT(global_success_i);
960     parse_script_a("Call reportSuccess");
961     CHECK_CALLED(global_success_d);
962     CHECK_CALLED(global_success_i);
963
964     SET_EXPECT(global_vbvar_d);
965     SET_EXPECT(global_vbvar_i);
966     parse_script_a("Option Explicit\nvbvar = 3");
967     CHECK_CALLED(global_vbvar_d);
968     CHECK_CALLED(global_vbvar_i);
969
970     SET_EXPECT(global_vbvar_d);
971     SET_EXPECT(global_vbvar_i);
972     parse_script_a("Option Explicit\nvbvar() = 3");
973     CHECK_CALLED(global_vbvar_d);
974     CHECK_CALLED(global_vbvar_i);
975
976     SET_EXPECT(testobj_propget_d);
977     SET_EXPECT(testobj_propget_i);
978     parse_script_a("dim x\nx = testObj.propget");
979     CHECK_CALLED(testobj_propget_d);
980     CHECK_CALLED(testobj_propget_i);
981
982     SET_EXPECT(testobj_propput_d);
983     SET_EXPECT(testobj_propput_i);
984     parse_script_a("testObj.propput = 1");
985     CHECK_CALLED(testobj_propput_d);
986     CHECK_CALLED(testobj_propput_i);
987
988     run_from_res("lang.vbs");
989 }
990
991 static BOOL check_vbscript(void)
992 {
993     IActiveScript *vbscript;
994     HRESULT hres;
995
996     hres = CoCreateInstance(&CLSID_VBScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
997             &IID_IActiveScript, (void**)&vbscript);
998     if(SUCCEEDED(hres))
999         IActiveScript_Release(vbscript);
1000
1001     return hres == S_OK;
1002 }
1003
1004 START_TEST(run)
1005 {
1006     int argc;
1007     char **argv;
1008
1009     argc = winetest_get_mainargs(&argv);
1010
1011     CoInitialize(NULL);
1012
1013     if(!check_vbscript()) {
1014         win_skip("Broken engine, probably too old\n");
1015     }else if(argc > 2) {
1016         run_from_file(argv[2]);
1017     }else {
1018         run_tests();
1019     }
1020
1021     CoUninitialize();
1022 }