vbscript: Added interp_lt implementation.
[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, defvalget_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     str = a2bstr("defValGet");
192     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &defvalget_id);
193     SysFreeString(str);
194     ok(hres == S_OK, "GetDispID(defValGet) failed: %08x\n", hres);
195     ok(defvalget_id == DISPID_VALUE, "id = %d\n", defvalget_id);
196
197     str = a2bstr("privateProp");
198     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id);
199     SysFreeString(str);
200     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateProp) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
201     ok(id == -1, "id = %d\n", id);
202
203     str = a2bstr("class_initialize");
204     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id);
205     SysFreeString(str);
206     ok(hres == S_OK, "GetDispID(publicProp2) failed: %08x\n", hres);
207
208     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
209     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
210     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
211
212     V_VT(args) = VT_BOOL;
213     V_BOOL(args) = VARIANT_TRUE;
214     dp.cArgs = dp.cNamedArgs = 1;
215     V_VT(&v) = VT_BOOL;
216     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUT, &dp, &v, &ei, NULL);
217     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
218     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
219
220     dp.cArgs = dp.cNamedArgs = 0;
221     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
222     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
223     ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
224     ok(V_BOOL(&v), "V_BOOL(v) = %x\n", V_BOOL(&v));
225
226     dp.cArgs = 1;
227     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
228     ok(hres == DISP_E_MEMBERNOTFOUND, "InvokeEx failed: %08x, expected DISP_E_MEMBERNOTFOUND\n", hres);
229     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
230
231     V_VT(args) = VT_BOOL;
232     V_BOOL(args) = VARIANT_FALSE;
233     dp.cArgs = 1;
234     V_VT(&v) = VT_BOOL;
235     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL);
236     ok(hres == DISP_E_PARAMNOTOPTIONAL, "InvokeEx failed: %08x, expected DISP_E_PARAMNOTOPTIONAL\n", hres);
237
238     str = a2bstr("publicFunction");
239     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_func_id);
240     SysFreeString(str);
241     ok(hres == S_OK, "GetDispID(publicFunction) failed: %08x\n", hres);
242     ok(public_func_id != -1, "public_func_id = -1\n");
243
244     str = a2bstr("publicSub");
245     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_sub_id);
246     SysFreeString(str);
247     ok(hres == S_OK, "GetDispID(publicSub) failed: %08x\n", hres);
248     ok(public_sub_id != -1, "public_func_id = -1\n");
249
250     dp.cArgs = dp.cNamedArgs = 0;
251     hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
252     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
253     ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
254     ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
255
256     dp.cArgs = dp.cNamedArgs = 0;
257     hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
258     ok(hres == DISP_E_MEMBERNOTFOUND, "InvokeEx failed: %08x, expected DISP_E_MEMBERNOTFOUND\n", hres);
259     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
260
261     dp.cArgs = dp.cNamedArgs = 0;
262     hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
263     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
264     ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
265     ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
266
267     dp.cArgs = dp.cNamedArgs = 0;
268     hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
269     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
270     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
271
272     dp.cArgs = dp.cNamedArgs = 0;
273     hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
274     ok(hres == DISP_E_MEMBERNOTFOUND, "InvokeEx failed: %08x, expected DISP_E_MEMBERNOTFOUND\n", hres);
275     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
276
277     dp.cArgs = dp.cNamedArgs = 0;
278     hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
279     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
280     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
281
282     V_VT(args) = VT_BOOL;
283     V_BOOL(args) = VARIANT_TRUE;
284     dp.cArgs = dp.cNamedArgs = 1;
285     hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL);
286     ok(FAILED(hres), "InvokeEx succeeded: %08x\n", hres);
287
288     dp.cArgs = dp.cNamedArgs = 0;
289     hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
290     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
291     ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
292     ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
293
294     dp.cArgs = dp.cNamedArgs = 0;
295     hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
296     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
297     ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
298     ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
299
300     dp.cArgs = dp.cNamedArgs = 0;
301     hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
302     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
303     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
304
305     dp.cArgs = dp.cNamedArgs = 0;
306     hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
307     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
308     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
309
310     str = a2bstr("privateSub");
311     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id);
312     SysFreeString(str);
313     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateSub) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
314     ok(id == -1, "id = %d\n", id);
315
316     str = a2bstr("dynprop");
317     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive|fdexNameEnsure, &id);
318     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateProp) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
319     ok(id == -1, "id = %d\n", id);
320     hres = IDispatchEx_GetDispID(dispex, str, fdexNameEnsure, &id);
321     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateProp) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
322     ok(id == -1, "id = %d\n", id);
323     SysFreeString(str);
324
325     IDispatchEx_Release(dispex);
326 }
327
328 #define test_grfdex(a,b) _test_grfdex(__LINE__,a,b)
329 static void _test_grfdex(unsigned line, DWORD grfdex, DWORD expect)
330 {
331     ok_(__FILE__,line)(grfdex == expect, "grfdex = %x, expected %x\n", grfdex, expect);
332 }
333
334 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
335 {
336     *ppv = NULL;
337
338     if(IsEqualGUID(riid, &IID_IUnknown)
339        || IsEqualGUID(riid, &IID_IDispatch)
340        || IsEqualGUID(riid, &IID_IDispatchEx))
341         *ppv = iface;
342     else
343         return E_NOINTERFACE;
344
345     return S_OK;
346 }
347
348 static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
349 {
350     return 2;
351 }
352
353 static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
354 {
355     return 1;
356 }
357
358 static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
359 {
360     ok(0, "unexpected call\n");
361     return E_NOTIMPL;
362 }
363
364 static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
365                                               LCID lcid, ITypeInfo **ppTInfo)
366 {
367     ok(0, "unexpected call\n");
368     return E_NOTIMPL;
369 }
370
371 static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
372                                                 LPOLESTR *rgszNames, UINT cNames,
373                                                 LCID lcid, DISPID *rgDispId)
374 {
375     ok(0, "unexpected call\n");
376     return E_NOTIMPL;
377 }
378
379 static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
380                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
381                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
382 {
383     ok(0, "unexpected call\n");
384     return E_NOTIMPL;
385 }
386
387 static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
388 {
389     ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
390     return E_NOTIMPL;
391 }
392
393 static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
394 {
395     ok(0, "unexpected call\n");
396     return E_NOTIMPL;
397 }
398
399 static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
400 {
401     ok(0, "unexpected call\n");
402     return E_NOTIMPL;
403 }
404
405 static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
406 {
407     ok(0, "unexpected call\n");
408     return E_NOTIMPL;
409 }
410
411 static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
412 {
413     ok(0, "unexpected call\n");
414     return E_NOTIMPL;
415 }
416
417 static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
418 {
419     ok(0, "unexpected call\n");
420     return E_NOTIMPL;
421 }
422
423 static HRESULT WINAPI testObj_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
424 {
425     if(!strcmp_wa(bstrName, "propget")) {
426         CHECK_EXPECT(testobj_propget_d);
427         test_grfdex(grfdex, fdexNameCaseInsensitive);
428         *pid = DISPID_TESTOBJ_PROPGET;
429         return S_OK;
430     }
431     if(!strcmp_wa(bstrName, "propput")) {
432         CHECK_EXPECT(testobj_propput_d);
433         test_grfdex(grfdex, fdexNameCaseInsensitive);
434         *pid = DISPID_TESTOBJ_PROPPUT;
435         return S_OK;
436     }
437
438     ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName));
439     return DISP_E_UNKNOWNNAME;
440 }
441
442 static HRESULT WINAPI testObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
443         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
444 {
445     switch(id) {
446     case DISPID_TESTOBJ_PROPGET:
447         CHECK_EXPECT(testobj_propget_i);
448
449         ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
450         ok(pdp != NULL, "pdp == NULL\n");
451         ok(!pdp->rgvarg, "rgvarg == NULL\n");
452         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
453         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
454         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
455         ok(pvarRes != NULL, "pvarRes == NULL\n");
456         ok(pei != NULL, "pei == NULL\n");
457
458         V_VT(pvarRes) = VT_I2;
459         V_I2(pvarRes) = 10;
460         return S_OK;
461     case DISPID_TESTOBJ_PROPPUT:
462         CHECK_EXPECT(testobj_propput_i);
463
464         ok(wFlags == DISPATCH_PROPERTYPUT, "wFlags = %x\n", wFlags);
465         ok(pdp != NULL, "pdp == NULL\n");
466         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
467         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
468         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
469         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
470         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
471         ok(!pvarRes, "pvarRes != NULL\n");
472         ok(pei != NULL, "pei == NULL\n");
473
474         ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
475         ok(V_I2(pdp->rgvarg) == 1, "V_I2(psp->rgvargs) = %d\n", V_I2(pdp->rgvarg));
476         return S_OK;
477     }
478
479     ok(0, "unexpected call %d\n", id);
480     return E_FAIL;
481 }
482
483 static IDispatchExVtbl testObjVtbl = {
484     DispatchEx_QueryInterface,
485     DispatchEx_AddRef,
486     DispatchEx_Release,
487     DispatchEx_GetTypeInfoCount,
488     DispatchEx_GetTypeInfo,
489     DispatchEx_GetIDsOfNames,
490     DispatchEx_Invoke,
491     testObj_GetDispID,
492     testObj_InvokeEx,
493     DispatchEx_DeleteMemberByName,
494     DispatchEx_DeleteMemberByDispID,
495     DispatchEx_GetMemberProperties,
496     DispatchEx_GetMemberName,
497     DispatchEx_GetNextDispID,
498     DispatchEx_GetNameSpaceParent
499 };
500
501 static IDispatchEx testObj = { &testObjVtbl };
502
503 static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
504 {
505     if(!strcmp_wa(bstrName, "ok")) {
506         test_grfdex(grfdex, fdexNameCaseInsensitive);
507         *pid = DISPID_GLOBAL_OK;
508         return S_OK;
509     }
510     if(!strcmp_wa(bstrName, "trace")) {
511         test_grfdex(grfdex, fdexNameCaseInsensitive);
512         *pid = DISPID_GLOBAL_TRACE;
513         return S_OK;
514     }
515     if(!strcmp_wa(bstrName, "reportSuccess")) {
516         CHECK_EXPECT(global_success_d);
517         test_grfdex(grfdex, fdexNameCaseInsensitive);
518         *pid = DISPID_GLOBAL_REPORTSUCCESS;
519         return S_OK;
520     }
521     if(!strcmp_wa(bstrName, "getVT")) {
522         test_grfdex(grfdex, fdexNameCaseInsensitive);
523         *pid = DISPID_GLOBAL_GETVT;
524         return S_OK;
525     }
526     if(!strcmp_wa(bstrName, "isEnglishLang")) {
527         test_grfdex(grfdex, fdexNameCaseInsensitive);
528         *pid = DISPID_GLOBAL_ISENGLANG;
529         return S_OK;
530     }
531     if(!strcmp_wa(bstrName, "testObj")) {
532         test_grfdex(grfdex, fdexNameCaseInsensitive);
533         *pid = DISPID_GLOBAL_TESTOBJ;
534         return S_OK;
535     }
536     if(!strcmp_wa(bstrName, "vbvar")) {
537         CHECK_EXPECT(global_vbvar_d);
538         test_grfdex(grfdex, fdexNameCaseInsensitive);
539         *pid = DISPID_GLOBAL_VBVAR;
540         return S_OK;
541     }
542     if(!strcmp_wa(bstrName, "isNullDisp")) {
543         test_grfdex(grfdex, fdexNameCaseInsensitive);
544         *pid = DISPID_GLOBAL_ISNULLDISP;
545         return S_OK;
546     }
547     if(!strcmp_wa(bstrName, "testDisp")) {
548         test_grfdex(grfdex, fdexNameCaseInsensitive);
549         *pid = DISPID_GLOBAL_TESTDISP;
550         return S_OK;
551     }
552
553     if(strict_dispid_check && strcmp_wa(bstrName, "x"))
554         ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
555     return DISP_E_UNKNOWNNAME;
556 }
557
558 static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
559         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
560 {
561     switch(id) {
562     case DISPID_GLOBAL_OK: {
563         VARIANT *b;
564
565         ok(wFlags == INVOKE_FUNC || wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
566         ok(pdp != NULL, "pdp == NULL\n");
567         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
568         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
569         ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
570         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
571         if(wFlags & INVOKE_PROPERTYGET)
572             ok(pvarRes != NULL, "pvarRes == NULL\n");
573         else
574             ok(!pvarRes, "pvarRes != NULL\n");
575         ok(pei != NULL, "pei == NULL\n");
576
577         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
578
579         b = pdp->rgvarg+1;
580         if(V_VT(b) == (VT_BYREF|VT_VARIANT))
581             b = V_BYREF(b);
582
583         ok(V_VT(b) == VT_BOOL, "V_VT(b) = %d\n", V_VT(b));
584
585         ok(V_BOOL(b), "%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
586         return S_OK;
587     }
588
589      case DISPID_GLOBAL_TRACE:
590         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
591         ok(pdp != NULL, "pdp == NULL\n");
592         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
593         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
594         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
595         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
596         ok(!pvarRes, "pvarRes != NULL\n");
597         ok(pei != NULL, "pei == NULL\n");
598
599         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
600         if(V_VT(pdp->rgvarg) == VT_BSTR)
601             trace("%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
602
603         return S_OK;
604
605     case DISPID_GLOBAL_REPORTSUCCESS:
606         CHECK_EXPECT(global_success_i);
607
608         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
609         ok(pdp != NULL, "pdp == NULL\n");
610         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
611         ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
612         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
613         ok(!pvarRes, "pvarRes != NULL\n");
614         ok(pei != NULL, "pei == NULL\n");
615
616         return S_OK;
617
618     case DISPID_GLOBAL_GETVT:
619         ok(pdp != NULL, "pdp == NULL\n");
620         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
621         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
622         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
623         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
624         ok(pvarRes != NULL, "pvarRes == NULL\n");
625         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
626         ok(pei != NULL, "pei == NULL\n");
627
628         V_VT(pvarRes) = VT_BSTR;
629         V_BSTR(pvarRes) = a2bstr(vt2a(pdp->rgvarg));
630         return S_OK;
631
632     case DISPID_GLOBAL_ISENGLANG:
633         ok(wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
634         ok(pdp != NULL, "pdp == NULL\n");
635         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
636         ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
637         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
638         ok(pvarRes != NULL, "pvarRes == NULL\n");
639         ok(pei != NULL, "pei == NULL\n");
640
641         V_VT(pvarRes) = VT_BOOL;
642         if(is_lang_english()) {
643             V_BOOL(pvarRes) = VARIANT_TRUE;
644         }else {
645             skip("Skipping some tests in non-English UIs\n");
646             V_BOOL(pvarRes) = VARIANT_FALSE;
647         }
648         return S_OK;
649
650     case DISPID_GLOBAL_VBVAR:
651         CHECK_EXPECT(global_vbvar_i);
652
653         ok(wFlags == DISPATCH_PROPERTYPUT, "wFlags = %x\n", wFlags);
654         ok(pdp != NULL, "pdp == NULL\n");
655         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
656         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
657         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
658         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
659         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
660         ok(!pvarRes, "pvarRes != NULL\n");
661         ok(pei != NULL, "pei == NULL\n");
662
663         ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
664         ok(V_I2(pdp->rgvarg) == 3, "V_I2(psp->rgvargs) = %d\n", V_I2(pdp->rgvarg));
665         return S_OK;
666
667     case DISPID_GLOBAL_TESTOBJ:
668         ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
669
670         ok(pdp != NULL, "pdp == NULL\n");
671         ok(!pdp->rgvarg, "rgvarg == NULL\n");
672         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
673         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
674         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
675         ok(pvarRes != NULL, "pvarRes == NULL\n");
676         ok(pei != NULL, "pei == NULL\n");
677
678         V_VT(pvarRes) = VT_DISPATCH;
679         V_DISPATCH(pvarRes) = (IDispatch*)&testObj;
680         return S_OK;
681
682     case DISPID_GLOBAL_ISNULLDISP: {
683         VARIANT *v;
684
685         ok(wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
686         ok(pdp != NULL, "pdp == NULL\n");
687         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
688         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
689         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
690         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
691         ok(pvarRes != NULL, "pvarRes == NULL\n");
692         ok(pei != NULL, "pei == NULL\n");
693
694         v = pdp->rgvarg;
695         if(V_VT(v) == (VT_VARIANT|VT_BYREF))
696             v = V_VARIANTREF(v);
697
698         ok(V_VT(v) == VT_DISPATCH, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
699         V_VT(pvarRes) = VT_BOOL;
700         V_BOOL(pvarRes) = V_DISPATCH(v) ? VARIANT_FALSE : VARIANT_TRUE;
701         return S_OK;
702     }
703
704     case DISPID_GLOBAL_TESTDISP:
705         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
706         ok(pdp != NULL, "pdp == NULL\n");
707         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
708         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
709         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
710         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
711         ok(!pvarRes, "pvarRes != NULL\n");
712         ok(pei != NULL, "pei == NULL\n");
713
714         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
715         test_disp(V_DISPATCH(pdp->rgvarg));
716         return S_OK;
717     }
718
719     ok(0, "unexpected call %d\n", id);
720     return DISP_E_MEMBERNOTFOUND;
721 }
722
723 static IDispatchExVtbl GlobalVtbl = {
724     DispatchEx_QueryInterface,
725     DispatchEx_AddRef,
726     DispatchEx_Release,
727     DispatchEx_GetTypeInfoCount,
728     DispatchEx_GetTypeInfo,
729     DispatchEx_GetIDsOfNames,
730     DispatchEx_Invoke,
731     Global_GetDispID,
732     Global_InvokeEx,
733     DispatchEx_DeleteMemberByName,
734     DispatchEx_DeleteMemberByDispID,
735     DispatchEx_GetMemberProperties,
736     DispatchEx_GetMemberName,
737     DispatchEx_GetNextDispID,
738     DispatchEx_GetNameSpaceParent
739 };
740
741 static IDispatchEx Global = { &GlobalVtbl };
742
743 static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
744 {
745     *ppv = NULL;
746
747     if(IsEqualGUID(&IID_IUnknown, riid))
748         *ppv = iface;
749     else if(IsEqualGUID(&IID_IActiveScriptSite, riid))
750         *ppv = iface;
751     else
752         return E_NOINTERFACE;
753
754     IUnknown_AddRef((IUnknown*)*ppv);
755     return S_OK;
756 }
757
758 static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
759 {
760     return 2;
761 }
762
763 static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
764 {
765     return 1;
766 }
767
768 static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *plcid)
769 {
770     *plcid = GetUserDefaultLCID();
771     return S_OK;
772 }
773
774 static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR pstrName,
775         DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti)
776 {
777     ok(dwReturnMask == SCRIPTINFO_IUNKNOWN, "unexpected dwReturnMask %x\n", dwReturnMask);
778     ok(!ppti, "ppti != NULL\n");
779
780     if(strcmp_wa(pstrName, "test"))
781         ok(0, "unexpected pstrName %s\n", wine_dbgstr_w(pstrName));
782
783     *ppiunkItem = (IUnknown*)&Global;
784     return S_OK;
785 }
786
787 static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *pbstrVersion)
788 {
789     return E_NOTIMPL;
790 }
791
792 static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface,
793         const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo)
794 {
795     return E_NOTIMPL;
796 }
797
798 static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE ssScriptState)
799 {
800     return E_NOTIMPL;
801 }
802
803 static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
804 {
805     return E_NOTIMPL;
806 }
807
808 static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
809 {
810     return E_NOTIMPL;
811 }
812
813 static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
814 {
815     return E_NOTIMPL;
816 }
817
818 #undef ACTSCPSITE_THIS
819
820 static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
821     ActiveScriptSite_QueryInterface,
822     ActiveScriptSite_AddRef,
823     ActiveScriptSite_Release,
824     ActiveScriptSite_GetLCID,
825     ActiveScriptSite_GetItemInfo,
826     ActiveScriptSite_GetDocVersionString,
827     ActiveScriptSite_OnScriptTerminate,
828     ActiveScriptSite_OnStateChange,
829     ActiveScriptSite_OnScriptError,
830     ActiveScriptSite_OnEnterScript,
831     ActiveScriptSite_OnLeaveScript
832 };
833
834 static IActiveScriptSite ActiveScriptSite = { &ActiveScriptSiteVtbl };
835
836 static IActiveScript *create_script(void)
837 {
838     IActiveScript *script;
839     HRESULT hres;
840
841     hres = CoCreateInstance(&CLSID_VBScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
842             &IID_IActiveScript, (void**)&script);
843     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
844
845     return script;
846 }
847
848 static HRESULT parse_script(DWORD flags, BSTR script_str)
849 {
850     IActiveScriptParse *parser;
851     IActiveScript *engine;
852     IDispatch *script_disp;
853     HRESULT hres;
854
855     engine = create_script();
856     if(!engine)
857         return S_OK;
858
859     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
860     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
861     if (FAILED(hres))
862     {
863         IActiveScript_Release(engine);
864         return hres;
865     }
866
867     hres = IActiveScriptParse64_InitNew(parser);
868     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
869
870     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
871     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
872
873     hres = IActiveScript_AddNamedItem(engine, testW,
874             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|flags);
875     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
876
877     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
878     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
879
880     hres = IActiveScript_GetScriptDispatch(engine, NULL, &script_disp);
881     ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres);
882     ok(script_disp != NULL, "script_disp == NULL\n");
883     ok(script_disp != (IDispatch*)&Global, "script_disp == Global\n");
884
885     hres = IActiveScriptParse64_ParseScriptText(parser, script_str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
886
887     IActiveScript_Close(engine);
888
889     IDispatch_Release(script_disp);
890     IActiveScript_Release(engine);
891     IUnknown_Release(parser);
892
893     return hres;
894 }
895
896 static void parse_script_af(DWORD flags, const char *src)
897 {
898     BSTR tmp;
899     HRESULT hres;
900
901     tmp = a2bstr(src);
902     hres = parse_script(flags, tmp);
903     SysFreeString(tmp);
904     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
905 }
906
907 static void parse_script_a(const char *src)
908 {
909     parse_script_af(SCRIPTITEM_GLOBALMEMBERS, src);
910 }
911
912 static void test_gc(void)
913 {
914     IActiveScriptParse *parser;
915     IActiveScript *engine;
916     BSTR src;
917     HRESULT hres;
918
919     strict_dispid_check = FALSE;
920
921     engine = create_script();
922     if(!engine)
923         return;
924
925     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
926     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
927
928     hres = IActiveScriptParse64_InitNew(parser);
929     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
930
931     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
932     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
933
934     hres = IActiveScript_AddNamedItem(engine, testW,
935             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
936     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
937
938     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
939     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
940
941     src = a2bstr(
942             "class C\n"
943             "    Public ref\n"
944             "    Public Sub Class_Terminate\n"
945             "        Call reportSuccess()\n"
946             "    End Sub\n"
947             "End Class\n"
948             "Dim x\n"
949             "set x = new C\n"
950             "set x.ref = x\n"
951             "set x = nothing\n");
952
953     hres = IActiveScriptParse64_ParseScriptText(parser, src, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
954     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
955     SysFreeString(src);
956
957     SET_EXPECT(global_success_d);
958     SET_EXPECT(global_success_i);
959     IActiveScript_Close(engine);
960     CHECK_CALLED(global_success_d);
961     CHECK_CALLED(global_success_i);
962
963     IActiveScript_Release(engine);
964     IUnknown_Release(parser);
965 }
966
967 static BSTR get_script_from_file(const char *filename)
968 {
969     DWORD size, len;
970     HANDLE file, map;
971     const char *file_map;
972     BSTR ret;
973
974     file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
975     if(file == INVALID_HANDLE_VALUE) {
976         trace("Could not open file: %u\n", GetLastError());
977         return NULL;
978     }
979
980     size = GetFileSize(file, NULL);
981
982     map = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
983     CloseHandle(file);
984     if(map == INVALID_HANDLE_VALUE) {
985         trace("Could not create file mapping: %u\n", GetLastError());
986         return NULL;
987     }
988
989     file_map = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
990     CloseHandle(map);
991     if(!file_map) {
992         trace("MapViewOfFile failed: %u\n", GetLastError());
993         return NULL;
994     }
995
996     len = MultiByteToWideChar(CP_ACP, 0, file_map, size, NULL, 0);
997     ret = SysAllocStringLen(NULL, len);
998     MultiByteToWideChar(CP_ACP, 0, file_map, size, ret, len);
999
1000     UnmapViewOfFile(file_map);
1001
1002     return ret;
1003 }
1004
1005 static void run_from_file(const char *filename)
1006 {
1007     BSTR script_str;
1008     HRESULT hres;
1009
1010     script_str = get_script_from_file(filename);
1011     if(!script_str)
1012         return;
1013
1014     strict_dispid_check = FALSE;
1015     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, script_str);
1016     SysFreeString(script_str);
1017     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
1018 }
1019
1020 static void run_from_res(const char *name)
1021 {
1022     const char *data;
1023     DWORD size, len;
1024     BSTR str;
1025     HRSRC src;
1026     HRESULT hres;
1027
1028     strict_dispid_check = FALSE;
1029     test_name = name;
1030
1031     src = FindResourceA(NULL, name, (LPCSTR)40);
1032     ok(src != NULL, "Could not find resource %s\n", name);
1033
1034     size = SizeofResource(NULL, src);
1035     data = LoadResource(NULL, src);
1036
1037     len = MultiByteToWideChar(CP_ACP, 0, data, size, NULL, 0);
1038     str = SysAllocStringLen(NULL, len);
1039     MultiByteToWideChar(CP_ACP, 0, data, size, str, len);
1040
1041     SET_EXPECT(global_success_d);
1042     SET_EXPECT(global_success_i);
1043     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, str);
1044     CHECK_CALLED(global_success_d);
1045     CHECK_CALLED(global_success_i);
1046
1047     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
1048     SysFreeString(str);
1049 }
1050
1051 static void run_tests(void)
1052 {
1053     strict_dispid_check = TRUE;
1054
1055     parse_script_a("");
1056     parse_script_a("' empty ;");
1057
1058     SET_EXPECT(global_success_d);
1059     SET_EXPECT(global_success_i);
1060     parse_script_a("reportSuccess");
1061     CHECK_CALLED(global_success_d);
1062     CHECK_CALLED(global_success_i);
1063
1064     SET_EXPECT(global_success_d);
1065     SET_EXPECT(global_success_i);
1066     parse_script_a("reportSuccess()");
1067     CHECK_CALLED(global_success_d);
1068     CHECK_CALLED(global_success_i);
1069
1070     SET_EXPECT(global_success_d);
1071     SET_EXPECT(global_success_i);
1072     parse_script_a("Call reportSuccess");
1073     CHECK_CALLED(global_success_d);
1074     CHECK_CALLED(global_success_i);
1075
1076     SET_EXPECT(global_vbvar_d);
1077     SET_EXPECT(global_vbvar_i);
1078     parse_script_a("Option Explicit\nvbvar = 3");
1079     CHECK_CALLED(global_vbvar_d);
1080     CHECK_CALLED(global_vbvar_i);
1081
1082     SET_EXPECT(global_vbvar_d);
1083     SET_EXPECT(global_vbvar_i);
1084     parse_script_a("Option Explicit\nvbvar() = 3");
1085     CHECK_CALLED(global_vbvar_d);
1086     CHECK_CALLED(global_vbvar_i);
1087
1088     SET_EXPECT(testobj_propget_d);
1089     SET_EXPECT(testobj_propget_i);
1090     parse_script_a("dim x\nx = testObj.propget");
1091     CHECK_CALLED(testobj_propget_d);
1092     CHECK_CALLED(testobj_propget_i);
1093
1094     SET_EXPECT(testobj_propput_d);
1095     SET_EXPECT(testobj_propput_i);
1096     parse_script_a("testObj.propput = 1");
1097     CHECK_CALLED(testobj_propput_d);
1098     CHECK_CALLED(testobj_propput_i);
1099
1100     run_from_res("lang.vbs");
1101
1102     test_gc();
1103 }
1104
1105 static BOOL check_vbscript(void)
1106 {
1107     IActiveScript *vbscript;
1108     HRESULT hres;
1109
1110     hres = CoCreateInstance(&CLSID_VBScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1111             &IID_IActiveScript, (void**)&vbscript);
1112     if(SUCCEEDED(hres))
1113         IActiveScript_Release(vbscript);
1114
1115     return hres == S_OK;
1116 }
1117
1118 START_TEST(run)
1119 {
1120     int argc;
1121     char **argv;
1122
1123     argc = winetest_get_mainargs(&argv);
1124
1125     CoInitialize(NULL);
1126
1127     if(!check_vbscript()) {
1128         win_skip("Broken engine, probably too old\n");
1129     }else if(argc > 2) {
1130         run_from_file(argv[2]);
1131     }else {
1132         run_tests();
1133     }
1134
1135     CoUninitialize();
1136 }