2 * Copyright 2011 Jacek Caban for CodeWeavers
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.
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.
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
28 #include "wine/test.h"
30 extern const CLSID CLSID_VBScript;
32 #define DEFINE_EXPECT(func) \
33 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
35 #define SET_EXPECT(func) \
36 expect_ ## func = TRUE
38 #define SET_CALLED(func) \
39 called_ ## func = TRUE
41 #define CHECK_EXPECT2(func) \
43 ok(expect_ ##func, "unexpected call " #func "\n"); \
44 called_ ## func = TRUE; \
47 #define CHECK_EXPECT(func) \
49 CHECK_EXPECT2(func); \
50 expect_ ## func = FALSE; \
53 #define CHECK_CALLED(func) \
55 ok(called_ ## func, "expected " #func "\n"); \
56 expect_ ## func = called_ ## func = FALSE; \
59 DEFINE_EXPECT(global_success_d);
60 DEFINE_EXPECT(global_success_i);
61 DEFINE_EXPECT(global_vbvar_d);
62 DEFINE_EXPECT(global_vbvar_i);
63 DEFINE_EXPECT(testobj_propget_d);
64 DEFINE_EXPECT(testobj_propget_i);
65 DEFINE_EXPECT(testobj_propput_d);
66 DEFINE_EXPECT(testobj_propput_i);
68 #define DISPID_GLOBAL_REPORTSUCCESS 1000
69 #define DISPID_GLOBAL_TRACE 1001
70 #define DISPID_GLOBAL_OK 1002
71 #define DISPID_GLOBAL_GETVT 1003
72 #define DISPID_GLOBAL_ISENGLANG 1004
73 #define DISPID_GLOBAL_VBVAR 1005
74 #define DISPID_GLOBAL_TESTOBJ 1006
75 #define DISPID_GLOBAL_ISNULLDISP 1007
76 #define DISPID_GLOBAL_TESTDISP 1008
78 #define DISPID_TESTOBJ_PROPGET 2000
79 #define DISPID_TESTOBJ_PROPPUT 2001
81 static const WCHAR testW[] = {'t','e','s','t',0};
83 static BOOL strict_dispid_check;
84 static const char *test_name = "(null)";
86 static BSTR a2bstr(const char *str)
91 len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
92 ret = SysAllocStringLen(NULL, len-1);
93 MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
98 static int strcmp_wa(LPCWSTR strw, const char *stra)
101 WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), 0, 0);
102 return lstrcmpA(buf, stra);
105 static const char *vt2a(VARIANT *v)
107 if(V_VT(v) == (VT_BYREF|VT_VARIANT)) {
109 sprintf(buf, "%s*", vt2a(V_BYREF(v)));
127 return "VT_DISPATCH";
130 case VT_ARRAY|VT_VARIANT:
131 return "VT_ARRAY|VT_VARIANT";
133 ok(0, "unknown vt %d\n", V_VT(v));
138 /* Returns true if the user interface is in English. Note that this does not
139 * presume of the formatting of dates, numbers, etc.
141 static BOOL is_lang_english(void)
143 static HMODULE hkernel32 = NULL;
144 static LANGID (WINAPI *pGetThreadUILanguage)(void) = NULL;
145 static LANGID (WINAPI *pGetUserDefaultUILanguage)(void) = NULL;
149 hkernel32 = GetModuleHandleA("kernel32.dll");
150 pGetThreadUILanguage = (void*)GetProcAddress(hkernel32, "GetThreadUILanguage");
151 pGetUserDefaultUILanguage = (void*)GetProcAddress(hkernel32, "GetUserDefaultUILanguage");
153 if (pGetThreadUILanguage)
154 return PRIMARYLANGID(pGetThreadUILanguage()) == LANG_ENGLISH;
155 if (pGetUserDefaultUILanguage)
156 return PRIMARYLANGID(pGetUserDefaultUILanguage()) == LANG_ENGLISH;
158 return PRIMARYLANGID(GetUserDefaultLangID()) == LANG_ENGLISH;
161 static void test_disp(IDispatch *disp)
163 DISPID id, public_prop_id, public_prop2_id, public_func_id, public_sub_id, defvalget_id;
164 DISPID named_args[5] = {DISPID_PROPERTYPUT};
166 DISPPARAMS dp = {args, named_args};
172 hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
173 ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
175 str = a2bstr("publicProp");
176 hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_prop_id);
178 ok(hres == S_OK, "GetDispID(publicProp) failed: %08x\n", hres);
180 str = a2bstr("PUBLICPROP");
181 hres = IDispatchEx_GetDispID(dispex, str, 0, &id);
183 ok(hres == S_OK, "GetDispID(PUBLICPROP) failed: %08x\n", hres);
184 ok(public_prop_id == id, "id = %d\n", public_prop_id);
186 str = a2bstr("publicPROP2");
187 hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_prop2_id);
189 ok(hres == S_OK, "GetDispID(publicProp2) failed: %08x\n", hres);
191 str = a2bstr("defValGet");
192 hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &defvalget_id);
194 ok(hres == S_OK, "GetDispID(defValGet) failed: %08x\n", hres);
195 ok(defvalget_id == DISPID_VALUE, "id = %d\n", defvalget_id);
197 str = a2bstr("privateProp");
198 hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id);
200 ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateProp) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
201 ok(id == -1, "id = %d\n", id);
203 str = a2bstr("class_initialize");
204 hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id);
206 ok(hres == S_OK, "GetDispID(publicProp2) failed: %08x\n", hres);
208 hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
209 ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
210 ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
212 V_VT(args) = VT_BOOL;
213 V_BOOL(args) = VARIANT_TRUE;
214 dp.cArgs = dp.cNamedArgs = 1;
216 hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUT, &dp, &v, &ei, NULL);
217 ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
218 ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
220 dp.cArgs = dp.cNamedArgs = 0;
221 hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
222 ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
223 ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
224 ok(V_BOOL(&v), "V_BOOL(v) = %x\n", V_BOOL(&v));
227 hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
228 ok(hres == DISP_E_MEMBERNOTFOUND, "InvokeEx failed: %08x, expected DISP_E_MEMBERNOTFOUND\n", hres);
229 ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
231 V_VT(args) = VT_BOOL;
232 V_BOOL(args) = VARIANT_FALSE;
235 hres = IDispatchEx_InvokeEx(dispex, public_prop_id, 0, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL);
236 ok(hres == DISP_E_PARAMNOTOPTIONAL, "InvokeEx failed: %08x, expected DISP_E_PARAMNOTOPTIONAL\n", hres);
238 str = a2bstr("publicFunction");
239 hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_func_id);
241 ok(hres == S_OK, "GetDispID(publicFunction) failed: %08x\n", hres);
242 ok(public_func_id != -1, "public_func_id = -1\n");
244 str = a2bstr("publicSub");
245 hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &public_sub_id);
247 ok(hres == S_OK, "GetDispID(publicSub) failed: %08x\n", hres);
248 ok(public_sub_id != -1, "public_func_id = -1\n");
250 dp.cArgs = dp.cNamedArgs = 0;
251 hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
252 ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
253 ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
254 ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
256 dp.cArgs = dp.cNamedArgs = 0;
257 hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
258 ok(hres == DISP_E_MEMBERNOTFOUND, "InvokeEx failed: %08x, expected DISP_E_MEMBERNOTFOUND\n", hres);
259 ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
261 dp.cArgs = dp.cNamedArgs = 0;
262 hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
263 ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
264 ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
265 ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
267 dp.cArgs = dp.cNamedArgs = 0;
268 hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
269 ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
270 ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
272 dp.cArgs = dp.cNamedArgs = 0;
273 hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
274 ok(hres == DISP_E_MEMBERNOTFOUND, "InvokeEx failed: %08x, expected DISP_E_MEMBERNOTFOUND\n", hres);
275 ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
277 dp.cArgs = dp.cNamedArgs = 0;
278 hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
279 ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
280 ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
282 V_VT(args) = VT_BOOL;
283 V_BOOL(args) = VARIANT_TRUE;
284 dp.cArgs = dp.cNamedArgs = 1;
285 hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL);
286 ok(FAILED(hres), "InvokeEx succeeded: %08x\n", hres);
288 dp.cArgs = dp.cNamedArgs = 0;
289 hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
290 ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
291 ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
292 ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
294 dp.cArgs = dp.cNamedArgs = 0;
295 hres = IDispatchEx_InvokeEx(dispex, public_func_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
296 ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
297 ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
298 ok(V_I2(&v) == 4, "V_I2(v) = %d\n", V_I2(&v));
300 dp.cArgs = dp.cNamedArgs = 0;
301 hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
302 ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
303 ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
305 dp.cArgs = dp.cNamedArgs = 0;
306 hres = IDispatchEx_InvokeEx(dispex, public_sub_id, 0, DISPATCH_METHOD, &dp, &v, &ei, NULL);
307 ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
308 ok(V_VT(&v) == VT_EMPTY, "V_VT(v) = %d\n", V_VT(&v));
310 str = a2bstr("privateSub");
311 hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id);
313 ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateSub) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
314 ok(id == -1, "id = %d\n", id);
316 str = a2bstr("dynprop");
317 hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive|fdexNameEnsure, &id);
318 ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateProp) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
319 ok(id == -1, "id = %d\n", id);
320 hres = IDispatchEx_GetDispID(dispex, str, fdexNameEnsure, &id);
321 ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(privateProp) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
322 ok(id == -1, "id = %d\n", id);
325 IDispatchEx_Release(dispex);
328 #define test_grfdex(a,b) _test_grfdex(__LINE__,a,b)
329 static void _test_grfdex(unsigned line, DWORD grfdex, DWORD expect)
331 ok_(__FILE__,line)(grfdex == expect, "grfdex = %x, expected %x\n", grfdex, expect);
334 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
338 if(IsEqualGUID(riid, &IID_IUnknown)
339 || IsEqualGUID(riid, &IID_IDispatch)
340 || IsEqualGUID(riid, &IID_IDispatchEx))
343 return E_NOINTERFACE;
348 static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
353 static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
358 static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
360 ok(0, "unexpected call\n");
364 static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
365 LCID lcid, ITypeInfo **ppTInfo)
367 ok(0, "unexpected call\n");
371 static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
372 LPOLESTR *rgszNames, UINT cNames,
373 LCID lcid, DISPID *rgDispId)
375 ok(0, "unexpected call\n");
379 static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
380 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
381 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
383 ok(0, "unexpected call\n");
387 static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
389 ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
393 static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
395 ok(0, "unexpected call\n");
399 static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
401 ok(0, "unexpected call\n");
405 static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
407 ok(0, "unexpected call\n");
411 static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
413 ok(0, "unexpected call\n");
417 static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
419 ok(0, "unexpected call\n");
423 static HRESULT WINAPI testObj_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
425 if(!strcmp_wa(bstrName, "propget")) {
426 CHECK_EXPECT(testobj_propget_d);
427 test_grfdex(grfdex, fdexNameCaseInsensitive);
428 *pid = DISPID_TESTOBJ_PROPGET;
431 if(!strcmp_wa(bstrName, "propput")) {
432 CHECK_EXPECT(testobj_propput_d);
433 test_grfdex(grfdex, fdexNameCaseInsensitive);
434 *pid = DISPID_TESTOBJ_PROPPUT;
438 ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName));
439 return DISP_E_UNKNOWNNAME;
442 static HRESULT WINAPI testObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
443 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
446 case DISPID_TESTOBJ_PROPGET:
447 CHECK_EXPECT(testobj_propget_i);
449 ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
450 ok(pdp != NULL, "pdp == NULL\n");
451 ok(!pdp->rgvarg, "rgvarg == NULL\n");
452 ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
453 ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
454 ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
455 ok(pvarRes != NULL, "pvarRes == NULL\n");
456 ok(pei != NULL, "pei == NULL\n");
458 V_VT(pvarRes) = VT_I2;
461 case DISPID_TESTOBJ_PROPPUT:
462 CHECK_EXPECT(testobj_propput_i);
464 ok(wFlags == DISPATCH_PROPERTYPUT, "wFlags = %x\n", wFlags);
465 ok(pdp != NULL, "pdp == NULL\n");
466 ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
467 ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
468 ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
469 ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
470 ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
471 ok(!pvarRes, "pvarRes != NULL\n");
472 ok(pei != NULL, "pei == NULL\n");
474 ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
475 ok(V_I2(pdp->rgvarg) == 1, "V_I2(psp->rgvargs) = %d\n", V_I2(pdp->rgvarg));
479 ok(0, "unexpected call %d\n", id);
483 static IDispatchExVtbl testObjVtbl = {
484 DispatchEx_QueryInterface,
487 DispatchEx_GetTypeInfoCount,
488 DispatchEx_GetTypeInfo,
489 DispatchEx_GetIDsOfNames,
493 DispatchEx_DeleteMemberByName,
494 DispatchEx_DeleteMemberByDispID,
495 DispatchEx_GetMemberProperties,
496 DispatchEx_GetMemberName,
497 DispatchEx_GetNextDispID,
498 DispatchEx_GetNameSpaceParent
501 static IDispatchEx testObj = { &testObjVtbl };
503 static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
505 if(!strcmp_wa(bstrName, "ok")) {
506 test_grfdex(grfdex, fdexNameCaseInsensitive);
507 *pid = DISPID_GLOBAL_OK;
510 if(!strcmp_wa(bstrName, "trace")) {
511 test_grfdex(grfdex, fdexNameCaseInsensitive);
512 *pid = DISPID_GLOBAL_TRACE;
515 if(!strcmp_wa(bstrName, "reportSuccess")) {
516 CHECK_EXPECT(global_success_d);
517 test_grfdex(grfdex, fdexNameCaseInsensitive);
518 *pid = DISPID_GLOBAL_REPORTSUCCESS;
521 if(!strcmp_wa(bstrName, "getVT")) {
522 test_grfdex(grfdex, fdexNameCaseInsensitive);
523 *pid = DISPID_GLOBAL_GETVT;
526 if(!strcmp_wa(bstrName, "isEnglishLang")) {
527 test_grfdex(grfdex, fdexNameCaseInsensitive);
528 *pid = DISPID_GLOBAL_ISENGLANG;
531 if(!strcmp_wa(bstrName, "testObj")) {
532 test_grfdex(grfdex, fdexNameCaseInsensitive);
533 *pid = DISPID_GLOBAL_TESTOBJ;
536 if(!strcmp_wa(bstrName, "vbvar")) {
537 CHECK_EXPECT(global_vbvar_d);
538 test_grfdex(grfdex, fdexNameCaseInsensitive);
539 *pid = DISPID_GLOBAL_VBVAR;
542 if(!strcmp_wa(bstrName, "isNullDisp")) {
543 test_grfdex(grfdex, fdexNameCaseInsensitive);
544 *pid = DISPID_GLOBAL_ISNULLDISP;
547 if(!strcmp_wa(bstrName, "testDisp")) {
548 test_grfdex(grfdex, fdexNameCaseInsensitive);
549 *pid = DISPID_GLOBAL_TESTDISP;
553 if(strict_dispid_check && strcmp_wa(bstrName, "x"))
554 ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
555 return DISP_E_UNKNOWNNAME;
558 static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
559 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
562 case DISPID_GLOBAL_OK: {
565 ok(wFlags == INVOKE_FUNC || wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
566 ok(pdp != NULL, "pdp == NULL\n");
567 ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
568 ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
569 ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
570 ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
571 if(wFlags & INVOKE_PROPERTYGET)
572 ok(pvarRes != NULL, "pvarRes == NULL\n");
574 ok(!pvarRes, "pvarRes != NULL\n");
575 ok(pei != NULL, "pei == NULL\n");
577 ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
580 if(V_VT(b) == (VT_BYREF|VT_VARIANT))
583 ok(V_VT(b) == VT_BOOL, "V_VT(b) = %d\n", V_VT(b));
585 ok(V_BOOL(b), "%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
589 case DISPID_GLOBAL_TRACE:
590 ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
591 ok(pdp != NULL, "pdp == NULL\n");
592 ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
593 ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
594 ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
595 ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
596 ok(!pvarRes, "pvarRes != NULL\n");
597 ok(pei != NULL, "pei == NULL\n");
599 ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
600 if(V_VT(pdp->rgvarg) == VT_BSTR)
601 trace("%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
605 case DISPID_GLOBAL_REPORTSUCCESS:
606 CHECK_EXPECT(global_success_i);
608 ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
609 ok(pdp != NULL, "pdp == NULL\n");
610 ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
611 ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
612 ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
613 ok(!pvarRes, "pvarRes != NULL\n");
614 ok(pei != NULL, "pei == NULL\n");
618 case DISPID_GLOBAL_GETVT:
619 ok(pdp != NULL, "pdp == NULL\n");
620 ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
621 ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
622 ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
623 ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
624 ok(pvarRes != NULL, "pvarRes == NULL\n");
625 ok(V_VT(pvarRes) == VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
626 ok(pei != NULL, "pei == NULL\n");
628 V_VT(pvarRes) = VT_BSTR;
629 V_BSTR(pvarRes) = a2bstr(vt2a(pdp->rgvarg));
632 case DISPID_GLOBAL_ISENGLANG:
633 ok(wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
634 ok(pdp != NULL, "pdp == NULL\n");
635 ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
636 ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
637 ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
638 ok(pvarRes != NULL, "pvarRes == NULL\n");
639 ok(pei != NULL, "pei == NULL\n");
641 V_VT(pvarRes) = VT_BOOL;
642 if(is_lang_english()) {
643 V_BOOL(pvarRes) = VARIANT_TRUE;
645 skip("Skipping some tests in non-English UIs\n");
646 V_BOOL(pvarRes) = VARIANT_FALSE;
650 case DISPID_GLOBAL_VBVAR:
651 CHECK_EXPECT(global_vbvar_i);
653 ok(wFlags == DISPATCH_PROPERTYPUT, "wFlags = %x\n", wFlags);
654 ok(pdp != NULL, "pdp == NULL\n");
655 ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
656 ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
657 ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
658 ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
659 ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
660 ok(!pvarRes, "pvarRes != NULL\n");
661 ok(pei != NULL, "pei == NULL\n");
663 ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
664 ok(V_I2(pdp->rgvarg) == 3, "V_I2(psp->rgvargs) = %d\n", V_I2(pdp->rgvarg));
667 case DISPID_GLOBAL_TESTOBJ:
668 ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags);
670 ok(pdp != NULL, "pdp == NULL\n");
671 ok(!pdp->rgvarg, "rgvarg == NULL\n");
672 ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
673 ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
674 ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
675 ok(pvarRes != NULL, "pvarRes == NULL\n");
676 ok(pei != NULL, "pei == NULL\n");
678 V_VT(pvarRes) = VT_DISPATCH;
679 V_DISPATCH(pvarRes) = (IDispatch*)&testObj;
682 case DISPID_GLOBAL_ISNULLDISP: {
685 ok(wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
686 ok(pdp != NULL, "pdp == NULL\n");
687 ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
688 ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
689 ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
690 ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
691 ok(pvarRes != NULL, "pvarRes == NULL\n");
692 ok(pei != NULL, "pei == NULL\n");
695 if(V_VT(v) == (VT_VARIANT|VT_BYREF))
698 ok(V_VT(v) == VT_DISPATCH, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
699 V_VT(pvarRes) = VT_BOOL;
700 V_BOOL(pvarRes) = V_DISPATCH(v) ? VARIANT_FALSE : VARIANT_TRUE;
704 case DISPID_GLOBAL_TESTDISP:
705 ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
706 ok(pdp != NULL, "pdp == NULL\n");
707 ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
708 ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
709 ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
710 ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
711 ok(!pvarRes, "pvarRes != NULL\n");
712 ok(pei != NULL, "pei == NULL\n");
714 ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
715 test_disp(V_DISPATCH(pdp->rgvarg));
719 ok(0, "unexpected call %d\n", id);
720 return DISP_E_MEMBERNOTFOUND;
723 static IDispatchExVtbl GlobalVtbl = {
724 DispatchEx_QueryInterface,
727 DispatchEx_GetTypeInfoCount,
728 DispatchEx_GetTypeInfo,
729 DispatchEx_GetIDsOfNames,
733 DispatchEx_DeleteMemberByName,
734 DispatchEx_DeleteMemberByDispID,
735 DispatchEx_GetMemberProperties,
736 DispatchEx_GetMemberName,
737 DispatchEx_GetNextDispID,
738 DispatchEx_GetNameSpaceParent
741 static IDispatchEx Global = { &GlobalVtbl };
743 static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
747 if(IsEqualGUID(&IID_IUnknown, riid))
749 else if(IsEqualGUID(&IID_IActiveScriptSite, riid))
752 return E_NOINTERFACE;
754 IUnknown_AddRef((IUnknown*)*ppv);
758 static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
763 static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
768 static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *plcid)
770 *plcid = GetUserDefaultLCID();
774 static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR pstrName,
775 DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti)
777 ok(dwReturnMask == SCRIPTINFO_IUNKNOWN, "unexpected dwReturnMask %x\n", dwReturnMask);
778 ok(!ppti, "ppti != NULL\n");
780 if(strcmp_wa(pstrName, "test"))
781 ok(0, "unexpected pstrName %s\n", wine_dbgstr_w(pstrName));
783 *ppiunkItem = (IUnknown*)&Global;
787 static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *pbstrVersion)
792 static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface,
793 const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo)
798 static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE ssScriptState)
803 static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
808 static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
813 static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
818 #undef ACTSCPSITE_THIS
820 static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
821 ActiveScriptSite_QueryInterface,
822 ActiveScriptSite_AddRef,
823 ActiveScriptSite_Release,
824 ActiveScriptSite_GetLCID,
825 ActiveScriptSite_GetItemInfo,
826 ActiveScriptSite_GetDocVersionString,
827 ActiveScriptSite_OnScriptTerminate,
828 ActiveScriptSite_OnStateChange,
829 ActiveScriptSite_OnScriptError,
830 ActiveScriptSite_OnEnterScript,
831 ActiveScriptSite_OnLeaveScript
834 static IActiveScriptSite ActiveScriptSite = { &ActiveScriptSiteVtbl };
836 static IActiveScript *create_script(void)
838 IActiveScript *script;
841 hres = CoCreateInstance(&CLSID_VBScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
842 &IID_IActiveScript, (void**)&script);
843 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
848 static HRESULT parse_script(DWORD flags, BSTR script_str)
850 IActiveScriptParse *parser;
851 IActiveScript *engine;
852 IDispatch *script_disp;
855 engine = create_script();
859 hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
860 ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
863 IActiveScript_Release(engine);
867 hres = IActiveScriptParse64_InitNew(parser);
868 ok(hres == S_OK, "InitNew failed: %08x\n", hres);
870 hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
871 ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
873 hres = IActiveScript_AddNamedItem(engine, testW,
874 SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|flags);
875 ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
877 hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
878 ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
880 hres = IActiveScript_GetScriptDispatch(engine, NULL, &script_disp);
881 ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres);
882 ok(script_disp != NULL, "script_disp == NULL\n");
883 ok(script_disp != (IDispatch*)&Global, "script_disp == Global\n");
885 hres = IActiveScriptParse64_ParseScriptText(parser, script_str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
887 IActiveScript_Close(engine);
889 IDispatch_Release(script_disp);
890 IActiveScript_Release(engine);
891 IUnknown_Release(parser);
896 static void parse_script_af(DWORD flags, const char *src)
902 hres = parse_script(flags, tmp);
904 ok(hres == S_OK, "parse_script failed: %08x\n", hres);
907 static void parse_script_a(const char *src)
909 parse_script_af(SCRIPTITEM_GLOBALMEMBERS, src);
912 static void test_gc(void)
914 IActiveScriptParse *parser;
915 IActiveScript *engine;
919 strict_dispid_check = FALSE;
921 engine = create_script();
925 hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
926 ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
928 hres = IActiveScriptParse64_InitNew(parser);
929 ok(hres == S_OK, "InitNew failed: %08x\n", hres);
931 hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
932 ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
934 hres = IActiveScript_AddNamedItem(engine, testW,
935 SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
936 ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
938 hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
939 ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
944 " Public Sub Class_Terminate\n"
945 " Call reportSuccess()\n"
951 "set x = nothing\n");
953 hres = IActiveScriptParse64_ParseScriptText(parser, src, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
954 ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
957 SET_EXPECT(global_success_d);
958 SET_EXPECT(global_success_i);
959 IActiveScript_Close(engine);
960 CHECK_CALLED(global_success_d);
961 CHECK_CALLED(global_success_i);
963 IActiveScript_Release(engine);
964 IUnknown_Release(parser);
967 static BSTR get_script_from_file(const char *filename)
971 const char *file_map;
974 file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
975 if(file == INVALID_HANDLE_VALUE) {
976 trace("Could not open file: %u\n", GetLastError());
980 size = GetFileSize(file, NULL);
982 map = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
984 if(map == INVALID_HANDLE_VALUE) {
985 trace("Could not create file mapping: %u\n", GetLastError());
989 file_map = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
992 trace("MapViewOfFile failed: %u\n", GetLastError());
996 len = MultiByteToWideChar(CP_ACP, 0, file_map, size, NULL, 0);
997 ret = SysAllocStringLen(NULL, len);
998 MultiByteToWideChar(CP_ACP, 0, file_map, size, ret, len);
1000 UnmapViewOfFile(file_map);
1005 static void run_from_file(const char *filename)
1010 script_str = get_script_from_file(filename);
1014 strict_dispid_check = FALSE;
1015 hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, script_str);
1016 SysFreeString(script_str);
1017 ok(hres == S_OK, "parse_script failed: %08x\n", hres);
1020 static void run_from_res(const char *name)
1028 strict_dispid_check = FALSE;
1031 src = FindResourceA(NULL, name, (LPCSTR)40);
1032 ok(src != NULL, "Could not find resource %s\n", name);
1034 size = SizeofResource(NULL, src);
1035 data = LoadResource(NULL, src);
1037 len = MultiByteToWideChar(CP_ACP, 0, data, size, NULL, 0);
1038 str = SysAllocStringLen(NULL, len);
1039 MultiByteToWideChar(CP_ACP, 0, data, size, str, len);
1041 SET_EXPECT(global_success_d);
1042 SET_EXPECT(global_success_i);
1043 hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, str);
1044 CHECK_CALLED(global_success_d);
1045 CHECK_CALLED(global_success_i);
1047 ok(hres == S_OK, "parse_script failed: %08x\n", hres);
1051 static void run_tests(void)
1053 strict_dispid_check = TRUE;
1056 parse_script_a("' empty ;");
1058 SET_EXPECT(global_success_d);
1059 SET_EXPECT(global_success_i);
1060 parse_script_a("reportSuccess");
1061 CHECK_CALLED(global_success_d);
1062 CHECK_CALLED(global_success_i);
1064 SET_EXPECT(global_success_d);
1065 SET_EXPECT(global_success_i);
1066 parse_script_a("reportSuccess()");
1067 CHECK_CALLED(global_success_d);
1068 CHECK_CALLED(global_success_i);
1070 SET_EXPECT(global_success_d);
1071 SET_EXPECT(global_success_i);
1072 parse_script_a("Call reportSuccess");
1073 CHECK_CALLED(global_success_d);
1074 CHECK_CALLED(global_success_i);
1076 SET_EXPECT(global_vbvar_d);
1077 SET_EXPECT(global_vbvar_i);
1078 parse_script_a("Option Explicit\nvbvar = 3");
1079 CHECK_CALLED(global_vbvar_d);
1080 CHECK_CALLED(global_vbvar_i);
1082 SET_EXPECT(global_vbvar_d);
1083 SET_EXPECT(global_vbvar_i);
1084 parse_script_a("Option Explicit\nvbvar() = 3");
1085 CHECK_CALLED(global_vbvar_d);
1086 CHECK_CALLED(global_vbvar_i);
1088 SET_EXPECT(testobj_propget_d);
1089 SET_EXPECT(testobj_propget_i);
1090 parse_script_a("dim x\nx = testObj.propget");
1091 CHECK_CALLED(testobj_propget_d);
1092 CHECK_CALLED(testobj_propget_i);
1094 SET_EXPECT(testobj_propput_d);
1095 SET_EXPECT(testobj_propput_i);
1096 parse_script_a("testObj.propput = 1");
1097 CHECK_CALLED(testobj_propput_d);
1098 CHECK_CALLED(testobj_propput_i);
1100 run_from_res("lang.vbs");
1105 static BOOL check_vbscript(void)
1107 IActiveScript *vbscript;
1110 hres = CoCreateInstance(&CLSID_VBScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1111 &IID_IActiveScript, (void**)&vbscript);
1113 IActiveScript_Release(vbscript);
1115 return hres == S_OK;
1123 argc = winetest_get_mainargs(&argv);
1127 if(!check_vbscript()) {
1128 win_skip("Broken engine, probably too old\n");
1129 }else if(argc > 2) {
1130 run_from_file(argv[2]);