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 #define COBJMACROS
20 #define CONST_VTABLE
21 
22 #include <initguid.h>
23 #include <ole2.h>
24 #include <activscp.h>
25 #include <objsafe.h>
26 #include <dispex.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 \
39     IActiveScriptParseProcedure2_64_Release
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 \
48     IActiveScriptParseProcedure2_32_Release
49 
50 #endif
51 
52 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
53 
54 #define DEFINE_EXPECT(func) \
55     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
56 
57 #define SET_EXPECT(func) \
58     expect_ ## func = TRUE
59 
60 #define CHECK_EXPECT2(func) \
61     do { \
62         ok(expect_ ##func, "unexpected call " #func "\n"); \
63         called_ ## func = TRUE; \
64     }while(0)
65 
66 #define CHECK_EXPECT(func) \
67     do { \
68         CHECK_EXPECT2(func); \
69         expect_ ## func = FALSE; \
70     }while(0)
71 
72 #define CHECK_CALLED(func) \
73     do { \
74         ok(called_ ## func, "expected " #func "\n"); \
75         expect_ ## func = called_ ## func = FALSE; \
76     }while(0)
77 
78 DEFINE_EXPECT(GetLCID);
79 DEFINE_EXPECT(OnStateChange_UNINITIALIZED);
80 DEFINE_EXPECT(OnStateChange_STARTED);
81 DEFINE_EXPECT(OnStateChange_CONNECTED);
82 DEFINE_EXPECT(OnStateChange_DISCONNECTED);
83 DEFINE_EXPECT(OnStateChange_CLOSED);
84 DEFINE_EXPECT(OnStateChange_INITIALIZED);
85 DEFINE_EXPECT(OnEnterScript);
86 DEFINE_EXPECT(OnLeaveScript);
87 
88 DEFINE_GUID(CLSID_VBScript, 0xb54f3741, 0x5b07, 0x11cf, 0xa4,0xb0, 0x00,0xaa,0x00,0x4a,0x55,0xe8);
89 DEFINE_GUID(CLSID_VBScriptRegExp, 0x3f4daca4, 0x160d, 0x11d2, 0xa8,0xe9, 0x00,0x10,0x4b,0x36,0x5c,0x9f);
90 
91 static BSTR a2bstr(const char *str)
92 {
93     BSTR ret;
94     int len;
95 
96     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
97     ret = SysAllocStringLen(NULL, len-1);
98     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
99 
100     return ret;
101 }
102 
103 #define test_state(s,ss) _test_state(__LINE__,s,ss)
104 static void _test_state(unsigned line, IActiveScript *script, SCRIPTSTATE exstate)
105 {
106     SCRIPTSTATE state = -1;
107     HRESULT hres;
108 
109     hres = IActiveScript_GetScriptState(script, &state);
110     ok_(__FILE__,line) (hres == S_OK, "GetScriptState failed: %08x\n", hres);
111     ok_(__FILE__,line) (state == exstate, "state=%d, expected %d\n", state, exstate);
112 }
113 
114 static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
115 {
116     *ppv = NULL;
117 
118     if(IsEqualGUID(&IID_IUnknown, riid))
119         *ppv = iface;
120     else if(IsEqualGUID(&IID_IActiveScriptSite, riid))
121         *ppv = iface;
122     else
123         return E_NOINTERFACE;
124 
125     IUnknown_AddRef((IUnknown*)*ppv);
126     return S_OK;
127 }
128 
129 static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
130 {
131     return 2;
132 }
133 
134 static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
135 {
136     return 1;
137 }
138 
139 static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *plcid)
140 {
141     CHECK_EXPECT(GetLCID);
142     return E_NOTIMPL;
143 }
144 
145 static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR pstrName,
146         DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti)
147 {
148     ok(0, "unexpected call\n");
149     return E_NOTIMPL;
150 }
151 
152 static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *pbstrVersion)
153 {
154     ok(0, "unexpected call\n");
155     return E_NOTIMPL;
156 }
157 
158 static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface,
159         const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo)
160 {
161     ok(0, "unexpected call\n");
162     return E_NOTIMPL;
163 }
164 
165 static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE ssScriptState)
166 {
167     switch(ssScriptState) {
168     case SCRIPTSTATE_UNINITIALIZED:
169         CHECK_EXPECT(OnStateChange_UNINITIALIZED);
170         return S_OK;
171     case SCRIPTSTATE_STARTED:
172         CHECK_EXPECT(OnStateChange_STARTED);
173         return S_OK;
174     case SCRIPTSTATE_CONNECTED:
175         CHECK_EXPECT(OnStateChange_CONNECTED);
176         return S_OK;
177     case SCRIPTSTATE_DISCONNECTED:
178         CHECK_EXPECT(OnStateChange_DISCONNECTED);
179         return S_OK;
180     case SCRIPTSTATE_CLOSED:
181         CHECK_EXPECT(OnStateChange_CLOSED);
182         return S_OK;
183     case SCRIPTSTATE_INITIALIZED:
184         CHECK_EXPECT(OnStateChange_INITIALIZED);
185         return S_OK;
186     default:
187         ok(0, "unexpected call %d\n", ssScriptState);
188     }
189 
190     return E_NOTIMPL;
191 }
192 
193 static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
194 {
195     ok(0, "unexpected call\n");
196     return E_NOTIMPL;
197 }
198 
199 static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
200 {
201     CHECK_EXPECT(OnEnterScript);
202     return S_OK;
203 }
204 
205 static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
206 {
207     CHECK_EXPECT(OnLeaveScript);
208     return S_OK;
209 }
210 
211 static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
212     ActiveScriptSite_QueryInterface,
213     ActiveScriptSite_AddRef,
214     ActiveScriptSite_Release,
215     ActiveScriptSite_GetLCID,
216     ActiveScriptSite_GetItemInfo,
217     ActiveScriptSite_GetDocVersionString,
218     ActiveScriptSite_OnScriptTerminate,
219     ActiveScriptSite_OnStateChange,
220     ActiveScriptSite_OnScriptError,
221     ActiveScriptSite_OnEnterScript,
222     ActiveScriptSite_OnLeaveScript
223 };
224 
225 static IActiveScriptSite ActiveScriptSite = { &ActiveScriptSiteVtbl };
226 
227 static void test_safety(IActiveScript *script)
228 {
229     IObjectSafety *safety;
230     DWORD supported, enabled;
231     HRESULT hres;
232 
233     hres = IActiveScript_QueryInterface(script, &IID_IObjectSafety, (void**)&safety);
234     ok(hres == S_OK, "Could not get IObjectSafety: %08x\n", hres);
235     if(FAILED(hres))
236         return;
237 
238     hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_NULL, &supported, NULL);
239     ok(hres == E_POINTER, "GetInterfaceSafetyOptions failed: %08x, expected E_POINTER\n", hres);
240     hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_NULL, NULL, &enabled);
241     ok(hres == E_POINTER, "GetInterfaceSafetyOptions failed: %08x, expected E_POINTER\n", hres);
242 
243     supported = enabled = 0xdeadbeef;
244     hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_NULL, &supported, &enabled);
245     ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
246     ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
247        "supported=%x\n", supported);
248     ok(enabled == INTERFACE_USES_DISPEX, "enabled=%x\n", enabled);
249 
250     supported = enabled = 0xdeadbeef;
251     hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScript, &supported, &enabled);
252     ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
253     ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
254        "supported=%x\n", supported);
255     ok(enabled == INTERFACE_USES_DISPEX, "enabled=%x\n", enabled);
256 
257     supported = enabled = 0xdeadbeef;
258     hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, &supported, &enabled);
259     ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
260     ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
261        "supported=%x\n", supported);
262     ok(enabled == INTERFACE_USES_DISPEX, "enabled=%x\n", enabled);
263 
264     hres = IObjectSafety_SetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse,
265             INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER
266                 |INTERFACESAFE_FOR_UNTRUSTED_CALLER,
267             INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER);
268     ok(hres == E_FAIL, "SetInterfaceSafetyOptions failed: %08x, expected E_FAIL\n", hres);
269 
270     hres = IObjectSafety_SetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse,
271             INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER,
272             INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER);
273     ok(hres == S_OK, "SetInterfaceSafetyOptions failed: %08x\n", hres);
274 
275     supported = enabled = 0xdeadbeef;
276     hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, &supported, &enabled);
277     ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
278     ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
279        "supported=%x\n", supported);
280     ok(enabled == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
281        "enabled=%x\n", enabled);
282 
283     hres = IObjectSafety_SetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, INTERFACESAFE_FOR_UNTRUSTED_DATA, 0);
284     ok(hres == S_OK, "SetInterfaceSafetyOptions failed: %08x\n", hres);
285 
286     supported = enabled = 0xdeadbeef;
287     hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, &supported, &enabled);
288     ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
289     ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
290        "supported=%x\n", supported);
291     ok(enabled == (INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER), "enabled=%x\n", enabled);
292 
293     hres = IObjectSafety_SetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse,
294             INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER, 0);
295     ok(hres == S_OK, "SetInterfaceSafetyOptions failed: %08x\n", hres);
296 
297     supported = enabled = 0xdeadbeef;
298     hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, &supported, &enabled);
299     ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
300     ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
301        "supported=%x\n", supported);
302     ok(enabled == INTERFACE_USES_DISPEX, "enabled=%x\n", enabled);
303 
304     hres = IObjectSafety_SetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse,
305             INTERFACE_USES_DISPEX, 0);
306     ok(hres == S_OK, "SetInterfaceSafetyOptions failed: %08x\n", hres);
307 
308     supported = enabled = 0xdeadbeef;
309     hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, &supported, &enabled);
310     ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
311     ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
312        "supported=%x\n", supported);
313     ok(enabled == INTERFACE_USES_DISPEX, "enabled=%x\n", enabled);
314 
315     IObjectSafety_Release(safety);
316 }
317 
318 static IDispatchEx *get_script_dispatch(IActiveScript *script)
319 {
320     IDispatchEx *dispex;
321     IDispatch *disp;
322     HRESULT hres;
323 
324     disp = (void*)0xdeadbeef;
325     hres = IActiveScript_GetScriptDispatch(script, NULL, &disp);
326     ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres);
327     if(FAILED(hres))
328         return NULL;
329 
330     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
331     IDispatch_Release(disp);
332     ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
333     return dispex;
334 }
335 
336 static void parse_script(IActiveScriptParse *parse, const char *src)
337 {
338     BSTR str;
339     HRESULT hres;
340 
341     SET_EXPECT(OnEnterScript);
342     SET_EXPECT(OnLeaveScript);
343 
344     str = a2bstr(src);
345     hres = IActiveScriptParse_ParseScriptText(parse, str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
346     SysFreeString(str);
347     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
348 
349     CHECK_CALLED(OnEnterScript);
350     CHECK_CALLED(OnLeaveScript);
351 }
352 
353 #define get_disp_id(a,b,c,d) _get_disp_id(__LINE__,a,b,c,d)
354 static void _get_disp_id(unsigned line, IDispatchEx *dispex, const char *name, HRESULT exhres, DISPID *id)
355 {
356     DISPID id2;
357     BSTR str;
358     HRESULT hres;
359 
360     str = a2bstr(name);
361     hres = IDispatchEx_GetDispID(dispex, str, 0, id);
362     ok_(__FILE__,line)(hres == exhres, "GetDispID(%s) returned %08x, expected %08x\n", name, hres, exhres);
363 
364     hres = IDispatchEx_GetIDsOfNames(dispex, &IID_NULL, &str, 1, 0, &id2);
365     SysFreeString(str);
366     ok_(__FILE__,line)(hres == exhres, "GetIDsOfNames(%s) returned %08x, expected %08x\n", name, hres, exhres);
367     ok_(__FILE__,line)(*id == id2, "GetIDsOfNames(%s) id != id2\n", name);
368 }
369 
370 static void test_no_script_dispatch(IActiveScript *script)
371 {
372     IDispatch *disp;
373     HRESULT hres;
374 
375     disp = (void*)0xdeadbeef;
376     hres = IActiveScript_GetScriptDispatch(script, NULL, &disp);
377     ok(hres == E_UNEXPECTED, "hres = %08x, expected E_UNEXPECTED\n", hres);
378     ok(!disp, "disp != NULL\n");
379 }
380 
381 static IActiveScript *create_vbscript(void)
382 {
383     IActiveScript *ret;
384     HRESULT hres;
385 
386     hres = CoCreateInstance(&CLSID_VBScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
387             &IID_IActiveScript, (void**)&ret);
388     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
389 
390     return ret;
391 }
392 
393 static void test_scriptdisp(void)
394 {
395     IActiveScriptParse *parser;
396     IDispatchEx *script_disp;
397     IActiveScript *vbscript;
398     DISPID id, id2;
399     DISPPARAMS dp;
400     EXCEPINFO ei;
401     VARIANT v;
402     ULONG ref;
403     HRESULT hres;
404 
405     vbscript = create_vbscript();
406 
407     hres = IActiveScript_QueryInterface(vbscript, &IID_IActiveScriptParse, (void**)&parser);
408     ok(hres == S_OK, "Could not get IActiveScriptParse iface: %08x\n", hres);
409 
410     test_state(vbscript, SCRIPTSTATE_UNINITIALIZED);
411     test_safety(vbscript);
412 
413     SET_EXPECT(GetLCID);
414     hres = IActiveScript_SetScriptSite(vbscript, &ActiveScriptSite);
415     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
416     CHECK_CALLED(GetLCID);
417 
418     test_state(vbscript, SCRIPTSTATE_UNINITIALIZED);
419 
420     SET_EXPECT(OnStateChange_INITIALIZED);
421     hres = IActiveScriptParse_InitNew(parser);
422     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
423     CHECK_CALLED(OnStateChange_INITIALIZED);
424 
425     test_state(vbscript, SCRIPTSTATE_INITIALIZED);
426 
427     SET_EXPECT(OnStateChange_CONNECTED);
428     hres = IActiveScript_SetScriptState(vbscript, SCRIPTSTATE_CONNECTED);
429     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_CONNECTED) failed: %08x\n", hres);
430     CHECK_CALLED(OnStateChange_CONNECTED);
431 
432     test_state(vbscript, SCRIPTSTATE_CONNECTED);
433 
434     script_disp = get_script_dispatch(vbscript);
435 
436     id = 100;
437     get_disp_id(script_disp, "LCase", DISP_E_UNKNOWNNAME, &id);
438     ok(id == -1, "id = %d, expected -1\n", id);
439 
440     get_disp_id(script_disp, "globalVariable", DISP_E_UNKNOWNNAME, &id);
441     parse_script(parser, "dim globalVariable\nglobalVariable = 3");
442     get_disp_id(script_disp, "globalVariable", S_OK, &id);
443 
444     memset(&dp, 0, sizeof(dp));
445     memset(&ei, 0, sizeof(ei));
446     V_VT(&v) = VT_EMPTY;
447     hres = IDispatchEx_InvokeEx(script_disp, id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
448     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
449     ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
450     ok(V_I2(&v) == 3, "V_I2(v) = %d\n", V_I2(&v));
451 
452     get_disp_id(script_disp, "globalVariable2", DISP_E_UNKNOWNNAME, &id);
453     parse_script(parser, "globalVariable2 = 4");
454     get_disp_id(script_disp, "globalVariable2", S_OK, &id);
455 
456     get_disp_id(script_disp, "globalFunction", DISP_E_UNKNOWNNAME, &id);
457     parse_script(parser, "function globalFunction()\nglobalFunction=5\nend function");
458     get_disp_id(script_disp, "globalFunction", S_OK, &id);
459 
460     SET_EXPECT(OnEnterScript);
461     SET_EXPECT(OnLeaveScript);
462 
463     memset(&dp, 0, sizeof(dp));
464     memset(&ei, 0, sizeof(ei));
465     V_VT(&v) = VT_EMPTY;
466     hres = IDispatchEx_InvokeEx(script_disp, id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
467     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
468     ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
469     ok(V_I2(&v) == 5, "V_I2(v) = %d\n", V_I2(&v));
470 
471     CHECK_CALLED(OnEnterScript);
472     CHECK_CALLED(OnLeaveScript);
473 
474     SET_EXPECT(OnEnterScript);
475     SET_EXPECT(OnLeaveScript);
476 
477     memset(&dp, 0, sizeof(dp));
478     memset(&ei, 0, sizeof(ei));
479     V_VT(&v) = VT_EMPTY;
480     hres = IDispatchEx_Invoke(script_disp, id, &IID_NULL, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &v, &ei, NULL);
481     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
482     ok(V_VT(&v) == VT_I2, "V_VT(v) = %d\n", V_VT(&v));
483     ok(V_I2(&v) == 5, "V_I2(v) = %d\n", V_I2(&v));
484 
485     CHECK_CALLED(OnEnterScript);
486     CHECK_CALLED(OnLeaveScript);
487 
488     get_disp_id(script_disp, "globalSub", DISP_E_UNKNOWNNAME, &id);
489     parse_script(parser, "sub globalSub()\nend sub");
490     get_disp_id(script_disp, "globalSub", S_OK, &id);
491     get_disp_id(script_disp, "globalSub", S_OK, &id2);
492     ok(id == id2, "id != id2\n");
493 
494     get_disp_id(script_disp, "constVariable", DISP_E_UNKNOWNNAME, &id);
495     parse_script(parser, "const constVariable = 6");
496     get_disp_id(script_disp, "ConstVariable", S_OK, &id);
497     get_disp_id(script_disp, "Constvariable", S_OK, &id2);
498     ok(id == id2, "id != id2\n");
499 
500     IDispatchEx_Release(script_disp);
501 
502     IActiveScriptParse_Release(parser);
503 
504     SET_EXPECT(OnStateChange_DISCONNECTED);
505     SET_EXPECT(OnStateChange_INITIALIZED);
506     SET_EXPECT(OnStateChange_CLOSED);
507     hres = IActiveScript_Close(vbscript);
508     ok(hres == S_OK, "Close failed: %08x\n", hres);
509     CHECK_CALLED(OnStateChange_DISCONNECTED);
510     CHECK_CALLED(OnStateChange_INITIALIZED);
511     CHECK_CALLED(OnStateChange_CLOSED);
512 
513     ref = IActiveScript_Release(vbscript);
514     ok(!ref, "ref = %d\n", ref);
515 }
516 
517 static void test_vbscript(void)
518 {
519     IActiveScriptParseProcedure2 *parse_proc;
520     IActiveScriptParse *parser;
521     IActiveScript *vbscript;
522     ULONG ref;
523     HRESULT hres;
524 
525     vbscript = create_vbscript();
526 
527     hres = IActiveScript_QueryInterface(vbscript, &IID_IActiveScriptParse, (void**)&parser);
528     ok(hres == S_OK, "Could not get IActiveScriptParse iface: %08x\n", hres);
529 
530     test_state(vbscript, SCRIPTSTATE_UNINITIALIZED);
531     test_safety(vbscript);
532 
533     SET_EXPECT(GetLCID);
534     hres = IActiveScript_SetScriptSite(vbscript, &ActiveScriptSite);
535     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
536     CHECK_CALLED(GetLCID);
537 
538     test_state(vbscript, SCRIPTSTATE_UNINITIALIZED);
539 
540     SET_EXPECT(OnStateChange_INITIALIZED);
541     hres = IActiveScriptParse_InitNew(parser);
542     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
543     CHECK_CALLED(OnStateChange_INITIALIZED);
544 
545     test_state(vbscript, SCRIPTSTATE_INITIALIZED);
546 
547     hres = IActiveScriptParse_InitNew(parser);
548     ok(hres == E_UNEXPECTED, "InitNew failed: %08x, expected E_UNEXPECTED\n", hres);
549 
550     SET_EXPECT(OnStateChange_CONNECTED);
551     hres = IActiveScript_SetScriptState(vbscript, SCRIPTSTATE_CONNECTED);
552     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_CONNECTED) failed: %08x\n", hres);
553     CHECK_CALLED(OnStateChange_CONNECTED);
554 
555     test_state(vbscript, SCRIPTSTATE_CONNECTED);
556 
557     SET_EXPECT(OnStateChange_DISCONNECTED);
558     SET_EXPECT(OnStateChange_INITIALIZED);
559     SET_EXPECT(OnStateChange_CLOSED);
560     hres = IActiveScript_Close(vbscript);
561     ok(hres == S_OK, "Close failed: %08x\n", hres);
562     CHECK_CALLED(OnStateChange_DISCONNECTED);
563     CHECK_CALLED(OnStateChange_INITIALIZED);
564     CHECK_CALLED(OnStateChange_CLOSED);
565 
566     test_state(vbscript, SCRIPTSTATE_CLOSED);
567     test_no_script_dispatch(vbscript);
568 
569     IActiveScriptParse_Release(parser);
570 
571     hres = IActiveScript_QueryInterface(vbscript, &IID_IActiveScriptParseProcedure, (void**)&parse_proc);
572     ok(hres == E_NOINTERFACE, "Got IActiveScriptParseProcedure interface, expected E_NOTIMPL\n");
573 
574     hres = IActiveScript_QueryInterface(vbscript, &IID_IActiveScriptParseProcedure2, (void**)&parse_proc);
575     ok(hres == S_OK, "Could not get IActiveScriptParseProcedure2 interface\n");
576     IActiveScriptParseProcedure2_Release(parse_proc);
577 
578     ref = IActiveScript_Release(vbscript);
579     ok(!ref, "ref = %d\n", ref);
580 }
581 
582 static void test_vbscript_uninitializing(void)
583 {
584     IActiveScriptParse *parse;
585     IActiveScript *script;
586     IDispatchEx *dispex;
587     ULONG ref;
588     HRESULT hres;
589 
590     static const WCHAR script_textW[] =
591         {'F','u','n','c','t','i','o','n',' ','f','\n','E','n','d',' ','F','u','n','c','t','i','o','n','\n',0};
592 
593     script = create_vbscript();
594 
595     hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParse, (void**)&parse);
596     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
597 
598     test_state(script, SCRIPTSTATE_UNINITIALIZED);
599 
600     hres = IActiveScriptParse_InitNew(parse);
601     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
602 
603     SET_EXPECT(GetLCID);
604     SET_EXPECT(OnStateChange_INITIALIZED);
605     hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
606     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
607     CHECK_CALLED(GetLCID);
608     CHECK_CALLED(OnStateChange_INITIALIZED);
609 
610     test_state(script, SCRIPTSTATE_INITIALIZED);
611 
612     hres = IActiveScriptParse_ParseScriptText(parse, script_textW, NULL, NULL, NULL, 0, 1, 0x42, NULL, NULL);
613     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
614 
615     hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
616     ok(hres == E_UNEXPECTED, "SetScriptSite failed: %08x, expected E_UNEXPECTED\n", hres);
617 
618     SET_EXPECT(OnStateChange_UNINITIALIZED);
619     hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_UNINITIALIZED);
620     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_UNINITIALIZED) failed: %08x\n", hres);
621     CHECK_CALLED(OnStateChange_UNINITIALIZED);
622 
623     test_state(script, SCRIPTSTATE_UNINITIALIZED);
624 
625     hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_UNINITIALIZED);
626     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_UNINITIALIZED) failed: %08x\n", hres);
627 
628     SET_EXPECT(GetLCID);
629     SET_EXPECT(OnStateChange_INITIALIZED);
630     hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
631     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
632     CHECK_CALLED(GetLCID);
633     CHECK_CALLED(OnStateChange_INITIALIZED);
634 
635     SET_EXPECT(OnStateChange_CONNECTED);
636     SET_EXPECT(OnEnterScript);
637     SET_EXPECT(OnLeaveScript);
638     hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_CONNECTED);
639     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_CONNECTED) failed: %08x\n", hres);
640     CHECK_CALLED(OnStateChange_CONNECTED);
641     CHECK_CALLED(OnEnterScript);
642     CHECK_CALLED(OnLeaveScript);
643 
644     test_state(script, SCRIPTSTATE_CONNECTED);
645 
646     dispex = get_script_dispatch(script);
647     ok(dispex != NULL, "dispex == NULL\n");
648     if(dispex)
649         IDispatchEx_Release(dispex);
650 
651     SET_EXPECT(OnStateChange_DISCONNECTED);
652     SET_EXPECT(OnStateChange_INITIALIZED);
653     SET_EXPECT(OnStateChange_UNINITIALIZED);
654     hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_UNINITIALIZED);
655     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_UNINITIALIZED) failed: %08x\n", hres);
656     CHECK_CALLED(OnStateChange_DISCONNECTED);
657     CHECK_CALLED(OnStateChange_INITIALIZED);
658     CHECK_CALLED(OnStateChange_UNINITIALIZED);
659 
660     test_state(script, SCRIPTSTATE_UNINITIALIZED);
661 
662     hres = IActiveScript_Close(script);
663     ok(hres == S_OK, "Close failed: %08x\n", hres);
664 
665     test_state(script, SCRIPTSTATE_CLOSED);
666 
667     hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_UNINITIALIZED);
668     ok(hres == E_UNEXPECTED, "SetScriptState(SCRIPTSTATE_UNINITIALIZED) failed: %08x, expected E_UNEXPECTED\n", hres);
669 
670     test_state(script, SCRIPTSTATE_CLOSED);
671 
672     SET_EXPECT(GetLCID);
673     SET_EXPECT(OnStateChange_INITIALIZED);
674     hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
675     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
676     CHECK_CALLED(GetLCID);
677     CHECK_CALLED(OnStateChange_INITIALIZED);
678 
679     test_state(script, SCRIPTSTATE_INITIALIZED);
680 
681     SET_EXPECT(OnStateChange_CLOSED);
682     hres = IActiveScript_Close(script);
683     ok(hres == S_OK, "Close failed: %08x\n", hres);
684     CHECK_CALLED(OnStateChange_CLOSED);
685 
686     test_state(script, SCRIPTSTATE_CLOSED);
687 
688     IActiveScriptParse_Release(parse);
689 
690     ref = IActiveScript_Release(script);
691     ok(!ref, "ref = %d\n", ref);
692 }
693 
694 static void test_vbscript_release(void)
695 {
696     IActiveScriptParse *parser;
697     IActiveScript *vbscript;
698     ULONG ref;
699     HRESULT hres;
700 
701     vbscript = create_vbscript();
702 
703     hres = IActiveScript_QueryInterface(vbscript, &IID_IActiveScriptParse, (void**)&parser);
704     ok(hres == S_OK, "Could not get IActiveScriptParse iface: %08x\n", hres);
705 
706     test_state(vbscript, SCRIPTSTATE_UNINITIALIZED);
707     test_safety(vbscript);
708 
709     SET_EXPECT(GetLCID);
710     hres = IActiveScript_SetScriptSite(vbscript, &ActiveScriptSite);
711     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
712     CHECK_CALLED(GetLCID);
713 
714     test_state(vbscript, SCRIPTSTATE_UNINITIALIZED);
715 
716     SET_EXPECT(OnStateChange_INITIALIZED);
717     hres = IActiveScriptParse_InitNew(parser);
718     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
719     CHECK_CALLED(OnStateChange_INITIALIZED);
720 
721     test_state(vbscript, SCRIPTSTATE_INITIALIZED);
722 
723     SET_EXPECT(OnStateChange_CONNECTED);
724     hres = IActiveScript_SetScriptState(vbscript, SCRIPTSTATE_CONNECTED);
725     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_CONNECTED) failed: %08x\n", hres);
726     CHECK_CALLED(OnStateChange_CONNECTED);
727 
728     test_state(vbscript, SCRIPTSTATE_CONNECTED);
729 
730     IActiveScriptParse_Release(parser);
731 
732     SET_EXPECT(OnStateChange_DISCONNECTED);
733     SET_EXPECT(OnStateChange_INITIALIZED);
734     SET_EXPECT(OnStateChange_CLOSED);
735     ref = IActiveScript_Release(vbscript);
736     ok(!ref, "ref = %d\n", ref);
737     CHECK_CALLED(OnStateChange_DISCONNECTED);
738     CHECK_CALLED(OnStateChange_INITIALIZED);
739     CHECK_CALLED(OnStateChange_CLOSED);
740 }
741 
742 static void test_vbscript_simplecreate(void)
743 {
744     IActiveScript *script;
745     ULONG ref;
746     HRESULT hres;
747 
748     script = create_vbscript();
749 
750     hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_UNINITIALIZED);
751     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_UNINITIALIZED) failed: %08x\n", hres);
752 
753     ref = IActiveScript_Release(script);
754     ok(!ref, "ref = %d\n", ref);
755 }
756 
757 static void test_vbscript_initializing(void)
758 {
759     IActiveScriptParse *parse;
760     IActiveScript *script;
761     ULONG ref;
762     HRESULT hres;
763 
764     script = create_vbscript();
765 
766     hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParse, (void**)&parse);
767     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
768 
769     test_state(script, SCRIPTSTATE_UNINITIALIZED);
770 
771     SET_EXPECT(GetLCID);
772     hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
773     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
774     CHECK_CALLED(GetLCID);
775 
776     SET_EXPECT(OnStateChange_INITIALIZED);
777     hres = IActiveScriptParse_InitNew(parse);
778     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
779     CHECK_CALLED(OnStateChange_INITIALIZED);
780 
781     hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
782     ok(hres == E_UNEXPECTED, "SetScriptSite failed: %08x, expected E_UNEXPECTED\n", hres);
783 
784     SET_EXPECT(OnStateChange_CLOSED);
785     hres = IActiveScript_Close(script);
786     ok(hres == S_OK, "Close failed: %08x\n", hres);
787     CHECK_CALLED(OnStateChange_CLOSED);
788 
789     test_state(script, SCRIPTSTATE_CLOSED);
790 
791     IActiveScriptParse_Release(parse);
792 
793     ref = IActiveScript_Release(script);
794     ok(!ref, "ref = %d\n", ref);
795 }
796 
797 static void test_RegExp(void)
798 {
799     IRegExp2 *regexp;
800     IMatchCollection2 *mc;
801     IMatch2 *match;
802     ISubMatches *sm;
803     IEnumVARIANT *ev;
804     IUnknown *unk;
805     IDispatch *disp;
806     HRESULT hres;
807     BSTR bstr;
808     LONG count;
809     VARIANT v;
810     ULONG fetched;
811 
812     hres = CoCreateInstance(&CLSID_VBScriptRegExp, NULL,
813             CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
814             &IID_IUnknown, (void**)&unk);
815     if(hres == REGDB_E_CLASSNOTREG) {
816         win_skip("VBScriptRegExp is not registered\n");
817         return;
818     }
819     ok(hres == S_OK, "CoCreateInstance(CLSID_VBScriptRegExp) failed: %x\n", hres);
820 
821     hres = IUnknown_QueryInterface(unk, &IID_IRegExp2, (void**)&regexp);
822     if(hres == E_NOINTERFACE) {
823         win_skip("IRegExp2 interface is not available\n");
824         return;
825     }
826     ok(hres == S_OK, "QueryInterface(IID_IRegExp2) failed: %x\n", hres);
827     IUnknown_Release(unk);
828 
829     hres = IRegExp2_QueryInterface(regexp, &IID_IRegExp, (void**)&unk);
830     ok(hres == S_OK, "QueryInterface(IID_IRegExp) returned %x\n", hres);
831     IUnknown_Release(unk);
832 
833     hres = IRegExp2_QueryInterface(regexp, &IID_IDispatchEx, (void**)&unk);
834     ok(hres == E_NOINTERFACE, "QueryInterface(IID_IDispatchEx) returned %x\n", hres);
835 
836     hres = IRegExp2_get_Pattern(regexp, &bstr);
837     ok(bstr == NULL, "bstr != NULL\n");
838     ok(hres == S_OK, "get_Pattern returned %x, expected S_OK\n", hres);
839 
840     hres = IRegExp2_get_Pattern(regexp, NULL);
841     ok(hres == E_POINTER, "get_Pattern returned %x, expected E_POINTER\n", hres);
842 
843     hres = IRegExp2_get_IgnoreCase(regexp, NULL);
844     ok(hres == E_POINTER, "get_IgnoreCase returned %x, expected E_POINTER\n", hres);
845 
846     hres = IRegExp2_get_Global(regexp, NULL);
847     ok(hres == E_POINTER, "get_Global returned %x, expected E_POINTER\n", hres);
848 
849     hres = IRegExp2_Execute(regexp, NULL, &disp);
850     ok(hres == S_OK, "Execute returned %x, expected S_OK\n", hres);
851     hres = IDispatch_QueryInterface(disp, &IID_IMatchCollection2, (void**)&mc);
852     ok(hres == S_OK, "QueryInterface(IID_IMatchCollection2) returned %x\n", hres);
853     IDispatch_Release(disp);
854 
855     hres = IMatchCollection2_QueryInterface(mc, &IID_IMatchCollection, (void**)&unk);
856     ok(hres == S_OK, "QueryInterface(IID_IMatchCollection) returned %x\n", hres);
857     IUnknown_Release(unk);
858 
859     hres = IMatchCollection2_get_Count(mc, NULL);
860     ok(hres == E_POINTER, "get_Count returned %x, expected E_POINTER\n", hres);
861 
862     hres = IMatchCollection2_get_Count(mc, &count);
863     ok(hres == S_OK, "get_Count returned %x, expected S_OK\n", hres);
864     ok(count == 1, "count = %d\n", count);
865 
866     hres = IMatchCollection2_get_Item(mc, 1, &disp);
867     ok(hres == E_INVALIDARG, "get_Item returned %x, expected E_INVALIDARG\n", hres);
868 
869     hres = IMatchCollection2_get_Item(mc, 1, NULL);
870     ok(hres == E_POINTER, "get_Item returned %x, expected E_POINTER\n", hres);
871 
872     hres = IMatchCollection2_get_Item(mc, 0, &disp);
873     ok(hres == S_OK, "get_Item returned %x, expected S_OK\n", hres);
874     hres = IDispatch_QueryInterface(disp, &IID_IMatch2, (void**)&match);
875     ok(hres == S_OK, "QueryInterface(IID_IMatch2) returned %x\n", hres);
876     IDispatch_Release(disp);
877 
878     hres = IMatch2_QueryInterface(match, &IID_IMatch, (void**)&unk);
879     ok(hres == S_OK, "QueryInterface(IID_IMatch) returned %x\n", hres);
880     IUnknown_Release(unk);
881 
882     hres = IMatch2_get_Value(match, NULL);
883     ok(hres == E_POINTER, "get_Value returned %x, expected E_POINTER\n", hres);
884 
885     hres = IMatch2_get_FirstIndex(match, NULL);
886     ok(hres == E_POINTER, "get_FirstIndex returned %x, expected E_POINTER\n", hres);
887 
888     hres = IMatch2_get_Length(match, NULL);
889     ok(hres == E_POINTER, "get_Length returned %x, expected E_POINTER\n", hres);
890 
891     hres = IMatch2_get_SubMatches(match, NULL);
892     ok(hres == E_POINTER, "get_SubMatches returned %x, expected E_POINTER\n", hres);
893 
894     hres = IMatch2_get_SubMatches(match, &disp);
895     ok(hres == S_OK, "get_SubMatches returned %x, expected S_OK\n", hres);
896     IMatch2_Release(match);
897     hres = IDispatch_QueryInterface(disp, &IID_ISubMatches, (void**)&sm);
898     ok(hres == S_OK, "QueryInterface(IID_ISubMatches) returned %x\n", hres);
899     IDispatch_Release(disp);
900 
901     hres = ISubMatches_get_Item(sm, 0, &v);
902     ok(hres == E_INVALIDARG, "get_Item returned %x, expected E_INVALIDARG\n", hres);
903 
904     hres = ISubMatches_get_Item(sm, 0, NULL);
905     ok(hres == E_POINTER, "get_Item returned %x, expected E_POINTER\n", hres);
906 
907     hres = ISubMatches_get_Count(sm, NULL);
908     ok(hres == E_POINTER, "get_Count returned %x, expected E_POINTER\n", hres);
909     ISubMatches_Release(sm);
910 
911     hres = IMatchCollection2_get__NewEnum(mc, &unk);
912     ok(hres == S_OK, "get__NewEnum returned %x, expected S_OK\n", hres);
913     hres = IUnknown_QueryInterface(unk, &IID_IEnumVARIANT, (void**)&ev);
914     ok(hres == S_OK, "QueryInterface(IID_IEnumVARIANT) returned %x\n", hres);
915     IUnknown_Release(unk);
916     IMatchCollection2_Release(mc);
917 
918     hres = IEnumVARIANT_Skip(ev, 2);
919     ok(hres == S_OK, "Skip returned %x\n", hres);
920 
921     hres = IEnumVARIANT_Next(ev, 1, &v, &fetched);
922     ok(hres == S_FALSE, "Next returned %x, expected S_FALSE\n", hres);
923     ok(fetched == 0, "fetched = %d\n", fetched);
924 
925     hres = IEnumVARIANT_Skip(ev, -1);
926     ok(hres == S_OK, "Skip returned %x\n", hres);
927 
928     hres = IEnumVARIANT_Next(ev, 1, &v, &fetched);
929     ok(hres == S_OK, "Next returned %x\n", hres);
930     ok(fetched == 1, "fetched = %d\n", fetched);
931     VariantClear(&v);
932     IEnumVARIANT_Release(ev);
933 
934     IRegExp2_Release(regexp);
935 }
936 
937 static BOOL check_vbscript(void)
938 {
939     IActiveScriptParseProcedure2 *vbscript;
940     HRESULT hres;
941 
942     hres = CoCreateInstance(&CLSID_VBScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
943             &IID_IActiveScriptParseProcedure2, (void**)&vbscript);
944     if(SUCCEEDED(hres))
945         IActiveScriptParseProcedure2_Release(vbscript);
946 
947     return hres == S_OK;
948 }
949 
950 START_TEST(vbscript)
951 {
952     CoInitialize(NULL);
953 
954     if(check_vbscript()) {
955         test_vbscript();
956         test_vbscript_uninitializing();
957         test_vbscript_release();
958         test_vbscript_simplecreate();
959         test_vbscript_initializing();
960         test_scriptdisp();
961         test_RegExp();
962     }else {
963         win_skip("VBScript engine not available or too old\n");
964     }
965 
966     CoUninitialize();
967 }
968