shell32/tests: Add a few more ShellExecute() file URL tests.
[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 #ifdef _WIN64
31
32 #define IActiveScriptParse_QueryInterface IActiveScriptParse64_QueryInterface
33 #define IActiveScriptParse_Release IActiveScriptParse64_Release
34 #define IActiveScriptParse_InitNew IActiveScriptParse64_InitNew
35 #define IActiveScriptParse_ParseScriptText IActiveScriptParse64_ParseScriptText
36 #define IActiveScriptParseProcedure2_Release IActiveScriptParseProcedure2_64_Release
37 #define IActiveScriptParseProcedure2_ParseProcedureText IActiveScriptParseProcedure2_64_ParseProcedureText
38
39 #else
40
41 #define IActiveScriptParse_QueryInterface IActiveScriptParse32_QueryInterface
42 #define IActiveScriptParse_Release IActiveScriptParse32_Release
43 #define IActiveScriptParse_InitNew IActiveScriptParse32_InitNew
44 #define IActiveScriptParse_ParseScriptText IActiveScriptParse32_ParseScriptText
45 #define IActiveScriptParseProcedure2_Release IActiveScriptParseProcedure2_32_Release
46 #define IActiveScriptParseProcedure2_ParseProcedureText IActiveScriptParseProcedure2_32_ParseProcedureText
47
48 #endif
49
50 extern const CLSID CLSID_VBScript;
51
52 #define DEFINE_EXPECT(func) \
53     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
54
55 #define SET_EXPECT(func) \
56     expect_ ## func = TRUE
57
58 #define CHECK_EXPECT2(func) \
59     do { \
60         ok(expect_ ##func, "unexpected call " #func "\n"); \
61         called_ ## func = TRUE; \
62     }while(0)
63
64 #define CHECK_EXPECT(func) \
65     do { \
66         CHECK_EXPECT2(func); \
67         expect_ ## func = FALSE; \
68     }while(0)
69
70 #define CHECK_CALLED(func) \
71     do { \
72         ok(called_ ## func, "expected " #func "\n"); \
73         expect_ ## func = called_ ## func = FALSE; \
74     }while(0)
75
76 DEFINE_EXPECT(global_success_d);
77 DEFINE_EXPECT(global_success_i);
78 DEFINE_EXPECT(global_vbvar_d);
79 DEFINE_EXPECT(global_vbvar_i);
80 DEFINE_EXPECT(testobj_propget_d);
81 DEFINE_EXPECT(testobj_propget_i);
82 DEFINE_EXPECT(testobj_propput_d);
83 DEFINE_EXPECT(testobj_propput_i);
84 DEFINE_EXPECT(global_propargput_d);
85 DEFINE_EXPECT(global_propargput_i);
86 DEFINE_EXPECT(global_propargput1_d);
87 DEFINE_EXPECT(global_propargput1_i);
88 DEFINE_EXPECT(collectionobj_newenum_i);
89 DEFINE_EXPECT(Next);
90
91 #define DISPID_GLOBAL_REPORTSUCCESS 1000
92 #define DISPID_GLOBAL_TRACE         1001
93 #define DISPID_GLOBAL_OK            1002
94 #define DISPID_GLOBAL_GETVT         1003
95 #define DISPID_GLOBAL_ISENGLANG     1004
96 #define DISPID_GLOBAL_VBVAR         1005
97 #define DISPID_GLOBAL_TESTOBJ       1006
98 #define DISPID_GLOBAL_ISNULLDISP    1007
99 #define DISPID_GLOBAL_TESTDISP      1008
100 #define DISPID_GLOBAL_REFOBJ        1009
101 #define DISPID_GLOBAL_COUNTER       1010
102 #define DISPID_GLOBAL_PROPARGPUT    1011
103 #define DISPID_GLOBAL_PROPARGPUT1   1012
104 #define DISPID_GLOBAL_COLLOBJ       1013
105 #define DISPID_GLOBAL_DOUBLEASSTRING 1014
106
107 #define DISPID_TESTOBJ_PROPGET      2000
108 #define DISPID_TESTOBJ_PROPPUT      2001
109
110 #define DISPID_COLLOBJ_RESET        3000
111
112 static const WCHAR testW[] = {'t','e','s','t',0};
113 static const WCHAR emptyW[] = {0};
114
115 static BOOL strict_dispid_check, is_english;
116 static const char *test_name = "(null)";
117 static int test_counter;
118
119 static BSTR a2bstr(const char *str)
120 {
121     BSTR ret;
122     int len;
123
124     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
125     ret = SysAllocStringLen(NULL, len-1);
126     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
127
128     return ret;
129 }
130
131 static int strcmp_wa(LPCWSTR strw, const char *stra)
132 {
133     CHAR buf[512];
134     WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), 0, 0);
135     return lstrcmpA(buf, stra);
136 }
137
138 static const char *debugstr_guid(REFIID riid)
139 {
140     static char buf[50];
141
142     sprintf(buf, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
143             riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
144             riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
145             riid->Data4[5], riid->Data4[6], riid->Data4[7]);
146
147     return buf;
148 }
149
150 static const char *vt2a(VARIANT *v)
151 {
152     if(V_VT(v) == (VT_BYREF|VT_VARIANT)) {
153         static char buf[64];
154         sprintf(buf, "%s*", vt2a(V_BYREF(v)));
155         return buf;
156     }
157
158     switch(V_VT(v)) {
159     case VT_EMPTY:
160         return "VT_EMPTY";
161     case VT_NULL:
162         return "VT_NULL";
163     case VT_I2:
164         return "VT_I2";
165     case VT_I4:
166         return "VT_I4";
167     case VT_R8:
168         return "VT_R8";
169     case VT_BSTR:
170         return "VT_BSTR";
171     case VT_DISPATCH:
172         return "VT_DISPATCH";
173     case VT_BOOL:
174         return "VT_BOOL";
175     case VT_ARRAY|VT_VARIANT:
176         return "VT_ARRAY|VT_VARIANT";
177     default:
178         ok(0, "unknown vt %d\n", V_VT(v));
179         return NULL;
180     }
181 }
182
183 /* Returns true if the user interface is in English. Note that this does not
184  * presume of the formatting of dates, numbers, etc.
185  */
186 static BOOL is_lang_english(void)
187 {
188     static HMODULE hkernel32 = NULL;
189     static LANGID (WINAPI *pGetThreadUILanguage)(void) = NULL;
190     static LANGID (WINAPI *pGetUserDefaultUILanguage)(void) = NULL;
191
192     if (!hkernel32)
193     {
194         hkernel32 = GetModuleHandleA("kernel32.dll");
195         pGetThreadUILanguage = (void*)GetProcAddress(hkernel32, "GetThreadUILanguage");
196         pGetUserDefaultUILanguage = (void*)GetProcAddress(hkernel32, "GetUserDefaultUILanguage");
197     }
198     if (pGetThreadUILanguage)
199         return PRIMARYLANGID(pGetThreadUILanguage()) == LANG_ENGLISH;
200     if (pGetUserDefaultUILanguage)
201         return PRIMARYLANGID(pGetUserDefaultUILanguage()) == LANG_ENGLISH;
202
203     return PRIMARYLANGID(GetUserDefaultLangID()) == LANG_ENGLISH;
204 }
205
206 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
207 {
208     ok(0, "unexpected call\n");
209     return E_NOINTERFACE;
210 }
211
212 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
213 {
214     return 2;
215 }
216
217 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
218 {
219     return 1;
220 }
221
222 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService,
223         REFIID riid, void **ppv)
224 {
225     ok(0, "unexpected service %s\n", debugstr_guid(guidService));
226     return E_NOINTERFACE;
227 }
228
229 static const IServiceProviderVtbl ServiceProviderVtbl = {
230     ServiceProvider_QueryInterface,
231     ServiceProvider_AddRef,
232     ServiceProvider_Release,
233     ServiceProvider_QueryService
234 };
235
236 static IServiceProvider caller_sp = { &ServiceProviderVtbl };
237
238 static void test_disp(IDispatch *disp)
239 {
240     DISPID id, public_prop_id, public_prop2_id, public_func_id, public_sub_id, defvalget_id;
241     DISPID named_args[5] = {DISPID_PROPERTYPUT};
242     VARIANT v, args[5];
243     DISPPARAMS dp = {args, named_args};
244     IDispatchEx *dispex;
245     EXCEPINFO ei = {0};
246     BSTR str;
247     HRESULT hres;
248
249     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
250     ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
251
252     str = a2bstr("publicProp");
253     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_prop_id);
254     SysFreeString(str);
255     ok(hres == S_OK, "GetDispID(publicProp) failed: %08x\n", hres);
256
257     str = a2bstr("PUBLICPROP");
258     hres = IDispatchEx_GetDispID(dispex, str, 0, &id);
259     SysFreeString(str);
260     ok(hres == S_OK, "GetDispID(PUBLICPROP) failed: %08x\n", hres);
261     ok(public_prop_id == id, "id = %d\n", public_prop_id);
262
263     str = a2bstr("publicPROP2");
264     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_prop2_id);
265     SysFreeString(str);
266     ok(hres == S_OK, "GetDispID(publicProp2) failed: %08x\n", hres);
267
268     str = a2bstr("defValGet");
269     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &defvalget_id);
270     SysFreeString(str);
271     ok(hres == S_OK, "GetDispID(defValGet) failed: %08x\n", hres);
272     ok(defvalget_id == DISPID_VALUE, "id = %d\n", defvalget_id);
273
274     str = a2bstr("privateProp");
275     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id);
276     SysFreeString(str);
277     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateProp) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
278     ok(id == -1, "id = %d\n", id);
279
280     str = a2bstr("class_initialize");
281     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id);
282     SysFreeString(str);
283     ok(hres == S_OK, "GetDispID(publicProp2) failed: %08x\n", hres);
284
285     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
286     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
287     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
288
289     V_VT(args) = VT_BOOL;
290     V_BOOL(args) = VARIANT_TRUE;
291     dp.cArgs = dp.cNamedArgs = 1;
292     V_VT(&v) = VT_BOOL;
293     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUT, &dp, &v, &ei, NULL);
294     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
295     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
296
297     dp.cArgs = dp.cNamedArgs = 0;
298     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
299     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
300     ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
301     ok(V_BOOL(&v), "V_BOOL(v) = %x\n", V_BOOL(&v));
302
303     dp.cArgs = dp.cNamedArgs = 0;
304     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
305     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
306     ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
307     ok(V_BOOL(&v), "V_BOOL(v) = %x\n", V_BOOL(&v));
308
309     dp.cArgs = 1;
310     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
311     ok(hres == DISP_E_MEMBERNOTFOUND, "InvokeEx failed: %08x, expected DISP_E_MEMBERNOTFOUND\n", hres);
312     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
313
314     V_VT(args) = VT_BOOL;
315     V_BOOL(args) = VARIANT_FALSE;
316     dp.cArgs = 1;
317     V_VT(&v) = VT_BOOL;
318     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL);
319     ok(hres == DISP_E_PARAMNOTOPTIONAL, "InvokeEx failed: %08x, expected DISP_E_PARAMNOTOPTIONAL\n", hres);
320
321     str = a2bstr("publicFunction");
322     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_func_id);
323     SysFreeString(str);
324     ok(hres == S_OK, "GetDispID(publicFunction) failed: %08x\n", hres);
325     ok(public_func_id != -1, "public_func_id = -1\n");
326
327     str = a2bstr("publicSub");
328     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_sub_id);
329     SysFreeString(str);
330     ok(hres == S_OK, "GetDispID(publicSub) failed: %08x\n", hres);
331     ok(public_sub_id != -1, "public_func_id = -1\n");
332
333     dp.cArgs = dp.cNamedArgs = 0;
334     hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
335     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
336     ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
337     ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
338
339     dp.cArgs = dp.cNamedArgs = 0;
340     hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
341     ok(hres == DISP_E_MEMBERNOTFOUND, "InvokeEx failed: %08x, expected DISP_E_MEMBERNOTFOUND\n", hres);
342     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
343
344     dp.cArgs = dp.cNamedArgs = 0;
345     hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
346     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
347     ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
348     ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
349
350     dp.cArgs = dp.cNamedArgs = 0;
351     hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
352     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
353     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
354
355     dp.cArgs = dp.cNamedArgs = 0;
356     hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
357     ok(hres == DISP_E_MEMBERNOTFOUND, "InvokeEx failed: %08x, expected DISP_E_MEMBERNOTFOUND\n", hres);
358     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
359
360     dp.cArgs = dp.cNamedArgs = 0;
361     hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
362     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
363     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
364
365     V_VT(args) = VT_BOOL;
366     V_BOOL(args) = VARIANT_TRUE;
367     dp.cArgs = dp.cNamedArgs = 1;
368     hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL);
369     ok(FAILED(hres), "InvokeEx succeeded: %08x\n", hres);
370
371     dp.cArgs = dp.cNamedArgs = 0;
372     hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
373     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
374     ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
375     ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
376
377     dp.cArgs = dp.cNamedArgs = 0;
378     hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
379     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
380     ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
381     ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
382
383     dp.cArgs = dp.cNamedArgs = 0;
384     hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
385     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
386     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
387
388     dp.cArgs = dp.cNamedArgs = 0;
389     hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
390     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
391     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
392
393     str = a2bstr("privateSub");
394     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id);
395     SysFreeString(str);
396     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateSub) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
397     ok(id == -1, "id = %d\n", id);
398
399     str = a2bstr("dynprop");
400     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive|fdexNameEnsure, &id);
401     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateProp) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
402     ok(id == -1, "id = %d\n", id);
403     hres = IDispatchEx_GetDispID(dispex, str, fdexNameEnsure, &id);
404     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateProp) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
405     ok(id == -1, "id = %d\n", id);
406     SysFreeString(str);
407
408     str = a2bstr("publicProp");
409     hres = IDispatchEx_GetDispID(dispex, str, 0x80000000|fdexNameCaseInsensitive, &public_prop_id);
410     SysFreeString(str);
411     ok(hres == S_OK, "GetDispID(publicProp) failed: %08x\n", hres);
412
413     id = 0xdeadbeef;
414     str = a2bstr("publicProp");
415     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseSensitive, &id);
416     SysFreeString(str);
417     ok(hres == S_OK, "GetDispID(publicProp) failed: %08x\n", hres);
418     ok(id == public_prop_id, "id = %d, expected %d\n", id, public_prop_id);
419
420     id = 0xdeadbeef;
421     str = a2bstr("publicprop");
422     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseSensitive, &id);
423     SysFreeString(str);
424     ok(hres == S_OK, "GetDispID(publicProp) failed: %08x\n", hres);
425     ok(id == public_prop_id, "id = %d, expected %d\n", id, public_prop_id);
426
427     IDispatchEx_Release(dispex);
428 }
429
430 #define test_grfdex(a,b) _test_grfdex(__LINE__,a,b)
431 static void _test_grfdex(unsigned line, DWORD grfdex, DWORD expect)
432 {
433     ok_(__FILE__,line)(grfdex == expect, "grfdex = %x, expected %x\n", grfdex, expect);
434 }
435
436 static IDispatchEx enumDisp;
437
438 static HRESULT WINAPI EnumVARIANT_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv)
439 {
440     if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IEnumVARIANT)) {
441         *ppv = iface;
442         return S_OK;
443     }
444
445     if(IsEqualGUID(riid, &IID_IDispatch)) {
446         *ppv = &enumDisp;
447         return S_OK;
448     }
449
450     ok(0, "unexpected call %s\n", debugstr_guid(riid));
451     return E_NOINTERFACE;
452 }
453
454 static ULONG WINAPI EnumVARIANT_AddRef(IEnumVARIANT *iface)
455 {
456     return 2;
457 }
458
459 static ULONG WINAPI EnumVARIANT_Release(IEnumVARIANT *iface)
460 {
461     return 1;
462 }
463
464 static unsigned next_cnt;
465
466 static HRESULT WINAPI EnumVARIANT_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
467 {
468     if(strict_dispid_check)
469         CHECK_EXPECT2(Next);
470
471     ok(celt == 1, "celt = %d\n", celt);
472     ok(V_VT(rgVar) == VT_EMPTY, "V_VT(rgVar) = %d\n", V_VT(rgVar));
473     ok(!pCeltFetched, "pCeltFetched = %p\n", pCeltFetched);
474
475     if(next_cnt++ < 3) {
476         V_VT(rgVar) = VT_I2;
477         V_I2(rgVar) = next_cnt;
478         return S_OK;
479     }
480
481     return S_FALSE;
482 }
483
484 static HRESULT WINAPI EnumVARIANT_Skip(IEnumVARIANT *iface, ULONG celt)
485 {
486     ok(0, "unexpected call\n");
487     return E_NOTIMPL;
488 }
489
490 static HRESULT WINAPI EnumVARIANT_Reset(IEnumVARIANT *iface)
491 {
492     ok(0, "unexpected call\n");
493     return E_NOTIMPL;
494 }
495
496 static HRESULT WINAPI EnumVARIANT_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum)
497 {
498     ok(0, "unexpected call\n");
499     return E_NOTIMPL;
500 }
501
502 static const IEnumVARIANTVtbl EnumVARIANTVtbl = {
503     EnumVARIANT_QueryInterface,
504     EnumVARIANT_AddRef,
505     EnumVARIANT_Release,
506     EnumVARIANT_Next,
507     EnumVARIANT_Skip,
508     EnumVARIANT_Reset,
509     EnumVARIANT_Clone
510 };
511
512 static IEnumVARIANT enumObj = { &EnumVARIANTVtbl };
513
514 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
515 {
516     *ppv = NULL;
517
518     if(IsEqualGUID(riid, &IID_IUnknown)
519        || IsEqualGUID(riid, &IID_IDispatch)
520        || IsEqualGUID(riid, &IID_IDispatchEx))
521         *ppv = iface;
522     else {
523         trace("QI %s\n", debugstr_guid(riid));
524         return E_NOINTERFACE;
525     }
526
527     IUnknown_AddRef((IUnknown*)*ppv);
528     return S_OK;
529 }
530
531 static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
532 {
533     return 2;
534 }
535
536 static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
537 {
538     return 1;
539 }
540
541 static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
542 {
543     ok(0, "unexpected call\n");
544     return E_NOTIMPL;
545 }
546
547 static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
548                                               LCID lcid, ITypeInfo **ppTInfo)
549 {
550     ok(0, "unexpected call\n");
551     return E_NOTIMPL;
552 }
553
554 static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
555                                                 LPOLESTR *rgszNames, UINT cNames,
556                                                 LCID lcid, DISPID *rgDispId)
557 {
558     ok(0, "unexpected call\n");
559     return E_NOTIMPL;
560 }
561
562 static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
563                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
564                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
565 {
566     ok(0, "unexpected call\n");
567     return E_NOTIMPL;
568 }
569
570 static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
571 {
572     ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
573     return E_NOTIMPL;
574 }
575
576 static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
577 {
578     ok(0, "unexpected call\n");
579     return E_NOTIMPL;
580 }
581
582 static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
583 {
584     ok(0, "unexpected call\n");
585     return E_NOTIMPL;
586 }
587
588 static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
589 {
590     ok(0, "unexpected call\n");
591     return E_NOTIMPL;
592 }
593
594 static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
595 {
596     ok(0, "unexpected call\n");
597     return E_NOTIMPL;
598 }
599
600 static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
601 {
602     ok(0, "unexpected call\n");
603     return E_NOTIMPL;
604 }
605
606 static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
607 {
608     ok(0, "unexpected call\n");
609     return E_NOTIMPL;
610 }
611
612 static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
613         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
614 {
615     ok(0, "unexpected call %d\n", id);
616     return E_NOTIMPL;
617 }
618
619 static HRESULT WINAPI testObj_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
620 {
621     if(!strcmp_wa(bstrName, "propget")) {
622         CHECK_EXPECT(testobj_propget_d);
623         test_grfdex(grfdex, fdexNameCaseInsensitive);
624         *pid = DISPID_TESTOBJ_PROPGET;
625         return S_OK;
626     }
627     if(!strcmp_wa(bstrName, "propput")) {
628         CHECK_EXPECT(testobj_propput_d);
629         test_grfdex(grfdex, fdexNameCaseInsensitive);
630         *pid = DISPID_TESTOBJ_PROPPUT;
631         return S_OK;
632     }
633
634     ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName));
635     return DISP_E_UNKNOWNNAME;
636 }
637
638 static HRESULT WINAPI testObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
639         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
640 {
641     switch(id) {
642     case DISPID_TESTOBJ_PROPGET:
643         CHECK_EXPECT(testobj_propget_i);
644
645         ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
646         ok(pdp != NULL, "pdp == NULL\n");
647         ok(!pdp->rgvarg, "rgvarg == NULL\n");
648         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
649         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
650         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
651         ok(pvarRes != NULL, "pvarRes == NULL\n");
652         ok(pei != NULL, "pei == NULL\n");
653
654         V_VT(pvarRes) = VT_I2;
655         V_I2(pvarRes) = 10;
656         return S_OK;
657     case DISPID_TESTOBJ_PROPPUT:
658         CHECK_EXPECT(testobj_propput_i);
659
660         ok(wFlags == DISPATCH_PROPERTYPUT, "wFlags = %x\n", wFlags);
661         ok(pdp != NULL, "pdp == NULL\n");
662         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
663         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
664         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
665         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
666         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
667         ok(!pvarRes, "pvarRes != NULL\n");
668         ok(pei != NULL, "pei == NULL\n");
669
670         ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
671         ok(V_I2(pdp->rgvarg) == 1, "V_I2(psp->rgvargs) = %d\n", V_I2(pdp->rgvarg));
672         return S_OK;
673     }
674
675     ok(0, "unexpected call %d\n", id);
676     return E_FAIL;
677 }
678
679 static IDispatchExVtbl testObjVtbl = {
680     DispatchEx_QueryInterface,
681     DispatchEx_AddRef,
682     DispatchEx_Release,
683     DispatchEx_GetTypeInfoCount,
684     DispatchEx_GetTypeInfo,
685     DispatchEx_GetIDsOfNames,
686     DispatchEx_Invoke,
687     testObj_GetDispID,
688     testObj_InvokeEx,
689     DispatchEx_DeleteMemberByName,
690     DispatchEx_DeleteMemberByDispID,
691     DispatchEx_GetMemberProperties,
692     DispatchEx_GetMemberName,
693     DispatchEx_GetNextDispID,
694     DispatchEx_GetNameSpaceParent
695 };
696
697 static IDispatchEx testObj = { &testObjVtbl };
698
699 static HRESULT WINAPI enumDisp_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
700 {
701     return IEnumVARIANT_QueryInterface(&enumObj, riid, ppv);
702 }
703
704 static IDispatchExVtbl enumDispVtbl = {
705     enumDisp_QueryInterface,
706     DispatchEx_AddRef,
707     DispatchEx_Release,
708     DispatchEx_GetTypeInfoCount,
709     DispatchEx_GetTypeInfo,
710     DispatchEx_GetIDsOfNames,
711     DispatchEx_Invoke,
712     DispatchEx_GetDispID,
713     DispatchEx_InvokeEx,
714     DispatchEx_DeleteMemberByName,
715     DispatchEx_DeleteMemberByDispID,
716     DispatchEx_GetMemberProperties,
717     DispatchEx_GetMemberName,
718     DispatchEx_GetNextDispID,
719     DispatchEx_GetNameSpaceParent
720 };
721
722 static IDispatchEx enumDisp = { &enumDispVtbl };
723
724 static HRESULT WINAPI collectionObj_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
725 {
726     if(!strcmp_wa(bstrName, "reset")) {
727         *pid = DISPID_COLLOBJ_RESET;
728         return S_OK;
729     }
730
731     ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName));
732     return DISP_E_UNKNOWNNAME;
733 }
734
735 static HRESULT WINAPI collectionObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
736         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
737 {
738     switch(id) {
739     case DISPID_NEWENUM:
740         if(strict_dispid_check)
741             CHECK_EXPECT(collectionobj_newenum_i);
742
743         ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
744         ok(pdp != NULL, "pdp == NULL\n");
745         ok(!pdp->rgvarg, "rgvarg == NULL\n");
746         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
747         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
748         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
749         ok(pvarRes != NULL, "pvarRes == NULL\n");
750         ok(pei != NULL, "pei == NULL\n");
751
752         V_VT(pvarRes) = VT_UNKNOWN;
753         V_UNKNOWN(pvarRes) = (IUnknown*)&enumObj;
754         return S_OK;
755     case DISPID_COLLOBJ_RESET:
756         next_cnt = 0;
757         return S_OK;
758     }
759
760     ok(0, "unexpected call %d\n", id);
761     return E_NOTIMPL;
762 }
763
764 static IDispatchExVtbl collectionObjVtbl = {
765     DispatchEx_QueryInterface,
766     DispatchEx_AddRef,
767     DispatchEx_Release,
768     DispatchEx_GetTypeInfoCount,
769     DispatchEx_GetTypeInfo,
770     DispatchEx_GetIDsOfNames,
771     DispatchEx_Invoke,
772     collectionObj_GetDispID,
773     collectionObj_InvokeEx,
774     DispatchEx_DeleteMemberByName,
775     DispatchEx_DeleteMemberByDispID,
776     DispatchEx_GetMemberProperties,
777     DispatchEx_GetMemberName,
778     DispatchEx_GetNextDispID,
779     DispatchEx_GetNameSpaceParent
780 };
781
782 static IDispatchEx collectionObj = { &collectionObjVtbl };
783
784 static ULONG refobj_ref;
785
786 static ULONG WINAPI RefObj_AddRef(IDispatchEx *iface)
787 {
788     return ++refobj_ref;
789 }
790
791 static ULONG WINAPI RefObj_Release(IDispatchEx *iface)
792 {
793     return --refobj_ref;
794 }
795
796 static IDispatchExVtbl RefObjVtbl = {
797     DispatchEx_QueryInterface,
798     RefObj_AddRef,
799     RefObj_Release,
800     DispatchEx_GetTypeInfoCount,
801     DispatchEx_GetTypeInfo,
802     DispatchEx_GetIDsOfNames,
803     DispatchEx_Invoke,
804     DispatchEx_GetDispID,
805     DispatchEx_InvokeEx,
806     DispatchEx_DeleteMemberByName,
807     DispatchEx_DeleteMemberByDispID,
808     DispatchEx_GetMemberProperties,
809     DispatchEx_GetMemberName,
810     DispatchEx_GetNextDispID,
811     DispatchEx_GetNameSpaceParent
812 };
813
814 static IDispatchEx RefObj = { &RefObjVtbl };
815
816 static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
817 {
818     if(!strcmp_wa(bstrName, "ok")) {
819         test_grfdex(grfdex, fdexNameCaseInsensitive);
820         *pid = DISPID_GLOBAL_OK;
821         return S_OK;
822     }
823     if(!strcmp_wa(bstrName, "trace")) {
824         test_grfdex(grfdex, fdexNameCaseInsensitive);
825         *pid = DISPID_GLOBAL_TRACE;
826         return S_OK;
827     }
828     if(!strcmp_wa(bstrName, "reportSuccess")) {
829         CHECK_EXPECT(global_success_d);
830         test_grfdex(grfdex, fdexNameCaseInsensitive);
831         *pid = DISPID_GLOBAL_REPORTSUCCESS;
832         return S_OK;
833     }
834     if(!strcmp_wa(bstrName, "getVT")) {
835         test_grfdex(grfdex, fdexNameCaseInsensitive);
836         *pid = DISPID_GLOBAL_GETVT;
837         return S_OK;
838     }
839     if(!strcmp_wa(bstrName, "isEnglishLang")) {
840         test_grfdex(grfdex, fdexNameCaseInsensitive);
841         *pid = DISPID_GLOBAL_ISENGLANG;
842         return S_OK;
843     }
844     if(!strcmp_wa(bstrName, "testObj")) {
845         test_grfdex(grfdex, fdexNameCaseInsensitive);
846         *pid = DISPID_GLOBAL_TESTOBJ;
847         return S_OK;
848     }
849     if(!strcmp_wa(bstrName, "collectionObj")) {
850         test_grfdex(grfdex, fdexNameCaseInsensitive);
851         *pid = DISPID_GLOBAL_COLLOBJ;
852         return S_OK;
853     }
854     if(!strcmp_wa(bstrName, "vbvar")) {
855         CHECK_EXPECT(global_vbvar_d);
856         test_grfdex(grfdex, fdexNameCaseInsensitive);
857         *pid = DISPID_GLOBAL_VBVAR;
858         return S_OK;
859     }
860     if(!strcmp_wa(bstrName, "isNullDisp")) {
861         test_grfdex(grfdex, fdexNameCaseInsensitive);
862         *pid = DISPID_GLOBAL_ISNULLDISP;
863         return S_OK;
864     }
865     if(!strcmp_wa(bstrName, "testDisp")) {
866         test_grfdex(grfdex, fdexNameCaseInsensitive);
867         *pid = DISPID_GLOBAL_TESTDISP;
868         return S_OK;
869     }
870     if(!strcmp_wa(bstrName, "RefObj")) {
871         test_grfdex(grfdex, fdexNameCaseInsensitive);
872         *pid = DISPID_GLOBAL_REFOBJ;
873         return S_OK;
874     }
875     if(!strcmp_wa(bstrName, "propargput")) {
876         CHECK_EXPECT(global_propargput_d);
877         test_grfdex(grfdex, fdexNameCaseInsensitive);
878         *pid = DISPID_GLOBAL_PROPARGPUT;
879         return S_OK;
880     }
881     if(!strcmp_wa(bstrName, "propargput1")) {
882         CHECK_EXPECT(global_propargput1_d);
883         test_grfdex(grfdex, fdexNameCaseInsensitive);
884         *pid = DISPID_GLOBAL_PROPARGPUT1;
885         return S_OK;
886     }
887     if(!strcmp_wa(bstrName, "counter")) {
888         test_grfdex(grfdex, fdexNameCaseInsensitive);
889         *pid = DISPID_GLOBAL_COUNTER;
890         return S_OK;
891     }
892     if(!strcmp_wa(bstrName, "doubleAsString")) {
893         test_grfdex(grfdex, fdexNameCaseInsensitive);
894         *pid = DISPID_GLOBAL_DOUBLEASSTRING;
895         return S_OK;
896     }
897
898     if(strict_dispid_check && strcmp_wa(bstrName, "x"))
899         ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
900     return DISP_E_UNKNOWNNAME;
901 }
902
903 static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
904         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
905 {
906     switch(id) {
907     case DISPID_GLOBAL_OK: {
908         VARIANT *b;
909
910         ok(wFlags == INVOKE_FUNC || wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
911         ok(pdp != NULL, "pdp == NULL\n");
912         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
913         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
914         ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
915         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
916         if(wFlags & INVOKE_PROPERTYGET)
917             ok(pvarRes != NULL, "pvarRes == NULL\n");
918         else
919             ok(!pvarRes, "pvarRes != NULL\n");
920         ok(pei != NULL, "pei == NULL\n");
921
922         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
923
924         b = pdp->rgvarg+1;
925         if(V_VT(b) == (VT_BYREF|VT_VARIANT))
926             b = V_BYREF(b);
927
928         ok(V_VT(b) == VT_BOOL, "V_VT(b) = %d\n", V_VT(b));
929
930         ok(V_BOOL(b), "%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
931         return S_OK;
932     }
933
934      case DISPID_GLOBAL_TRACE:
935         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
936         ok(pdp != NULL, "pdp == NULL\n");
937         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
938         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
939         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
940         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
941         ok(!pvarRes, "pvarRes != NULL\n");
942         ok(pei != NULL, "pei == NULL\n");
943
944         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
945         if(V_VT(pdp->rgvarg) == VT_BSTR)
946             trace("%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
947
948         return S_OK;
949
950     case DISPID_GLOBAL_REPORTSUCCESS:
951         CHECK_EXPECT(global_success_i);
952
953         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
954         ok(pdp != NULL, "pdp == NULL\n");
955         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
956         ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
957         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
958         ok(!pvarRes, "pvarRes != NULL\n");
959         ok(pei != NULL, "pei == NULL\n");
960
961         return S_OK;
962
963     case DISPID_GLOBAL_GETVT:
964         ok(pdp != NULL, "pdp == NULL\n");
965         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
966         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
967         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
968         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
969         ok(pvarRes != NULL, "pvarRes == NULL\n");
970         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
971         ok(pei != NULL, "pei == NULL\n");
972
973         V_VT(pvarRes) = VT_BSTR;
974         V_BSTR(pvarRes) = a2bstr(vt2a(pdp->rgvarg));
975         return S_OK;
976
977     case DISPID_GLOBAL_ISENGLANG:
978         ok(wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
979         ok(pdp != NULL, "pdp == NULL\n");
980         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
981         ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
982         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
983         ok(pvarRes != NULL, "pvarRes == NULL\n");
984         ok(pei != NULL, "pei == NULL\n");
985
986         V_VT(pvarRes) = VT_BOOL;
987         V_BOOL(pvarRes) = is_english ? VARIANT_TRUE : VARIANT_FALSE;
988         return S_OK;
989
990     case DISPID_GLOBAL_VBVAR:
991         CHECK_EXPECT(global_vbvar_i);
992
993         ok(wFlags == DISPATCH_PROPERTYPUT, "wFlags = %x\n", wFlags);
994         ok(pdp != NULL, "pdp == NULL\n");
995         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
996         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
997         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
998         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
999         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
1000         ok(!pvarRes, "pvarRes != NULL\n");
1001         ok(pei != NULL, "pei == NULL\n");
1002
1003         ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
1004         ok(V_I2(pdp->rgvarg) == 3, "V_I2(psp->rgvargs) = %d\n", V_I2(pdp->rgvarg));
1005         return S_OK;
1006
1007     case DISPID_GLOBAL_TESTOBJ:
1008         ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
1009
1010         ok(pdp != NULL, "pdp == NULL\n");
1011         ok(!pdp->rgvarg, "rgvarg != NULL\n");
1012         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1013         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
1014         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1015         ok(pvarRes != NULL, "pvarRes == NULL\n");
1016         ok(pei != NULL, "pei == NULL\n");
1017
1018         V_VT(pvarRes) = VT_DISPATCH;
1019         V_DISPATCH(pvarRes) = (IDispatch*)&testObj;
1020         return S_OK;
1021
1022     case DISPID_GLOBAL_COLLOBJ:
1023         ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
1024
1025         ok(pdp != NULL, "pdp == NULL\n");
1026         ok(!pdp->rgvarg, "rgvarg != NULL\n");
1027         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1028         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
1029         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1030         ok(pvarRes != NULL, "pvarRes == NULL\n");
1031         ok(pei != NULL, "pei == NULL\n");
1032
1033         V_VT(pvarRes) = VT_DISPATCH;
1034         V_DISPATCH(pvarRes) = (IDispatch*)&collectionObj;
1035         return S_OK;
1036
1037     case DISPID_GLOBAL_REFOBJ:
1038         ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
1039
1040         ok(pdp != NULL, "pdp == NULL\n");
1041         ok(!pdp->rgvarg, "rgvarg == NULL\n");
1042         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1043         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
1044         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1045         ok(pvarRes != NULL, "pvarRes == NULL\n");
1046         ok(pei != NULL, "pei == NULL\n");
1047
1048         IDispatchEx_AddRef(&RefObj);
1049         V_VT(pvarRes) = VT_DISPATCH;
1050         V_DISPATCH(pvarRes) = (IDispatch*)&RefObj;
1051         return S_OK;
1052
1053     case DISPID_GLOBAL_ISNULLDISP: {
1054         VARIANT *v;
1055
1056         ok(wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
1057         ok(pdp != NULL, "pdp == NULL\n");
1058         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1059         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1060         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1061         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1062         ok(pvarRes != NULL, "pvarRes == NULL\n");
1063         ok(pei != NULL, "pei == NULL\n");
1064
1065         v = pdp->rgvarg;
1066         if(V_VT(v) == (VT_VARIANT|VT_BYREF))
1067             v = V_VARIANTREF(v);
1068
1069         ok(V_VT(v) == VT_DISPATCH, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
1070         V_VT(pvarRes) = VT_BOOL;
1071         V_BOOL(pvarRes) = V_DISPATCH(v) ? VARIANT_FALSE : VARIANT_TRUE;
1072         return S_OK;
1073     }
1074
1075     case DISPID_GLOBAL_TESTDISP:
1076         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
1077         ok(pdp != NULL, "pdp == NULL\n");
1078         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1079         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1080         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1081         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1082         ok(!pvarRes, "pvarRes != NULL\n");
1083         ok(pei != NULL, "pei == NULL\n");
1084
1085         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
1086         test_disp(V_DISPATCH(pdp->rgvarg));
1087         return S_OK;
1088
1089     case DISPID_GLOBAL_PROPARGPUT:
1090         CHECK_EXPECT(global_propargput_i);
1091
1092         ok(wFlags == DISPATCH_PROPERTYPUT, "wFlags = %x\n", wFlags);
1093         ok(pdp != NULL, "pdp == NULL\n");
1094         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1095         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
1096         ok(pdp->cArgs == 3, "cArgs = %d\n", pdp->cArgs);
1097         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
1098         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
1099         ok(!pvarRes, "pvarRes != NULL\n");
1100         ok(pei != NULL, "pei == NULL\n");
1101
1102         ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
1103         ok(V_I2(pdp->rgvarg) == 0, "V_I2(psp->rgvargs) = %d\n", V_I2(pdp->rgvarg));
1104
1105         ok(V_VT(pdp->rgvarg+1) == VT_I2, "V_VT(psp->rgvargs+1) = %d\n", V_VT(pdp->rgvarg+1));
1106         ok(V_I2(pdp->rgvarg+1) == 2, "V_I2(psp->rgvargs+1) = %d\n", V_I2(pdp->rgvarg+1));
1107
1108         ok(V_VT(pdp->rgvarg+2) == VT_I2, "V_VT(psp->rgvargs+2) = %d\n", V_VT(pdp->rgvarg+2));
1109         ok(V_I2(pdp->rgvarg+2) == 1, "V_I2(psp->rgvargs+2) = %d\n", V_I2(pdp->rgvarg+2));
1110         return S_OK;
1111
1112     case DISPID_GLOBAL_PROPARGPUT1:
1113         CHECK_EXPECT(global_propargput1_i);
1114
1115         ok(wFlags == DISPATCH_PROPERTYPUT, "wFlags = %x\n", wFlags);
1116         ok(pdp != NULL, "pdp == NULL\n");
1117         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1118         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
1119         ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
1120         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
1121         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
1122         ok(!pvarRes, "pvarRes != NULL\n");
1123         ok(pei != NULL, "pei == NULL\n");
1124
1125         ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
1126         ok(V_I2(pdp->rgvarg) == 0, "V_I2(psp->rgvargs) = %d\n", V_I2(pdp->rgvarg));
1127
1128         ok(V_VT(pdp->rgvarg+1) == VT_I2, "V_VT(psp->rgvargs+1) = %d\n", V_VT(pdp->rgvarg+1));
1129         ok(V_I2(pdp->rgvarg+1) == 1, "V_I2(psp->rgvargs+1) = %d\n", V_I2(pdp->rgvarg+1));
1130
1131         return S_OK;
1132
1133     case DISPID_GLOBAL_COUNTER:
1134         ok(pdp != NULL, "pdp == NULL\n");
1135         todo_wine ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1136         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1137         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
1138         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1139         ok(pvarRes != NULL, "pvarRes == NULL\n");
1140         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1141         ok(pei != NULL, "pei == NULL\n");
1142
1143         V_VT(pvarRes) = VT_I2;
1144         V_I2(pvarRes) = test_counter++;
1145         return S_OK;
1146
1147     case DISPID_GLOBAL_DOUBLEASSTRING:
1148         ok(wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
1149         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1150         ok(V_VT(pdp->rgvarg) == VT_R8, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
1151         ok(pvarRes != NULL, "pvarRes == NULL\n");
1152
1153         V_VT(pvarRes) = VT_BSTR;
1154         return VarBstrFromR8(V_R8(pdp->rgvarg), 0, 0, &V_BSTR(pvarRes));
1155     }
1156
1157     ok(0, "unexpected call %d\n", id);
1158     return DISP_E_MEMBERNOTFOUND;
1159 }
1160
1161 static IDispatchExVtbl GlobalVtbl = {
1162     DispatchEx_QueryInterface,
1163     DispatchEx_AddRef,
1164     DispatchEx_Release,
1165     DispatchEx_GetTypeInfoCount,
1166     DispatchEx_GetTypeInfo,
1167     DispatchEx_GetIDsOfNames,
1168     DispatchEx_Invoke,
1169     Global_GetDispID,
1170     Global_InvokeEx,
1171     DispatchEx_DeleteMemberByName,
1172     DispatchEx_DeleteMemberByDispID,
1173     DispatchEx_GetMemberProperties,
1174     DispatchEx_GetMemberName,
1175     DispatchEx_GetNextDispID,
1176     DispatchEx_GetNameSpaceParent
1177 };
1178
1179 static IDispatchEx Global = { &GlobalVtbl };
1180
1181 static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
1182 {
1183     *ppv = NULL;
1184
1185     if(IsEqualGUID(&IID_IUnknown, riid))
1186         *ppv = iface;
1187     else if(IsEqualGUID(&IID_IActiveScriptSite, riid))
1188         *ppv = iface;
1189     else
1190         return E_NOINTERFACE;
1191
1192     IUnknown_AddRef((IUnknown*)*ppv);
1193     return S_OK;
1194 }
1195
1196 static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
1197 {
1198     return 2;
1199 }
1200
1201 static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
1202 {
1203     return 1;
1204 }
1205
1206 static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *plcid)
1207 {
1208     *plcid = GetUserDefaultLCID();
1209     return S_OK;
1210 }
1211
1212 static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR pstrName,
1213         DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti)
1214 {
1215     ok(dwReturnMask == SCRIPTINFO_IUNKNOWN, "unexpected dwReturnMask %x\n", dwReturnMask);
1216     ok(!ppti, "ppti != NULL\n");
1217
1218     if(strcmp_wa(pstrName, "test"))
1219         ok(0, "unexpected pstrName %s\n", wine_dbgstr_w(pstrName));
1220
1221     *ppiunkItem = (IUnknown*)&Global;
1222     return S_OK;
1223 }
1224
1225 static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *pbstrVersion)
1226 {
1227     return E_NOTIMPL;
1228 }
1229
1230 static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface,
1231         const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo)
1232 {
1233     return E_NOTIMPL;
1234 }
1235
1236 static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE ssScriptState)
1237 {
1238     return E_NOTIMPL;
1239 }
1240
1241 static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
1242 {
1243     return E_NOTIMPL;
1244 }
1245
1246 static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
1247 {
1248     return E_NOTIMPL;
1249 }
1250
1251 static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
1252 {
1253     return E_NOTIMPL;
1254 }
1255
1256 #undef ACTSCPSITE_THIS
1257
1258 static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
1259     ActiveScriptSite_QueryInterface,
1260     ActiveScriptSite_AddRef,
1261     ActiveScriptSite_Release,
1262     ActiveScriptSite_GetLCID,
1263     ActiveScriptSite_GetItemInfo,
1264     ActiveScriptSite_GetDocVersionString,
1265     ActiveScriptSite_OnScriptTerminate,
1266     ActiveScriptSite_OnStateChange,
1267     ActiveScriptSite_OnScriptError,
1268     ActiveScriptSite_OnEnterScript,
1269     ActiveScriptSite_OnLeaveScript
1270 };
1271
1272 static IActiveScriptSite ActiveScriptSite = { &ActiveScriptSiteVtbl };
1273
1274 static IActiveScript *create_script(void)
1275 {
1276     IActiveScript *script;
1277     HRESULT hres;
1278
1279     hres = CoCreateInstance(&CLSID_VBScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1280             &IID_IActiveScript, (void**)&script);
1281     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
1282
1283     return script;
1284 }
1285
1286 static IActiveScript *create_and_init_script(DWORD flags)
1287 {
1288     IActiveScriptParse *parser;
1289     IActiveScript *engine;
1290     HRESULT hres;
1291
1292     engine = create_script();
1293     if(!engine)
1294         return NULL;
1295
1296     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
1297     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1298
1299     hres = IActiveScriptParse_InitNew(parser);
1300     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
1301
1302     IActiveScriptParse_Release(parser);
1303
1304     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
1305     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
1306
1307     hres = IActiveScript_AddNamedItem(engine, testW,
1308             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|flags);
1309     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
1310
1311     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
1312     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
1313
1314     return engine;
1315 }
1316
1317 static void close_script(IActiveScript *script)
1318 {
1319     ULONG ref;
1320     HRESULT hres;
1321
1322     hres = IActiveScript_Close(script);
1323     ok(hres == S_OK, "Close failed: %08x\n", hres);
1324
1325     ref = IActiveScript_Release(script);
1326     ok(!ref, "ref=%u\n", ref);
1327 }
1328
1329 static HRESULT parse_script(DWORD flags, BSTR script_str)
1330 {
1331     IActiveScriptParse *parser;
1332     IActiveScript *engine;
1333     IDispatch *script_disp;
1334     LONG ref;
1335     HRESULT hres;
1336
1337     engine = create_and_init_script(flags);
1338     if(!engine)
1339         return S_OK;
1340
1341     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
1342     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1343     if (FAILED(hres))
1344     {
1345         IActiveScript_Release(engine);
1346         return hres;
1347     }
1348
1349     hres = IActiveScript_GetScriptDispatch(engine, NULL, &script_disp);
1350     ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres);
1351     ok(script_disp != NULL, "script_disp == NULL\n");
1352     ok(script_disp != (IDispatch*)&Global, "script_disp == Global\n");
1353
1354     test_counter = 0;
1355
1356     hres = IActiveScriptParse_ParseScriptText(parser, script_str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
1357
1358     IActiveScript_Close(engine);
1359
1360     IDispatch_Release(script_disp);
1361     IActiveScript_Release(engine);
1362
1363     ref = IActiveScriptParse_Release(parser);
1364     ok(!ref, "ref=%d\n", ref);
1365     return hres;
1366 }
1367
1368 static void parse_script_af(DWORD flags, const char *src)
1369 {
1370     BSTR tmp;
1371     HRESULT hres;
1372
1373     tmp = a2bstr(src);
1374     hres = parse_script(flags, tmp);
1375     SysFreeString(tmp);
1376     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
1377 }
1378
1379 static void parse_script_a(const char *src)
1380 {
1381     parse_script_af(SCRIPTITEM_GLOBALMEMBERS, src);
1382 }
1383
1384 static IDispatchEx *parse_procedure(IActiveScriptParseProcedure2 *parse_proc, const char *src)
1385 {
1386     IDispatchEx *dispex;
1387     IDispatch *disp;
1388     BSTR str;
1389     HRESULT hres;
1390
1391     static const WCHAR delimiterW[] = {'\"',0};
1392
1393     str = a2bstr(src);
1394     hres = IActiveScriptParseProcedure2_ParseProcedureText(parse_proc, str, NULL, emptyW, NULL, NULL, delimiterW, 0, 0,
1395             SCRIPTPROC_HOSTMANAGESSOURCE|SCRIPTPROC_IMPLICIT_THIS|SCRIPTPROC_IMPLICIT_PARENTS, &disp);
1396     SysFreeString(str);
1397     ok(hres == S_OK, "ParseProcedureText failed: %08x\n", hres);
1398     ok(disp != NULL, "disp = NULL\n");
1399
1400     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
1401     IDispatch_Release(disp);
1402     ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
1403
1404     return dispex;
1405 }
1406
1407
1408 static void test_procedures(void)
1409 {
1410     IActiveScriptParseProcedure2 *parse_proc;
1411     DISPPARAMS dp = {NULL};
1412     IActiveScript *script;
1413     IDispatchEx *proc;
1414     EXCEPINFO ei = {0};
1415     VARIANT v;
1416     HRESULT hres;
1417
1418     script = create_and_init_script(0);
1419
1420     hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParseProcedure2, (void**)&parse_proc);
1421     ok(hres == S_OK, "Could not get IActiveScriptParseProcedure2 iface: %08x\n", hres);
1422
1423     proc = parse_procedure(parse_proc, "dim x\nif true then x=false");
1424
1425     V_VT(&v) = VT_EMPTY;
1426     hres = IDispatchEx_InvokeEx(proc, DISPID_VALUE, 0, DISPATCH_METHOD, &dp, &v, &ei, &caller_sp);
1427     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1428
1429     IDispatchEx_Release(proc);
1430
1431     IActiveScriptParseProcedure2_Release(parse_proc);
1432
1433     close_script(script);
1434 }
1435
1436 static void test_gc(void)
1437 {
1438     IActiveScriptParse *parser;
1439     IActiveScript *engine;
1440     BSTR src;
1441     HRESULT hres;
1442
1443     strict_dispid_check = FALSE;
1444
1445     engine = create_script();
1446     if(!engine)
1447         return;
1448
1449     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
1450     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1451
1452     hres = IActiveScriptParse_InitNew(parser);
1453     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
1454
1455     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
1456     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
1457
1458     hres = IActiveScript_AddNamedItem(engine, testW,
1459             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
1460     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
1461
1462     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
1463     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
1464
1465     src = a2bstr(
1466             "class C\n"
1467             "    Public ref\n"
1468             "    Public Sub Class_Terminate\n"
1469             "        Call reportSuccess()\n"
1470             "    End Sub\n"
1471             "End Class\n"
1472             "Dim x\n"
1473             "set x = new C\n"
1474             "set x.ref = x\n"
1475             "set x = nothing\n");
1476
1477     hres = IActiveScriptParse_ParseScriptText(parser, src, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
1478     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
1479     SysFreeString(src);
1480
1481     SET_EXPECT(global_success_d);
1482     SET_EXPECT(global_success_i);
1483     IActiveScript_Close(engine);
1484     CHECK_CALLED(global_success_d);
1485     CHECK_CALLED(global_success_i);
1486
1487     IActiveScript_Release(engine);
1488     IActiveScriptParse_Release(parser);
1489 }
1490
1491 static HRESULT test_global_vars_ref(BOOL use_close)
1492 {
1493     IActiveScriptParse *parser;
1494     IActiveScript *engine;
1495     BSTR script_str;
1496     LONG ref;
1497     HRESULT hres;
1498
1499     engine = create_script();
1500     if(!engine)
1501         return S_OK;
1502
1503     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
1504     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1505     if (FAILED(hres))
1506     {
1507         IActiveScript_Release(engine);
1508         return hres;
1509     }
1510
1511     hres = IActiveScriptParse_InitNew(parser);
1512     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
1513
1514     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
1515     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
1516
1517     hres = IActiveScript_AddNamedItem(engine, testW, SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
1518     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
1519
1520     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
1521     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
1522
1523     refobj_ref = 0;
1524
1525     script_str = a2bstr("Dim x\nset x = RefObj\n");
1526     hres = IActiveScriptParse_ParseScriptText(parser, script_str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
1527     SysFreeString(script_str);
1528
1529     ok(refobj_ref, "refobj_ref = 0\n");
1530
1531     if(use_close) {
1532         hres = IActiveScript_Close(engine);
1533         ok(hres == S_OK, "Close failed: %08x\n", hres);
1534     }else {
1535         hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_UNINITIALIZED);
1536         ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
1537     }
1538
1539     ok(!refobj_ref, "refobj_ref = %d\n", refobj_ref);
1540
1541     IActiveScript_Release(engine);
1542
1543     ref = IActiveScriptParse_Release(parser);
1544     ok(!ref, "ref=%d\n", ref);
1545     return hres;
1546 }
1547
1548 static BSTR get_script_from_file(const char *filename)
1549 {
1550     DWORD size, len;
1551     HANDLE file, map;
1552     const char *file_map;
1553     BSTR ret;
1554
1555     file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
1556     if(file == INVALID_HANDLE_VALUE) {
1557         trace("Could not open file: %u\n", GetLastError());
1558         return NULL;
1559     }
1560
1561     size = GetFileSize(file, NULL);
1562
1563     map = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
1564     CloseHandle(file);
1565     if(map == INVALID_HANDLE_VALUE) {
1566         trace("Could not create file mapping: %u\n", GetLastError());
1567         return NULL;
1568     }
1569
1570     file_map = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
1571     CloseHandle(map);
1572     if(!file_map) {
1573         trace("MapViewOfFile failed: %u\n", GetLastError());
1574         return NULL;
1575     }
1576
1577     len = MultiByteToWideChar(CP_ACP, 0, file_map, size, NULL, 0);
1578     ret = SysAllocStringLen(NULL, len);
1579     MultiByteToWideChar(CP_ACP, 0, file_map, size, ret, len);
1580
1581     UnmapViewOfFile(file_map);
1582
1583     return ret;
1584 }
1585
1586 static void run_from_file(const char *filename)
1587 {
1588     BSTR script_str;
1589     HRESULT hres;
1590
1591     script_str = get_script_from_file(filename);
1592     if(!script_str)
1593         return;
1594
1595     strict_dispid_check = FALSE;
1596     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, script_str);
1597     SysFreeString(script_str);
1598     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
1599 }
1600
1601 static void run_from_res(const char *name)
1602 {
1603     const char *data;
1604     DWORD size, len;
1605     BSTR str;
1606     HRSRC src;
1607     HRESULT hres;
1608
1609     strict_dispid_check = FALSE;
1610     test_name = name;
1611
1612     src = FindResourceA(NULL, name, (LPCSTR)40);
1613     ok(src != NULL, "Could not find resource %s\n", name);
1614
1615     size = SizeofResource(NULL, src);
1616     data = LoadResource(NULL, src);
1617
1618     len = MultiByteToWideChar(CP_ACP, 0, data, size, NULL, 0);
1619     str = SysAllocStringLen(NULL, len);
1620     MultiByteToWideChar(CP_ACP, 0, data, size, str, len);
1621
1622     SET_EXPECT(global_success_d);
1623     SET_EXPECT(global_success_i);
1624     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, str);
1625     CHECK_CALLED(global_success_d);
1626     CHECK_CALLED(global_success_i);
1627
1628     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
1629     SysFreeString(str);
1630 }
1631
1632 static void run_tests(void)
1633 {
1634     strict_dispid_check = TRUE;
1635
1636     parse_script_a("");
1637     parse_script_a("' empty ;");
1638
1639     SET_EXPECT(global_success_d);
1640     SET_EXPECT(global_success_i);
1641     parse_script_a("reportSuccess");
1642     CHECK_CALLED(global_success_d);
1643     CHECK_CALLED(global_success_i);
1644
1645     SET_EXPECT(global_success_d);
1646     SET_EXPECT(global_success_i);
1647     parse_script_a("reportSuccess()");
1648     CHECK_CALLED(global_success_d);
1649     CHECK_CALLED(global_success_i);
1650
1651     SET_EXPECT(global_success_d);
1652     SET_EXPECT(global_success_i);
1653     parse_script_a("Call reportSuccess");
1654     CHECK_CALLED(global_success_d);
1655     CHECK_CALLED(global_success_i);
1656
1657     SET_EXPECT(global_success_d);
1658     SET_EXPECT(global_success_i);
1659     parse_script_a("test.reportSuccess()");
1660     CHECK_CALLED(global_success_d);
1661     CHECK_CALLED(global_success_i);
1662
1663     SET_EXPECT(global_vbvar_d);
1664     SET_EXPECT(global_vbvar_i);
1665     parse_script_a("Option Explicit\nvbvar = 3");
1666     CHECK_CALLED(global_vbvar_d);
1667     CHECK_CALLED(global_vbvar_i);
1668
1669     SET_EXPECT(global_vbvar_d);
1670     SET_EXPECT(global_vbvar_i);
1671     parse_script_a("Option Explicit\nvbvar() = 3");
1672     CHECK_CALLED(global_vbvar_d);
1673     CHECK_CALLED(global_vbvar_i);
1674
1675     SET_EXPECT(testobj_propget_d);
1676     SET_EXPECT(testobj_propget_i);
1677     parse_script_a("dim x\nx = testObj.propget");
1678     CHECK_CALLED(testobj_propget_d);
1679     CHECK_CALLED(testobj_propget_i);
1680
1681     SET_EXPECT(testobj_propput_d);
1682     SET_EXPECT(testobj_propput_i);
1683     parse_script_a("testObj.propput = 1");
1684     CHECK_CALLED(testobj_propput_d);
1685     CHECK_CALLED(testobj_propput_i);
1686
1687     SET_EXPECT(global_propargput_d);
1688     SET_EXPECT(global_propargput_i);
1689     parse_script_a("propargput(counter(), counter()) = counter()");
1690     CHECK_CALLED(global_propargput_d);
1691     CHECK_CALLED(global_propargput_i);
1692
1693     SET_EXPECT(global_propargput_d);
1694     SET_EXPECT(global_propargput_i);
1695     parse_script_a("test.propargput(counter(), counter()) = counter()");
1696     CHECK_CALLED(global_propargput_d);
1697     CHECK_CALLED(global_propargput_i);
1698
1699     SET_EXPECT(global_propargput1_d);
1700     SET_EXPECT(global_propargput1_i);
1701     parse_script_a("propargput1 (counter()) = counter()");
1702     CHECK_CALLED(global_propargput1_d);
1703     CHECK_CALLED(global_propargput1_i);
1704
1705     SET_EXPECT(global_propargput1_d);
1706     SET_EXPECT(global_propargput1_i);
1707     parse_script_a("test.propargput1(counter()) = counter()");
1708     CHECK_CALLED(global_propargput1_d);
1709     CHECK_CALLED(global_propargput1_i);
1710
1711     next_cnt = 0;
1712     SET_EXPECT(collectionobj_newenum_i);
1713     SET_EXPECT(Next);
1714     parse_script_a("for each x in collectionObj\nnext");
1715     CHECK_CALLED(collectionobj_newenum_i);
1716     CHECK_CALLED(Next);
1717     ok(next_cnt == 4, "next_cnt = %d\n", next_cnt);
1718
1719     parse_script_a("x = 1\n Call ok(x = 1, \"x = \" & x)");
1720
1721     parse_script_a("x = _    \n3");
1722
1723     test_global_vars_ref(TRUE);
1724     test_global_vars_ref(FALSE);
1725
1726     strict_dispid_check = FALSE;
1727
1728     parse_script_a("Sub testsub\n"
1729                    "x = 1\n"
1730                    "Call ok(x = 1, \"x = \" & x)\n"
1731                    "End Sub\n"
1732                    "Call testsub()");
1733
1734     run_from_res("lang.vbs");
1735     run_from_res("api.vbs");
1736
1737     test_procedures();
1738     test_gc();
1739 }
1740
1741 static BOOL check_vbscript(void)
1742 {
1743     IActiveScriptParseProcedure2 *vbscript;
1744     HRESULT hres;
1745
1746     hres = CoCreateInstance(&CLSID_VBScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1747             &IID_IActiveScriptParseProcedure2, (void**)&vbscript);
1748     if(SUCCEEDED(hres))
1749         IActiveScriptParseProcedure2_Release(vbscript);
1750
1751     return hres == S_OK;
1752 }
1753
1754 START_TEST(run)
1755 {
1756     int argc;
1757     char **argv;
1758
1759     is_english = is_lang_english();
1760     if(!is_english)
1761         skip("Skipping some tests in non-English UIs\n");
1762
1763     argc = winetest_get_mainargs(&argv);
1764
1765     CoInitialize(NULL);
1766
1767     if(!check_vbscript()) {
1768         win_skip("Broken engine, probably too old\n");
1769     }else if(argc > 2) {
1770         run_from_file(argv[2]);
1771     }else {
1772         run_tests();
1773     }
1774
1775     CoUninitialize();
1776 }