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