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