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 "vbsregexp55.h"
29 
30 #include "wine/test.h"
31 
32 #ifdef _WIN64
33 
34 #define IActiveScriptParse_QueryInterface IActiveScriptParse64_QueryInterface
35 #define IActiveScriptParse_Release IActiveScriptParse64_Release
36 #define IActiveScriptParse_InitNew IActiveScriptParse64_InitNew
37 #define IActiveScriptParse_ParseScriptText IActiveScriptParse64_ParseScriptText
38 #define IActiveScriptParseProcedure2_Release IActiveScriptParseProcedure2_64_Release
39 #define IActiveScriptParseProcedure2_ParseProcedureText IActiveScriptParseProcedure2_64_ParseProcedureText
40 
41 #else
42 
43 #define IActiveScriptParse_QueryInterface IActiveScriptParse32_QueryInterface
44 #define IActiveScriptParse_Release IActiveScriptParse32_Release
45 #define IActiveScriptParse_InitNew IActiveScriptParse32_InitNew
46 #define IActiveScriptParse_ParseScriptText IActiveScriptParse32_ParseScriptText
47 #define IActiveScriptParseProcedure2_Release IActiveScriptParseProcedure2_32_Release
48 #define IActiveScriptParseProcedure2_ParseProcedureText IActiveScriptParseProcedure2_32_ParseProcedureText
49 
50 #endif
51 
52 extern const CLSID CLSID_VBScript;
53 extern const CLSID CLSID_VBScriptRegExp;
54 
55 #define DEFINE_EXPECT(func) \
56     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
57 
58 #define SET_EXPECT(func) \
59     expect_ ## func = TRUE
60 
61 #define CHECK_EXPECT2(func) \
62     do { \
63         ok(expect_ ##func, "unexpected call " #func "\n"); \
64         called_ ## func = TRUE; \
65     }while(0)
66 
67 #define CHECK_EXPECT(func) \
68     do { \
69         CHECK_EXPECT2(func); \
70         expect_ ## func = FALSE; \
71     }while(0)
72 
73 #define CHECK_CALLED(func) \
74     do { \
75         ok(called_ ## func, "expected " #func "\n"); \
76         expect_ ## func = called_ ## func = FALSE; \
77     }while(0)
78 
79 #define CLEAR_CALLED(func) \
80     expect_ ## func = called_ ## func = FALSE
81 
82 DEFINE_EXPECT(global_success_d);
83 DEFINE_EXPECT(global_success_i);
84 DEFINE_EXPECT(global_vbvar_d);
85 DEFINE_EXPECT(global_vbvar_i);
86 DEFINE_EXPECT(global_letobj_i);
87 DEFINE_EXPECT(global_setobj_i);
88 DEFINE_EXPECT(testobj_propget_d);
89 DEFINE_EXPECT(testobj_propget_i);
90 DEFINE_EXPECT(testobj_propput_d);
91 DEFINE_EXPECT(testobj_propput_i);
92 DEFINE_EXPECT(testobj_value_i);
93 DEFINE_EXPECT(global_propargput_d);
94 DEFINE_EXPECT(global_propargput_i);
95 DEFINE_EXPECT(global_propargput1_d);
96 DEFINE_EXPECT(global_propargput1_i);
97 DEFINE_EXPECT(global_testoptionalarg_i);
98 DEFINE_EXPECT(collectionobj_newenum_i);
99 DEFINE_EXPECT(Next);
100 DEFINE_EXPECT(GetWindow);
101 DEFINE_EXPECT(GetUIBehavior);
102 DEFINE_EXPECT(EnableModeless);
103 DEFINE_EXPECT(OnScriptError);
104 
105 #define DISPID_GLOBAL_REPORTSUCCESS 1000
106 #define DISPID_GLOBAL_TRACE         1001
107 #define DISPID_GLOBAL_OK            1002
108 #define DISPID_GLOBAL_GETVT         1003
109 #define DISPID_GLOBAL_ISENGLANG     1004
110 #define DISPID_GLOBAL_VBVAR         1005
111 #define DISPID_GLOBAL_TESTOBJ       1006
112 #define DISPID_GLOBAL_ISNULLDISP    1007
113 #define DISPID_GLOBAL_TESTDISP      1008
114 #define DISPID_GLOBAL_REFOBJ        1009
115 #define DISPID_GLOBAL_COUNTER       1010
116 #define DISPID_GLOBAL_PROPARGPUT    1011
117 #define DISPID_GLOBAL_PROPARGPUT1   1012
118 #define DISPID_GLOBAL_COLLOBJ       1013
119 #define DISPID_GLOBAL_DOUBLEASSTRING 1014
120 #define DISPID_GLOBAL_TESTARRAY     1015
121 #define DISPID_GLOBAL_THROWINT      1016
122 #define DISPID_GLOBAL_TESTOPTIONALARG 1017
123 #define DISPID_GLOBAL_LETOBJ        1018
124 #define DISPID_GLOBAL_SETOBJ        1019
125 #define DISPID_GLOBAL_TODO_WINE_OK  1020
126 #define DISPID_GLOBAL_WEEKSTARTDAY  1021
127 
128 #define DISPID_TESTOBJ_PROPGET      2000
129 #define DISPID_TESTOBJ_PROPPUT      2001
130 
131 #define DISPID_COLLOBJ_RESET        3000
132 
133 #define FACILITY_VBS 0xa
134 #define MAKE_VBSERROR(code) MAKE_HRESULT(SEVERITY_ERROR, FACILITY_VBS, code)
135 
136 static const WCHAR testW[] = {'t','e','s','t',0};
137 static const WCHAR emptyW[] = {0};
138 
139 static BOOL strict_dispid_check, is_english, allow_ui;
140 static int first_day_of_week;
141 static const char *test_name = "(null)";
142 static int test_counter;
143 static SCRIPTUICHANDLING uic_handling = SCRIPTUICHANDLING_NOUIERROR;
144 static IDispatchEx testObj;
145 static HRESULT onerror_hres = E_NOTIMPL;
146 
147 static BSTR a2bstr(const char *str)
148 {
149     BSTR ret;
150     int len;
151 
152     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
153     ret = SysAllocStringLen(NULL, len-1);
154     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
155 
156     return ret;
157 }
158 
159 static int strcmp_wa(LPCWSTR strw, const char *stra)
160 {
161     CHAR buf[512];
162     WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), 0, 0);
163     return lstrcmpA(buf, stra);
164 }
165 
166 static const char *vt2a(VARIANT *v)
167 {
168     if(V_VT(v) == (VT_BYREF|VT_VARIANT)) {
169         static char buf[64];
170         sprintf(buf, "%s*", vt2a(V_BYREF(v)));
171         return buf;
172     }
173 
174     switch(V_VT(v)) {
175     case VT_EMPTY:
176         return "VT_EMPTY";
177     case VT_NULL:
178         return "VT_NULL";
179     case VT_I2:
180         return "VT_I2";
181     case VT_I4:
182         return "VT_I4";
183     case VT_R4:
184         return "VT_R4";
185     case VT_R8:
186         return "VT_R8";
187     case VT_CY:
188         return "VT_CY";
189     case VT_DATE:
190         return "VT_DATE";
191     case VT_BSTR:
192         return "VT_BSTR";
193     case VT_DISPATCH:
194         return "VT_DISPATCH";
195     case VT_BOOL:
196         return "VT_BOOL";
197     case VT_ARRAY|VT_VARIANT:
198         return "VT_ARRAY|VT_VARIANT";
199     case VT_ARRAY|VT_BYREF|VT_VARIANT:
200         return "VT_ARRAY|VT_BYREF|VT_VARIANT";
201     case VT_UI1:
202         return "VT_UI1";
203     default:
204         ok(0, "unknown vt %d\n", V_VT(v));
205         return NULL;
206     }
207 }
208 
209 /* Sets is_english to true if the user interface is in English. Note that this
210  * does not presume the formatting of dates, numbers, etc.
211  * Sets first_day_of_week to 1 if Sunday, 2 if Monday, and so on.
212  */
213 static void detect_locale(void)
214 {
215     HMODULE kernel32 = GetModuleHandleA("kernel32.dll");
216     LANGID (WINAPI *pGetThreadUILanguage)(void) = (void*)GetProcAddress(kernel32, "GetThreadUILanguage");
217 
218     is_english = ((!pGetThreadUILanguage || PRIMARYLANGID(pGetThreadUILanguage()) == LANG_ENGLISH) &&
219                   PRIMARYLANGID(GetUserDefaultUILanguage()) == LANG_ENGLISH &&
220                   PRIMARYLANGID(GetUserDefaultLangID()) == LANG_ENGLISH);
221 
222     GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IFIRSTDAYOFWEEK | LOCALE_RETURN_NUMBER,
223                    (void*)&first_day_of_week, sizeof(first_day_of_week));
224     first_day_of_week = 1 + (first_day_of_week + 1) % 7;
225 }
226 
227 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
228 {
229     ok(0, "unexpected call\n");
230     return E_NOINTERFACE;
231 }
232 
233 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
234 {
235     return 2;
236 }
237 
238 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
239 {
240     return 1;
241 }
242 
243 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService,
244         REFIID riid, void **ppv)
245 {
246     ok(0, "unexpected service %s\n", wine_dbgstr_guid(guidService));
247     return E_NOINTERFACE;
248 }
249 
250 static const IServiceProviderVtbl ServiceProviderVtbl = {
251     ServiceProvider_QueryInterface,
252     ServiceProvider_AddRef,
253     ServiceProvider_Release,
254     ServiceProvider_QueryService
255 };
256 
257 static IServiceProvider caller_sp = { &ServiceProviderVtbl };
258 
259 static void test_disp(IDispatch *disp)
260 {
261     DISPID id, public_prop_id, public_prop2_id, public_func_id, public_sub_id, defvalget_id, gs_getter_id;
262     DISPID named_args[5] = {DISPID_PROPERTYPUT};
263     VARIANT v, args[5];
264     DISPPARAMS dp = {args, named_args};
265     IDispatchEx *dispex;
266     EXCEPINFO ei = {0};
267     BSTR str;
268     HRESULT hres;
269 
270     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
271     ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
272 
273     str = a2bstr("publicProp");
274     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_prop_id);
275     SysFreeString(str);
276     ok(hres == S_OK, "GetDispID(publicProp) failed: %08x\n", hres);
277 
278     str = a2bstr("PUBLICPROP");
279     hres = IDispatchEx_GetDispID(dispex, str, 0, &id);
280     SysFreeString(str);
281     ok(hres == S_OK, "GetDispID(PUBLICPROP) failed: %08x\n", hres);
282     ok(public_prop_id == id, "id = %d\n", public_prop_id);
283 
284     str = a2bstr("publicPROP2");
285     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_prop2_id);
286     SysFreeString(str);
287     ok(hres == S_OK, "GetDispID(publicProp2) failed: %08x\n", hres);
288 
289     str = a2bstr("defValGet");
290     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &defvalget_id);
291     SysFreeString(str);
292     ok(hres == S_OK, "GetDispID(defValGet) failed: %08x\n", hres);
293     ok(defvalget_id == DISPID_VALUE, "id = %d\n", defvalget_id);
294 
295     str = a2bstr("privateProp");
296     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id);
297     SysFreeString(str);
298     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateProp) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
299     ok(id == -1, "id = %d\n", id);
300 
301     str = a2bstr("class_initialize");
302     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id);
303     SysFreeString(str);
304     ok(hres == S_OK, "GetDispID(publicProp2) failed: %08x\n", hres);
305 
306     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|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     V_VT(&v) = VT_BOOL;
314     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUT, &dp, &v, &ei, NULL);
315     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
316     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
317 
318     dp.cArgs = dp.cNamedArgs = 0;
319     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
320     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
321     ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
322     ok(V_BOOL(&v), "V_BOOL(v) = %x\n", V_BOOL(&v));
323 
324     dp.cArgs = dp.cNamedArgs = 0;
325     hres = IDispatchEx_Invoke(dispex, public_prop_id, &IID_NULL, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
326     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
327     ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
328     ok(V_BOOL(&v), "V_BOOL(v) = %x\n", V_BOOL(&v));
329 
330     dp.cArgs = dp.cNamedArgs = 0;
331     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
332     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
333     ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
334     ok(V_BOOL(&v), "V_BOOL(v) = %x\n", V_BOOL(&v));
335 
336     dp.cArgs = 1;
337     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
338     ok(hres == DISP_E_MEMBERNOTFOUND, "InvokeEx failed: %08x, expected DISP_E_MEMBERNOTFOUND\n", hres);
339     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
340 
341     SET_EXPECT(testobj_value_i);
342     V_VT(args) = VT_DISPATCH;
343     V_DISPATCH(args) = (IDispatch*)&testObj;
344     dp.cArgs = dp.cNamedArgs = 1;
345     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL);
346     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
347     CHECK_CALLED(testobj_value_i);
348 
349     dp.cArgs = dp.cNamedArgs = 0;
350     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
351     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
352     ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
353     ok(V_I2(&v) == 0, "V_I2(v) = %d\n", V_I2(&v));
354 
355     V_VT(args) = VT_DISPATCH;
356     V_DISPATCH(args) = (IDispatch*)&testObj;
357     dp.cArgs = dp.cNamedArgs = 1;
358     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF, &dp, NULL, &ei, NULL);
359     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
360 
361     V_VT(args) = VT_DISPATCH;
362     V_DISPATCH(args) = (IDispatch*)&testObj;
363     dp.cArgs = dp.cNamedArgs = 1;
364     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUTREF, &dp, NULL, &ei, NULL);
365     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
366 
367     dp.cArgs = dp.cNamedArgs = 0;
368     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
369     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
370     ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v));
371     ok(V_DISPATCH(&v) == (IDispatch*)&testObj, "V_DISPATCH(v) != testObj\n");
372 
373     V_VT(args) = VT_BOOL;
374     V_BOOL(args) = VARIANT_TRUE;
375     dp.cArgs = dp.cNamedArgs = 1;
376     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF, &dp, NULL, &ei, NULL);
377     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
378 
379     dp.cArgs = dp.cNamedArgs = 0;
380     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
381     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
382     ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
383     ok(V_BOOL(&v) == VARIANT_TRUE, "V_BOOL(v) = %x\n", V_BOOL(&v));
384 
385     V_VT(args) = VT_BOOL;
386     V_BOOL(args) = VARIANT_FALSE;
387     dp.cArgs = dp.cNamedArgs = 1;
388     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUTREF, &dp, NULL, &ei, NULL);
389     ok(hres == DISP_E_EXCEPTION, "InvokeEx failed: %08x, expected DISP_E_EXCEPTION\n", hres);
390 
391     V_VT(args) = VT_BOOL;
392     V_BOOL(args) = VARIANT_FALSE;
393     dp.cArgs = 1;
394     dp.cNamedArgs = 0;
395     V_VT(&v) = VT_BOOL;
396     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL);
397     ok(hres == DISP_E_PARAMNOTOPTIONAL, "InvokeEx failed: %08x, expected DISP_E_PARAMNOTOPTIONAL\n", hres);
398 
399     str = a2bstr("publicFunction");
400     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_func_id);
401     SysFreeString(str);
402     ok(hres == S_OK, "GetDispID(publicFunction) failed: %08x\n", hres);
403     ok(public_func_id != -1, "public_func_id = -1\n");
404 
405     str = a2bstr("publicSub");
406     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_sub_id);
407     SysFreeString(str);
408     ok(hres == S_OK, "GetDispID(publicSub) failed: %08x\n", hres);
409     ok(public_sub_id != -1, "public_func_id = -1\n");
410 
411     dp.cArgs = dp.cNamedArgs = 0;
412     hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
413     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
414     ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
415     ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
416 
417     dp.cArgs = dp.cNamedArgs = 0;
418     hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
419     ok(hres == DISP_E_MEMBERNOTFOUND, "InvokeEx failed: %08x, expected DISP_E_MEMBERNOTFOUND\n", hres);
420     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
421 
422     dp.cArgs = dp.cNamedArgs = 0;
423     hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
424     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
425     ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
426     ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
427 
428     dp.cArgs = dp.cNamedArgs = 0;
429     hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
430     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
431     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
432 
433     dp.cArgs = dp.cNamedArgs = 0;
434     hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
435     ok(hres == DISP_E_MEMBERNOTFOUND, "InvokeEx failed: %08x, expected DISP_E_MEMBERNOTFOUND\n", hres);
436     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
437 
438     dp.cArgs = dp.cNamedArgs = 0;
439     hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
440     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
441     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
442 
443     V_VT(args) = VT_BOOL;
444     V_BOOL(args) = VARIANT_TRUE;
445     dp.cArgs = dp.cNamedArgs = 1;
446     hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL);
447     ok(FAILED(hres), "InvokeEx succeeded: %08x\n", hres);
448 
449     dp.cArgs = dp.cNamedArgs = 0;
450     hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
451     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
452     ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
453     ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
454 
455     dp.cArgs = dp.cNamedArgs = 0;
456     hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
457     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
458     ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
459     ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
460 
461     dp.cArgs = dp.cNamedArgs = 0;
462     hres = IDispatchEx_Invoke(dispex, public_func_id, &IID_NULL, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
463     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
464     ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
465     ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
466 
467     dp.cArgs = dp.cNamedArgs = 0;
468     hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
469     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
470     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
471 
472     dp.cArgs = dp.cNamedArgs = 0;
473     hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
474     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
475     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
476 
477     str = a2bstr("privateSub");
478     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id);
479     SysFreeString(str);
480     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateSub) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
481     ok(id == -1, "id = %d\n", id);
482 
483     str = a2bstr("dynprop");
484     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive|fdexNameEnsure, &id);
485     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateProp) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
486     ok(id == -1, "id = %d\n", id);
487     hres = IDispatchEx_GetDispID(dispex, str, fdexNameEnsure, &id);
488     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateProp) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
489     ok(id == -1, "id = %d\n", id);
490     SysFreeString(str);
491 
492     str = a2bstr("publicProp");
493     hres = IDispatchEx_GetDispID(dispex, str, 0x80000000|fdexNameCaseInsensitive, &public_prop_id);
494     SysFreeString(str);
495     ok(hres == S_OK, "GetDispID(publicProp) failed: %08x\n", hres);
496 
497     id = 0xdeadbeef;
498     str = a2bstr("publicProp");
499     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseSensitive, &id);
500     SysFreeString(str);
501     ok(hres == S_OK, "GetDispID(publicProp) failed: %08x\n", hres);
502     ok(id == public_prop_id, "id = %d, expected %d\n", id, public_prop_id);
503 
504     id = 0xdeadbeef;
505     str = a2bstr("publicprop");
506     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseSensitive, &id);
507     SysFreeString(str);
508     ok(hres == S_OK, "GetDispID(publicProp) failed: %08x\n", hres);
509     ok(id == public_prop_id, "id = %d, expected %d\n", id, public_prop_id);
510 
511     str = a2bstr("gsGetProp");
512     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &gs_getter_id);
513     SysFreeString(str);
514     ok(hres == S_OK, "GetDispID(publicFunction) failed: %08x\n", hres);
515     ok(gs_getter_id != -1, "gs_getter_id = -1\n");
516 
517     V_VT(args) = VT_BOOL;
518     V_BOOL(args) = VARIANT_TRUE;
519     dp.cNamedArgs = 0;
520     dp.cArgs = 1;
521     V_VT(&v) = VT_I8;
522     hres = IDispatchEx_InvokeEx(dispex, gs_getter_id, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
523     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
524     ok(V_VT(&v) == VT_BOOL && V_BOOL(&v), "V_VT(v) = %d\n", V_VT(&v));
525 
526     hres = IDispatchEx_InvokeEx(dispex, gs_getter_id, 0, DISPATCH_PROPERTYGET, &dp, NULL, &ei, NULL);
527     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
528 
529     V_VT(args) = VT_BOOL;
530     V_BOOL(args) = VARIANT_FALSE;
531     dp.cArgs = 1;
532     V_VT(&v) = VT_I8;
533     hres = IDispatchEx_InvokeEx(dispex, gs_getter_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
534     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
535     ok(V_VT(&v) == VT_BOOL && !V_BOOL(&v), "V_VT(v) = %d\n", V_VT(&v));
536 
537     V_VT(args) = VT_BOOL;
538     V_BOOL(args) = VARIANT_TRUE;
539     V_VT(&v) = VT_I8;
540     dp.cArgs = 1;
541     hres = IDispatchEx_InvokeEx(dispex, gs_getter_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
542     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
543     ok(V_VT(&v) == VT_BOOL && V_BOOL(&v), "V_VT(v) = %d\n", V_VT(&v));
544 
545     IDispatchEx_Release(dispex);
546 }
547 
548 static void test_safearray(SAFEARRAY *safearray, unsigned indims)
549 {
550     int i, exdims = indims;
551 
552     if(!exdims)
553         exdims = 1;
554     ok(safearray->cDims == exdims, "safearray->cDims = %d, expected %d\n", safearray->cDims, exdims);
555     todo_wine
556     ok(safearray->fFeatures == (FADF_VARIANT|FADF_HAVEVARTYPE|FADF_FIXEDSIZE|FADF_STATIC),
557        "safearray->fFeatures = %x\n", safearray->fFeatures);
558     ok(safearray->cbElements == sizeof(VARIANT), "safearray->cbElements = %x\n", safearray->cbElements);
559     ok(!safearray->cLocks, "safearray->cLocks = %x\n", safearray->cLocks);
560 
561     for(i=0; i < safearray->cDims; i++) {
562         ok(safearray->rgsabound[i].cElements == (indims ? i+4 : 1), "safearray->rgsabound[%d].cElements = %d\n", i,
563            safearray->rgsabound[i].cElements);
564         ok(!safearray->rgsabound[i].lLbound, "safearray->rgsabound[%d].lLbound = %d\n", i, safearray->rgsabound[i].lLbound);
565     }
566 }
567 
568 #define test_grfdex(a,b) _test_grfdex(__LINE__,a,b)
569 static void _test_grfdex(unsigned line, DWORD grfdex, DWORD expect)
570 {
571     ok_(__FILE__,line)(grfdex == expect, "grfdex = %x, expected %x\n", grfdex, expect);
572 }
573 
574 static IDispatchEx enumDisp;
575 
576 static HRESULT WINAPI EnumVARIANT_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv)
577 {
578     if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IEnumVARIANT)) {
579         *ppv = iface;
580         return S_OK;
581     }
582 
583     if(IsEqualGUID(riid, &IID_IDispatch)) {
584         *ppv = &enumDisp;
585         return S_OK;
586     }
587 
588     ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
589     return E_NOINTERFACE;
590 }
591 
592 static ULONG WINAPI EnumVARIANT_AddRef(IEnumVARIANT *iface)
593 {
594     return 2;
595 }
596 
597 static ULONG WINAPI EnumVARIANT_Release(IEnumVARIANT *iface)
598 {
599     return 1;
600 }
601 
602 static unsigned next_cnt;
603 
604 static HRESULT WINAPI EnumVARIANT_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
605 {
606     if(strict_dispid_check)
607         CHECK_EXPECT2(Next);
608 
609     ok(celt == 1, "celt = %d\n", celt);
610     ok(V_VT(rgVar) == VT_EMPTY, "V_VT(rgVar) = %d\n", V_VT(rgVar));
611     ok(!pCeltFetched, "pCeltFetched = %p\n", pCeltFetched);
612 
613     if(next_cnt++ < 3) {
614         V_VT(rgVar) = VT_I2;
615         V_I2(rgVar) = next_cnt;
616         return S_OK;
617     }
618 
619     return S_FALSE;
620 }
621 
622 static HRESULT WINAPI EnumVARIANT_Skip(IEnumVARIANT *iface, ULONG celt)
623 {
624     ok(0, "unexpected call\n");
625     return E_NOTIMPL;
626 }
627 
628 static HRESULT WINAPI EnumVARIANT_Reset(IEnumVARIANT *iface)
629 {
630     ok(0, "unexpected call\n");
631     return E_NOTIMPL;
632 }
633 
634 static HRESULT WINAPI EnumVARIANT_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum)
635 {
636     ok(0, "unexpected call\n");
637     return E_NOTIMPL;
638 }
639 
640 static const IEnumVARIANTVtbl EnumVARIANTVtbl = {
641     EnumVARIANT_QueryInterface,
642     EnumVARIANT_AddRef,
643     EnumVARIANT_Release,
644     EnumVARIANT_Next,
645     EnumVARIANT_Skip,
646     EnumVARIANT_Reset,
647     EnumVARIANT_Clone
648 };
649 
650 static IEnumVARIANT enumObj = { &EnumVARIANTVtbl };
651 
652 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
653 {
654     *ppv = NULL;
655 
656     if(IsEqualGUID(riid, &IID_IUnknown)
657        || IsEqualGUID(riid, &IID_IDispatch)
658        || IsEqualGUID(riid, &IID_IDispatchEx))
659         *ppv = iface;
660     else {
661         trace("QI %s\n", wine_dbgstr_guid(riid));
662         return E_NOINTERFACE;
663     }
664 
665     IUnknown_AddRef((IUnknown*)*ppv);
666     return S_OK;
667 }
668 
669 static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
670 {
671     return 2;
672 }
673 
674 static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
675 {
676     return 1;
677 }
678 
679 static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
680 {
681     ok(0, "unexpected call\n");
682     return E_NOTIMPL;
683 }
684 
685 static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
686                                               LCID lcid, ITypeInfo **ppTInfo)
687 {
688     ok(0, "unexpected call\n");
689     return E_NOTIMPL;
690 }
691 
692 static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
693                                                 LPOLESTR *rgszNames, UINT cNames,
694                                                 LCID lcid, DISPID *rgDispId)
695 {
696     ok(0, "unexpected call\n");
697     return E_NOTIMPL;
698 }
699 
700 static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
701                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
702                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
703 {
704     ok(0, "unexpected call\n");
705     return E_NOTIMPL;
706 }
707 
708 static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
709 {
710     ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
711     return E_NOTIMPL;
712 }
713 
714 static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
715 {
716     ok(0, "unexpected call\n");
717     return E_NOTIMPL;
718 }
719 
720 static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
721 {
722     ok(0, "unexpected call\n");
723     return E_NOTIMPL;
724 }
725 
726 static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
727 {
728     ok(0, "unexpected call\n");
729     return E_NOTIMPL;
730 }
731 
732 static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
733 {
734     ok(0, "unexpected call\n");
735     return E_NOTIMPL;
736 }
737 
738 static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
739 {
740     ok(0, "unexpected call\n");
741     return E_NOTIMPL;
742 }
743 
744 static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
745 {
746     ok(0, "unexpected call\n");
747     return E_NOTIMPL;
748 }
749 
750 static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
751         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
752 {
753     ok(0, "unexpected call %d\n", id);
754     return E_NOTIMPL;
755 }
756 
757 static HRESULT WINAPI testObj_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
758 {
759     if(!strcmp_wa(bstrName, "propget")) {
760         CHECK_EXPECT(testobj_propget_d);
761         test_grfdex(grfdex, fdexNameCaseInsensitive);
762         *pid = DISPID_TESTOBJ_PROPGET;
763         return S_OK;
764     }
765     if(!strcmp_wa(bstrName, "propput")) {
766         CHECK_EXPECT(testobj_propput_d);
767         test_grfdex(grfdex, fdexNameCaseInsensitive);
768         *pid = DISPID_TESTOBJ_PROPPUT;
769         return S_OK;
770     }
771 
772     ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName));
773     return DISP_E_UNKNOWNNAME;
774 }
775 
776 static HRESULT WINAPI testObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
777         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
778 {
779     switch(id) {
780     case DISPID_VALUE: {
781         VARIANT *arg;
782         int i;
783 
784         CHECK_EXPECT(testobj_value_i);
785 
786         ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
787         ok(pdp != NULL, "pdp == NULL\n");
788         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
789         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
790         ok(pvarRes != NULL, "pvarRes == NULL\n");
791         ok(pei != NULL, "pei == NULL\n");
792 
793         for(i=0; i<pdp->cArgs; i++) {
794             arg = pdp->rgvarg+pdp->cArgs-i-1;
795             ok(V_VT(arg) == VT_I2, "V_VT(arg) = %d\n", V_VT(arg));
796             ok(V_I2(arg) == i+1, "V_I2(arg) = %d\n", V_I2(arg));
797         }
798 
799         V_VT(pvarRes) = VT_I2;
800         V_I2(pvarRes) = pdp->cArgs;
801         return S_OK;
802     }
803     case DISPID_TESTOBJ_PROPGET:
804         CHECK_EXPECT(testobj_propget_i);
805 
806         ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
807         ok(pdp != NULL, "pdp == NULL\n");
808         ok(!pdp->rgvarg, "rgvarg == NULL\n");
809         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
810         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
811         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
812         ok(pvarRes != NULL, "pvarRes == NULL\n");
813         ok(pei != NULL, "pei == NULL\n");
814 
815         V_VT(pvarRes) = VT_I2;
816         V_I2(pvarRes) = 10;
817         return S_OK;
818     case DISPID_TESTOBJ_PROPPUT:
819         CHECK_EXPECT(testobj_propput_i);
820 
821         ok(wFlags == DISPATCH_PROPERTYPUT, "wFlags = %x\n", wFlags);
822         ok(pdp != NULL, "pdp == NULL\n");
823         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
824         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
825         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
826         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
827         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
828         ok(!pvarRes, "pvarRes != NULL\n");
829         ok(pei != NULL, "pei == NULL\n");
830 
831         ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
832         ok(V_I2(pdp->rgvarg) == 1, "V_I2(psp->rgvargs) = %d\n", V_I2(pdp->rgvarg));
833         return S_OK;
834     }
835 
836     ok(0, "unexpected call %d\n", id);
837     return E_FAIL;
838 }
839 
840 static IDispatchExVtbl testObjVtbl = {
841     DispatchEx_QueryInterface,
842     DispatchEx_AddRef,
843     DispatchEx_Release,
844     DispatchEx_GetTypeInfoCount,
845     DispatchEx_GetTypeInfo,
846     DispatchEx_GetIDsOfNames,
847     DispatchEx_Invoke,
848     testObj_GetDispID,
849     testObj_InvokeEx,
850     DispatchEx_DeleteMemberByName,
851     DispatchEx_DeleteMemberByDispID,
852     DispatchEx_GetMemberProperties,
853     DispatchEx_GetMemberName,
854     DispatchEx_GetNextDispID,
855     DispatchEx_GetNameSpaceParent
856 };
857 
858 static IDispatchEx testObj = { &testObjVtbl };
859 
860 static HRESULT WINAPI enumDisp_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
861 {
862     return IEnumVARIANT_QueryInterface(&enumObj, riid, ppv);
863 }
864 
865 static IDispatchExVtbl enumDispVtbl = {
866     enumDisp_QueryInterface,
867     DispatchEx_AddRef,
868     DispatchEx_Release,
869     DispatchEx_GetTypeInfoCount,
870     DispatchEx_GetTypeInfo,
871     DispatchEx_GetIDsOfNames,
872     DispatchEx_Invoke,
873     DispatchEx_GetDispID,
874     DispatchEx_InvokeEx,
875     DispatchEx_DeleteMemberByName,
876     DispatchEx_DeleteMemberByDispID,
877     DispatchEx_GetMemberProperties,
878     DispatchEx_GetMemberName,
879     DispatchEx_GetNextDispID,
880     DispatchEx_GetNameSpaceParent
881 };
882 
883 static IDispatchEx enumDisp = { &enumDispVtbl };
884 
885 static HRESULT WINAPI collectionObj_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
886 {
887     if(!strcmp_wa(bstrName, "reset")) {
888         *pid = DISPID_COLLOBJ_RESET;
889         return S_OK;
890     }
891 
892     ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName));
893     return DISP_E_UNKNOWNNAME;
894 }
895 
896 static HRESULT WINAPI collectionObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
897         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
898 {
899     switch(id) {
900     case DISPID_NEWENUM:
901         if(strict_dispid_check)
902             CHECK_EXPECT(collectionobj_newenum_i);
903 
904         ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
905         ok(pdp != NULL, "pdp == NULL\n");
906         ok(!pdp->rgvarg, "rgvarg == NULL\n");
907         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
908         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
909         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
910         ok(pvarRes != NULL, "pvarRes == NULL\n");
911         ok(pei != NULL, "pei == NULL\n");
912 
913         V_VT(pvarRes) = VT_UNKNOWN;
914         V_UNKNOWN(pvarRes) = (IUnknown*)&enumObj;
915         return S_OK;
916     case DISPID_COLLOBJ_RESET:
917         next_cnt = 0;
918         return S_OK;
919     }
920 
921     ok(0, "unexpected call %d\n", id);
922     return E_NOTIMPL;
923 }
924 
925 static IDispatchExVtbl collectionObjVtbl = {
926     DispatchEx_QueryInterface,
927     DispatchEx_AddRef,
928     DispatchEx_Release,
929     DispatchEx_GetTypeInfoCount,
930     DispatchEx_GetTypeInfo,
931     DispatchEx_GetIDsOfNames,
932     DispatchEx_Invoke,
933     collectionObj_GetDispID,
934     collectionObj_InvokeEx,
935     DispatchEx_DeleteMemberByName,
936     DispatchEx_DeleteMemberByDispID,
937     DispatchEx_GetMemberProperties,
938     DispatchEx_GetMemberName,
939     DispatchEx_GetNextDispID,
940     DispatchEx_GetNameSpaceParent
941 };
942 
943 static IDispatchEx collectionObj = { &collectionObjVtbl };
944 
945 static ULONG refobj_ref;
946 
947 static ULONG WINAPI RefObj_AddRef(IDispatchEx *iface)
948 {
949     return ++refobj_ref;
950 }
951 
952 static ULONG WINAPI RefObj_Release(IDispatchEx *iface)
953 {
954     return --refobj_ref;
955 }
956 
957 static IDispatchExVtbl RefObjVtbl = {
958     DispatchEx_QueryInterface,
959     RefObj_AddRef,
960     RefObj_Release,
961     DispatchEx_GetTypeInfoCount,
962     DispatchEx_GetTypeInfo,
963     DispatchEx_GetIDsOfNames,
964     DispatchEx_Invoke,
965     DispatchEx_GetDispID,
966     DispatchEx_InvokeEx,
967     DispatchEx_DeleteMemberByName,
968     DispatchEx_DeleteMemberByDispID,
969     DispatchEx_GetMemberProperties,
970     DispatchEx_GetMemberName,
971     DispatchEx_GetNextDispID,
972     DispatchEx_GetNameSpaceParent
973 };
974 
975 static IDispatchEx RefObj = { &RefObjVtbl };
976 
977 static ULONG global_ref;
978 
979 static ULONG WINAPI Global_AddRef(IDispatchEx *iface)
980 {
981     return ++global_ref;
982 }
983 
984 static ULONG WINAPI Global_Release(IDispatchEx *iface)
985 {
986     return --global_ref;
987 }
988 
989 static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
990 {
991     if(!strcmp_wa(bstrName, "ok")) {
992         test_grfdex(grfdex, fdexNameCaseInsensitive);
993         *pid = DISPID_GLOBAL_OK;
994         return S_OK;
995     }
996     if(!strcmp_wa(bstrName, "todo_wine_ok")) {
997         test_grfdex(grfdex, fdexNameCaseInsensitive);
998         *pid = DISPID_GLOBAL_TODO_WINE_OK;
999         return S_OK;
1000     }
1001     if(!strcmp_wa(bstrName, "trace")) {
1002         test_grfdex(grfdex, fdexNameCaseInsensitive);
1003         *pid = DISPID_GLOBAL_TRACE;
1004         return S_OK;
1005     }
1006     if(!strcmp_wa(bstrName, "reportSuccess")) {
1007         CHECK_EXPECT(global_success_d);
1008         test_grfdex(grfdex, fdexNameCaseInsensitive);
1009         *pid = DISPID_GLOBAL_REPORTSUCCESS;
1010         return S_OK;
1011     }
1012     if(!strcmp_wa(bstrName, "getVT")) {
1013         test_grfdex(grfdex, fdexNameCaseInsensitive);
1014         *pid = DISPID_GLOBAL_GETVT;
1015         return S_OK;
1016     }
1017     if(!strcmp_wa(bstrName, "isEnglishLang")) {
1018         test_grfdex(grfdex, fdexNameCaseInsensitive);
1019         *pid = DISPID_GLOBAL_ISENGLANG;
1020         return S_OK;
1021     }
1022     if(!strcmp_wa(bstrName, "firstDayOfWeek")) {
1023         test_grfdex(grfdex, fdexNameCaseInsensitive);
1024         *pid = DISPID_GLOBAL_WEEKSTARTDAY;
1025         return S_OK;
1026     }
1027     if(!strcmp_wa(bstrName, "testObj")) {
1028         test_grfdex(grfdex, fdexNameCaseInsensitive);
1029         *pid = DISPID_GLOBAL_TESTOBJ;
1030         return S_OK;
1031     }
1032     if(!strcmp_wa(bstrName, "collectionObj")) {
1033         test_grfdex(grfdex, fdexNameCaseInsensitive);
1034         *pid = DISPID_GLOBAL_COLLOBJ;
1035         return S_OK;
1036     }
1037     if(!strcmp_wa(bstrName, "vbvar")) {
1038         CHECK_EXPECT(global_vbvar_d);
1039         test_grfdex(grfdex, fdexNameCaseInsensitive);
1040         *pid = DISPID_GLOBAL_VBVAR;
1041         return S_OK;
1042     }
1043     if(!strcmp_wa(bstrName, "letobj")) {
1044         test_grfdex(grfdex, fdexNameCaseInsensitive);
1045         *pid = DISPID_GLOBAL_LETOBJ;
1046         return S_OK;
1047     }
1048     if(!strcmp_wa(bstrName, "setobj")) {
1049         test_grfdex(grfdex, fdexNameCaseInsensitive);
1050         *pid = DISPID_GLOBAL_SETOBJ;
1051         return S_OK;
1052     }
1053     if(!strcmp_wa(bstrName, "isNullDisp")) {
1054         test_grfdex(grfdex, fdexNameCaseInsensitive);
1055         *pid = DISPID_GLOBAL_ISNULLDISP;
1056         return S_OK;
1057     }
1058     if(!strcmp_wa(bstrName, "testDisp")) {
1059         test_grfdex(grfdex, fdexNameCaseInsensitive);
1060         *pid = DISPID_GLOBAL_TESTDISP;
1061         return S_OK;
1062     }
1063     if(!strcmp_wa(bstrName, "RefObj")) {
1064         test_grfdex(grfdex, fdexNameCaseInsensitive);
1065         *pid = DISPID_GLOBAL_REFOBJ;
1066         return S_OK;
1067     }
1068     if(!strcmp_wa(bstrName, "propargput")) {
1069         CHECK_EXPECT(global_propargput_d);
1070         test_grfdex(grfdex, fdexNameCaseInsensitive);
1071         *pid = DISPID_GLOBAL_PROPARGPUT;
1072         return S_OK;
1073     }
1074     if(!strcmp_wa(bstrName, "propargput1")) {
1075         CHECK_EXPECT(global_propargput1_d);
1076         test_grfdex(grfdex, fdexNameCaseInsensitive);
1077         *pid = DISPID_GLOBAL_PROPARGPUT1;
1078         return S_OK;
1079     }
1080     if(!strcmp_wa(bstrName, "counter")) {
1081         test_grfdex(grfdex, fdexNameCaseInsensitive);
1082         *pid = DISPID_GLOBAL_COUNTER;
1083         return S_OK;
1084     }
1085     if(!strcmp_wa(bstrName, "doubleAsString")) {
1086         test_grfdex(grfdex, fdexNameCaseInsensitive);
1087         *pid = DISPID_GLOBAL_DOUBLEASSTRING;
1088         return S_OK;
1089     }
1090     if(!strcmp_wa(bstrName, "testArray")) {
1091         test_grfdex(grfdex, fdexNameCaseInsensitive);
1092         *pid = DISPID_GLOBAL_TESTARRAY;
1093         return S_OK;
1094     }
1095     if(!strcmp_wa(bstrName, "throwInt")) {
1096         test_grfdex(grfdex, fdexNameCaseInsensitive);
1097         *pid = DISPID_GLOBAL_THROWINT;
1098         return S_OK;
1099     }
1100     if(!strcmp_wa(bstrName, "testOptionalArg")) {
1101         test_grfdex(grfdex, fdexNameCaseInsensitive);
1102         *pid = DISPID_GLOBAL_TESTOPTIONALARG;
1103         return S_OK;
1104     }
1105 
1106     if(strict_dispid_check && strcmp_wa(bstrName, "x"))
1107         ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
1108     return DISP_E_UNKNOWNNAME;
1109 }
1110 
1111 static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
1112         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
1113 {
1114     switch(id) {
1115     case DISPID_GLOBAL_TODO_WINE_OK:
1116     case DISPID_GLOBAL_OK: {
1117         VARIANT *b;
1118 
1119         ok(wFlags == INVOKE_FUNC || wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
1120         ok(pdp != NULL, "pdp == NULL\n");
1121         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1122         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1123         ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
1124         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1125         if(wFlags & INVOKE_PROPERTYGET)
1126             ok(pvarRes != NULL, "pvarRes == NULL\n");
1127         else
1128             ok(!pvarRes, "pvarRes != NULL\n");
1129         ok(pei != NULL, "pei == NULL\n");
1130 
1131         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
1132 
1133         b = pdp->rgvarg+1;
1134         if(V_VT(b) == (VT_BYREF|VT_VARIANT))
1135             b = V_BYREF(b);
1136 
1137         ok(V_VT(b) == VT_BOOL, "V_VT(b) = %d\n", V_VT(b));
1138 
1139         todo_wine_if(id == DISPID_GLOBAL_TODO_WINE_OK)
1140             ok(V_BOOL(b), "%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
1141         return S_OK;
1142     }
1143 
1144     case DISPID_GLOBAL_TRACE:
1145         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
1146         ok(pdp != NULL, "pdp == NULL\n");
1147         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1148         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1149         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1150         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1151         ok(!pvarRes, "pvarRes != NULL\n");
1152         ok(pei != NULL, "pei == NULL\n");
1153 
1154         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
1155         if(V_VT(pdp->rgvarg) == VT_BSTR)
1156             trace("%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
1157 
1158         return S_OK;
1159 
1160     case DISPID_GLOBAL_REPORTSUCCESS:
1161         CHECK_EXPECT(global_success_i);
1162 
1163         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
1164         ok(pdp != NULL, "pdp == NULL\n");
1165         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1166         ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
1167         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1168         ok(!pvarRes, "pvarRes != NULL\n");
1169         ok(pei != NULL, "pei == NULL\n");
1170 
1171         return S_OK;
1172 
1173     case DISPID_GLOBAL_GETVT:
1174         ok(pdp != NULL, "pdp == NULL\n");
1175         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1176         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1177         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1178         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1179         ok(pvarRes != NULL, "pvarRes == NULL\n");
1180         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1181         ok(pei != NULL, "pei == NULL\n");
1182 
1183         V_VT(pvarRes) = VT_BSTR;
1184         V_BSTR(pvarRes) = a2bstr(vt2a(pdp->rgvarg));
1185         return S_OK;
1186 
1187     case DISPID_GLOBAL_ISENGLANG:
1188         ok(wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
1189         ok(pdp != NULL, "pdp == NULL\n");
1190         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1191         ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
1192         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1193         ok(pvarRes != NULL, "pvarRes == NULL\n");
1194         ok(pei != NULL, "pei == NULL\n");
1195 
1196         V_VT(pvarRes) = VT_BOOL;
1197         V_BOOL(pvarRes) = is_english ? VARIANT_TRUE : VARIANT_FALSE;
1198         return S_OK;
1199 
1200     case DISPID_GLOBAL_WEEKSTARTDAY:
1201         V_VT(pvarRes) = VT_I4;
1202         V_I4(pvarRes) = first_day_of_week;
1203         return S_OK;
1204 
1205     case DISPID_GLOBAL_VBVAR:
1206         CHECK_EXPECT(global_vbvar_i);
1207 
1208         ok(wFlags == DISPATCH_PROPERTYPUT, "wFlags = %x\n", wFlags);
1209         ok(pdp != NULL, "pdp == NULL\n");
1210         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1211         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
1212         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1213         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
1214         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
1215         ok(!pvarRes, "pvarRes != NULL\n");
1216         ok(pei != NULL, "pei == NULL\n");
1217 
1218         ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
1219         ok(V_I2(pdp->rgvarg) == 3, "V_I2(psp->rgvargs) = %d\n", V_I2(pdp->rgvarg));
1220         return S_OK;
1221 
1222     case DISPID_GLOBAL_LETOBJ:
1223         CHECK_EXPECT(global_letobj_i);
1224 
1225         ok(wFlags == DISPATCH_PROPERTYPUT, "wFlags = %x\n", wFlags);
1226         ok(pdp != NULL, "pdp == NULL\n");
1227         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1228         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
1229         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1230         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
1231         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
1232         ok(!pvarRes, "pvarRes != NULL\n");
1233         ok(pei != NULL, "pei == NULL\n");
1234 
1235         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
1236         ok(V_DISPATCH(pdp->rgvarg) == (IDispatch*)&testObj, "V_DISPATCH(psp->rgvargs) != testObj\n");
1237         return S_OK;
1238 
1239     case DISPID_GLOBAL_SETOBJ:
1240         CHECK_EXPECT(global_setobj_i);
1241 
1242         ok(wFlags == DISPATCH_PROPERTYPUTREF, "wFlags = %x\n", wFlags);
1243         ok(pdp != NULL, "pdp == NULL\n");
1244         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1245         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
1246         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1247         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
1248         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
1249         ok(!pvarRes, "pvarRes != NULL\n");
1250         ok(pei != NULL, "pei == NULL\n");
1251 
1252         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
1253         ok(V_DISPATCH(pdp->rgvarg) == (IDispatch*)&testObj, "V_DISPATCH(psp->rgvargs) != testObj\n");
1254         return S_OK;
1255 
1256     case DISPID_GLOBAL_TESTOBJ:
1257         ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
1258 
1259         ok(pdp != NULL, "pdp == NULL\n");
1260         ok(!pdp->rgvarg, "rgvarg != NULL\n");
1261         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1262         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
1263         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1264         ok(pvarRes != NULL, "pvarRes == NULL\n");
1265         ok(pei != NULL, "pei == NULL\n");
1266 
1267         V_VT(pvarRes) = VT_DISPATCH;
1268         V_DISPATCH(pvarRes) = (IDispatch*)&testObj;
1269         return S_OK;
1270 
1271     case DISPID_GLOBAL_COLLOBJ:
1272         ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
1273 
1274         ok(pdp != NULL, "pdp == NULL\n");
1275         ok(!pdp->rgvarg, "rgvarg != NULL\n");
1276         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1277         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
1278         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1279         ok(pvarRes != NULL, "pvarRes == NULL\n");
1280         ok(pei != NULL, "pei == NULL\n");
1281 
1282         V_VT(pvarRes) = VT_DISPATCH;
1283         V_DISPATCH(pvarRes) = (IDispatch*)&collectionObj;
1284         return S_OK;
1285 
1286     case DISPID_GLOBAL_REFOBJ:
1287         ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
1288 
1289         ok(pdp != NULL, "pdp == NULL\n");
1290         ok(!pdp->rgvarg, "rgvarg == NULL\n");
1291         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1292         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
1293         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1294         ok(pvarRes != NULL, "pvarRes == NULL\n");
1295         ok(pei != NULL, "pei == NULL\n");
1296 
1297         IDispatchEx_AddRef(&RefObj);
1298         V_VT(pvarRes) = VT_DISPATCH;
1299         V_DISPATCH(pvarRes) = (IDispatch*)&RefObj;
1300         return S_OK;
1301 
1302     case DISPID_GLOBAL_ISNULLDISP: {
1303         VARIANT *v;
1304 
1305         ok(wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
1306         ok(pdp != NULL, "pdp == NULL\n");
1307         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1308         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1309         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1310         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1311         ok(pvarRes != NULL, "pvarRes == NULL\n");
1312         ok(pei != NULL, "pei == NULL\n");
1313 
1314         v = pdp->rgvarg;
1315         if(V_VT(v) == (VT_VARIANT|VT_BYREF))
1316             v = V_VARIANTREF(v);
1317 
1318         ok(V_VT(v) == VT_DISPATCH, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
1319         V_VT(pvarRes) = VT_BOOL;
1320         V_BOOL(pvarRes) = V_DISPATCH(v) ? VARIANT_FALSE : VARIANT_TRUE;
1321         return S_OK;
1322     }
1323 
1324     case DISPID_GLOBAL_TESTDISP:
1325         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
1326         ok(pdp != NULL, "pdp == NULL\n");
1327         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1328         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1329         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1330         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1331         ok(!pvarRes, "pvarRes != NULL\n");
1332         ok(pei != NULL, "pei == NULL\n");
1333 
1334         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
1335         test_disp(V_DISPATCH(pdp->rgvarg));
1336         return S_OK;
1337 
1338     case DISPID_GLOBAL_PROPARGPUT:
1339         CHECK_EXPECT(global_propargput_i);
1340 
1341         ok(wFlags == DISPATCH_PROPERTYPUT, "wFlags = %x\n", wFlags);
1342         ok(pdp != NULL, "pdp == NULL\n");
1343         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1344         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
1345         ok(pdp->cArgs == 3, "cArgs = %d\n", pdp->cArgs);
1346         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
1347         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
1348         ok(!pvarRes, "pvarRes != NULL\n");
1349         ok(pei != NULL, "pei == NULL\n");
1350 
1351         ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
1352         ok(V_I2(pdp->rgvarg) == 0, "V_I2(psp->rgvargs) = %d\n", V_I2(pdp->rgvarg));
1353 
1354         ok(V_VT(pdp->rgvarg+1) == VT_I2, "V_VT(psp->rgvargs+1) = %d\n", V_VT(pdp->rgvarg+1));
1355         ok(V_I2(pdp->rgvarg+1) == 2, "V_I2(psp->rgvargs+1) = %d\n", V_I2(pdp->rgvarg+1));
1356 
1357         ok(V_VT(pdp->rgvarg+2) == VT_I2, "V_VT(psp->rgvargs+2) = %d\n", V_VT(pdp->rgvarg+2));
1358         ok(V_I2(pdp->rgvarg+2) == 1, "V_I2(psp->rgvargs+2) = %d\n", V_I2(pdp->rgvarg+2));
1359         return S_OK;
1360 
1361     case DISPID_GLOBAL_PROPARGPUT1:
1362         CHECK_EXPECT(global_propargput1_i);
1363 
1364         ok(wFlags == DISPATCH_PROPERTYPUT, "wFlags = %x\n", wFlags);
1365         ok(pdp != NULL, "pdp == NULL\n");
1366         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1367         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
1368         ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
1369         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
1370         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
1371         ok(!pvarRes, "pvarRes != NULL\n");
1372         ok(pei != NULL, "pei == NULL\n");
1373 
1374         ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
1375         ok(V_I2(pdp->rgvarg) == 0, "V_I2(psp->rgvargs) = %d\n", V_I2(pdp->rgvarg));
1376 
1377         ok(V_VT(pdp->rgvarg+1) == VT_I2, "V_VT(psp->rgvargs+1) = %d\n", V_VT(pdp->rgvarg+1));
1378         ok(V_I2(pdp->rgvarg+1) == 1, "V_I2(psp->rgvargs+1) = %d\n", V_I2(pdp->rgvarg+1));
1379 
1380         return S_OK;
1381 
1382     case DISPID_GLOBAL_COUNTER:
1383         ok(pdp != NULL, "pdp == NULL\n");
1384         todo_wine ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1385         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1386         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
1387         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1388         ok(pvarRes != NULL, "pvarRes == NULL\n");
1389         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1390         ok(pei != NULL, "pei == NULL\n");
1391 
1392         V_VT(pvarRes) = VT_I2;
1393         V_I2(pvarRes) = test_counter++;
1394         return S_OK;
1395 
1396     case DISPID_GLOBAL_DOUBLEASSTRING:
1397         ok(wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
1398         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1399         ok(V_VT(pdp->rgvarg) == VT_R8, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
1400         ok(pvarRes != NULL, "pvarRes == NULL\n");
1401 
1402         V_VT(pvarRes) = VT_BSTR;
1403         return VarBstrFromR8(V_R8(pdp->rgvarg), 0, 0, &V_BSTR(pvarRes));
1404 
1405     case DISPID_GLOBAL_TESTARRAY:
1406         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
1407         ok(pdp != NULL, "pdp == NULL\n");
1408         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1409         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1410         ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
1411         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1412         ok(!pvarRes, "pvarRes != NULL\n");
1413         ok(pei != NULL, "pei == NULL\n");
1414 
1415         ok(V_VT(pdp->rgvarg+1) == VT_I2, "V_VT(psp->rgvargs+1) = %d\n", V_VT(pdp->rgvarg+1));
1416         ok(V_VT(pdp->rgvarg) == (VT_BYREF|VT_VARIANT), "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
1417         ok(V_VT(V_VARIANTREF(pdp->rgvarg)) == (VT_ARRAY|VT_BYREF|VT_VARIANT),
1418            "V_VT(V_VARIANTREF(psp->rgvargs)) = %d\n", V_VT(V_VARIANTREF(pdp->rgvarg)));
1419         if(V_I2(pdp->rgvarg+1) == -1)
1420             ok(!*V_ARRAYREF(V_VARIANTREF(pdp->rgvarg)), "*V_ARRAYREF(V_VARIANTREF(pdp->rgvarg)) != NULL\n");
1421         else
1422             test_safearray(*V_ARRAYREF(V_VARIANTREF(pdp->rgvarg)), V_I2(pdp->rgvarg+1));
1423         return S_OK;
1424 
1425     case DISPID_GLOBAL_THROWINT: {
1426         VARIANT *v = pdp->rgvarg;
1427         HRESULT hres;
1428 
1429         ok((wFlags & ~INVOKE_PROPERTYGET) == INVOKE_FUNC, "wFlags = %x\n", wFlags);
1430         ok(pdp != NULL, "pdp == NULL\n");
1431         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1432         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1433         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1434         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1435         ok(pei != NULL, "pei == NULL\n");
1436         if(pvarRes) {
1437             ok(V_VT(pvarRes) == VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1438             V_VT(pvarRes) = VT_BOOL;
1439             V_BOOL(pvarRes) = VARIANT_FALSE;
1440         }
1441 
1442         if(V_VT(v) == (VT_VARIANT|VT_BYREF))
1443             v = V_VARIANTREF(v);
1444 
1445         switch(V_VT(v)) {
1446         case VT_I2:
1447             hres = V_I2(v);
1448             break;
1449         case VT_I4:
1450             hres = V_I4(v);
1451             break;
1452         default:
1453             ok(0, "unexpected vt %d\n", V_VT(v));
1454             return E_INVALIDARG;
1455         }
1456 
1457         return hres;
1458     }
1459 
1460     case DISPID_GLOBAL_TESTOPTIONALARG: {
1461         VARIANT *v;
1462         int opt;
1463 
1464         CHECK_EXPECT(global_testoptionalarg_i);
1465 
1466         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
1467         ok(pdp != NULL, "pdp == NULL\n");
1468         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1469         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1470         ok(pdp->cArgs == 3, "cArgs = %d\n", pdp->cArgs);
1471         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1472         ok(!pvarRes, "pvarRes != NULL\n");
1473         ok(pei != NULL, "pei == NULL\n");
1474 
1475         ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
1476         opt = V_I2(pdp->rgvarg);
1477         ok(opt == 1 || opt == 2, "opt = %d\n", opt);
1478         v = pdp->rgvarg+pdp->cArgs-opt;
1479         ok(V_VT(v) == VT_ERROR, "V_VT(v) = %d\n", V_VT(v));
1480         ok(V_ERROR(v) == DISP_E_PARAMNOTFOUND, "V_ERROR(v) = %08x\n", V_ERROR(v));
1481         return S_OK;
1482     }
1483     }
1484 
1485     ok(0, "unexpected call %d\n", id);
1486     return DISP_E_MEMBERNOTFOUND;
1487 }
1488 
1489 static IDispatchExVtbl GlobalVtbl = {
1490     DispatchEx_QueryInterface,
1491     Global_AddRef,
1492     Global_Release,
1493     DispatchEx_GetTypeInfoCount,
1494     DispatchEx_GetTypeInfo,
1495     DispatchEx_GetIDsOfNames,
1496     DispatchEx_Invoke,
1497     Global_GetDispID,
1498     Global_InvokeEx,
1499     DispatchEx_DeleteMemberByName,
1500     DispatchEx_DeleteMemberByDispID,
1501     DispatchEx_GetMemberProperties,
1502     DispatchEx_GetMemberName,
1503     DispatchEx_GetNextDispID,
1504     DispatchEx_GetNameSpaceParent
1505 };
1506 
1507 static IDispatchEx Global = { &GlobalVtbl };
1508 
1509 static HRESULT WINAPI ActiveScriptSiteWindow_QueryInterface(IActiveScriptSiteWindow *iface, REFIID riid, void **ppv)
1510 {
1511     ok(0, "unexpected call\n");
1512     return E_NOINTERFACE;
1513 }
1514 
1515 static ULONG WINAPI ActiveScriptSiteWindow_AddRef(IActiveScriptSiteWindow *iface)
1516 {
1517     return 2;
1518 }
1519 
1520 static ULONG WINAPI ActiveScriptSiteWindow_Release(IActiveScriptSiteWindow *iface)
1521 {
1522     return 1;
1523 }
1524 
1525 static HRESULT WINAPI ActiveScriptSiteWindow_GetWindow(IActiveScriptSiteWindow *iface, HWND *phwnd)
1526 {
1527     if(!allow_ui)
1528         CHECK_EXPECT(GetWindow);
1529     *phwnd = NULL;
1530     return S_OK;
1531 }
1532 
1533 static HRESULT WINAPI ActiveScriptSiteWindow_EnableModeless(IActiveScriptSiteWindow *iface, BOOL fEnable)
1534 {
1535     if(allow_ui)
1536         return S_OK;
1537 
1538     CHECK_EXPECT(EnableModeless);
1539     ok(!fEnable, "fEnable = %x\n", fEnable);
1540     return E_FAIL;
1541 }
1542 
1543 static const IActiveScriptSiteWindowVtbl ActiveScriptSiteWindowVtbl = {
1544     ActiveScriptSiteWindow_QueryInterface,
1545     ActiveScriptSiteWindow_AddRef,
1546     ActiveScriptSiteWindow_Release,
1547     ActiveScriptSiteWindow_GetWindow,
1548     ActiveScriptSiteWindow_EnableModeless
1549 };
1550 
1551 static IActiveScriptSiteWindow ActiveScriptSiteWindow = { &ActiveScriptSiteWindowVtbl };
1552 
1553 static HRESULT WINAPI ActiveScriptSiteUIControl_QueryInterface(IActiveScriptSiteUIControl *iface, REFIID riid, void **ppv)
1554 {
1555     ok(0, "unexpected call\n");
1556     return E_NOINTERFACE;
1557 }
1558 
1559 static ULONG WINAPI ActiveScriptSiteUIControl_AddRef(IActiveScriptSiteUIControl *iface)
1560 {
1561     return 2;
1562 }
1563 
1564 static ULONG WINAPI ActiveScriptSiteUIControl_Release(IActiveScriptSiteUIControl *iface)
1565 {
1566     return 1;
1567 }
1568 
1569 static HRESULT WINAPI ActiveScriptSiteUIControl_GetUIBehavior(IActiveScriptSiteUIControl *iface, SCRIPTUICITEM UicItem,
1570         SCRIPTUICHANDLING *pUicHandling)
1571 {
1572     if(!allow_ui) {
1573         CHECK_EXPECT(GetUIBehavior);
1574         ok(UicItem == SCRIPTUICITEM_MSGBOX, "UidItem = %d\n", UicItem);
1575     }
1576     *pUicHandling = uic_handling;
1577     return S_OK;
1578 }
1579 
1580 static const IActiveScriptSiteUIControlVtbl ActiveScriptSiteUIControlVtbl = {
1581     ActiveScriptSiteUIControl_QueryInterface,
1582     ActiveScriptSiteUIControl_AddRef,
1583     ActiveScriptSiteUIControl_Release,
1584     ActiveScriptSiteUIControl_GetUIBehavior
1585 };
1586 
1587 static IActiveScriptSiteUIControl ActiveScriptSiteUIControl = { &ActiveScriptSiteUIControlVtbl };
1588 
1589 static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
1590 {
1591     *ppv = NULL;
1592 
1593     if(IsEqualGUID(&IID_IUnknown, riid))
1594         *ppv = iface;
1595     else if(IsEqualGUID(&IID_IActiveScriptSite, riid))
1596         *ppv = iface;
1597     else if(IsEqualGUID(&IID_IActiveScriptSiteWindow, riid))
1598         *ppv = &ActiveScriptSiteWindow;
1599     else if(IsEqualGUID(&IID_IActiveScriptSiteUIControl, riid))
1600         *ppv = &ActiveScriptSiteUIControl;
1601     else
1602         return E_NOINTERFACE;
1603 
1604     IUnknown_AddRef((IUnknown*)*ppv);
1605     return S_OK;
1606 }
1607 
1608 static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
1609 {
1610     return 2;
1611 }
1612 
1613 static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
1614 {
1615     return 1;
1616 }
1617 
1618 static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *plcid)
1619 {
1620     *plcid = GetUserDefaultLCID();
1621     return S_OK;
1622 }
1623 
1624 static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR pstrName,
1625         DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti)
1626 {
1627     ok(dwReturnMask == SCRIPTINFO_IUNKNOWN, "unexpected dwReturnMask %x\n", dwReturnMask);
1628     ok(!ppti, "ppti != NULL\n");
1629 
1630     if(strcmp_wa(pstrName, "test"))
1631         ok(0, "unexpected pstrName %s\n", wine_dbgstr_w(pstrName));
1632 
1633     *ppiunkItem = (IUnknown*)&Global;
1634     IUnknown_AddRef(*ppiunkItem);
1635     return S_OK;
1636 }
1637 
1638 static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *pbstrVersion)
1639 {
1640     return E_NOTIMPL;
1641 }
1642 
1643 static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface,
1644         const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo)
1645 {
1646     return E_NOTIMPL;
1647 }
1648 
1649 static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE ssScriptState)
1650 {
1651     return E_NOTIMPL;
1652 }
1653 
1654 static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
1655 {
1656     HRESULT hr = onerror_hres;
1657 
1658     if(!expect_OnScriptError) {
1659         EXCEPINFO info;
1660         ULONG line;
1661         HRESULT hres;
1662 
1663         hres = IActiveScriptError_GetSourcePosition(pscripterror, NULL, &line, NULL);
1664         if(SUCCEEDED(hres))
1665             hres = IActiveScriptError_GetExceptionInfo(pscripterror, &info);
1666         if(SUCCEEDED(hres))
1667             trace("Error in line %u: %s\n", line+1, wine_dbgstr_w(info.bstrDescription));
1668     }
1669 
1670     CHECK_EXPECT(OnScriptError);
1671     onerror_hres = E_NOTIMPL;
1672 
1673     return hr;
1674 }
1675 
1676 static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
1677 {
1678     return E_NOTIMPL;
1679 }
1680 
1681 static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
1682 {
1683     return E_NOTIMPL;
1684 }
1685 
1686 #undef ACTSCPSITE_THIS
1687 
1688 static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
1689     ActiveScriptSite_QueryInterface,
1690     ActiveScriptSite_AddRef,
1691     ActiveScriptSite_Release,
1692     ActiveScriptSite_GetLCID,
1693     ActiveScriptSite_GetItemInfo,
1694     ActiveScriptSite_GetDocVersionString,
1695     ActiveScriptSite_OnScriptTerminate,
1696     ActiveScriptSite_OnStateChange,
1697     ActiveScriptSite_OnScriptError,
1698     ActiveScriptSite_OnEnterScript,
1699     ActiveScriptSite_OnLeaveScript
1700 };
1701 
1702 static IActiveScriptSite ActiveScriptSite = { &ActiveScriptSiteVtbl };
1703 
1704 static IActiveScript *create_script(void)
1705 {
1706     IActiveScript *script;
1707     HRESULT hres;
1708 
1709     hres = CoCreateInstance(&CLSID_VBScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1710             &IID_IActiveScript, (void**)&script);
1711     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
1712 
1713     return script;
1714 }
1715 
1716 static IActiveScript *create_and_init_script(DWORD flags)
1717 {
1718     IActiveScriptParse *parser;
1719     IActiveScript *engine;
1720     HRESULT hres;
1721 
1722     engine = create_script();
1723     if(!engine)
1724         return NULL;
1725 
1726     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
1727     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1728 
1729     hres = IActiveScriptParse_InitNew(parser);
1730     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
1731 
1732     IActiveScriptParse_Release(parser);
1733 
1734     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
1735     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
1736 
1737     hres = IActiveScript_AddNamedItem(engine, testW,
1738             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|flags);
1739     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
1740 
1741     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
1742     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
1743 
1744     return engine;
1745 }
1746 
1747 static void close_script(IActiveScript *script)
1748 {
1749     ULONG ref;
1750     HRESULT hres;
1751 
1752     hres = IActiveScript_Close(script);
1753     ok(hres == S_OK, "Close failed: %08x\n", hres);
1754 
1755     ref = IActiveScript_Release(script);
1756     ok(!ref, "ref=%u\n", ref);
1757 }
1758 
1759 static HRESULT parse_script(DWORD flags, BSTR script_str, const WCHAR *delim)
1760 {
1761     IActiveScriptParse *parser;
1762     IActiveScript *engine;
1763     IDispatch *script_disp;
1764     LONG ref;
1765     HRESULT hres;
1766 
1767     engine = create_and_init_script(flags);
1768     if(!engine)
1769         return S_OK;
1770 
1771     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
1772     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1773     if (FAILED(hres))
1774     {
1775         IActiveScript_Release(engine);
1776         return hres;
1777     }
1778 
1779     hres = IActiveScript_GetScriptDispatch(engine, NULL, &script_disp);
1780     ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres);
1781     ok(script_disp != NULL, "script_disp == NULL\n");
1782     ok(script_disp != (IDispatch*)&Global, "script_disp == Global\n");
1783 
1784     test_counter = 0;
1785 
1786     hres = IActiveScriptParse_ParseScriptText(parser, script_str, NULL, NULL, delim, 0, 0, 0, NULL, NULL);
1787 
1788     IActiveScript_Close(engine);
1789 
1790     IDispatch_Release(script_disp);
1791     IActiveScript_Release(engine);
1792 
1793     ref = IActiveScriptParse_Release(parser);
1794     ok(!ref, "ref=%d\n", ref);
1795     return hres;
1796 }
1797 
1798 static void parse_script_af(DWORD flags, const char *src)
1799 {
1800     BSTR tmp;
1801     HRESULT hres;
1802 
1803     tmp = a2bstr(src);
1804     hres = parse_script(flags, tmp, NULL);
1805     SysFreeString(tmp);
1806     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
1807 }
1808 
1809 static HRESULT parse_script_ar(const char *src)
1810 {
1811     BSTR tmp;
1812     HRESULT hres;
1813 
1814     tmp = a2bstr(src);
1815     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, tmp, NULL);
1816     SysFreeString(tmp);
1817     return hres;
1818 }
1819 
1820 static void test_parse_context(void)
1821 {
1822     IActiveScriptParse *parser;
1823     IActiveScript *engine;
1824     BSTR str;
1825     HRESULT hres;
1826 
1827     static const WCHAR xW[] = {'x',0};
1828     static const WCHAR yW[] = {'y',0};
1829 
1830     global_ref = 1;
1831     engine = create_and_init_script(0);
1832     if(!engine)
1833         return;
1834 
1835     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
1836     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1837 
1838     /* unknown identifier context is not a valid argument */
1839     str = a2bstr("Call reportSuccess()\n");
1840     hres = IActiveScriptParse_ParseScriptText(parser, str, yW, NULL, NULL, 0, 0, 0, NULL, NULL);
1841     ok(hres == E_INVALIDARG, "ParseScriptText failed: %08x\n", hres);
1842     SysFreeString(str);
1843 
1844     str = a2bstr("class Cl\n"
1845                  "    Public Sub ClMethod\n"
1846                  "        Call reportSuccess()\n"
1847                  "    End Sub\n"
1848                  "End Class\n"
1849                  "Dim x\n"
1850                  "set x = new Cl\n");
1851     hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
1852     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
1853     SysFreeString(str);
1854 
1855     /* known global variable is not a valid context */
1856     str = a2bstr("Call reportSuccess()\n");
1857     hres = IActiveScriptParse_ParseScriptText(parser, str, xW, NULL, NULL, 0, 0, 0, NULL, NULL);
1858     ok(hres == E_INVALIDARG, "ParseScriptText failed: %08x\n", hres);
1859     SysFreeString(str);
1860 
1861     SET_EXPECT(global_success_d);
1862     SET_EXPECT(global_success_i);
1863     str = a2bstr("Call reportSuccess()\n");
1864     hres = IActiveScriptParse_ParseScriptText(parser, str, testW, NULL, NULL, 0, 0, 0, NULL, NULL);
1865     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
1866     SysFreeString(str);
1867     CHECK_CALLED(global_success_d);
1868     CHECK_CALLED(global_success_i);
1869 
1870     IActiveScriptParse_Release(parser);
1871     close_script(engine);
1872     ok(global_ref == 1, "global_ref = %u\n", global_ref);
1873 }
1874 
1875 static void parse_script_a(const char *src)
1876 {
1877     parse_script_af(SCRIPTITEM_GLOBALMEMBERS, src);
1878 }
1879 
1880 #define parse_htmlscript_a(a) _parse_htmlscript_a(__LINE__,a)
1881 static void _parse_htmlscript_a(unsigned line, const char *src)
1882 {
1883     BSTR tmp;
1884     HRESULT hres;
1885 
1886     static const WCHAR script_delimW[] = {'<','/','S','C','R','I','P','T','>',0};
1887 
1888     tmp = a2bstr(src);
1889     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, tmp, script_delimW);
1890     SysFreeString(tmp);
1891     ok_(__FILE__,line)(hres == S_OK, "parse_script failed: %08x\n", hres);
1892 }
1893 
1894 static IDispatchEx *parse_procedure(IActiveScriptParseProcedure2 *parse_proc, const char *src)
1895 {
1896     IDispatchEx *dispex;
1897     IDispatch *disp;
1898     BSTR str;
1899     HRESULT hres;
1900 
1901     static const WCHAR delimiterW[] = {'\"',0};
1902 
1903     str = a2bstr(src);
1904     hres = IActiveScriptParseProcedure2_ParseProcedureText(parse_proc, str, NULL, emptyW, NULL, NULL, delimiterW, 0, 0,
1905             SCRIPTPROC_HOSTMANAGESSOURCE|SCRIPTPROC_IMPLICIT_THIS|SCRIPTPROC_IMPLICIT_PARENTS, &disp);
1906     SysFreeString(str);
1907     ok(hres == S_OK, "ParseProcedureText failed: %08x\n", hres);
1908     ok(disp != NULL, "disp = NULL\n");
1909 
1910     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
1911     IDispatch_Release(disp);
1912     ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
1913 
1914     return dispex;
1915 }
1916 
1917 
1918 static void test_procedures(void)
1919 {
1920     IActiveScriptParseProcedure2 *parse_proc;
1921     DISPPARAMS dp = {NULL};
1922     IActiveScript *script;
1923     IDispatchEx *proc;
1924     EXCEPINFO ei = {0};
1925     VARIANT v;
1926     HRESULT hres;
1927 
1928     script = create_and_init_script(0);
1929 
1930     hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParseProcedure2, (void**)&parse_proc);
1931     ok(hres == S_OK, "Could not get IActiveScriptParseProcedure2 iface: %08x\n", hres);
1932 
1933     proc = parse_procedure(parse_proc, "dim x\nif true then x=false");
1934 
1935     V_VT(&v) = VT_EMPTY;
1936     hres = IDispatchEx_InvokeEx(proc, DISPID_VALUE, 0, DISPATCH_METHOD, &dp, &v, &ei, &caller_sp);
1937     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1938 
1939     IDispatchEx_Release(proc);
1940 
1941     IActiveScriptParseProcedure2_Release(parse_proc);
1942 
1943     close_script(script);
1944 }
1945 
1946 static void test_gc(void)
1947 {
1948     IActiveScriptParse *parser;
1949     IActiveScript *engine;
1950     BSTR src;
1951     HRESULT hres;
1952 
1953     strict_dispid_check = FALSE;
1954 
1955     engine = create_script();
1956     if(!engine)
1957         return;
1958 
1959     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
1960     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1961 
1962     hres = IActiveScriptParse_InitNew(parser);
1963     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
1964 
1965     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
1966     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
1967 
1968     hres = IActiveScript_AddNamedItem(engine, testW,
1969             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
1970     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
1971 
1972     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
1973     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
1974 
1975     src = a2bstr(
1976             "class C\n"
1977             "    Public ref\n"
1978             "    Public Sub Class_Terminate\n"
1979             "        Call reportSuccess()\n"
1980             "    End Sub\n"
1981             "End Class\n"
1982             "Dim x\n"
1983             "set x = new C\n"
1984             "set x.ref = x\n"
1985             "set x = nothing\n");
1986 
1987     hres = IActiveScriptParse_ParseScriptText(parser, src, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
1988     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
1989     SysFreeString(src);
1990 
1991     SET_EXPECT(global_success_d);
1992     SET_EXPECT(global_success_i);
1993     IActiveScript_Close(engine);
1994     CHECK_CALLED(global_success_d);
1995     CHECK_CALLED(global_success_i);
1996 
1997     IActiveScript_Release(engine);
1998     IActiveScriptParse_Release(parser);
1999 }
2000 
2001 static void test_msgbox(void)
2002 {
2003     HRESULT hres;
2004 
2005     uic_handling = SCRIPTUICHANDLING_NOUIDEFAULT;
2006 
2007     SET_EXPECT(GetUIBehavior);
2008     SET_EXPECT(GetWindow);
2009     SET_EXPECT(EnableModeless);
2010     hres = parse_script_ar("MsgBox \"testing...\"");
2011     CLEAR_CALLED(GetUIBehavior);
2012     CLEAR_CALLED(GetWindow);
2013     CLEAR_CALLED(EnableModeless);
2014     if(FAILED(hres)) {
2015         win_skip("Skipping MsgBox tests, broken (probably too old) vbscript\n");
2016         return;
2017     }
2018 
2019     SET_EXPECT(GetUIBehavior);
2020     parse_script_a("dim r\n r=MsgBox(\"testing...\")\n Call ok(r=0, \"r=\"&r)");
2021     CHECK_CALLED(GetUIBehavior);
2022 
2023     SET_EXPECT(GetUIBehavior);
2024     parse_script_a("MsgBox 10");
2025     CHECK_CALLED(GetUIBehavior);
2026 
2027     uic_handling = SCRIPTUICHANDLING_ALLOW;
2028 
2029     SET_EXPECT(GetUIBehavior);
2030     SET_EXPECT(GetWindow);
2031     SET_EXPECT(EnableModeless);
2032     SET_EXPECT(OnScriptError);
2033     hres = parse_script_ar("MsgBox \"testing...\"");
2034     ok(FAILED(hres), "script not failed\n");
2035     CHECK_CALLED(GetUIBehavior);
2036     CHECK_CALLED(GetWindow);
2037     CHECK_CALLED(EnableModeless);
2038     todo_wine CHECK_CALLED(OnScriptError);
2039 
2040     uic_handling = SCRIPTUICHANDLING_NOUIERROR;
2041 
2042     SET_EXPECT(GetUIBehavior);
2043     SET_EXPECT(OnScriptError);
2044     hres = parse_script_ar("MsgBox \"testing...\"");
2045     ok(FAILED(hres), "script not failed\n");
2046     CHECK_CALLED(GetUIBehavior);
2047     todo_wine CHECK_CALLED(OnScriptError);
2048 }
2049 
2050 static HRESULT test_global_vars_ref(BOOL use_close)
2051 {
2052     IActiveScriptParse *parser;
2053     IActiveScript *engine;
2054     BSTR script_str;
2055     LONG ref;
2056     HRESULT hres;
2057 
2058     engine = create_script();
2059     if(!engine)
2060         return S_OK;
2061 
2062     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
2063     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
2064     if (FAILED(hres))
2065     {
2066         IActiveScript_Release(engine);
2067         return hres;
2068     }
2069 
2070     hres = IActiveScriptParse_InitNew(parser);
2071     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
2072 
2073     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
2074     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
2075 
2076     hres = IActiveScript_AddNamedItem(engine, testW, SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
2077     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
2078 
2079     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
2080     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
2081 
2082     refobj_ref = 0;
2083 
2084     script_str = a2bstr("Dim x\nset x = RefObj\n");
2085     hres = IActiveScriptParse_ParseScriptText(parser, script_str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
2086     SysFreeString(script_str);
2087 
2088     ok(refobj_ref, "refobj_ref = 0\n");
2089 
2090     if(use_close) {
2091         hres = IActiveScript_Close(engine);
2092         ok(hres == S_OK, "Close failed: %08x\n", hres);
2093     }else {
2094         hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_UNINITIALIZED);
2095         ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
2096     }
2097 
2098     ok(!refobj_ref, "refobj_ref = %d\n", refobj_ref);
2099 
2100     IActiveScript_Release(engine);
2101 
2102     ref = IActiveScriptParse_Release(parser);
2103     ok(!ref, "ref=%d\n", ref);
2104     return hres;
2105 }
2106 
2107 static BSTR get_script_from_file(const char *filename)
2108 {
2109     DWORD size, len;
2110     HANDLE file, map;
2111     const char *file_map;
2112     BSTR ret;
2113 
2114     file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
2115     if(file == INVALID_HANDLE_VALUE) {
2116         trace("Could not open file: %u\n", GetLastError());
2117         return NULL;
2118     }
2119 
2120     size = GetFileSize(file, NULL);
2121 
2122     map = CreateFileMappingW(file, NULL, PAGE_READONLY, 0, 0, NULL);
2123     CloseHandle(file);
2124     if(map == INVALID_HANDLE_VALUE) {
2125         trace("Could not create file mapping: %u\n", GetLastError());
2126         return NULL;
2127     }
2128 
2129     file_map = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
2130     CloseHandle(map);
2131     if(!file_map) {
2132         trace("MapViewOfFile failed: %u\n", GetLastError());
2133         return NULL;
2134     }
2135 
2136     len = MultiByteToWideChar(CP_ACP, 0, file_map, size, NULL, 0);
2137     ret = SysAllocStringLen(NULL, len);
2138     MultiByteToWideChar(CP_ACP, 0, file_map, size, ret, len);
2139 
2140     UnmapViewOfFile(file_map);
2141 
2142     return ret;
2143 }
2144 
2145 static void run_from_file(const char *filename)
2146 {
2147     BSTR script_str;
2148     HRESULT hres;
2149 
2150     script_str = get_script_from_file(filename);
2151     if(!script_str)
2152         return;
2153 
2154     strict_dispid_check = FALSE;
2155     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, script_str, NULL);
2156     SysFreeString(script_str);
2157     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
2158 }
2159 
2160 static void run_from_res(const char *name)
2161 {
2162     const char *data;
2163     DWORD size, len;
2164     BSTR str;
2165     HRSRC src;
2166     HRESULT hres;
2167 
2168     strict_dispid_check = FALSE;
2169     test_name = name;
2170 
2171     src = FindResourceA(NULL, name, (LPCSTR)40);
2172     ok(src != NULL, "Could not find resource %s\n", name);
2173 
2174     size = SizeofResource(NULL, src);
2175     data = LoadResource(NULL, src);
2176 
2177     len = MultiByteToWideChar(CP_ACP, 0, data, size, NULL, 0);
2178     str = SysAllocStringLen(NULL, len);
2179     MultiByteToWideChar(CP_ACP, 0, data, size, str, len);
2180 
2181     SET_EXPECT(global_success_d);
2182     SET_EXPECT(global_success_i);
2183     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, str, NULL);
2184     CHECK_CALLED(global_success_d);
2185     CHECK_CALLED(global_success_i);
2186 
2187     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
2188     SysFreeString(str);
2189 }
2190 
2191 static void run_tests(void)
2192 {
2193     HRESULT hres;
2194 
2195     strict_dispid_check = TRUE;
2196 
2197     parse_script_a("");
2198     parse_script_a("' empty ;");
2199 
2200     SET_EXPECT(global_success_d);
2201     SET_EXPECT(global_success_i);
2202     parse_script_a("reportSuccess");
2203     CHECK_CALLED(global_success_d);
2204     CHECK_CALLED(global_success_i);
2205 
2206     SET_EXPECT(global_success_d);
2207     SET_EXPECT(global_success_i);
2208     parse_script_a("reportSuccess()");
2209     CHECK_CALLED(global_success_d);
2210     CHECK_CALLED(global_success_i);
2211 
2212     SET_EXPECT(global_success_d);
2213     SET_EXPECT(global_success_i);
2214     parse_script_a("Call reportSuccess");
2215     CHECK_CALLED(global_success_d);
2216     CHECK_CALLED(global_success_i);
2217 
2218     SET_EXPECT(global_success_d);
2219     SET_EXPECT(global_success_i);
2220     parse_script_a("test.reportSuccess()");
2221     CHECK_CALLED(global_success_d);
2222     CHECK_CALLED(global_success_i);
2223 
2224     SET_EXPECT(global_success_d);
2225     SET_EXPECT(global_success_i);
2226     parse_script_af(0, "TEST.reportSuccess()");
2227     CHECK_CALLED(global_success_d);
2228     CHECK_CALLED(global_success_i);
2229 
2230     SET_EXPECT(global_vbvar_d);
2231     SET_EXPECT(global_vbvar_i);
2232     parse_script_a("Option Explicit\nvbvar = 3");
2233     CHECK_CALLED(global_vbvar_d);
2234     CHECK_CALLED(global_vbvar_i);
2235 
2236     SET_EXPECT(global_vbvar_d);
2237     SET_EXPECT(global_vbvar_i);
2238     parse_script_a("Option Explicit\nvbvar() = 3");
2239     CHECK_CALLED(global_vbvar_d);
2240     CHECK_CALLED(global_vbvar_i);
2241 
2242     SET_EXPECT(global_letobj_i);
2243     parse_script_a("Option Explicit\nletobj = testObj");
2244     CHECK_CALLED(global_letobj_i);
2245 
2246     SET_EXPECT(global_letobj_i);
2247     parse_script_a("Option Explicit\ntest.letobj = testObj");
2248     CHECK_CALLED(global_letobj_i);
2249 
2250     SET_EXPECT(global_setobj_i);
2251     parse_script_a("Option Explicit\nset setobj = testObj");
2252     CHECK_CALLED(global_setobj_i);
2253 
2254     SET_EXPECT(global_setobj_i);
2255     parse_script_a("Option Explicit\nset test.setobj = testObj");
2256     CHECK_CALLED(global_setobj_i);
2257 
2258     SET_EXPECT(testobj_propget_d);
2259     SET_EXPECT(testobj_propget_i);
2260     parse_script_a("dim x\nx = testObj.propget");
2261     CHECK_CALLED(testobj_propget_d);
2262     CHECK_CALLED(testobj_propget_i);
2263 
2264     SET_EXPECT(testobj_propput_d);
2265     SET_EXPECT(testobj_propput_i);
2266     parse_script_a("testObj.propput = 1");
2267     CHECK_CALLED(testobj_propput_d);
2268     CHECK_CALLED(testobj_propput_i);
2269 
2270     SET_EXPECT(global_propargput_d);
2271     SET_EXPECT(global_propargput_i);
2272     parse_script_a("propargput(counter(), counter()) = counter()");
2273     CHECK_CALLED(global_propargput_d);
2274     CHECK_CALLED(global_propargput_i);
2275 
2276     SET_EXPECT(global_propargput_d);
2277     SET_EXPECT(global_propargput_i);
2278     parse_script_a("test.propargput(counter(), counter()) = counter()");
2279     CHECK_CALLED(global_propargput_d);
2280     CHECK_CALLED(global_propargput_i);
2281 
2282     SET_EXPECT(global_propargput1_d);
2283     SET_EXPECT(global_propargput1_i);
2284     parse_script_a("propargput1 (counter()) = counter()");
2285     CHECK_CALLED(global_propargput1_d);
2286     CHECK_CALLED(global_propargput1_i);
2287 
2288     SET_EXPECT(global_propargput1_d);
2289     SET_EXPECT(global_propargput1_i);
2290     parse_script_a("test.propargput1(counter()) = counter()");
2291     CHECK_CALLED(global_propargput1_d);
2292     CHECK_CALLED(global_propargput1_i);
2293 
2294     parse_htmlscript_a("<!--");
2295     parse_htmlscript_a(" -->");
2296     parse_htmlscript_a("<!--\ndim x\nx=1\n-->\n");
2297     parse_htmlscript_a("<!--\ndim x\n-->\n<!--\nx=1\n-->\n");
2298 
2299     SET_EXPECT(OnScriptError);
2300     hres = parse_script_ar("<!--");
2301     ok(FAILED(hres), "script didn't fail\n");
2302     todo_wine CHECK_CALLED(OnScriptError);
2303 
2304     SET_EXPECT(global_success_d);
2305     SET_EXPECT(global_success_i);
2306     parse_htmlscript_a("<!--\n<!-- ignore this <> <>\n--> <>\nCall reportSuccess()\n-->\n");
2307     CHECK_CALLED(global_success_d);
2308     CHECK_CALLED(global_success_i);
2309 
2310     next_cnt = 0;
2311     SET_EXPECT(collectionobj_newenum_i);
2312     SET_EXPECT(Next);
2313     parse_script_a("for each x in collectionObj\nnext");
2314     CHECK_CALLED(collectionobj_newenum_i);
2315     CHECK_CALLED(Next);
2316     ok(next_cnt == 4, "next_cnt = %d\n", next_cnt);
2317 
2318     parse_script_a("x = 1\n Call ok(x = 1, \"x = \" & x)");
2319 
2320     parse_script_a("x = _    \n3");
2321 
2322     test_global_vars_ref(TRUE);
2323     test_global_vars_ref(FALSE);
2324 
2325     SET_EXPECT(OnScriptError);
2326     hres = parse_script_ar("throwInt(&h80080008&)");
2327     ok(hres == 0x80080008, "hres = %08x\n", hres);
2328     todo_wine CHECK_CALLED(OnScriptError);
2329 
2330     /* DISP_E_BADINDEX */
2331     SET_EXPECT(OnScriptError);
2332     hres = parse_script_ar("throwInt(&h8002000b&)");
2333     ok(hres == MAKE_VBSERROR(9), "hres = %08x\n", hres);
2334     todo_wine CHECK_CALLED(OnScriptError);
2335 
2336     SET_EXPECT(OnScriptError);
2337     hres = parse_script_ar("throwInt(&h800a0009&)");
2338     ok(hres == MAKE_VBSERROR(9), "hres = %08x\n", hres);
2339     todo_wine CHECK_CALLED(OnScriptError);
2340 
2341     onerror_hres = S_OK;
2342     SET_EXPECT(OnScriptError);
2343     hres = parse_script_ar("throwInt(&h800a0009&)");
2344     todo_wine ok(hres == SCRIPT_E_REPORTED, "hres = %08x\n", hres);
2345     todo_wine CHECK_CALLED(OnScriptError);
2346 
2347     /* E_NOTIMPL */
2348     SET_EXPECT(OnScriptError);
2349     hres = parse_script_ar("throwInt(&h80004001&)");
2350     ok(hres == MAKE_VBSERROR(445), "hres = %08x\n", hres);
2351     todo_wine CHECK_CALLED(OnScriptError);
2352 
2353     onerror_hres = S_OK;
2354     SET_EXPECT(OnScriptError);
2355     hres = parse_script_ar("throwInt(&h80004001&)");
2356     todo_wine ok(hres == SCRIPT_E_REPORTED, "hres = %08x\n", hres);
2357     todo_wine CHECK_CALLED(OnScriptError);
2358 
2359     SET_EXPECT(global_testoptionalarg_i);
2360     parse_script_a("call testOptionalArg(1,,2)");
2361     CHECK_CALLED(global_testoptionalarg_i);
2362 
2363     SET_EXPECT(global_testoptionalarg_i);
2364     parse_script_a("call testOptionalArg(,1,1)");
2365     CHECK_CALLED(global_testoptionalarg_i);
2366 
2367     SET_EXPECT(global_testoptionalarg_i);
2368     parse_script_a("testOptionalArg 1,,2");
2369     CHECK_CALLED(global_testoptionalarg_i);
2370 
2371     strict_dispid_check = FALSE;
2372 
2373     SET_EXPECT(testobj_value_i);
2374     parse_script_a("dim n,o\n set o = testObj\n n = o(1,2)\n call ok(n=2, \"n = \" & n)\n");
2375     CHECK_CALLED(testobj_value_i);
2376 
2377     SET_EXPECT(testobj_value_i);
2378     parse_script_a("dim n,o\n set o = testObj\n n = o\n call ok(n=0, \"n = \" & n)\n");
2379     CHECK_CALLED(testobj_value_i);
2380 
2381     parse_script_a("Sub testsub\n"
2382                    "x = 1\n"
2383                    "Call ok(x = 1, \"x = \" & x)\n"
2384                    "End Sub\n"
2385                    "Call testsub()");
2386 
2387     parse_script_a("Call ok(getVT(x) = \"VT_EMPTY*\", \"getVT(x) = \" & getVT(x))\n");
2388     parse_script_a("Call ok(x = \"\", \"x = \" & x)\n");
2389     parse_script_a("x = y\n"
2390                    "Call ok(getVT(x) = \"VT_EMPTY*\", \"getVT(x) = \" & getVT(x))\n"
2391                    "Call ok(getVT(y) = \"VT_EMPTY*\", \"getVT(y) = \" & getVT(y))");
2392     SET_EXPECT(OnScriptError);
2393     hres = parse_script_ar("x = y(\"a\")");
2394     ok(FAILED(hres), "script didn't fail\n");
2395     todo_wine CHECK_CALLED(OnScriptError);
2396 
2397     SET_EXPECT(global_success_d);
2398     SET_EXPECT(global_success_i);
2399     parse_script_a("' comment\r"
2400                    "Sub testsub(arg)\r"
2401                    "If arg = 1 Then\r\r"
2402                    "Call reportSuccess()\n\n"
2403                    "End If\r\n"
2404                    "End Sub\n\r"
2405                    "Call testsub(1)");
2406     CHECK_CALLED(global_success_d);
2407     CHECK_CALLED(global_success_i);
2408 
2409     run_from_res("lang.vbs");
2410     run_from_res("api.vbs");
2411     run_from_res("regexp.vbs");
2412     run_from_res("error.vbs");
2413 
2414     test_procedures();
2415     test_gc();
2416     test_msgbox();
2417     test_parse_context();
2418 }
2419 
2420 static BOOL check_vbscript(void)
2421 {
2422     IRegExp2 *regexp;
2423     IUnknown *unk;
2424     HRESULT hres;
2425 
2426     hres = CoCreateInstance(&CLSID_VBScriptRegExp, NULL,
2427             CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2428             &IID_IUnknown, (void**)&unk);
2429     if(hres == REGDB_E_CLASSNOTREG)
2430         return FALSE;
2431     ok(hres == S_OK, "CoCreateInstance(CLSID_VBScriptRegExp) failed: %x\n", hres);
2432 
2433     hres = IUnknown_QueryInterface(unk, &IID_IRegExp2, (void**)&regexp);
2434     if(SUCCEEDED(hres))
2435         IRegExp2_Release(regexp);
2436     IUnknown_Release(unk);
2437 
2438     return hres == S_OK;
2439 }
2440 
2441 START_TEST(run)
2442 {
2443     int argc;
2444     char **argv;
2445 
2446     detect_locale();
2447     if(!is_english)
2448         skip("Skipping some tests in non-English locale\n");
2449 
2450     argc = winetest_get_mainargs(&argv);
2451 
2452     CoInitialize(NULL);
2453 
2454     if(!check_vbscript()) {
2455         win_skip("Broken engine, probably too old\n");
2456     }else if(argc > 2) {
2457         allow_ui = TRUE;
2458         uic_handling = SCRIPTUICHANDLING_ALLOW;
2459         run_from_file(argv[2]);
2460     }else {
2461         run_tests();
2462     }
2463 
2464     CoUninitialize();
2465 }
2466