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