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