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 REF_EXPECT(func) \
62     (&expect_ ## func), (&called_ ## func)
63 
64 #define CHECK_EXPECT2(func) \
65     do { \
66         ok(expect_ ##func, "unexpected call " #func "\n"); \
67         called_ ## func = TRUE; \
68     }while(0)
69 
70 #define CHECK_EXPECT(func) \
71     do { \
72         CHECK_EXPECT2(func); \
73         expect_ ## func = FALSE; \
74     }while(0)
75 
76 #define CHECK_CALLED(func) \
77     do { \
78         ok(called_ ## func, "expected " #func "\n"); \
79         expect_ ## func = called_ ## func = FALSE; \
80     }while(0)
81 
82 #define CHECK_NOT_CALLED(func) \
83     do { \
84         ok(!called_ ## func, "unexpected " #func "\n"); \
85         expect_ ## func = called_ ## func = FALSE; \
86     }while(0)
87 
88 #define CLEAR_CALLED(func) \
89     expect_ ## func = called_ ## func = FALSE
90 
91 DEFINE_EXPECT(global_success_d);
92 DEFINE_EXPECT(global_success_i);
93 DEFINE_EXPECT(global_vbvar_d);
94 DEFINE_EXPECT(global_vbvar_i);
95 DEFINE_EXPECT(global_letobj_i);
96 DEFINE_EXPECT(global_setobj_i);
97 DEFINE_EXPECT(global_globalcallback_i);
98 DEFINE_EXPECT(testobj_propget_d);
99 DEFINE_EXPECT(testobj_propget_i);
100 DEFINE_EXPECT(testobj_propput_d);
101 DEFINE_EXPECT(testobj_propput_i);
102 DEFINE_EXPECT(testobj_value_i);
103 DEFINE_EXPECT(global_propargput_d);
104 DEFINE_EXPECT(global_propargput_i);
105 DEFINE_EXPECT(global_propargput1_d);
106 DEFINE_EXPECT(global_propargput1_i);
107 DEFINE_EXPECT(global_testoptionalarg_i);
108 DEFINE_EXPECT(global_testerrorobject_i);
109 DEFINE_EXPECT(collectionobj_newenum_i);
110 DEFINE_EXPECT(Next);
111 DEFINE_EXPECT(GetWindow);
112 DEFINE_EXPECT(GetUIBehavior);
113 DEFINE_EXPECT(EnableModeless);
114 DEFINE_EXPECT(OnScriptError);
115 DEFINE_EXPECT(OnEnterScript);
116 DEFINE_EXPECT(OnLeaveScript);
117 
118 #define DISPID_GLOBAL_REPORTSUCCESS 1000
119 #define DISPID_GLOBAL_TRACE         1001
120 #define DISPID_GLOBAL_OK            1002
121 #define DISPID_GLOBAL_GETVT         1003
122 #define DISPID_GLOBAL_ISENGLANG     1004
123 #define DISPID_GLOBAL_VBVAR         1005
124 #define DISPID_GLOBAL_TESTOBJ       1006
125 #define DISPID_GLOBAL_ISNULLDISP    1007
126 #define DISPID_GLOBAL_TESTDISP      1008
127 #define DISPID_GLOBAL_REFOBJ        1009
128 #define DISPID_GLOBAL_COUNTER       1010
129 #define DISPID_GLOBAL_PROPARGPUT    1011
130 #define DISPID_GLOBAL_PROPARGPUT1   1012
131 #define DISPID_GLOBAL_COLLOBJ       1013
132 #define DISPID_GLOBAL_DOUBLEASSTRING 1014
133 #define DISPID_GLOBAL_TESTARRAY     1015
134 #define DISPID_GLOBAL_THROWINT      1016
135 #define DISPID_GLOBAL_TESTOPTIONALARG 1017
136 #define DISPID_GLOBAL_LETOBJ        1018
137 #define DISPID_GLOBAL_SETOBJ        1019
138 #define DISPID_GLOBAL_TODO_WINE_OK  1020
139 #define DISPID_GLOBAL_WEEKSTARTDAY  1021
140 #define DISPID_GLOBAL_GLOBALCALLBACK  1022
141 #define DISPID_GLOBAL_TESTERROROBJECT 1023
142 
143 #define DISPID_TESTOBJ_PROPGET      2000
144 #define DISPID_TESTOBJ_PROPPUT      2001
145 #define DISPID_TESTOBJ_KEYWORD      2002
146 
147 #define DISPID_COLLOBJ_RESET        3000
148 
149 #define FACILITY_VBS 0xa
150 #define MAKE_VBSERROR(code) MAKE_HRESULT(SEVERITY_ERROR, FACILITY_VBS, code)
151 
152 static const WCHAR testW[] = {'t','e','s','t',0};
153 static const WCHAR emptyW[] = {0};
154 
155 static BOOL strict_dispid_check, is_english, allow_ui;
156 static int first_day_of_week;
157 static const char *test_name = "(null)";
158 static int test_counter;
159 static SCRIPTUICHANDLING uic_handling = SCRIPTUICHANDLING_NOUIERROR;
160 static IDispatchEx testObj;
161 static HRESULT onerror_hres = E_NOTIMPL;
162 static BOOL strict_enter_script;
163 
164 static BSTR a2bstr(const char *str)
165 {
166     BSTR ret;
167     int len;
168 
169     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
170     ret = SysAllocStringLen(NULL, len-1);
171     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
172 
173     return ret;
174 }
175 
176 static int strcmp_wa(LPCWSTR strw, const char *stra)
177 {
178     CHAR buf[512];
179     WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), 0, 0);
180     return lstrcmpA(buf, stra);
181 }
182 
183 static int stricmp_wa(LPCWSTR strw, const char *stra)
184 {
185     CHAR buf[512];
186     WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), 0, 0);
187     return lstrcmpiA(buf, stra);
188 }
189 
190 static const char *vt2a(VARIANT *v)
191 {
192     if(V_VT(v) == (VT_BYREF|VT_VARIANT)) {
193         static char buf[64];
194         sprintf(buf, "%s*", vt2a(V_BYREF(v)));
195         return buf;
196     }
197 
198     switch(V_VT(v)) {
199     case VT_EMPTY:
200         return "VT_EMPTY";
201     case VT_NULL:
202         return "VT_NULL";
203     case VT_I2:
204         return "VT_I2";
205     case VT_I4:
206         return "VT_I4";
207     case VT_R4:
208         return "VT_R4";
209     case VT_R8:
210         return "VT_R8";
211     case VT_CY:
212         return "VT_CY";
213     case VT_DATE:
214         return "VT_DATE";
215     case VT_BSTR:
216         return "VT_BSTR";
217     case VT_DISPATCH:
218         return "VT_DISPATCH";
219     case VT_BOOL:
220         return "VT_BOOL";
221     case VT_ARRAY|VT_VARIANT:
222         return "VT_ARRAY|VT_VARIANT";
223     case VT_ARRAY|VT_BYREF|VT_VARIANT:
224         return "VT_ARRAY|VT_BYREF|VT_VARIANT";
225     case VT_UI1:
226         return "VT_UI1";
227     default:
228         ok(0, "unknown vt %d\n", V_VT(v));
229         return NULL;
230     }
231 }
232 
233 /* Sets is_english to true if the user interface is in English. Note that this
234  * does not presume the formatting of dates, numbers, etc.
235  * Sets first_day_of_week to 1 if Sunday, 2 if Monday, and so on.
236  */
237 static void detect_locale(void)
238 {
239     HMODULE kernel32 = GetModuleHandleA("kernel32.dll");
240     LANGID (WINAPI *pGetThreadUILanguage)(void) = (void*)GetProcAddress(kernel32, "GetThreadUILanguage");
241 
242     is_english = ((!pGetThreadUILanguage || PRIMARYLANGID(pGetThreadUILanguage()) == LANG_ENGLISH) &&
243                   PRIMARYLANGID(GetUserDefaultUILanguage()) == LANG_ENGLISH &&
244                   PRIMARYLANGID(GetUserDefaultLangID()) == LANG_ENGLISH);
245 
246     GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IFIRSTDAYOFWEEK | LOCALE_RETURN_NUMBER,
247                    (void*)&first_day_of_week, sizeof(first_day_of_week));
248     first_day_of_week = 1 + (first_day_of_week + 1) % 7;
249 }
250 
251 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
252 {
253     ok(0, "unexpected call\n");
254     return E_NOINTERFACE;
255 }
256 
257 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
258 {
259     return 2;
260 }
261 
262 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
263 {
264     return 1;
265 }
266 
267 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService,
268         REFIID riid, void **ppv)
269 {
270     ok(0, "unexpected service %s\n", wine_dbgstr_guid(guidService));
271     return E_NOINTERFACE;
272 }
273 
274 static const IServiceProviderVtbl ServiceProviderVtbl = {
275     ServiceProvider_QueryInterface,
276     ServiceProvider_AddRef,
277     ServiceProvider_Release,
278     ServiceProvider_QueryService
279 };
280 
281 static IServiceProvider caller_sp = { &ServiceProviderVtbl };
282 
283 static void test_disp(IDispatch *disp)
284 {
285     DISPID id, public_prop_id, public_prop2_id, public_func_id, public_sub_id, defvalget_id, gs_getter_id;
286     DISPID named_args[5] = {DISPID_PROPERTYPUT};
287     VARIANT v, args[5];
288     DISPPARAMS dp = {args, named_args};
289     IDispatchEx *dispex;
290     EXCEPINFO ei = {0};
291     BSTR str;
292     HRESULT hres;
293 
294     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
295     ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
296 
297     str = a2bstr("publicProp");
298     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_prop_id);
299     SysFreeString(str);
300     ok(hres == S_OK, "GetDispID(publicProp) failed: %08x\n", hres);
301 
302     str = a2bstr("PUBLICPROP");
303     hres = IDispatchEx_GetDispID(dispex, str, 0, &id);
304     SysFreeString(str);
305     ok(hres == S_OK, "GetDispID(PUBLICPROP) failed: %08x\n", hres);
306     ok(public_prop_id == id, "id = %d\n", public_prop_id);
307 
308     str = a2bstr("publicPROP2");
309     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_prop2_id);
310     SysFreeString(str);
311     ok(hres == S_OK, "GetDispID(publicProp2) failed: %08x\n", hres);
312 
313     str = a2bstr("defValGet");
314     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &defvalget_id);
315     SysFreeString(str);
316     ok(hres == S_OK, "GetDispID(defValGet) failed: %08x\n", hres);
317     ok(defvalget_id == DISPID_VALUE, "id = %d\n", defvalget_id);
318 
319     str = a2bstr("privateProp");
320     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id);
321     SysFreeString(str);
322     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateProp) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
323     ok(id == -1, "id = %d\n", id);
324 
325     str = a2bstr("class_initialize");
326     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id);
327     SysFreeString(str);
328     ok(hres == S_OK, "GetDispID(publicProp2) failed: %08x\n", hres);
329 
330     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
331     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
332     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
333 
334     V_VT(args) = VT_BOOL;
335     V_BOOL(args) = VARIANT_TRUE;
336     dp.cArgs = dp.cNamedArgs = 1;
337     V_VT(&v) = VT_BOOL;
338     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUT, &dp, &v, &ei, NULL);
339     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
340     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
341 
342     dp.cArgs = dp.cNamedArgs = 0;
343     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
344     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
345     ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
346     ok(V_BOOL(&v), "V_BOOL(v) = %x\n", V_BOOL(&v));
347 
348     dp.cArgs = dp.cNamedArgs = 0;
349     hres = IDispatchEx_Invoke(dispex, public_prop_id, &IID_NULL, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
350     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
351     ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
352     ok(V_BOOL(&v), "V_BOOL(v) = %x\n", V_BOOL(&v));
353 
354     dp.cArgs = dp.cNamedArgs = 0;
355     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
356     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
357     ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
358     ok(V_BOOL(&v), "V_BOOL(v) = %x\n", V_BOOL(&v));
359 
360     dp.cArgs = 1;
361     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
362     ok(hres == DISP_E_MEMBERNOTFOUND, "InvokeEx failed: %08x, expected DISP_E_MEMBERNOTFOUND\n", hres);
363     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
364 
365     SET_EXPECT(testobj_value_i);
366     V_VT(args) = VT_DISPATCH;
367     V_DISPATCH(args) = (IDispatch*)&testObj;
368     dp.cArgs = dp.cNamedArgs = 1;
369     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL);
370     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
371     CHECK_CALLED(testobj_value_i);
372 
373     dp.cArgs = dp.cNamedArgs = 0;
374     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
375     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
376     ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
377     ok(V_I2(&v) == 0, "V_I2(v) = %d\n", V_I2(&v));
378 
379     V_VT(args) = VT_DISPATCH;
380     V_DISPATCH(args) = (IDispatch*)&testObj;
381     dp.cArgs = dp.cNamedArgs = 1;
382     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF, &dp, NULL, &ei, NULL);
383     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
384 
385     V_VT(args) = VT_DISPATCH;
386     V_DISPATCH(args) = (IDispatch*)&testObj;
387     dp.cArgs = dp.cNamedArgs = 1;
388     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUTREF, &dp, NULL, &ei, NULL);
389     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
390 
391     dp.cArgs = dp.cNamedArgs = 0;
392     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
393     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
394     ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v));
395     ok(V_DISPATCH(&v) == (IDispatch*)&testObj, "V_DISPATCH(v) != testObj\n");
396 
397     V_VT(args) = VT_BOOL;
398     V_BOOL(args) = VARIANT_TRUE;
399     dp.cArgs = dp.cNamedArgs = 1;
400     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF, &dp, NULL, &ei, NULL);
401     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
402 
403     dp.cArgs = dp.cNamedArgs = 0;
404     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
405     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
406     ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
407     ok(V_BOOL(&v) == VARIANT_TRUE, "V_BOOL(v) = %x\n", V_BOOL(&v));
408 
409     V_VT(args) = VT_BOOL;
410     V_BOOL(args) = VARIANT_FALSE;
411     dp.cArgs = dp.cNamedArgs = 1;
412     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUTREF, &dp, NULL, &ei, NULL);
413     ok(hres == DISP_E_EXCEPTION, "InvokeEx failed: %08x, expected DISP_E_EXCEPTION\n", hres);
414 
415     V_VT(args) = VT_BOOL;
416     V_BOOL(args) = VARIANT_FALSE;
417     dp.cArgs = 1;
418     dp.cNamedArgs = 0;
419     V_VT(&v) = VT_BOOL;
420     hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL);
421     ok(hres == DISP_E_PARAMNOTOPTIONAL, "InvokeEx failed: %08x, expected DISP_E_PARAMNOTOPTIONAL\n", hres);
422 
423     str = a2bstr("publicFunction");
424     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_func_id);
425     SysFreeString(str);
426     ok(hres == S_OK, "GetDispID(publicFunction) failed: %08x\n", hres);
427     ok(public_func_id != -1, "public_func_id = -1\n");
428 
429     str = a2bstr("publicSub");
430     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_sub_id);
431     SysFreeString(str);
432     ok(hres == S_OK, "GetDispID(publicSub) failed: %08x\n", hres);
433     ok(public_sub_id != -1, "public_func_id = -1\n");
434 
435     dp.cArgs = dp.cNamedArgs = 0;
436     hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
437     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
438     ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
439     ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
440 
441     dp.cArgs = dp.cNamedArgs = 0;
442     hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
443     ok(hres == DISP_E_MEMBERNOTFOUND, "InvokeEx failed: %08x, expected DISP_E_MEMBERNOTFOUND\n", hres);
444     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
445 
446     dp.cArgs = dp.cNamedArgs = 0;
447     hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
448     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
449     ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
450     ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
451 
452     dp.cArgs = dp.cNamedArgs = 0;
453     hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
454     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
455     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
456 
457     dp.cArgs = dp.cNamedArgs = 0;
458     hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
459     ok(hres == DISP_E_MEMBERNOTFOUND, "InvokeEx failed: %08x, expected DISP_E_MEMBERNOTFOUND\n", hres);
460     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
461 
462     dp.cArgs = dp.cNamedArgs = 0;
463     hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
464     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
465     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
466 
467     V_VT(args) = VT_BOOL;
468     V_BOOL(args) = VARIANT_TRUE;
469     dp.cArgs = dp.cNamedArgs = 1;
470     hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL);
471     ok(FAILED(hres), "InvokeEx succeeded: %08x\n", hres);
472 
473     dp.cArgs = dp.cNamedArgs = 0;
474     hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
475     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
476     ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
477     ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
478 
479     dp.cArgs = dp.cNamedArgs = 0;
480     hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
481     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
482     ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
483     ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
484 
485     dp.cArgs = dp.cNamedArgs = 0;
486     hres = IDispatchEx_Invoke(dispex, public_func_id, &IID_NULL, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
487     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
488     ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
489     ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
490 
491     dp.cArgs = dp.cNamedArgs = 0;
492     hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
493     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
494     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
495 
496     dp.cArgs = dp.cNamedArgs = 0;
497     hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
498     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
499     ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
500 
501     str = a2bstr("privateSub");
502     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id);
503     SysFreeString(str);
504     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateSub) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
505     ok(id == -1, "id = %d\n", id);
506 
507     str = a2bstr("dynprop");
508     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive|fdexNameEnsure, &id);
509     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateProp) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
510     ok(id == -1, "id = %d\n", id);
511     hres = IDispatchEx_GetDispID(dispex, str, fdexNameEnsure, &id);
512     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateProp) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
513     ok(id == -1, "id = %d\n", id);
514     SysFreeString(str);
515 
516     str = a2bstr("publicProp");
517     hres = IDispatchEx_GetDispID(dispex, str, 0x80000000|fdexNameCaseInsensitive, &public_prop_id);
518     SysFreeString(str);
519     ok(hres == S_OK, "GetDispID(publicProp) failed: %08x\n", hres);
520 
521     id = 0xdeadbeef;
522     str = a2bstr("publicProp");
523     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseSensitive, &id);
524     SysFreeString(str);
525     ok(hres == S_OK, "GetDispID(publicProp) failed: %08x\n", hres);
526     ok(id == public_prop_id, "id = %d, expected %d\n", id, public_prop_id);
527 
528     id = 0xdeadbeef;
529     str = a2bstr("publicprop");
530     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseSensitive, &id);
531     SysFreeString(str);
532     ok(hres == S_OK, "GetDispID(publicProp) failed: %08x\n", hres);
533     ok(id == public_prop_id, "id = %d, expected %d\n", id, public_prop_id);
534 
535     str = a2bstr("gsGetProp");
536     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &gs_getter_id);
537     SysFreeString(str);
538     ok(hres == S_OK, "GetDispID(publicFunction) failed: %08x\n", hres);
539     ok(gs_getter_id != -1, "gs_getter_id = -1\n");
540 
541     V_VT(args) = VT_BOOL;
542     V_BOOL(args) = VARIANT_TRUE;
543     dp.cNamedArgs = 0;
544     dp.cArgs = 1;
545     V_VT(&v) = VT_I8;
546     hres = IDispatchEx_InvokeEx(dispex, gs_getter_id, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
547     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
548     ok(V_VT(&v) == VT_BOOL && V_BOOL(&v), "V_VT(v) = %d\n", V_VT(&v));
549 
550     hres = IDispatchEx_InvokeEx(dispex, gs_getter_id, 0, DISPATCH_PROPERTYGET, &dp, NULL, &ei, NULL);
551     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
552 
553     V_VT(args) = VT_BOOL;
554     V_BOOL(args) = VARIANT_FALSE;
555     dp.cArgs = 1;
556     V_VT(&v) = VT_I8;
557     hres = IDispatchEx_InvokeEx(dispex, gs_getter_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
558     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
559     ok(V_VT(&v) == VT_BOOL && !V_BOOL(&v), "V_VT(v) = %d\n", V_VT(&v));
560 
561     V_VT(args) = VT_BOOL;
562     V_BOOL(args) = VARIANT_TRUE;
563     V_VT(&v) = VT_I8;
564     dp.cArgs = 1;
565     hres = IDispatchEx_InvokeEx(dispex, gs_getter_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
566     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
567     ok(V_VT(&v) == VT_BOOL && V_BOOL(&v), "V_VT(v) = %d\n", V_VT(&v));
568 
569     IDispatchEx_Release(dispex);
570 }
571 
572 static void test_safearray(SAFEARRAY *safearray, unsigned indims)
573 {
574     int i, exdims = indims;
575 
576     if(!exdims)
577         exdims = 1;
578     ok(safearray->cDims == exdims, "safearray->cDims = %d, expected %d\n", safearray->cDims, exdims);
579     todo_wine
580     ok(safearray->fFeatures == (FADF_VARIANT|FADF_HAVEVARTYPE|FADF_FIXEDSIZE|FADF_STATIC),
581        "safearray->fFeatures = %x\n", safearray->fFeatures);
582     ok(safearray->cbElements == sizeof(VARIANT), "safearray->cbElements = %x\n", safearray->cbElements);
583     ok(!safearray->cLocks, "safearray->cLocks = %x\n", safearray->cLocks);
584 
585     for(i=0; i < safearray->cDims; i++) {
586         ok(safearray->rgsabound[i].cElements == (indims ? i+4 : 1), "safearray->rgsabound[%d].cElements = %d\n", i,
587            safearray->rgsabound[i].cElements);
588         ok(!safearray->rgsabound[i].lLbound, "safearray->rgsabound[%d].lLbound = %d\n", i, safearray->rgsabound[i].lLbound);
589     }
590 }
591 
592 #define test_grfdex(a,b) _test_grfdex(__LINE__,a,b)
593 static void _test_grfdex(unsigned line, DWORD grfdex, DWORD expect)
594 {
595     ok_(__FILE__,line)(grfdex == expect, "grfdex = %x, expected %x\n", grfdex, expect);
596 }
597 
598 static IDispatchEx enumDisp;
599 
600 static HRESULT WINAPI EnumVARIANT_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv)
601 {
602     if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IEnumVARIANT)) {
603         *ppv = iface;
604         return S_OK;
605     }
606 
607     if(IsEqualGUID(riid, &IID_IDispatch)) {
608         *ppv = &enumDisp;
609         return S_OK;
610     }
611 
612     ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid));
613     return E_NOINTERFACE;
614 }
615 
616 static ULONG WINAPI EnumVARIANT_AddRef(IEnumVARIANT *iface)
617 {
618     return 2;
619 }
620 
621 static ULONG WINAPI EnumVARIANT_Release(IEnumVARIANT *iface)
622 {
623     return 1;
624 }
625 
626 static unsigned next_cnt;
627 
628 static HRESULT WINAPI EnumVARIANT_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
629 {
630     if(strict_dispid_check)
631         CHECK_EXPECT2(Next);
632 
633     ok(celt == 1, "celt = %d\n", celt);
634     ok(V_VT(rgVar) == VT_EMPTY, "V_VT(rgVar) = %d\n", V_VT(rgVar));
635     ok(!pCeltFetched, "pCeltFetched = %p\n", pCeltFetched);
636 
637     if(next_cnt++ < 3) {
638         V_VT(rgVar) = VT_I2;
639         V_I2(rgVar) = next_cnt;
640         return S_OK;
641     }
642 
643     return S_FALSE;
644 }
645 
646 static HRESULT WINAPI EnumVARIANT_Skip(IEnumVARIANT *iface, ULONG celt)
647 {
648     ok(0, "unexpected call\n");
649     return E_NOTIMPL;
650 }
651 
652 static HRESULT WINAPI EnumVARIANT_Reset(IEnumVARIANT *iface)
653 {
654     ok(0, "unexpected call\n");
655     return E_NOTIMPL;
656 }
657 
658 static HRESULT WINAPI EnumVARIANT_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum)
659 {
660     ok(0, "unexpected call\n");
661     return E_NOTIMPL;
662 }
663 
664 static const IEnumVARIANTVtbl EnumVARIANTVtbl = {
665     EnumVARIANT_QueryInterface,
666     EnumVARIANT_AddRef,
667     EnumVARIANT_Release,
668     EnumVARIANT_Next,
669     EnumVARIANT_Skip,
670     EnumVARIANT_Reset,
671     EnumVARIANT_Clone
672 };
673 
674 static IEnumVARIANT enumObj = { &EnumVARIANTVtbl };
675 
676 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
677 {
678     *ppv = NULL;
679 
680     if(IsEqualGUID(riid, &IID_IUnknown)
681        || IsEqualGUID(riid, &IID_IDispatch)
682        || IsEqualGUID(riid, &IID_IDispatchEx))
683         *ppv = iface;
684     else {
685         trace("QI %s\n", wine_dbgstr_guid(riid));
686         return E_NOINTERFACE;
687     }
688 
689     IUnknown_AddRef((IUnknown*)*ppv);
690     return S_OK;
691 }
692 
693 static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
694 {
695     return 2;
696 }
697 
698 static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
699 {
700     return 1;
701 }
702 
703 static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
704 {
705     ok(0, "unexpected call\n");
706     return E_NOTIMPL;
707 }
708 
709 static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
710                                               LCID lcid, ITypeInfo **ppTInfo)
711 {
712     return E_NOTIMPL;
713 }
714 
715 static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
716                                                 LPOLESTR *rgszNames, UINT cNames,
717                                                 LCID lcid, DISPID *rgDispId)
718 {
719     ok(0, "unexpected call\n");
720     return E_NOTIMPL;
721 }
722 
723 static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
724                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
725                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
726 {
727     ok(0, "unexpected call\n");
728     return E_NOTIMPL;
729 }
730 
731 static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
732 {
733     ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
734     return E_NOTIMPL;
735 }
736 
737 static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
738 {
739     ok(0, "unexpected call\n");
740     return E_NOTIMPL;
741 }
742 
743 static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
744 {
745     ok(0, "unexpected call\n");
746     return E_NOTIMPL;
747 }
748 
749 static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
750 {
751     ok(0, "unexpected call\n");
752     return E_NOTIMPL;
753 }
754 
755 static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
756 {
757     ok(0, "unexpected call\n");
758     return E_NOTIMPL;
759 }
760 
761 static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
762 {
763     ok(0, "unexpected call\n");
764     return E_NOTIMPL;
765 }
766 
767 static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
768 {
769     ok(0, "unexpected call\n");
770     return E_NOTIMPL;
771 }
772 
773 static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
774         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
775 {
776     ok(0, "unexpected call %d\n", id);
777     return E_NOTIMPL;
778 }
779 
780 static HRESULT WINAPI testObj_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
781 {
782     typedef struct {
783           const char * const name;
784           DISPID pid;
785           BOOL *expect;
786           BOOL *called;
787     } dispid_t;
788 
789     dispid_t dispids[] = {
790        { "propget", DISPID_TESTOBJ_PROPGET, REF_EXPECT(testobj_propget_d) },
791        { "propput", DISPID_TESTOBJ_PROPPUT, REF_EXPECT(testobj_propput_d) },
792        { "rem", DISPID_TESTOBJ_KEYWORD, NULL },
793        { "true", DISPID_TESTOBJ_KEYWORD, NULL },
794        { "false", DISPID_TESTOBJ_KEYWORD, NULL },
795        { "not", DISPID_TESTOBJ_KEYWORD, NULL },
796        { "and", DISPID_TESTOBJ_KEYWORD, NULL },
797        { "or", DISPID_TESTOBJ_KEYWORD, NULL },
798        { "xor", DISPID_TESTOBJ_KEYWORD, NULL },
799        { "eqv", DISPID_TESTOBJ_KEYWORD, NULL },
800        { "imp", DISPID_TESTOBJ_KEYWORD, NULL },
801        { "is", DISPID_TESTOBJ_KEYWORD, NULL },
802        { "mod", DISPID_TESTOBJ_KEYWORD, NULL },
803        { "call", DISPID_TESTOBJ_KEYWORD, NULL },
804        { "dim", DISPID_TESTOBJ_KEYWORD, NULL },
805        { "sub", DISPID_TESTOBJ_KEYWORD, NULL },
806        { "function", DISPID_TESTOBJ_KEYWORD, NULL },
807        { "get", DISPID_TESTOBJ_KEYWORD, NULL },
808        { "let", DISPID_TESTOBJ_KEYWORD, NULL },
809        { "const", DISPID_TESTOBJ_KEYWORD, NULL },
810        { "if", DISPID_TESTOBJ_KEYWORD, NULL },
811        { "else", DISPID_TESTOBJ_KEYWORD, NULL },
812        { "elseif", DISPID_TESTOBJ_KEYWORD, NULL },
813        { "end", DISPID_TESTOBJ_KEYWORD, NULL },
814        { "then", DISPID_TESTOBJ_KEYWORD, NULL },
815        { "exit", DISPID_TESTOBJ_KEYWORD, NULL },
816        { "while", DISPID_TESTOBJ_KEYWORD, NULL },
817        { "wend", DISPID_TESTOBJ_KEYWORD, NULL },
818        { "do", DISPID_TESTOBJ_KEYWORD, NULL },
819        { "loop", DISPID_TESTOBJ_KEYWORD, NULL },
820        { "until", DISPID_TESTOBJ_KEYWORD, NULL },
821        { "for", DISPID_TESTOBJ_KEYWORD, NULL },
822        { "to", DISPID_TESTOBJ_KEYWORD, NULL },
823        { "each", DISPID_TESTOBJ_KEYWORD, NULL },
824        { "in", DISPID_TESTOBJ_KEYWORD, NULL },
825        { "select", DISPID_TESTOBJ_KEYWORD, NULL },
826        { "case", DISPID_TESTOBJ_KEYWORD, NULL },
827        { "byref", DISPID_TESTOBJ_KEYWORD, NULL },
828        { "byval", DISPID_TESTOBJ_KEYWORD, NULL },
829        { "option", DISPID_TESTOBJ_KEYWORD, NULL },
830        { "nothing", DISPID_TESTOBJ_KEYWORD, NULL },
831        { "empty", DISPID_TESTOBJ_KEYWORD, NULL },
832        { "null", DISPID_TESTOBJ_KEYWORD, NULL },
833        { "class", DISPID_TESTOBJ_KEYWORD, NULL },
834        { "set", DISPID_TESTOBJ_KEYWORD, NULL },
835        { "new", DISPID_TESTOBJ_KEYWORD, NULL },
836        { "public", DISPID_TESTOBJ_KEYWORD, NULL },
837        { "private", DISPID_TESTOBJ_KEYWORD, NULL },
838        { "next", DISPID_TESTOBJ_KEYWORD, NULL },
839        { "on", DISPID_TESTOBJ_KEYWORD, NULL },
840        { "resume", DISPID_TESTOBJ_KEYWORD, NULL },
841        { "goto", DISPID_TESTOBJ_KEYWORD, NULL },
842     };
843     int i;
844 
845     for (i = 0; i < ARRAY_SIZE(dispids); i++) {
846         if(!stricmp_wa(bstrName, dispids[i].name)) {
847             dispid_t *d = &dispids[i];
848             if(d->expect) {
849                ok(*d->expect, "unexpected call %s\n", d->name);
850                *d->called = TRUE;
851                *d->expect = FALSE;
852             }
853             test_grfdex(grfdex, fdexNameCaseInsensitive);
854             *pid = d->pid;
855             return S_OK;
856         }
857     }
858 
859     ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName));
860     return DISP_E_UNKNOWNNAME;
861 }
862 
863 static HRESULT WINAPI testObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
864         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
865 {
866     switch(id) {
867     case DISPID_VALUE: {
868         VARIANT *arg;
869         int i;
870 
871         CHECK_EXPECT(testobj_value_i);
872 
873         ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
874         ok(pdp != NULL, "pdp == NULL\n");
875         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
876         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
877         ok(pvarRes != NULL, "pvarRes == NULL\n");
878         ok(pei != NULL, "pei == NULL\n");
879 
880         for(i=0; i<pdp->cArgs; i++) {
881             arg = pdp->rgvarg+pdp->cArgs-i-1;
882             ok(V_VT(arg) == VT_I2, "V_VT(arg) = %d\n", V_VT(arg));
883             ok(V_I2(arg) == i+1, "V_I2(arg) = %d\n", V_I2(arg));
884         }
885 
886         V_VT(pvarRes) = VT_I2;
887         V_I2(pvarRes) = pdp->cArgs;
888         return S_OK;
889     }
890     case DISPID_TESTOBJ_PROPGET:
891         CHECK_EXPECT(testobj_propget_i);
892 
893         ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
894         ok(pdp != NULL, "pdp == NULL\n");
895         ok(!pdp->rgvarg, "rgvarg == NULL\n");
896         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
897         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
898         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
899         ok(pvarRes != NULL, "pvarRes == NULL\n");
900         ok(pei != NULL, "pei == NULL\n");
901 
902         V_VT(pvarRes) = VT_I2;
903         V_I2(pvarRes) = 10;
904         return S_OK;
905     case DISPID_TESTOBJ_PROPPUT:
906         CHECK_EXPECT(testobj_propput_i);
907 
908         ok(wFlags == DISPATCH_PROPERTYPUT, "wFlags = %x\n", wFlags);
909         ok(pdp != NULL, "pdp == NULL\n");
910         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
911         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
912         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
913         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
914         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
915         ok(!pvarRes, "pvarRes != NULL\n");
916         ok(pei != NULL, "pei == NULL\n");
917 
918         ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
919         ok(V_I2(pdp->rgvarg) == 1, "V_I2(psp->rgvargs) = %d\n", V_I2(pdp->rgvarg));
920         return S_OK;
921 
922     case DISPID_TESTOBJ_KEYWORD:
923         V_VT(pvarRes) = VT_I2;
924         V_I2(pvarRes) = 10;
925         return S_OK;
926     }
927 
928     ok(0, "unexpected call %d\n", id);
929     return E_FAIL;
930 }
931 
932 static IDispatchExVtbl testObjVtbl = {
933     DispatchEx_QueryInterface,
934     DispatchEx_AddRef,
935     DispatchEx_Release,
936     DispatchEx_GetTypeInfoCount,
937     DispatchEx_GetTypeInfo,
938     DispatchEx_GetIDsOfNames,
939     DispatchEx_Invoke,
940     testObj_GetDispID,
941     testObj_InvokeEx,
942     DispatchEx_DeleteMemberByName,
943     DispatchEx_DeleteMemberByDispID,
944     DispatchEx_GetMemberProperties,
945     DispatchEx_GetMemberName,
946     DispatchEx_GetNextDispID,
947     DispatchEx_GetNameSpaceParent
948 };
949 
950 static IDispatchEx testObj = { &testObjVtbl };
951 
952 static HRESULT WINAPI enumDisp_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
953 {
954     return IEnumVARIANT_QueryInterface(&enumObj, riid, ppv);
955 }
956 
957 static IDispatchExVtbl enumDispVtbl = {
958     enumDisp_QueryInterface,
959     DispatchEx_AddRef,
960     DispatchEx_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 enumDisp = { &enumDispVtbl };
976 
977 static HRESULT WINAPI collectionObj_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
978 {
979     if(!strcmp_wa(bstrName, "reset")) {
980         *pid = DISPID_COLLOBJ_RESET;
981         return S_OK;
982     }
983 
984     ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName));
985     return DISP_E_UNKNOWNNAME;
986 }
987 
988 static HRESULT WINAPI collectionObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
989         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
990 {
991     switch(id) {
992     case DISPID_NEWENUM:
993         if(strict_dispid_check)
994             CHECK_EXPECT(collectionobj_newenum_i);
995 
996         ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
997         ok(pdp != NULL, "pdp == NULL\n");
998         ok(!pdp->rgvarg, "rgvarg == NULL\n");
999         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1000         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
1001         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1002         ok(pvarRes != NULL, "pvarRes == NULL\n");
1003         ok(pei != NULL, "pei == NULL\n");
1004 
1005         V_VT(pvarRes) = VT_UNKNOWN;
1006         V_UNKNOWN(pvarRes) = (IUnknown*)&enumObj;
1007         return S_OK;
1008     case DISPID_COLLOBJ_RESET:
1009         next_cnt = 0;
1010         return S_OK;
1011     }
1012 
1013     ok(0, "unexpected call %d\n", id);
1014     return E_NOTIMPL;
1015 }
1016 
1017 static IDispatchExVtbl collectionObjVtbl = {
1018     DispatchEx_QueryInterface,
1019     DispatchEx_AddRef,
1020     DispatchEx_Release,
1021     DispatchEx_GetTypeInfoCount,
1022     DispatchEx_GetTypeInfo,
1023     DispatchEx_GetIDsOfNames,
1024     DispatchEx_Invoke,
1025     collectionObj_GetDispID,
1026     collectionObj_InvokeEx,
1027     DispatchEx_DeleteMemberByName,
1028     DispatchEx_DeleteMemberByDispID,
1029     DispatchEx_GetMemberProperties,
1030     DispatchEx_GetMemberName,
1031     DispatchEx_GetNextDispID,
1032     DispatchEx_GetNameSpaceParent
1033 };
1034 
1035 static IDispatchEx collectionObj = { &collectionObjVtbl };
1036 
1037 static ULONG refobj_ref;
1038 
1039 static ULONG WINAPI RefObj_AddRef(IDispatchEx *iface)
1040 {
1041     return ++refobj_ref;
1042 }
1043 
1044 static ULONG WINAPI RefObj_Release(IDispatchEx *iface)
1045 {
1046     return --refobj_ref;
1047 }
1048 
1049 static IDispatchExVtbl RefObjVtbl = {
1050     DispatchEx_QueryInterface,
1051     RefObj_AddRef,
1052     RefObj_Release,
1053     DispatchEx_GetTypeInfoCount,
1054     DispatchEx_GetTypeInfo,
1055     DispatchEx_GetIDsOfNames,
1056     DispatchEx_Invoke,
1057     DispatchEx_GetDispID,
1058     DispatchEx_InvokeEx,
1059     DispatchEx_DeleteMemberByName,
1060     DispatchEx_DeleteMemberByDispID,
1061     DispatchEx_GetMemberProperties,
1062     DispatchEx_GetMemberName,
1063     DispatchEx_GetNextDispID,
1064     DispatchEx_GetNameSpaceParent
1065 };
1066 
1067 static IDispatchEx RefObj = { &RefObjVtbl };
1068 
1069 static ULONG global_ref;
1070 
1071 static ULONG WINAPI Global_AddRef(IDispatchEx *iface)
1072 {
1073     return ++global_ref;
1074 }
1075 
1076 static ULONG WINAPI Global_Release(IDispatchEx *iface)
1077 {
1078     return --global_ref;
1079 }
1080 
1081 static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
1082 {
1083     if(!strcmp_wa(bstrName, "ok")) {
1084         test_grfdex(grfdex, fdexNameCaseInsensitive);
1085         *pid = DISPID_GLOBAL_OK;
1086         return S_OK;
1087     }
1088     if(!strcmp_wa(bstrName, "todo_wine_ok")) {
1089         test_grfdex(grfdex, fdexNameCaseInsensitive);
1090         *pid = DISPID_GLOBAL_TODO_WINE_OK;
1091         return S_OK;
1092     }
1093     if(!strcmp_wa(bstrName, "trace")) {
1094         test_grfdex(grfdex, fdexNameCaseInsensitive);
1095         *pid = DISPID_GLOBAL_TRACE;
1096         return S_OK;
1097     }
1098     if(!strcmp_wa(bstrName, "reportSuccess")) {
1099         CHECK_EXPECT(global_success_d);
1100         test_grfdex(grfdex, fdexNameCaseInsensitive);
1101         *pid = DISPID_GLOBAL_REPORTSUCCESS;
1102         return S_OK;
1103     }
1104     if(!strcmp_wa(bstrName, "getVT")) {
1105         test_grfdex(grfdex, fdexNameCaseInsensitive);
1106         *pid = DISPID_GLOBAL_GETVT;
1107         return S_OK;
1108     }
1109     if(!strcmp_wa(bstrName, "isEnglishLang")) {
1110         test_grfdex(grfdex, fdexNameCaseInsensitive);
1111         *pid = DISPID_GLOBAL_ISENGLANG;
1112         return S_OK;
1113     }
1114     if(!strcmp_wa(bstrName, "firstDayOfWeek")) {
1115         test_grfdex(grfdex, fdexNameCaseInsensitive);
1116         *pid = DISPID_GLOBAL_WEEKSTARTDAY;
1117         return S_OK;
1118     }
1119     if(!strcmp_wa(bstrName, "globalCallback")) {
1120         test_grfdex(grfdex, fdexNameCaseInsensitive);
1121         *pid = DISPID_GLOBAL_GLOBALCALLBACK;
1122         return S_OK;
1123     }
1124     if(!strcmp_wa(bstrName, "testObj")) {
1125         test_grfdex(grfdex, fdexNameCaseInsensitive);
1126         *pid = DISPID_GLOBAL_TESTOBJ;
1127         return S_OK;
1128     }
1129     if(!strcmp_wa(bstrName, "collectionObj")) {
1130         test_grfdex(grfdex, fdexNameCaseInsensitive);
1131         *pid = DISPID_GLOBAL_COLLOBJ;
1132         return S_OK;
1133     }
1134     if(!strcmp_wa(bstrName, "vbvar")) {
1135         CHECK_EXPECT(global_vbvar_d);
1136         test_grfdex(grfdex, fdexNameCaseInsensitive);
1137         *pid = DISPID_GLOBAL_VBVAR;
1138         return S_OK;
1139     }
1140     if(!strcmp_wa(bstrName, "letobj")) {
1141         test_grfdex(grfdex, fdexNameCaseInsensitive);
1142         *pid = DISPID_GLOBAL_LETOBJ;
1143         return S_OK;
1144     }
1145     if(!strcmp_wa(bstrName, "setobj")) {
1146         test_grfdex(grfdex, fdexNameCaseInsensitive);
1147         *pid = DISPID_GLOBAL_SETOBJ;
1148         return S_OK;
1149     }
1150     if(!strcmp_wa(bstrName, "isNullDisp")) {
1151         test_grfdex(grfdex, fdexNameCaseInsensitive);
1152         *pid = DISPID_GLOBAL_ISNULLDISP;
1153         return S_OK;
1154     }
1155     if(!strcmp_wa(bstrName, "testDisp")) {
1156         test_grfdex(grfdex, fdexNameCaseInsensitive);
1157         *pid = DISPID_GLOBAL_TESTDISP;
1158         return S_OK;
1159     }
1160     if(!strcmp_wa(bstrName, "RefObj")) {
1161         test_grfdex(grfdex, fdexNameCaseInsensitive);
1162         *pid = DISPID_GLOBAL_REFOBJ;
1163         return S_OK;
1164     }
1165     if(!strcmp_wa(bstrName, "propargput")) {
1166         CHECK_EXPECT(global_propargput_d);
1167         test_grfdex(grfdex, fdexNameCaseInsensitive);
1168         *pid = DISPID_GLOBAL_PROPARGPUT;
1169         return S_OK;
1170     }
1171     if(!strcmp_wa(bstrName, "propargput1")) {
1172         CHECK_EXPECT(global_propargput1_d);
1173         test_grfdex(grfdex, fdexNameCaseInsensitive);
1174         *pid = DISPID_GLOBAL_PROPARGPUT1;
1175         return S_OK;
1176     }
1177     if(!strcmp_wa(bstrName, "counter")) {
1178         test_grfdex(grfdex, fdexNameCaseInsensitive);
1179         *pid = DISPID_GLOBAL_COUNTER;
1180         return S_OK;
1181     }
1182     if(!strcmp_wa(bstrName, "doubleAsString")) {
1183         test_grfdex(grfdex, fdexNameCaseInsensitive);
1184         *pid = DISPID_GLOBAL_DOUBLEASSTRING;
1185         return S_OK;
1186     }
1187     if(!strcmp_wa(bstrName, "testArray")) {
1188         test_grfdex(grfdex, fdexNameCaseInsensitive);
1189         *pid = DISPID_GLOBAL_TESTARRAY;
1190         return S_OK;
1191     }
1192     if(!strcmp_wa(bstrName, "throwInt")) {
1193         test_grfdex(grfdex, fdexNameCaseInsensitive);
1194         *pid = DISPID_GLOBAL_THROWINT;
1195         return S_OK;
1196     }
1197     if(!strcmp_wa(bstrName, "testOptionalArg")) {
1198         test_grfdex(grfdex, fdexNameCaseInsensitive);
1199         *pid = DISPID_GLOBAL_TESTOPTIONALARG;
1200         return S_OK;
1201     }
1202     if(!strcmp_wa(bstrName, "testErrorObject")) {
1203         test_grfdex(grfdex, fdexNameCaseInsensitive);
1204         *pid = DISPID_GLOBAL_TESTERROROBJECT;
1205         return S_OK;
1206     }
1207 
1208     if(strict_dispid_check && strcmp_wa(bstrName, "x"))
1209         ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
1210     return DISP_E_UNKNOWNNAME;
1211 }
1212 
1213 static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
1214         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
1215 {
1216     switch(id) {
1217     case DISPID_GLOBAL_TODO_WINE_OK:
1218     case DISPID_GLOBAL_OK: {
1219         VARIANT *b;
1220 
1221         ok(wFlags == INVOKE_FUNC || wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
1222         ok(pdp != NULL, "pdp == NULL\n");
1223         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1224         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1225         ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
1226         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1227         if(wFlags & INVOKE_PROPERTYGET)
1228             ok(pvarRes != NULL, "pvarRes == NULL\n");
1229         else
1230             ok(!pvarRes, "pvarRes != NULL\n");
1231         ok(pei != NULL, "pei == NULL\n");
1232 
1233         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
1234 
1235         b = pdp->rgvarg+1;
1236         if(V_VT(b) == (VT_BYREF|VT_VARIANT))
1237             b = V_BYREF(b);
1238 
1239         ok(V_VT(b) == VT_BOOL, "V_VT(b) = %d\n", V_VT(b));
1240 
1241         todo_wine_if(id == DISPID_GLOBAL_TODO_WINE_OK)
1242             ok(V_BOOL(b), "%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
1243         return S_OK;
1244     }
1245 
1246     case DISPID_GLOBAL_TRACE:
1247         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
1248         ok(pdp != NULL, "pdp == NULL\n");
1249         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1250         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1251         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1252         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1253         ok(!pvarRes, "pvarRes != NULL\n");
1254         ok(pei != NULL, "pei == NULL\n");
1255 
1256         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
1257         if(V_VT(pdp->rgvarg) == VT_BSTR)
1258             trace("%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
1259 
1260         return S_OK;
1261 
1262     case DISPID_GLOBAL_REPORTSUCCESS:
1263         CHECK_EXPECT(global_success_i);
1264 
1265         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
1266         ok(pdp != NULL, "pdp == NULL\n");
1267         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1268         ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
1269         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1270         ok(!pvarRes, "pvarRes != NULL\n");
1271         ok(pei != NULL, "pei == NULL\n");
1272 
1273         return S_OK;
1274 
1275     case DISPID_GLOBAL_GETVT:
1276         ok(pdp != NULL, "pdp == NULL\n");
1277         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1278         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1279         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1280         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1281         ok(pvarRes != NULL, "pvarRes == NULL\n");
1282         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1283         ok(pei != NULL, "pei == NULL\n");
1284 
1285         V_VT(pvarRes) = VT_BSTR;
1286         V_BSTR(pvarRes) = a2bstr(vt2a(pdp->rgvarg));
1287         return S_OK;
1288 
1289     case DISPID_GLOBAL_ISENGLANG:
1290         ok(wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
1291         ok(pdp != NULL, "pdp == NULL\n");
1292         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1293         ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
1294         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1295         ok(pvarRes != NULL, "pvarRes == NULL\n");
1296         ok(pei != NULL, "pei == NULL\n");
1297 
1298         V_VT(pvarRes) = VT_BOOL;
1299         V_BOOL(pvarRes) = is_english ? VARIANT_TRUE : VARIANT_FALSE;
1300         return S_OK;
1301 
1302     case DISPID_GLOBAL_WEEKSTARTDAY:
1303         V_VT(pvarRes) = VT_I4;
1304         V_I4(pvarRes) = first_day_of_week;
1305         return S_OK;
1306 
1307     case DISPID_GLOBAL_VBVAR:
1308         CHECK_EXPECT(global_vbvar_i);
1309 
1310         ok(wFlags == DISPATCH_PROPERTYPUT, "wFlags = %x\n", wFlags);
1311         ok(pdp != NULL, "pdp == NULL\n");
1312         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1313         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
1314         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1315         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
1316         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
1317         ok(!pvarRes, "pvarRes != NULL\n");
1318         ok(pei != NULL, "pei == NULL\n");
1319 
1320         ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
1321         ok(V_I2(pdp->rgvarg) == 3, "V_I2(psp->rgvargs) = %d\n", V_I2(pdp->rgvarg));
1322         return S_OK;
1323 
1324     case DISPID_GLOBAL_LETOBJ:
1325         CHECK_EXPECT(global_letobj_i);
1326 
1327         ok(wFlags == DISPATCH_PROPERTYPUT, "wFlags = %x\n", wFlags);
1328         ok(pdp != NULL, "pdp == NULL\n");
1329         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1330         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
1331         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1332         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
1333         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
1334         ok(!pvarRes, "pvarRes != NULL\n");
1335         ok(pei != NULL, "pei == NULL\n");
1336 
1337         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
1338         ok(V_DISPATCH(pdp->rgvarg) == (IDispatch*)&testObj, "V_DISPATCH(psp->rgvargs) != testObj\n");
1339         return S_OK;
1340 
1341     case DISPID_GLOBAL_SETOBJ:
1342         CHECK_EXPECT(global_setobj_i);
1343 
1344         ok(wFlags == DISPATCH_PROPERTYPUTREF, "wFlags = %x\n", wFlags);
1345         ok(pdp != NULL, "pdp == NULL\n");
1346         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1347         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
1348         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1349         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
1350         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
1351         ok(!pvarRes, "pvarRes != NULL\n");
1352         ok(pei != NULL, "pei == NULL\n");
1353 
1354         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
1355         ok(V_DISPATCH(pdp->rgvarg) == (IDispatch*)&testObj, "V_DISPATCH(psp->rgvargs) != testObj\n");
1356         return S_OK;
1357 
1358     case DISPID_GLOBAL_TESTOBJ:
1359         ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
1360 
1361         ok(pdp != NULL, "pdp == NULL\n");
1362         ok(!pdp->rgvarg, "rgvarg != NULL\n");
1363         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1364         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
1365         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1366         ok(pvarRes != NULL, "pvarRes == NULL\n");
1367         ok(pei != NULL, "pei == NULL\n");
1368 
1369         V_VT(pvarRes) = VT_DISPATCH;
1370         V_DISPATCH(pvarRes) = (IDispatch*)&testObj;
1371         return S_OK;
1372 
1373     case DISPID_GLOBAL_COLLOBJ:
1374         ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
1375 
1376         ok(pdp != NULL, "pdp == NULL\n");
1377         ok(!pdp->rgvarg, "rgvarg != NULL\n");
1378         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1379         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
1380         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1381         ok(pvarRes != NULL, "pvarRes == NULL\n");
1382         ok(pei != NULL, "pei == NULL\n");
1383 
1384         V_VT(pvarRes) = VT_DISPATCH;
1385         V_DISPATCH(pvarRes) = (IDispatch*)&collectionObj;
1386         return S_OK;
1387 
1388     case DISPID_GLOBAL_REFOBJ:
1389         ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
1390 
1391         ok(pdp != NULL, "pdp == NULL\n");
1392         ok(!pdp->rgvarg, "rgvarg == NULL\n");
1393         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1394         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
1395         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1396         ok(pvarRes != NULL, "pvarRes == NULL\n");
1397         ok(pei != NULL, "pei == NULL\n");
1398 
1399         IDispatchEx_AddRef(&RefObj);
1400         V_VT(pvarRes) = VT_DISPATCH;
1401         V_DISPATCH(pvarRes) = (IDispatch*)&RefObj;
1402         return S_OK;
1403 
1404     case DISPID_GLOBAL_ISNULLDISP: {
1405         VARIANT *v;
1406 
1407         ok(wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
1408         ok(pdp != NULL, "pdp == NULL\n");
1409         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1410         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1411         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1412         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1413         ok(pvarRes != NULL, "pvarRes == NULL\n");
1414         ok(pei != NULL, "pei == NULL\n");
1415 
1416         v = pdp->rgvarg;
1417         if(V_VT(v) == (VT_VARIANT|VT_BYREF))
1418             v = V_VARIANTREF(v);
1419 
1420         ok(V_VT(v) == VT_DISPATCH, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
1421         V_VT(pvarRes) = VT_BOOL;
1422         V_BOOL(pvarRes) = V_DISPATCH(v) ? VARIANT_FALSE : VARIANT_TRUE;
1423         return S_OK;
1424     }
1425 
1426     case DISPID_GLOBAL_TESTDISP:
1427         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
1428         ok(pdp != NULL, "pdp == NULL\n");
1429         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1430         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1431         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1432         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1433         ok(!pvarRes, "pvarRes != NULL\n");
1434         ok(pei != NULL, "pei == NULL\n");
1435 
1436         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
1437         test_disp(V_DISPATCH(pdp->rgvarg));
1438         return S_OK;
1439 
1440     case DISPID_GLOBAL_PROPARGPUT:
1441         CHECK_EXPECT(global_propargput_i);
1442 
1443         ok(wFlags == DISPATCH_PROPERTYPUT, "wFlags = %x\n", wFlags);
1444         ok(pdp != NULL, "pdp == NULL\n");
1445         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1446         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
1447         ok(pdp->cArgs == 3, "cArgs = %d\n", pdp->cArgs);
1448         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
1449         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
1450         ok(!pvarRes, "pvarRes != NULL\n");
1451         ok(pei != NULL, "pei == NULL\n");
1452 
1453         ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
1454         ok(V_I2(pdp->rgvarg) == 0, "V_I2(psp->rgvargs) = %d\n", V_I2(pdp->rgvarg));
1455 
1456         ok(V_VT(pdp->rgvarg+1) == VT_I2, "V_VT(psp->rgvargs+1) = %d\n", V_VT(pdp->rgvarg+1));
1457         ok(V_I2(pdp->rgvarg+1) == 2, "V_I2(psp->rgvargs+1) = %d\n", V_I2(pdp->rgvarg+1));
1458 
1459         ok(V_VT(pdp->rgvarg+2) == VT_I2, "V_VT(psp->rgvargs+2) = %d\n", V_VT(pdp->rgvarg+2));
1460         ok(V_I2(pdp->rgvarg+2) == 1, "V_I2(psp->rgvargs+2) = %d\n", V_I2(pdp->rgvarg+2));
1461         return S_OK;
1462 
1463     case DISPID_GLOBAL_PROPARGPUT1:
1464         CHECK_EXPECT(global_propargput1_i);
1465 
1466         ok(wFlags == DISPATCH_PROPERTYPUT, "wFlags = %x\n", wFlags);
1467         ok(pdp != NULL, "pdp == NULL\n");
1468         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1469         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
1470         ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
1471         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
1472         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
1473         ok(!pvarRes, "pvarRes != NULL\n");
1474         ok(pei != NULL, "pei == NULL\n");
1475 
1476         ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
1477         ok(V_I2(pdp->rgvarg) == 0, "V_I2(psp->rgvargs) = %d\n", V_I2(pdp->rgvarg));
1478 
1479         ok(V_VT(pdp->rgvarg+1) == VT_I2, "V_VT(psp->rgvargs+1) = %d\n", V_VT(pdp->rgvarg+1));
1480         ok(V_I2(pdp->rgvarg+1) == 1, "V_I2(psp->rgvargs+1) = %d\n", V_I2(pdp->rgvarg+1));
1481 
1482         return S_OK;
1483 
1484     case DISPID_GLOBAL_COUNTER:
1485         ok(pdp != NULL, "pdp == NULL\n");
1486         todo_wine ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1487         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1488         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
1489         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1490         ok(pvarRes != NULL, "pvarRes == NULL\n");
1491         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1492         ok(pei != NULL, "pei == NULL\n");
1493 
1494         V_VT(pvarRes) = VT_I2;
1495         V_I2(pvarRes) = test_counter++;
1496         return S_OK;
1497 
1498     case DISPID_GLOBAL_DOUBLEASSTRING:
1499         ok(wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
1500         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1501         ok(V_VT(pdp->rgvarg) == VT_R8, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
1502         ok(pvarRes != NULL, "pvarRes == NULL\n");
1503 
1504         V_VT(pvarRes) = VT_BSTR;
1505         return VarBstrFromR8(V_R8(pdp->rgvarg), 0, 0, &V_BSTR(pvarRes));
1506 
1507     case DISPID_GLOBAL_TESTARRAY:
1508         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
1509         ok(pdp != NULL, "pdp == NULL\n");
1510         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1511         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1512         ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
1513         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1514         ok(!pvarRes, "pvarRes != NULL\n");
1515         ok(pei != NULL, "pei == NULL\n");
1516 
1517         ok(V_VT(pdp->rgvarg+1) == VT_I2, "V_VT(psp->rgvargs+1) = %d\n", V_VT(pdp->rgvarg+1));
1518         ok(V_VT(pdp->rgvarg) == (VT_BYREF|VT_VARIANT), "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
1519         ok(V_VT(V_VARIANTREF(pdp->rgvarg)) == (VT_ARRAY|VT_BYREF|VT_VARIANT),
1520            "V_VT(V_VARIANTREF(psp->rgvargs)) = %d\n", V_VT(V_VARIANTREF(pdp->rgvarg)));
1521         if(V_I2(pdp->rgvarg+1) == -1)
1522             ok(!*V_ARRAYREF(V_VARIANTREF(pdp->rgvarg)), "*V_ARRAYREF(V_VARIANTREF(pdp->rgvarg)) != NULL\n");
1523         else
1524             test_safearray(*V_ARRAYREF(V_VARIANTREF(pdp->rgvarg)), V_I2(pdp->rgvarg+1));
1525         return S_OK;
1526 
1527     case DISPID_GLOBAL_THROWINT: {
1528         VARIANT *v = pdp->rgvarg;
1529         HRESULT hres;
1530 
1531         ok((wFlags & ~INVOKE_PROPERTYGET) == INVOKE_FUNC, "wFlags = %x\n", wFlags);
1532         ok(pdp != NULL, "pdp == NULL\n");
1533         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1534         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1535         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1536         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1537         ok(pei != NULL, "pei == NULL\n");
1538         if(pvarRes) {
1539             ok(V_VT(pvarRes) == VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
1540             V_VT(pvarRes) = VT_BOOL;
1541             V_BOOL(pvarRes) = VARIANT_FALSE;
1542         }
1543 
1544         if(V_VT(v) == (VT_VARIANT|VT_BYREF))
1545             v = V_VARIANTREF(v);
1546 
1547         switch(V_VT(v)) {
1548         case VT_I2:
1549             hres = V_I2(v);
1550             break;
1551         case VT_I4:
1552             hres = V_I4(v);
1553             break;
1554         default:
1555             ok(0, "unexpected vt %d\n", V_VT(v));
1556             return E_INVALIDARG;
1557         }
1558 
1559         return hres;
1560     }
1561 
1562     case DISPID_GLOBAL_TESTOPTIONALARG: {
1563         VARIANT *v;
1564         int opt;
1565 
1566         CHECK_EXPECT(global_testoptionalarg_i);
1567 
1568         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
1569         ok(pdp != NULL, "pdp == NULL\n");
1570         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1571         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1572         ok(pdp->cArgs == 3, "cArgs = %d\n", pdp->cArgs);
1573         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1574         ok(!pvarRes, "pvarRes != NULL\n");
1575         ok(pei != NULL, "pei == NULL\n");
1576 
1577         ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
1578         opt = V_I2(pdp->rgvarg);
1579         ok(opt == 1 || opt == 2, "opt = %d\n", opt);
1580         v = pdp->rgvarg+pdp->cArgs-opt;
1581         ok(V_VT(v) == VT_ERROR, "V_VT(v) = %d\n", V_VT(v));
1582         ok(V_ERROR(v) == DISP_E_PARAMNOTFOUND, "V_ERROR(v) = %08x\n", V_ERROR(v));
1583         return S_OK;
1584     }
1585     case DISPID_GLOBAL_GLOBALCALLBACK: {
1586         DISPPARAMS dp = {0};
1587         IDispatchEx *dispex;
1588         EXCEPINFO ei;
1589         VARIANT v;
1590         DISPID id;
1591         BSTR str;
1592         HRESULT hres;
1593 
1594         CHECK_EXPECT(global_globalcallback_i);
1595         CHECK_CALLED(OnEnterScript);
1596 
1597         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
1598         ok(pdp != NULL, "pdp == NULL\n");
1599         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1600         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
1601         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1602         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1603         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1604         ok(!pvarRes, "pvarRes != NULL\n");
1605         ok(pei != NULL, "pei == NULL\n");
1606 
1607         hres = IDispatch_QueryInterface(V_DISPATCH(pdp->rgvarg), &IID_IDispatchEx, (void**)&dispex);
1608         ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
1609 
1610         str = SysAllocString(L"callback");
1611         hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id);
1612         ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
1613         SysFreeString(str);
1614 
1615         SET_EXPECT(OnEnterScript);
1616         SET_EXPECT(OnLeaveScript);
1617         memset(&ei, 0, sizeof(ei));
1618         hres = IDispatchEx_InvokeEx(dispex, id, 0, DISPATCH_METHOD, &dp, &v, &ei, pspCaller);
1619         ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1620         CHECK_CALLED(OnEnterScript);
1621         CHECK_CALLED(OnLeaveScript);
1622         ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
1623         ok(V_BOOL(&v) == VARIANT_TRUE, "V_BOOL(v) = %x\n", V_BOOL(&v));
1624 
1625         IDispatchEx_Release(dispex);
1626 
1627         SET_EXPECT(OnLeaveScript);
1628         return S_OK;
1629     }
1630     case DISPID_GLOBAL_TESTERROROBJECT: {
1631         ITypeInfo *typeinfo;
1632         IDispatchEx *dispex;
1633         DISPPARAMS dp;
1634         VARIANT v, r;
1635         EXCEPINFO ei;
1636         IDispatch *disp;
1637         WCHAR *names[1];
1638         UINT count, i;
1639         DISPID id;
1640         HRESULT hres;
1641 
1642         static WCHAR props[][32] = { L"clear", L"description", L"helpcontext", L"helpFILE", L"number", L"raise", L"source" };
1643 
1644         CHECK_EXPECT(global_testerrorobject_i);
1645 
1646         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
1647         ok(pdp != NULL, "pdp == NULL\n");
1648         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
1649         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
1650         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
1651         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
1652         ok(!pvarRes, "pvarRes != NULL\n");
1653         ok(pei != NULL, "pei == NULL\n");
1654 
1655         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
1656         disp = V_DISPATCH(pdp->rgvarg);
1657         hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
1658         ok(hres == E_NOINTERFACE, "Could not get IDispatchEx iface: %08x\n", hres);
1659 
1660         hres = IDispatch_GetTypeInfoCount(disp, &count);
1661         ok(hres == S_OK, "GetTypeInfoCount returned: %08x\n", hres);
1662         ok(count == 0, "count = %u\n", count);
1663 
1664         hres = IDispatch_GetTypeInfo(disp, 0, 0, &typeinfo);
1665         ok(hres == DISP_E_BADINDEX, "GetTypeInfo returned: %08x\n", hres);
1666 
1667         for(i = 0; i < ARRAY_SIZE(props); i++) {
1668             names[0] = props[i];
1669             hres = IDispatch_GetIDsOfNames(disp, &IID_NULL, names, 1, 0, &id);
1670             ok(hres == S_OK, "GetIDsOfNames failed: %08x\n", hres);
1671             ok(id == i + 1, "%s id = %u\n", wine_dbgstr_w(props[i]), id);
1672         }
1673 
1674         memset(&dp, 0, sizeof(dp));
1675         memset(&ei, 0, sizeof(ei));
1676         V_VT(&v) = VT_ERROR;
1677         hres = IDispatch_Invoke(disp, 5, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
1678         ok(hres == S_OK, "Invoke failed: %08x\n", hres);
1679         ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
1680         ok(V_I4(&v) == 1, "V_I4(v) = %d\n", V_I4(&v));
1681         hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
1682         ok(hres == S_OK, "Invoke failed: %08x\n", hres);
1683         ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
1684         ok(V_I4(&v) == 1, "V_I4(v) = %d\n", V_I4(&v));
1685 
1686         dp.rgvarg = &v;
1687         V_VT(&v) = VT_I4;
1688         V_I4(&v) = 6;
1689         V_VT(&r) = VT_EMPTY;
1690         hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 6, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dp, &r, &ei, NULL);
1691         ok(hres == S_OK, "Invoke failed: %08x\n", hres);
1692         return S_OK;
1693     }
1694     }
1695 
1696     ok(0, "unexpected call %d\n", id);
1697     return DISP_E_MEMBERNOTFOUND;
1698 }
1699 
1700 static IDispatchExVtbl GlobalVtbl = {
1701     DispatchEx_QueryInterface,
1702     Global_AddRef,
1703     Global_Release,
1704     DispatchEx_GetTypeInfoCount,
1705     DispatchEx_GetTypeInfo,
1706     DispatchEx_GetIDsOfNames,
1707     DispatchEx_Invoke,
1708     Global_GetDispID,
1709     Global_InvokeEx,
1710     DispatchEx_DeleteMemberByName,
1711     DispatchEx_DeleteMemberByDispID,
1712     DispatchEx_GetMemberProperties,
1713     DispatchEx_GetMemberName,
1714     DispatchEx_GetNextDispID,
1715     DispatchEx_GetNameSpaceParent
1716 };
1717 
1718 static IDispatchEx Global = { &GlobalVtbl };
1719 
1720 static HRESULT WINAPI ActiveScriptSiteWindow_QueryInterface(IActiveScriptSiteWindow *iface, REFIID riid, void **ppv)
1721 {
1722     ok(0, "unexpected call\n");
1723     return E_NOINTERFACE;
1724 }
1725 
1726 static ULONG WINAPI ActiveScriptSiteWindow_AddRef(IActiveScriptSiteWindow *iface)
1727 {
1728     return 2;
1729 }
1730 
1731 static ULONG WINAPI ActiveScriptSiteWindow_Release(IActiveScriptSiteWindow *iface)
1732 {
1733     return 1;
1734 }
1735 
1736 static HRESULT WINAPI ActiveScriptSiteWindow_GetWindow(IActiveScriptSiteWindow *iface, HWND *phwnd)
1737 {
1738     if(!allow_ui)
1739         CHECK_EXPECT(GetWindow);
1740     *phwnd = NULL;
1741     return S_OK;
1742 }
1743 
1744 static HRESULT WINAPI ActiveScriptSiteWindow_EnableModeless(IActiveScriptSiteWindow *iface, BOOL fEnable)
1745 {
1746     if(allow_ui)
1747         return S_OK;
1748 
1749     CHECK_EXPECT(EnableModeless);
1750     ok(!fEnable, "fEnable = %x\n", fEnable);
1751     return E_FAIL;
1752 }
1753 
1754 static const IActiveScriptSiteWindowVtbl ActiveScriptSiteWindowVtbl = {
1755     ActiveScriptSiteWindow_QueryInterface,
1756     ActiveScriptSiteWindow_AddRef,
1757     ActiveScriptSiteWindow_Release,
1758     ActiveScriptSiteWindow_GetWindow,
1759     ActiveScriptSiteWindow_EnableModeless
1760 };
1761 
1762 static IActiveScriptSiteWindow ActiveScriptSiteWindow = { &ActiveScriptSiteWindowVtbl };
1763 
1764 static HRESULT WINAPI ActiveScriptSiteUIControl_QueryInterface(IActiveScriptSiteUIControl *iface, REFIID riid, void **ppv)
1765 {
1766     ok(0, "unexpected call\n");
1767     return E_NOINTERFACE;
1768 }
1769 
1770 static ULONG WINAPI ActiveScriptSiteUIControl_AddRef(IActiveScriptSiteUIControl *iface)
1771 {
1772     return 2;
1773 }
1774 
1775 static ULONG WINAPI ActiveScriptSiteUIControl_Release(IActiveScriptSiteUIControl *iface)
1776 {
1777     return 1;
1778 }
1779 
1780 static HRESULT WINAPI ActiveScriptSiteUIControl_GetUIBehavior(IActiveScriptSiteUIControl *iface, SCRIPTUICITEM UicItem,
1781         SCRIPTUICHANDLING *pUicHandling)
1782 {
1783     if(!allow_ui) {
1784         CHECK_EXPECT(GetUIBehavior);
1785         ok(UicItem == SCRIPTUICITEM_MSGBOX, "UidItem = %d\n", UicItem);
1786     }
1787     *pUicHandling = uic_handling;
1788     return S_OK;
1789 }
1790 
1791 static const IActiveScriptSiteUIControlVtbl ActiveScriptSiteUIControlVtbl = {
1792     ActiveScriptSiteUIControl_QueryInterface,
1793     ActiveScriptSiteUIControl_AddRef,
1794     ActiveScriptSiteUIControl_Release,
1795     ActiveScriptSiteUIControl_GetUIBehavior
1796 };
1797 
1798 static IActiveScriptSiteUIControl ActiveScriptSiteUIControl = { &ActiveScriptSiteUIControlVtbl };
1799 
1800 static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
1801 {
1802     *ppv = NULL;
1803 
1804     if(IsEqualGUID(&IID_IUnknown, riid))
1805         *ppv = iface;
1806     else if(IsEqualGUID(&IID_IActiveScriptSite, riid))
1807         *ppv = iface;
1808     else if(IsEqualGUID(&IID_IActiveScriptSiteWindow, riid))
1809         *ppv = &ActiveScriptSiteWindow;
1810     else if(IsEqualGUID(&IID_IActiveScriptSiteUIControl, riid))
1811         *ppv = &ActiveScriptSiteUIControl;
1812     else
1813         return E_NOINTERFACE;
1814 
1815     IUnknown_AddRef((IUnknown*)*ppv);
1816     return S_OK;
1817 }
1818 
1819 static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
1820 {
1821     return 2;
1822 }
1823 
1824 static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
1825 {
1826     return 1;
1827 }
1828 
1829 static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *plcid)
1830 {
1831     *plcid = GetUserDefaultLCID();
1832     return S_OK;
1833 }
1834 
1835 static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR pstrName,
1836         DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti)
1837 {
1838     ok(dwReturnMask == SCRIPTINFO_IUNKNOWN, "unexpected dwReturnMask %x\n", dwReturnMask);
1839     ok(!ppti, "ppti != NULL\n");
1840 
1841     if(strcmp_wa(pstrName, "test"))
1842         ok(0, "unexpected pstrName %s\n", wine_dbgstr_w(pstrName));
1843 
1844     *ppiunkItem = (IUnknown*)&Global;
1845     IUnknown_AddRef(*ppiunkItem);
1846     return S_OK;
1847 }
1848 
1849 static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *pbstrVersion)
1850 {
1851     return E_NOTIMPL;
1852 }
1853 
1854 static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface,
1855         const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo)
1856 {
1857     return E_NOTIMPL;
1858 }
1859 
1860 static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE ssScriptState)
1861 {
1862     return E_NOTIMPL;
1863 }
1864 
1865 static IActiveScriptError **store_script_error;
1866 
1867 static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
1868 {
1869     HRESULT hr = onerror_hres, hres;
1870 
1871     if(!expect_OnScriptError) {
1872         EXCEPINFO info;
1873         ULONG line;
1874         HRESULT hres;
1875 
1876         hres = IActiveScriptError_GetSourcePosition(pscripterror, NULL, &line, NULL);
1877         if(SUCCEEDED(hres))
1878             hres = IActiveScriptError_GetExceptionInfo(pscripterror, &info);
1879         if(SUCCEEDED(hres))
1880             trace("Error in line %u: %x %s\n", line+1, info.wCode, wine_dbgstr_w(info.bstrDescription));
1881     }else {
1882         IDispatchEx *dispex;
1883 
1884         hres = IActiveScriptError_QueryInterface(pscripterror, &IID_IDispatchEx, (void**)&dispex);
1885         ok(hres == E_NOINTERFACE, "QI(IDispatchEx) returned: %08x\n", hres);
1886     }
1887 
1888     if(store_script_error) {
1889         IActiveScriptError_AddRef(pscripterror);
1890         *store_script_error = pscripterror;
1891         store_script_error = NULL;
1892     }
1893 
1894     CHECK_EXPECT(OnScriptError);
1895     onerror_hres = E_NOTIMPL;
1896 
1897     return hr;
1898 }
1899 
1900 static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
1901 {
1902     if(strict_enter_script)
1903         CHECK_EXPECT(OnEnterScript);
1904     return E_NOTIMPL;
1905 }
1906 
1907 static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
1908 {
1909     if(strict_enter_script)
1910         CHECK_EXPECT(OnLeaveScript);
1911     return E_NOTIMPL;
1912 }
1913 
1914 static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
1915     ActiveScriptSite_QueryInterface,
1916     ActiveScriptSite_AddRef,
1917     ActiveScriptSite_Release,
1918     ActiveScriptSite_GetLCID,
1919     ActiveScriptSite_GetItemInfo,
1920     ActiveScriptSite_GetDocVersionString,
1921     ActiveScriptSite_OnScriptTerminate,
1922     ActiveScriptSite_OnStateChange,
1923     ActiveScriptSite_OnScriptError,
1924     ActiveScriptSite_OnEnterScript,
1925     ActiveScriptSite_OnLeaveScript
1926 };
1927 
1928 static IActiveScriptSite ActiveScriptSite = { &ActiveScriptSiteVtbl };
1929 
1930 static IActiveScript *create_script(void)
1931 {
1932     IActiveScript *script;
1933     HRESULT hres;
1934 
1935     hres = CoCreateInstance(&CLSID_VBScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1936             &IID_IActiveScript, (void**)&script);
1937     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
1938 
1939     return script;
1940 }
1941 
1942 static IActiveScript *create_and_init_script(DWORD flags, BOOL start)
1943 {
1944     IActiveScriptParse *parser;
1945     IActiveScript *engine;
1946     HRESULT hres;
1947 
1948     engine = create_script();
1949     if(!engine)
1950         return NULL;
1951 
1952     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
1953     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1954 
1955     hres = IActiveScriptParse_InitNew(parser);
1956     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
1957 
1958     IActiveScriptParse_Release(parser);
1959 
1960     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
1961     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
1962 
1963     hres = IActiveScript_AddNamedItem(engine, testW,
1964             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|flags);
1965     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
1966 
1967     if (start)
1968     {
1969         hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
1970         ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
1971     }
1972 
1973     return engine;
1974 }
1975 
1976 static void close_script(IActiveScript *script)
1977 {
1978     ULONG ref;
1979     HRESULT hres;
1980 
1981     hres = IActiveScript_Close(script);
1982     ok(hres == S_OK, "Close failed: %08x\n", hres);
1983 
1984     ref = IActiveScript_Release(script);
1985     ok(!ref, "ref=%u\n", ref);
1986 }
1987 
1988 static HRESULT parse_script(DWORD flags, BSTR script_str, const WCHAR *delim)
1989 {
1990     IActiveScriptParse *parser;
1991     IActiveScript *engine;
1992     IDispatch *script_disp;
1993     LONG ref;
1994     HRESULT hres;
1995 
1996     engine = create_and_init_script(flags, TRUE);
1997     if(!engine)
1998         return S_OK;
1999 
2000     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
2001     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
2002     if (FAILED(hres))
2003     {
2004         IActiveScript_Release(engine);
2005         return hres;
2006     }
2007 
2008     hres = IActiveScript_GetScriptDispatch(engine, NULL, &script_disp);
2009     ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres);
2010     ok(script_disp != NULL, "script_disp == NULL\n");
2011     ok(script_disp != (IDispatch*)&Global, "script_disp == Global\n");
2012 
2013     test_counter = 0;
2014 
2015     hres = IActiveScriptParse_ParseScriptText(parser, script_str, NULL, NULL, delim, 0, 0, 0, NULL, NULL);
2016 
2017     IActiveScript_Close(engine);
2018 
2019     IDispatch_Release(script_disp);
2020     IActiveScript_Release(engine);
2021 
2022     ref = IActiveScriptParse_Release(parser);
2023     ok(!ref, "ref=%d\n", ref);
2024     return hres;
2025 }
2026 
2027 static void parse_script_af(DWORD flags, const char *src)
2028 {
2029     BSTR tmp;
2030     HRESULT hres;
2031 
2032     tmp = a2bstr(src);
2033     hres = parse_script(flags, tmp, NULL);
2034     SysFreeString(tmp);
2035     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
2036 }
2037 
2038 static HRESULT parse_script_ar(const char *src)
2039 {
2040     BSTR tmp;
2041     HRESULT hres;
2042 
2043     tmp = a2bstr(src);
2044     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, tmp, NULL);
2045     SysFreeString(tmp);
2046     return hres;
2047 }
2048 
2049 static void test_parse_context(void)
2050 {
2051     IActiveScriptParse *parser;
2052     IActiveScript *engine;
2053     BSTR str;
2054     HRESULT hres;
2055 
2056     static const WCHAR xW[] = {'x',0};
2057     static const WCHAR yW[] = {'y',0};
2058 
2059     global_ref = 1;
2060     engine = create_and_init_script(0, TRUE);
2061     if(!engine)
2062         return;
2063 
2064     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
2065     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
2066 
2067     /* NULL code text succeeds but does nothing */
2068     hres = IActiveScriptParse_ParseScriptText(parser, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
2069     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2070 
2071     /* unknown identifier context is not a valid argument */
2072     str = a2bstr("Call reportSuccess()\n");
2073     hres = IActiveScriptParse_ParseScriptText(parser, str, yW, NULL, NULL, 0, 0, 0, NULL, NULL);
2074     ok(hres == E_INVALIDARG, "ParseScriptText failed: %08x\n", hres);
2075     SysFreeString(str);
2076 
2077     str = a2bstr("class Cl\n"
2078                  "    Public Sub ClMethod\n"
2079                  "        Call reportSuccess()\n"
2080                  "    End Sub\n"
2081                  "End Class\n"
2082                  "Dim x\n"
2083                  "set x = new Cl\n");
2084     hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
2085     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2086     SysFreeString(str);
2087 
2088     /* known global variable is not a valid context */
2089     str = a2bstr("Call reportSuccess()\n");
2090     hres = IActiveScriptParse_ParseScriptText(parser, str, xW, NULL, NULL, 0, 0, 0, NULL, NULL);
2091     ok(hres == E_INVALIDARG, "ParseScriptText failed: %08x\n", hres);
2092     SysFreeString(str);
2093 
2094     SET_EXPECT(global_success_d);
2095     SET_EXPECT(global_success_i);
2096     str = a2bstr("Call reportSuccess()\n");
2097     hres = IActiveScriptParse_ParseScriptText(parser, str, testW, NULL, NULL, 0, 0, 0, NULL, NULL);
2098     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2099     SysFreeString(str);
2100     CHECK_CALLED(global_success_d);
2101     CHECK_CALLED(global_success_i);
2102 
2103     IActiveScriptParse_Release(parser);
2104     close_script(engine);
2105     ok(global_ref == 1, "global_ref = %u\n", global_ref);
2106 }
2107 
2108 static void parse_script_a(const char *src)
2109 {
2110     parse_script_af(SCRIPTITEM_GLOBALMEMBERS, src);
2111 }
2112 
2113 #define parse_htmlscript_a(a) _parse_htmlscript_a(__LINE__,a)
2114 static void _parse_htmlscript_a(unsigned line, const char *src)
2115 {
2116     BSTR tmp;
2117     HRESULT hres;
2118 
2119     static const WCHAR script_delimW[] = {'<','/','S','C','R','I','P','T','>',0};
2120 
2121     tmp = a2bstr(src);
2122     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, tmp, script_delimW);
2123     SysFreeString(tmp);
2124     ok_(__FILE__,line)(hres == S_OK, "parse_script failed: %08x\n", hres);
2125 }
2126 
2127 static IDispatchEx *parse_procedure(IActiveScriptParseProcedure2 *parse_proc, const char *src, DWORD flags)
2128 {
2129     IDispatchEx *dispex;
2130     IDispatch *disp;
2131     BSTR str;
2132     HRESULT hres;
2133 
2134     static const WCHAR delimiterW[] = {'\"',0};
2135 
2136     str = a2bstr(src);
2137     hres = IActiveScriptParseProcedure2_ParseProcedureText(parse_proc, str, NULL, emptyW, NULL, NULL, delimiterW, 0, 0,
2138             SCRIPTPROC_HOSTMANAGESSOURCE|SCRIPTPROC_IMPLICIT_THIS|SCRIPTPROC_IMPLICIT_PARENTS|flags, &disp);
2139     SysFreeString(str);
2140     ok(hres == S_OK, "ParseProcedureText failed: %08x\n", hres);
2141     ok(disp != NULL, "disp = NULL\n");
2142 
2143     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
2144     IDispatch_Release(disp);
2145     ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
2146 
2147     return dispex;
2148 }
2149 
2150 
2151 static void test_procedures(void)
2152 {
2153     IActiveScriptParseProcedure2 *parse_proc;
2154     DISPPARAMS dp = {NULL};
2155     IActiveScript *script;
2156     IDispatchEx *proc;
2157     IDispatch *disp;
2158     EXCEPINFO ei = {0};
2159     VARIANT v;
2160     HRESULT hres;
2161 
2162     strict_enter_script = TRUE;
2163     script = create_and_init_script(0, TRUE);
2164 
2165     hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParseProcedure2, (void**)&parse_proc);
2166     ok(hres == S_OK, "Could not get IActiveScriptParseProcedure2 iface: %08x\n", hres);
2167 
2168     hres = IActiveScriptParseProcedure2_ParseProcedureText(parse_proc, NULL, NULL, emptyW, NULL, NULL, NULL, 0, 0, 0, &disp);
2169     ok(hres == S_OK, "ParseProcedureText failed: %08x\n", hres);
2170     IDispatch_Release(disp);
2171 
2172     proc = parse_procedure(parse_proc, "dim x\nif true then x=false", 0);
2173 
2174     SET_EXPECT(OnEnterScript);
2175     SET_EXPECT(OnLeaveScript);
2176     V_VT(&v) = VT_EMPTY;
2177     hres = IDispatchEx_InvokeEx(proc, DISPID_VALUE, 0, DISPATCH_METHOD, &dp, &v, &ei, &caller_sp);
2178     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2179     CHECK_CALLED(OnEnterScript);
2180     CHECK_CALLED(OnLeaveScript);
2181     VariantClear(&v);
2182     IDispatchEx_Release(proc);
2183 
2184     proc = parse_procedure(parse_proc, "\"foobar\"", SCRIPTPROC_ISEXPRESSION);
2185 
2186     SET_EXPECT(OnEnterScript);
2187     SET_EXPECT(OnLeaveScript);
2188     hres = IDispatchEx_InvokeEx(proc, DISPID_VALUE, 0, DISPATCH_METHOD, &dp, &v, &ei, &caller_sp);
2189     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2190     CHECK_CALLED(OnEnterScript);
2191     CHECK_CALLED(OnLeaveScript);
2192     ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR, got %s\n", vt2a(&v));
2193     ok(!strcmp_wa(V_BSTR(&v), "foobar"), "Wrong string, got %s\n", wine_dbgstr_w(V_BSTR(&v)));
2194     VariantClear(&v);
2195     IDispatchEx_Release(proc);
2196 
2197     IActiveScriptParseProcedure2_Release(parse_proc);
2198 
2199     close_script(script);
2200     strict_enter_script = FALSE;
2201 }
2202 
2203 static void free_ei(EXCEPINFO *ei)
2204 {
2205     SysFreeString(ei->bstrSource);
2206     SysFreeString(ei->bstrDescription);
2207     SysFreeString(ei->bstrHelpFile);
2208 }
2209 
2210 static void test_callbacks(void)
2211 {
2212     IActiveScriptError *error1, *error2;
2213     IActiveScriptParse *parser;
2214     DISPPARAMS dp = {NULL};
2215     IActiveScript *script;
2216     IDispatchEx *dispex;
2217     IDispatch *disp;
2218     DISPID id;
2219     EXCEPINFO ei = {0};
2220     BSTR str;
2221     VARIANT v;
2222     HRESULT hres;
2223 
2224     strict_enter_script = TRUE;
2225     script = create_and_init_script(SCRIPTITEM_GLOBALMEMBERS, TRUE);
2226 
2227     hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParse, (void**)&parser);
2228     ok(hres == S_OK, "Could not get IActiveScriptParseProcedure2 iface: %08x\n", hres);
2229 
2230     SET_EXPECT(OnEnterScript);
2231     SET_EXPECT(OnLeaveScript);
2232     hres = IActiveScriptParse_ParseScriptText(parser,
2233                                               L"class CallbackClass\n"
2234                                               L"    public function callback()\n"
2235                                               L"        call ok(err.number = 2, \"err.number = \" & err.number)\n"
2236                                               L"        callback = true\n"
2237                                               L"    end function\n"
2238                                               L"end class\n"
2239                                               L"function callGlobalCallback()\n"
2240                                               L"    on error resume next\n"
2241                                               L"    err.raise 2\n"
2242                                               L"    call test.globalCallback(new CallbackClass)\n"
2243                                               L"    call ok(err.number = 2, \"err.number = \" & err.numner)\n"
2244                                               L"end function\n",
2245                                               NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
2246     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2247     CHECK_CALLED(OnEnterScript);
2248     CHECK_CALLED(OnLeaveScript);
2249 
2250     hres = IActiveScript_GetScriptDispatch(script, NULL, &disp);
2251     ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres);
2252 
2253     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
2254     ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
2255     IDispatch_Release(disp);
2256 
2257     str = SysAllocString(L"callGlobalCallback");
2258     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id);
2259     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
2260     SysFreeString(str);
2261 
2262     SET_EXPECT(OnEnterScript);
2263     /* OnLeaveScript will be set in global callback */
2264     SET_EXPECT(global_globalcallback_i);
2265     hres = IDispatchEx_InvokeEx(dispex, id, 0, DISPATCH_METHOD, &dp, &v, &ei, &caller_sp);
2266     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
2267     /* OnEnterScript was checked in global callback */
2268     CHECK_CALLED(OnLeaveScript);
2269     CHECK_CALLED(global_globalcallback_i);
2270 
2271     store_script_error = &error1;
2272 
2273     SET_EXPECT(OnEnterScript);
2274     SET_EXPECT(OnLeaveScript);
2275     SET_EXPECT(OnScriptError);
2276     hres = IActiveScriptParse_ParseScriptText(parser, L"err.raise 2\n",
2277                                               NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
2278     ok(hres == MAKE_VBSERROR(2), "ParseScriptText failed: %08x\n", hres);
2279     CHECK_CALLED(OnEnterScript);
2280     CHECK_CALLED(OnLeaveScript);
2281     CHECK_CALLED(OnScriptError);
2282 
2283     store_script_error = &error2;
2284 
2285     SET_EXPECT(OnEnterScript);
2286     SET_EXPECT(OnLeaveScript);
2287     SET_EXPECT(OnScriptError);
2288     hres = IActiveScriptParse_ParseScriptText(parser,
2289                                               L"call ok(err.number = 0, \"err.number = \" & err.number)\n"
2290                                               L"err.raise &h86664004&, \"src\", \"desc\", \"help\", 1\n",
2291                                               NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
2292     ok(hres == SCRIPT_E_RECORDED, "ParseScriptText failed: %08x\n", hres);
2293     CHECK_CALLED(OnEnterScript);
2294     CHECK_CALLED(OnLeaveScript);
2295     CHECK_CALLED(OnScriptError);
2296 
2297     memset(&ei, 0xcc, sizeof(ei));
2298     hres = IActiveScriptError_GetExceptionInfo(error1, &ei);
2299     ok(hres == S_OK, "GetExceptionInfo returned %08x\n", hres);
2300     ok(!ei.wCode, "wCode = %x\n", ei.wCode);
2301     ok(!ei.wReserved, "wReserved = %x\n", ei.wReserved);
2302     if(is_english) {
2303         ok(!wcscmp(ei.bstrSource, L"Microsoft VBScript runtime error"),
2304            "bstrSource = %s\n", wine_dbgstr_w(ei.bstrSource));
2305         ok(!wcscmp(ei.bstrDescription, L"Object doesn't support this property or method"),
2306            "bstrDescription = %s\n", wine_dbgstr_w(ei.bstrDescription));
2307     }
2308     ok(!ei.bstrHelpFile, "bstrHelpFile = %s\n", wine_dbgstr_w(ei.bstrHelpFile));
2309     ok(!ei.dwHelpContext, "dwHelpContext = %x\n", ei.dwHelpContext);
2310     ok(!ei.pvReserved, "pvReserved = %p\n", ei.pvReserved);
2311     ok(!ei.pfnDeferredFillIn, "pfnDeferredFillIn = %p\n", ei.pfnDeferredFillIn);
2312     ok(ei.scode == MAKE_VBSERROR(2), "scode = %x\n", ei.scode);
2313     free_ei(&ei);
2314 
2315     IActiveScriptError_Release(error1);
2316 
2317     memset(&ei, 0xcc, sizeof(ei));
2318     hres = IActiveScriptError_GetExceptionInfo(error2, &ei);
2319     ok(hres == S_OK, "GetExceptionInfo returned %08x\n", hres);
2320     ok(!ei.wCode, "wCode = %x\n", ei.wCode);
2321     ok(!ei.wReserved, "wReserved = %x\n", ei.wReserved);
2322     ok(!wcscmp(ei.bstrSource, L"src"), "bstrSource = %s\n", wine_dbgstr_w(ei.bstrSource));
2323     ok(!wcscmp(ei.bstrDescription, L"desc"), "bstrDescription = %s\n", wine_dbgstr_w(ei.bstrDescription));
2324     ok(!wcscmp(ei.bstrHelpFile, L"help"), "bstrHelpFile = %s\n", wine_dbgstr_w(ei.bstrHelpFile));
2325     ok(ei.dwHelpContext == 1, "dwHelpContext = %x\n", ei.dwHelpContext);
2326     ok(!ei.pvReserved, "pvReserved = %p\n", ei.pvReserved);
2327     ok(!ei.pfnDeferredFillIn, "pfnDeferredFillIn = %p\n", ei.pfnDeferredFillIn);
2328     ok(ei.scode == SCRIPT_E_RECORDED, "scode = %x\n", ei.scode);
2329     free_ei(&ei);
2330 
2331     IActiveScriptError_Release(error2);
2332 
2333     SET_EXPECT(OnEnterScript);
2334     SET_EXPECT(OnLeaveScript);
2335     SET_EXPECT(OnScriptError);
2336     hres = IActiveScriptParse_ParseScriptText(parser, L"err.raise &hffff&\n",
2337                                               NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
2338     ok(hres == MAKE_VBSERROR(0xffff), "ParseScriptText failed: %08x\n", hres);
2339     CHECK_CALLED(OnEnterScript);
2340     CHECK_CALLED(OnLeaveScript);
2341     CHECK_CALLED(OnScriptError);
2342 
2343     SET_EXPECT(OnEnterScript);
2344     SET_EXPECT(OnLeaveScript);
2345     SET_EXPECT(OnScriptError);
2346     hres = IActiveScriptParse_ParseScriptText(parser, L"err.raise &h80102030&\n",
2347                                               NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
2348     ok(hres == 0x80102030, "ParseScriptText failed: %08x\n", hres);
2349     CHECK_CALLED(OnEnterScript);
2350     CHECK_CALLED(OnLeaveScript);
2351     CHECK_CALLED(OnScriptError);
2352 
2353     SET_EXPECT(OnEnterScript);
2354     SET_EXPECT(global_testerrorobject_i);
2355     SET_EXPECT(OnLeaveScript);
2356     hres = IActiveScriptParse_ParseScriptText(parser,
2357                                               L"on error resume next\n"
2358                                               L"err.raise 1\n"
2359                                               L"testErrorObject err\n",
2360                                               NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
2361     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2362     CHECK_CALLED(OnEnterScript);
2363     CHECK_CALLED(global_testerrorobject_i);
2364     CHECK_CALLED(OnLeaveScript);
2365 
2366     IDispatchEx_Release(dispex);
2367 
2368     IActiveScriptParse_Release(parser);
2369     close_script(script);
2370     strict_enter_script = FALSE;
2371 }
2372 
2373 static void test_gc(void)
2374 {
2375     IActiveScriptParse *parser;
2376     IActiveScript *engine;
2377     BSTR src;
2378     HRESULT hres;
2379 
2380     strict_dispid_check = FALSE;
2381 
2382     engine = create_script();
2383     if(!engine)
2384         return;
2385 
2386     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
2387     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
2388 
2389     hres = IActiveScriptParse_InitNew(parser);
2390     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
2391 
2392     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
2393     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
2394 
2395     hres = IActiveScript_AddNamedItem(engine, testW,
2396             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
2397     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
2398 
2399     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
2400     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
2401 
2402     src = a2bstr(
2403             "class C\n"
2404             "    Public ref\n"
2405             "    Public Sub Class_Terminate\n"
2406             "        Call reportSuccess()\n"
2407             "    End Sub\n"
2408             "End Class\n"
2409             "Dim x\n"
2410             "set x = new C\n"
2411             "set x.ref = x\n"
2412             "set x = nothing\n");
2413 
2414     hres = IActiveScriptParse_ParseScriptText(parser, src, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
2415     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2416     SysFreeString(src);
2417 
2418     SET_EXPECT(global_success_d);
2419     SET_EXPECT(global_success_i);
2420     IActiveScript_Close(engine);
2421     CHECK_CALLED(global_success_d);
2422     CHECK_CALLED(global_success_i);
2423 
2424     IActiveScript_Release(engine);
2425     IActiveScriptParse_Release(parser);
2426 }
2427 
2428 static void test_parse_errors(void)
2429 {
2430     static const char *invalid_scripts[] =
2431     {
2432         /* If...End If */
2433         "If 0 > 1 Then\n"
2434         "    x = 0 End If\n",
2435 
2436         /* While...End While */
2437         "While False\n"
2438         "    x = 0 End While\n",
2439 
2440         /* While...Wend */
2441         "While False\n"
2442         "    x = 0 Wend\n",
2443 
2444         /* Do While...Loop */
2445         "Do While False\n"
2446         "    x = 0 Loop\n",
2447 
2448         /* Do Until...Loop */
2449         "Do Until True\n"
2450         "    x = 0 Loop\n",
2451 
2452         /* Do...Loop While */
2453         "Do\n"
2454         "    x = 0 Loop While False\n",
2455 
2456         /* Do...Loop Until */
2457         "Do\n"
2458         "    x = 0 Loop Until True\n",
2459 
2460         /* Select...End Select */
2461         "x = False\n"
2462         "Select Case 42\n"
2463         "    Case 0\n"
2464         "        Call ok(False, \"unexpected case\")\n"
2465         "    Case 42\n"
2466         "        x = True End Select\n"
2467         "Call ok(x, \"wrong case\")\n",
2468 
2469         /* Class...End Class  (empty) */
2470         "Class C End Class"
2471     };
2472     HRESULT hres;
2473     UINT i;
2474 
2475     for (i = 0; i < ARRAY_SIZE(invalid_scripts); i++)
2476     {
2477         SET_EXPECT(OnScriptError);
2478         hres = parse_script_ar(invalid_scripts[i]);
2479         ok(FAILED(hres), "[%u] script did not fail\n", i);
2480         CHECK_CALLED(OnScriptError);
2481     }
2482 }
2483 
2484 static void test_msgbox(void)
2485 {
2486     HRESULT hres;
2487 
2488     uic_handling = SCRIPTUICHANDLING_NOUIDEFAULT;
2489 
2490     SET_EXPECT(GetUIBehavior);
2491     SET_EXPECT(GetWindow);
2492     SET_EXPECT(EnableModeless);
2493     hres = parse_script_ar("MsgBox \"testing...\"");
2494     CLEAR_CALLED(GetUIBehavior);
2495     CLEAR_CALLED(GetWindow);
2496     CLEAR_CALLED(EnableModeless);
2497     if(FAILED(hres)) {
2498         win_skip("Skipping MsgBox tests, broken (probably too old) vbscript\n");
2499         return;
2500     }
2501 
2502     SET_EXPECT(GetUIBehavior);
2503     parse_script_a("dim r\n r=MsgBox(\"testing...\")\n Call ok(r=0, \"r=\"&r)");
2504     CHECK_CALLED(GetUIBehavior);
2505 
2506     SET_EXPECT(GetUIBehavior);
2507     parse_script_a("MsgBox 10");
2508     CHECK_CALLED(GetUIBehavior);
2509 
2510     uic_handling = SCRIPTUICHANDLING_ALLOW;
2511 
2512     SET_EXPECT(GetUIBehavior);
2513     SET_EXPECT(GetWindow);
2514     SET_EXPECT(EnableModeless);
2515     SET_EXPECT(OnScriptError);
2516     hres = parse_script_ar("MsgBox \"testing...\"");
2517     ok(FAILED(hres), "script not failed\n");
2518     CHECK_CALLED(GetUIBehavior);
2519     CHECK_CALLED(GetWindow);
2520     CHECK_CALLED(EnableModeless);
2521     CHECK_CALLED(OnScriptError);
2522 
2523     uic_handling = SCRIPTUICHANDLING_NOUIERROR;
2524 
2525     SET_EXPECT(GetUIBehavior);
2526     SET_EXPECT(OnScriptError);
2527     hres = parse_script_ar("MsgBox \"testing...\"");
2528     ok(FAILED(hres), "script not failed\n");
2529     CHECK_CALLED(GetUIBehavior);
2530     CHECK_CALLED(OnScriptError);
2531 }
2532 
2533 static HRESULT test_global_vars_ref(BOOL use_close)
2534 {
2535     IActiveScriptParse *parser;
2536     IActiveScript *engine;
2537     BSTR script_str;
2538     LONG ref;
2539     HRESULT hres;
2540 
2541     engine = create_script();
2542     if(!engine)
2543         return S_OK;
2544 
2545     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
2546     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
2547     if (FAILED(hres))
2548     {
2549         IActiveScript_Release(engine);
2550         return hres;
2551     }
2552 
2553     hres = IActiveScriptParse_InitNew(parser);
2554     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
2555 
2556     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
2557     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
2558 
2559     hres = IActiveScript_AddNamedItem(engine, testW, SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
2560     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
2561 
2562     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
2563     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
2564 
2565     refobj_ref = 0;
2566 
2567     script_str = a2bstr("Dim x\nset x = RefObj\n");
2568     hres = IActiveScriptParse_ParseScriptText(parser, script_str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
2569     SysFreeString(script_str);
2570 
2571     ok(refobj_ref, "refobj_ref = 0\n");
2572 
2573     if(use_close) {
2574         hres = IActiveScript_Close(engine);
2575         ok(hres == S_OK, "Close failed: %08x\n", hres);
2576     }else {
2577         hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_UNINITIALIZED);
2578         ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
2579     }
2580 
2581     ok(!refobj_ref, "refobj_ref = %d\n", refobj_ref);
2582 
2583     IActiveScript_Release(engine);
2584 
2585     ref = IActiveScriptParse_Release(parser);
2586     ok(!ref, "ref=%d\n", ref);
2587     return hres;
2588 }
2589 
2590 static void test_isexpression(void)
2591 {
2592     IActiveScriptParse *parser;
2593     IActiveScript *engine;
2594     SCRIPTSTATE ss;
2595     HRESULT hres;
2596     VARIANT var;
2597     BSTR str;
2598 
2599     if (!(engine = create_and_init_script(0, FALSE)))
2600         return;
2601 
2602     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
2603     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
2604     if (FAILED(hres))
2605     {
2606         close_script(engine);
2607         return;
2608     }
2609 
2610     /* Expression when script is not started is still executed */
2611     hres = IActiveScript_GetScriptState(engine, &ss);
2612     ok(hres == S_OK, "GetScriptState failed: %08x\n", hres);
2613     ok(ss == SCRIPTSTATE_INITIALIZED, "Wrong script state %u\n", ss);
2614 
2615     str = a2bstr("13");
2616     hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL);
2617     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2618     ok(V_VT(&var) == VT_I2, "Expected VT_I2, got %s\n", vt2a(&var));
2619     ok(V_I2(&var) == 13, "Expected 13, got %d\n", V_I2(&var));
2620     VariantClear(&var);
2621     SysFreeString(str);
2622 
2623     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
2624     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
2625 
2626     /* Empty expressions */
2627     V_VT(&var) = VT_I2;
2628     str = a2bstr("");
2629     hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL);
2630     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2631     ok(V_VT(&var) == VT_EMPTY, "Expected VT_EMPTY, got %s\n", vt2a(&var));
2632     VariantClear(&var);
2633     SysFreeString(str);
2634 
2635     /* Two expressions fail */
2636     str = a2bstr("1\n3");
2637     SET_EXPECT(OnScriptError);
2638     hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL);
2639     ok(FAILED(hres), "ParseScriptText did not fail: %08x\n", hres);
2640     CHECK_CALLED(OnScriptError);
2641     VariantClear(&var);
2642     SysFreeString(str);
2643 
2644     /* Simple numerical expression */
2645     str = a2bstr("(1 + 7) * 2 - 3");
2646     hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, NULL, NULL);
2647     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2648 
2649     hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL);
2650     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2651     ok(V_VT(&var) == VT_I2, "Expected VT_I2, got %s\n", vt2a(&var));
2652     ok(V_I2(&var) == 13, "Expected 13, got %d\n", V_I2(&var));
2653     VariantClear(&var);
2654     SysFreeString(str);
2655 
2656     /* An expression can also refer to a variable, function, class, etc previously set */
2657     V_VT(&var) = VT_I2;
2658     str = a2bstr("If True Then foo = 42 Else foo = 0\n");
2659     hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, &var, NULL);
2660     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2661     ok(V_VT(&var) == VT_EMPTY, "Expected VT_EMPTY, got %s\n", vt2a(&var));
2662     VariantClear(&var);
2663     SysFreeString(str);
2664 
2665     str = a2bstr("foo\n\n");
2666     hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL);
2667     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2668     ok(V_VT(&var) == VT_I2, "Expected VT_I2, got %s\n", vt2a(&var));
2669     ok(V_I2(&var) == 42, "Expected 42, got %d\n", V_I2(&var));
2670     VariantClear(&var);
2671     SysFreeString(str);
2672 
2673     str = a2bstr("foo : ");
2674     SET_EXPECT(OnScriptError);
2675     hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL);
2676     ok(FAILED(hres), "ParseScriptText did not fail: %08x\n", hres);
2677     CHECK_CALLED(OnScriptError);
2678     VariantClear(&var);
2679     SysFreeString(str);
2680 
2681     str = a2bstr("\"foo is \" & CStr(foo)  \n  \n\n ");
2682     hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL);
2683     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2684     ok(V_VT(&var) == VT_BSTR, "Expected VT_BSTR, got %s\n", vt2a(&var));
2685     ok(!strcmp_wa(V_BSTR(&var), "foo is 42"), "Wrong string, got %s\n", wine_dbgstr_w(V_BSTR(&var)));
2686     VariantClear(&var);
2687     SysFreeString(str);
2688 
2689     str = a2bstr("Function test(x)\n"
2690                  "    test = x + 0.5\n"
2691                  "End Function\n");
2692     hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
2693     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2694     SysFreeString(str);
2695 
2696     str = a2bstr("test(4) * 3\n");
2697     hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL);
2698     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2699     ok(V_VT(&var) == VT_R8, "Expected VT_R8, got %s\n", vt2a(&var));
2700     ok(V_R8(&var) == 13.5, "Expected %lf, got %lf\n", 13.5, V_R8(&var));
2701     VariantClear(&var);
2702     SysFreeString(str);
2703 
2704     str = a2bstr("Class C\n"
2705                  "    Public x\n"
2706                  "End Class\n"
2707                  "Set obj = New C\n"
2708                  "obj.x = True\n");
2709     hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
2710     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2711     SysFreeString(str);
2712 
2713     str = a2bstr("obj.x");
2714     hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL);
2715     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
2716     ok(V_VT(&var) == VT_BOOL, "Expected VT_BOOL, got %s\n", vt2a(&var));
2717     ok(V_BOOL(&var) == VARIANT_TRUE, "Expected %x, got %x\n", VARIANT_TRUE, V_BOOL(&var));
2718     VariantClear(&var);
2719     SysFreeString(str);
2720 
2721     IActiveScriptParse_Release(parser);
2722     close_script(engine);
2723 }
2724 
2725 static BSTR get_script_from_file(const char *filename)
2726 {
2727     DWORD size, len;
2728     HANDLE file, map;
2729     const char *file_map;
2730     BSTR ret;
2731 
2732     file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
2733     if(file == INVALID_HANDLE_VALUE) {
2734         trace("Could not open file: %u\n", GetLastError());
2735         return NULL;
2736     }
2737 
2738     size = GetFileSize(file, NULL);
2739 
2740     map = CreateFileMappingW(file, NULL, PAGE_READONLY, 0, 0, NULL);
2741     CloseHandle(file);
2742     if(map == INVALID_HANDLE_VALUE) {
2743         trace("Could not create file mapping: %u\n", GetLastError());
2744         return NULL;
2745     }
2746 
2747     file_map = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
2748     CloseHandle(map);
2749     if(!file_map) {
2750         trace("MapViewOfFile failed: %u\n", GetLastError());
2751         return NULL;
2752     }
2753 
2754     len = MultiByteToWideChar(CP_ACP, 0, file_map, size, NULL, 0);
2755     ret = SysAllocStringLen(NULL, len);
2756     MultiByteToWideChar(CP_ACP, 0, file_map, size, ret, len);
2757 
2758     UnmapViewOfFile(file_map);
2759 
2760     return ret;
2761 }
2762 
2763 static void run_from_file(const char *filename)
2764 {
2765     BSTR script_str;
2766     HRESULT hres;
2767 
2768     script_str = get_script_from_file(filename);
2769     if(!script_str)
2770         return;
2771 
2772     strict_dispid_check = FALSE;
2773     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, script_str, NULL);
2774     SysFreeString(script_str);
2775     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
2776 }
2777 
2778 static void run_from_res(const char *name)
2779 {
2780     const char *data;
2781     DWORD size, len;
2782     BSTR str;
2783     HRSRC src;
2784     HRESULT hres;
2785 
2786     strict_dispid_check = FALSE;
2787     test_name = name;
2788 
2789     src = FindResourceA(NULL, name, (LPCSTR)40);
2790     ok(src != NULL, "Could not find resource %s\n", name);
2791 
2792     size = SizeofResource(NULL, src);
2793     data = LoadResource(NULL, src);
2794 
2795     len = MultiByteToWideChar(CP_ACP, 0, data, size, NULL, 0);
2796     str = SysAllocStringLen(NULL, len);
2797     MultiByteToWideChar(CP_ACP, 0, data, size, str, len);
2798 
2799     SET_EXPECT(global_success_d);
2800     SET_EXPECT(global_success_i);
2801     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, str, NULL);
2802     CHECK_CALLED(global_success_d);
2803     CHECK_CALLED(global_success_i);
2804 
2805     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
2806     SysFreeString(str);
2807     test_name = "";
2808 }
2809 
2810 static void run_tests(void)
2811 {
2812     HRESULT hres;
2813 
2814     strict_dispid_check = TRUE;
2815 
2816     parse_script_a("");
2817     parse_script_a("' empty ;");
2818 
2819     SET_EXPECT(global_success_d);
2820     SET_EXPECT(global_success_i);
2821     parse_script_a("reportSuccess");
2822     CHECK_CALLED(global_success_d);
2823     CHECK_CALLED(global_success_i);
2824 
2825     SET_EXPECT(global_success_d);
2826     SET_EXPECT(global_success_i);
2827     parse_script_a("reportSuccess()");
2828     CHECK_CALLED(global_success_d);
2829     CHECK_CALLED(global_success_i);
2830 
2831     SET_EXPECT(global_success_d);
2832     SET_EXPECT(global_success_i);
2833     parse_script_a("Call reportSuccess");
2834     CHECK_CALLED(global_success_d);
2835     CHECK_CALLED(global_success_i);
2836 
2837     SET_EXPECT(global_success_d);
2838     SET_EXPECT(global_success_i);
2839     parse_script_a("test.reportSuccess()");
2840     CHECK_CALLED(global_success_d);
2841     CHECK_CALLED(global_success_i);
2842 
2843     SET_EXPECT(global_success_d);
2844     SET_EXPECT(global_success_i);
2845     parse_script_af(0, "TEST.reportSuccess()");
2846     CHECK_CALLED(global_success_d);
2847     CHECK_CALLED(global_success_i);
2848 
2849     SET_EXPECT(global_vbvar_d);
2850     SET_EXPECT(global_vbvar_i);
2851     parse_script_a("Option Explicit\nvbvar = 3");
2852     CHECK_CALLED(global_vbvar_d);
2853     CHECK_CALLED(global_vbvar_i);
2854 
2855     SET_EXPECT(global_vbvar_d);
2856     SET_EXPECT(global_vbvar_i);
2857     parse_script_a("Option Explicit\nvbvar() = 3");
2858     CHECK_CALLED(global_vbvar_d);
2859     CHECK_CALLED(global_vbvar_i);
2860 
2861     SET_EXPECT(global_letobj_i);
2862     parse_script_a("Option Explicit\nletobj = testObj");
2863     CHECK_CALLED(global_letobj_i);
2864 
2865     SET_EXPECT(global_letobj_i);
2866     parse_script_a("Option Explicit\ntest.letobj = testObj");
2867     CHECK_CALLED(global_letobj_i);
2868 
2869     SET_EXPECT(global_setobj_i);
2870     parse_script_a("Option Explicit\nset setobj = testObj");
2871     CHECK_CALLED(global_setobj_i);
2872 
2873     SET_EXPECT(global_setobj_i);
2874     parse_script_a("Option Explicit\nset test.setobj = testObj");
2875     CHECK_CALLED(global_setobj_i);
2876 
2877     SET_EXPECT(OnScriptError);
2878     hres = parse_script_ar("dim x\nx = testObj.rem");
2879     todo_wine
2880     ok(hres == S_OK, "use of 'rem' as dot identifier failed: %x08\n", hres);
2881     todo_wine
2882     CHECK_NOT_CALLED(OnScriptError);
2883 
2884     SET_EXPECT(testobj_propget_d);
2885     SET_EXPECT(testobj_propget_i);
2886     parse_script_a("dim x\nx = testObj.propget");
2887     CHECK_CALLED(testobj_propget_d);
2888     CHECK_CALLED(testobj_propget_i);
2889 
2890     SET_EXPECT(testobj_propput_d);
2891     SET_EXPECT(testobj_propput_i);
2892     parse_script_a("testObj.propput = 1");
2893     CHECK_CALLED(testobj_propput_d);
2894     CHECK_CALLED(testobj_propput_i);
2895 
2896     SET_EXPECT(global_propargput_d);
2897     SET_EXPECT(global_propargput_i);
2898     parse_script_a("propargput(counter(), counter()) = counter()");
2899     CHECK_CALLED(global_propargput_d);
2900     CHECK_CALLED(global_propargput_i);
2901 
2902     SET_EXPECT(global_propargput_d);
2903     SET_EXPECT(global_propargput_i);
2904     parse_script_a("test.propargput(counter(), counter()) = counter()");
2905     CHECK_CALLED(global_propargput_d);
2906     CHECK_CALLED(global_propargput_i);
2907 
2908     SET_EXPECT(global_propargput1_d);
2909     SET_EXPECT(global_propargput1_i);
2910     parse_script_a("propargput1 (counter()) = counter()");
2911     CHECK_CALLED(global_propargput1_d);
2912     CHECK_CALLED(global_propargput1_i);
2913 
2914     SET_EXPECT(global_propargput1_d);
2915     SET_EXPECT(global_propargput1_i);
2916     parse_script_a("test.propargput1(counter()) = counter()");
2917     CHECK_CALLED(global_propargput1_d);
2918     CHECK_CALLED(global_propargput1_i);
2919 
2920     parse_htmlscript_a("<!--");
2921     parse_htmlscript_a(" -->");
2922     parse_htmlscript_a("<!--\ndim x\nx=1\n-->\n");
2923     parse_htmlscript_a("<!--\ndim x\n-->\n<!--\nx=1\n-->\n");
2924 
2925     SET_EXPECT(OnScriptError);
2926     hres = parse_script_ar("<!--");
2927     ok(FAILED(hres), "script didn't fail\n");
2928     CHECK_CALLED(OnScriptError);
2929 
2930     SET_EXPECT(global_success_d);
2931     SET_EXPECT(global_success_i);
2932     parse_htmlscript_a("<!--\n<!-- ignore this <> <>\n--> <>\nCall reportSuccess()\n-->\n");
2933     CHECK_CALLED(global_success_d);
2934     CHECK_CALLED(global_success_i);
2935 
2936     next_cnt = 0;
2937     SET_EXPECT(collectionobj_newenum_i);
2938     SET_EXPECT(Next);
2939     parse_script_a("for each x in collectionObj\nnext");
2940     CHECK_CALLED(collectionobj_newenum_i);
2941     CHECK_CALLED(Next);
2942     ok(next_cnt == 4, "next_cnt = %d\n", next_cnt);
2943 
2944     parse_script_a("x = 1\n Call ok(x = 1, \"x = \" & x)");
2945 
2946     parse_script_a("x = _    \n3");
2947 
2948     test_global_vars_ref(TRUE);
2949     test_global_vars_ref(FALSE);
2950 
2951     SET_EXPECT(OnScriptError);
2952     hres = parse_script_ar("throwInt(&h80080008&)");
2953     ok(hres == 0x80080008, "hres = %08x\n", hres);
2954     CHECK_CALLED(OnScriptError);
2955 
2956     /* DISP_E_BADINDEX */
2957     SET_EXPECT(OnScriptError);
2958     hres = parse_script_ar("throwInt(&h8002000b&)");
2959     ok(hres == MAKE_VBSERROR(9), "hres = %08x\n", hres);
2960     CHECK_CALLED(OnScriptError);
2961 
2962     SET_EXPECT(OnScriptError);
2963     hres = parse_script_ar("throwInt(&h800a0009&)");
2964     ok(hres == MAKE_VBSERROR(9), "hres = %08x\n", hres);
2965     CHECK_CALLED(OnScriptError);
2966 
2967     onerror_hres = S_OK;
2968     SET_EXPECT(OnScriptError);
2969     hres = parse_script_ar("throwInt(&h800a0009&)");
2970     ok(hres == SCRIPT_E_REPORTED, "hres = %08x\n", hres);
2971     CHECK_CALLED(OnScriptError);
2972 
2973     /* E_NOTIMPL */
2974     SET_EXPECT(OnScriptError);
2975     hres = parse_script_ar("throwInt(&h80004001&)");
2976     ok(hres == MAKE_VBSERROR(445), "hres = %08x\n", hres);
2977     CHECK_CALLED(OnScriptError);
2978 
2979     onerror_hres = S_OK;
2980     SET_EXPECT(OnScriptError);
2981     hres = parse_script_ar("throwInt(&h80004001&)");
2982     ok(hres == SCRIPT_E_REPORTED, "hres = %08x\n", hres);
2983     CHECK_CALLED(OnScriptError);
2984 
2985     SET_EXPECT(global_testoptionalarg_i);
2986     parse_script_a("call testOptionalArg(1,,2)");
2987     CHECK_CALLED(global_testoptionalarg_i);
2988 
2989     SET_EXPECT(global_testoptionalarg_i);
2990     parse_script_a("call testOptionalArg(,1,1)");
2991     CHECK_CALLED(global_testoptionalarg_i);
2992 
2993     SET_EXPECT(global_testoptionalarg_i);
2994     parse_script_a("testOptionalArg 1,,2");
2995     CHECK_CALLED(global_testoptionalarg_i);
2996 
2997     strict_dispid_check = FALSE;
2998 
2999     SET_EXPECT(testobj_value_i);
3000     parse_script_a("dim n,o\n set o = testObj\n n = o(1,2)\n call ok(n=2, \"n = \" & n)\n");
3001     CHECK_CALLED(testobj_value_i);
3002 
3003     SET_EXPECT(testobj_value_i);
3004     parse_script_a("dim n,o\n set o = testObj\n n = o\n call ok(n=0, \"n = \" & n)\n");
3005     CHECK_CALLED(testobj_value_i);
3006 
3007     parse_script_a("Sub testsub\n"
3008                    "x = 1\n"
3009                    "Call ok(x = 1, \"x = \" & x)\n"
3010                    "End Sub\n"
3011                    "Call testsub()");
3012 
3013     parse_script_a("Call ok(getVT(x) = \"VT_EMPTY*\", \"getVT(x) = \" & getVT(x))\n");
3014     parse_script_a("Call ok(x = \"\", \"x = \" & x)\n");
3015     parse_script_a("x = y\n"
3016                    "Call ok(getVT(x) = \"VT_EMPTY*\", \"getVT(x) = \" & getVT(x))\n"
3017                    "Call ok(getVT(y) = \"VT_EMPTY*\", \"getVT(y) = \" & getVT(y))");
3018     SET_EXPECT(OnScriptError);
3019     hres = parse_script_ar("x = y(\"a\")");
3020     ok(FAILED(hres), "script didn't fail\n");
3021     CHECK_CALLED(OnScriptError);
3022 
3023     SET_EXPECT(global_success_d);
3024     SET_EXPECT(global_success_i);
3025     parse_script_a("' comment\r"
3026                    "x = _\r3\r"
3027                    "x = _\n3\r"
3028                    "x = _\r\n3\r"
3029                    "Sub testsub(arg)\r"
3030                    "If arg = 1 Then\r\r"
3031                    "Call reportSuccess()\n\n"
3032                    "End If\r\n"
3033                    "End Sub\n\r"
3034                    "Call testsub(1)");
3035     CHECK_CALLED(global_success_d);
3036     CHECK_CALLED(global_success_i);
3037 
3038     run_from_res("lang.vbs");
3039     run_from_res("api.vbs");
3040     run_from_res("regexp.vbs");
3041     run_from_res("error.vbs");
3042 
3043     test_procedures();
3044     test_gc();
3045     test_msgbox();
3046     test_isexpression();
3047     test_parse_errors();
3048     test_parse_context();
3049     test_callbacks();
3050 }
3051 
3052 static BOOL check_vbscript(void)
3053 {
3054     IRegExp2 *regexp;
3055     IUnknown *unk;
3056     HRESULT hres;
3057 
3058     hres = CoCreateInstance(&CLSID_VBScriptRegExp, NULL,
3059             CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
3060             &IID_IUnknown, (void**)&unk);
3061     if(hres == REGDB_E_CLASSNOTREG)
3062         return FALSE;
3063     ok(hres == S_OK, "CoCreateInstance(CLSID_VBScriptRegExp) failed: %x\n", hres);
3064 
3065     hres = IUnknown_QueryInterface(unk, &IID_IRegExp2, (void**)&regexp);
3066     if(SUCCEEDED(hres))
3067         IRegExp2_Release(regexp);
3068     IUnknown_Release(unk);
3069 
3070     return hres == S_OK;
3071 }
3072 
3073 START_TEST(run)
3074 {
3075     int argc;
3076     char **argv;
3077 
3078     detect_locale();
3079     if(!is_english)
3080         skip("Skipping some tests in non-English locale\n");
3081 
3082     argc = winetest_get_mainargs(&argv);
3083 
3084     CoInitialize(NULL);
3085 
3086     if(!check_vbscript()) {
3087         win_skip("Broken engine, probably too old\n");
3088     }else if(argc > 2) {
3089         allow_ui = TRUE;
3090         uic_handling = SCRIPTUICHANDLING_ALLOW;
3091         run_from_file(argv[2]);
3092     }else {
3093         run_tests();
3094     }
3095 
3096     CoUninitialize();
3097 }
3098