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