scrobj/tests: Fix a typo.
[wine.git] / dlls / scrobj / tests / scrobj.c
blob4154af43de999b2416afa23a75ed73c0842a6aa0
1 /*
2 * Copyright 2019 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
19 #define COBJMACROS
20 #define CONST_VTABLE
22 #include <ole2.h>
23 #include <dispex.h>
24 #include <activscp.h>
25 #include <activdbg.h>
26 #include <objsafe.h>
27 #include <mshtmhst.h>
29 #include "wine/test.h"
30 #include "wine/heap.h"
32 static HRESULT (WINAPI *pDllInstall)(BOOL, const WCHAR *);
34 static const CLSID CLSID_WineTest = {0xa8a83483,0xa6ac,0x474d,{0xb2,0x2a,0x9a,0x5f,0x2d,0x68,0xcb,0x7f}};
35 #define CLSID_STR "{a8a83483-a6ac-474d-b22a-9a5f2d68cb7f}"
37 #define TESTSCRIPT_CLSID "{178fc164-f585-4e24-9c13-4bb7faf80746}"
38 static const GUID CLSID_TestScript =
39 {0x178fc164,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x07,0x46}};
41 #ifdef _WIN64
43 #define CTXARG_T DWORDLONG
44 #define IActiveScriptParseVtbl IActiveScriptParse64Vtbl
45 #define IActiveScriptSiteDebug_Release IActiveScriptSiteDebug64_Release
47 #else
49 #define CTXARG_T DWORD
50 #define IActiveScriptParseVtbl IActiveScriptParse32Vtbl
51 #define IActiveScriptSiteDebug_Release IActiveScriptSiteDebug32_Release
53 #endif
55 #define DEFINE_EXPECT(func) \
56 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
58 #define SET_EXPECT(func) \
59 do { called_ ## func = FALSE; expect_ ## func = TRUE; } while(0)
61 #define CHECK_EXPECT2(func) \
62 do { \
63 ok(expect_ ##func, "unexpected call " #func "\n"); \
64 called_ ## func = TRUE; \
65 }while(0)
67 #define CHECK_EXPECT(func) \
68 do { \
69 CHECK_EXPECT2(func); \
70 expect_ ## func = FALSE; \
71 }while(0)
73 #define CHECK_CALLED(func) \
74 do { \
75 ok(called_ ## func, "expected " #func "\n"); \
76 expect_ ## func = called_ ## func = FALSE; \
77 }while(0)
79 #define CHECK_CALLED_BROKEN(func) \
80 do { \
81 ok(called_ ## func || broken(!called_ ## func), "expected " #func "\n"); \
82 expect_ ## func = called_ ## func = FALSE; \
83 }while(0)
85 #define CHECK_NOT_CALLED(func) \
86 do { \
87 ok(!called_ ## func, "unexpected " #func "\n"); \
88 expect_ ## func = called_ ## func = FALSE; \
89 }while(0)
91 #define CLEAR_CALLED(func) \
92 expect_ ## func = called_ ## func = FALSE
94 DEFINE_EXPECT(CreateInstance);
95 DEFINE_EXPECT(InitNew);
96 DEFINE_EXPECT(Close);
97 DEFINE_EXPECT(SetScriptSite);
98 DEFINE_EXPECT(QI_IActiveScriptParse);
99 DEFINE_EXPECT(SetScriptState_INITIALIZED);
100 DEFINE_EXPECT(SetScriptState_UNINITIALIZED);
101 DEFINE_EXPECT(SetScriptState_STARTED);
102 DEFINE_EXPECT(AddNamedItem_scriptlet);
103 DEFINE_EXPECT(AddNamedItem_globals);
104 DEFINE_EXPECT(ParseScriptText);
105 DEFINE_EXPECT(Clone);
106 DEFINE_EXPECT(GetScriptDispatch);
107 DEFINE_EXPECT(GetDispID_vbAddOne);
108 DEFINE_EXPECT(GetDispID_wtTest);
109 DEFINE_EXPECT(GetDispID_get_gsProp);
110 DEFINE_EXPECT(GetDispID_put_gsProp);
111 DEFINE_EXPECT(InvokeEx);
112 DEFINE_EXPECT(InvokeEx_get_gsProp);
113 DEFINE_EXPECT(InvokeEx_put_gsProp);
115 #define DISPID_WTTEST 100
116 #define DISPID_GET_GSPROP 101
117 #define DISPID_PUT_GSPROP 102
119 static DWORD parse_flags;
120 static BOOL support_clone;
122 static IActiveScriptSite *site;
123 static SCRIPTSTATE state;
125 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
127 *ppv = NULL;
129 if (IsEqualGUID(riid, &IID_IUnknown)
130 || IsEqualGUID(riid, &IID_IDispatch)
131 || IsEqualGUID(riid, &IID_IDispatchEx))
132 *ppv = iface;
133 else
134 return E_NOINTERFACE;
136 return S_OK;
139 static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
141 return 2;
144 static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
146 return 1;
149 static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
151 ok(0, "unexpected call\n");
152 return E_NOTIMPL;
155 static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
156 LCID lcid, ITypeInfo **ppTInfo)
158 return E_NOTIMPL;
161 static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
162 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
164 ok(0, "unexpected call\n");
165 return E_NOTIMPL;
168 static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
169 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
170 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
172 ok(0, "unexpected call\n");
173 return E_NOTIMPL;
176 static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR name, DWORD grfdex, DISPID *pid)
178 if (!wcscmp(name, L"vbAddOne"))
180 CHECK_EXPECT(GetDispID_vbAddOne);
181 ok(grfdex == fdexNameCaseInsensitive, "grfdex = %x\n", grfdex);
182 return DISP_E_UNKNOWNNAME;
184 if (!wcscmp(name, L"wtTest"))
186 CHECK_EXPECT(GetDispID_wtTest);
187 ok(!grfdex, "grfdex = %x\n", grfdex);
188 *pid = DISPID_WTTEST;
189 return S_OK;
191 if (!wcscmp(name, L"get_gsProp"))
193 CHECK_EXPECT(GetDispID_get_gsProp);
194 ok(!grfdex, "grfdex = %x\n", grfdex);
195 *pid = DISPID_GET_GSPROP;
196 return S_OK;
198 if (!wcscmp(name, L"put_gsProp"))
200 CHECK_EXPECT(GetDispID_put_gsProp);
201 ok(!grfdex, "grfdex = %x\n", grfdex);
202 *pid = DISPID_PUT_GSPROP;
203 return S_OK;
205 ok(0, "unexpected name %s\n", wine_dbgstr_w(name));
206 return DISP_E_UNKNOWNNAME;
209 static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD flags, DISPPARAMS *pdp,
210 VARIANT *res, EXCEPINFO *pei, IServiceProvider *caller)
212 switch (id)
214 case DISPID_WTTEST:
215 CHECK_EXPECT(InvokeEx);
216 ok(lcid == 0x100, "lcid = %x\n", lcid);
217 ok(flags == DISPATCH_METHOD, "flags = %x\n", flags);
218 ok(caller == (void*)0xdeadbeef, "called = %p\n", caller);
219 V_VT(res) = VT_BOOL;
220 V_BOOL(res) = VARIANT_TRUE;
221 return S_OK;
222 case DISPID_GET_GSPROP:
223 CHECK_EXPECT(InvokeEx_get_gsProp);
224 ok(flags == DISPATCH_METHOD, "flags = %x\n", flags);
225 ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
226 V_VT(res) = VT_BOOL;
227 V_BOOL(res) = VARIANT_TRUE;
228 return S_OK;
229 case DISPID_PUT_GSPROP:
230 CHECK_EXPECT(InvokeEx_put_gsProp);
231 ok(flags == DISPATCH_METHOD, "flags = %x\n", flags);
232 ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
233 ok(pdp->cNamedArgs == 0, "cNamedArgs = %d\n", pdp->cNamedArgs);
234 V_VT(res) = VT_BOOL;
235 V_BOOL(res) = VARIANT_FALSE;
236 return S_OK;
239 ok(0, "unexpected id %u\n", id);
240 return E_FAIL;
243 static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR name, DWORD grfdex)
245 ok(0, "unexpected call %s %x\n", wine_dbgstr_w(name), grfdex);
246 return E_NOTIMPL;
249 static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
251 ok(0, "unexpected call\n");
252 return E_NOTIMPL;
255 static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
257 ok(0, "unexpected call\n");
258 return E_NOTIMPL;
261 static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *name)
263 ok(0, "unexpected call\n");
264 return E_NOTIMPL;
267 static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
269 ok(0, "unexpected call\n");
270 return E_NOTIMPL;
273 static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
275 ok(0, "unexpected call\n");
276 return E_NOTIMPL;
279 static IDispatchExVtbl DispatchExVtbl = {
280 DispatchEx_QueryInterface,
281 DispatchEx_AddRef,
282 DispatchEx_Release,
283 DispatchEx_GetTypeInfoCount,
284 DispatchEx_GetTypeInfo,
285 DispatchEx_GetIDsOfNames,
286 DispatchEx_Invoke,
287 DispatchEx_GetDispID,
288 DispatchEx_InvokeEx,
289 DispatchEx_DeleteMemberByName,
290 DispatchEx_DeleteMemberByDispID,
291 DispatchEx_GetMemberProperties,
292 DispatchEx_GetMemberName,
293 DispatchEx_GetNextDispID,
294 DispatchEx_GetNameSpaceParent
297 static IDispatchEx script_global = { &DispatchExVtbl };
299 static HRESULT WINAPI ActiveScriptParse_QueryInterface(IActiveScriptParse *iface, REFIID riid, void **ppv)
301 *ppv = NULL;
302 ok(0, "unexpected call\n");
303 return E_NOINTERFACE;
306 static ULONG WINAPI ActiveScriptParse_AddRef(IActiveScriptParse *iface)
308 return 2;
311 static ULONG WINAPI ActiveScriptParse_Release(IActiveScriptParse *iface)
313 return 1;
316 static HRESULT WINAPI ActiveScriptParse_InitNew(IActiveScriptParse *iface)
318 CHECK_EXPECT(InitNew);
319 return S_OK;
322 static HRESULT WINAPI ActiveScriptParse_AddScriptlet(IActiveScriptParse *iface,
323 LPCOLESTR pstrDefaultName, LPCOLESTR pstrCode, LPCOLESTR pstrItemName,
324 LPCOLESTR pstrSubItemName, LPCOLESTR pstrEventName, LPCOLESTR pstrDelimiter,
325 CTXARG_T dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags,
326 BSTR *pbstrName, EXCEPINFO *pexcepinfo)
328 ok(0, "unexpected call\n");
329 return E_NOTIMPL;
332 static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *iface,
333 LPCOLESTR code, LPCOLESTR item_name, IUnknown *context,
334 LPCOLESTR delimiter, CTXARG_T dwSourceContextCookie, ULONG ulStartingLine,
335 DWORD flags, VARIANT *result, EXCEPINFO *excepinfo)
337 CHECK_EXPECT(ParseScriptText);
338 ok(!wcscmp(code, L"WTTest body"), "unexpected code %s\n", wine_dbgstr_w(code));
339 ok(!item_name, "pstrItemName = %s\n", wine_dbgstr_w(item_name));
340 ok(!context, "punkContext = %p\n", context);
341 ok(!delimiter, "pstrDelimiter = %s\n", wine_dbgstr_w(delimiter));
342 ok(flags == parse_flags, "dwFlags = %x\n", flags);
343 ok(!result, "pvarResult = NULL\n");
344 ok(!excepinfo, "pexcepinfo = %p\n", excepinfo);
345 return S_OK;
348 static const IActiveScriptParseVtbl ActiveScriptParseVtbl = {
349 ActiveScriptParse_QueryInterface,
350 ActiveScriptParse_AddRef,
351 ActiveScriptParse_Release,
352 ActiveScriptParse_InitNew,
353 ActiveScriptParse_AddScriptlet,
354 ActiveScriptParse_ParseScriptText
357 static IActiveScriptParse ActiveScriptParse = { &ActiveScriptParseVtbl };
359 static HRESULT WINAPI ActiveScript_QueryInterface(IActiveScript *iface, REFIID riid, void **ppv)
361 if (IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IActiveScript, riid))
363 *ppv = iface;
364 return S_OK;
367 if (IsEqualGUID(&IID_IActiveScriptParse, riid))
369 CHECK_EXPECT(QI_IActiveScriptParse);
370 *ppv = &ActiveScriptParse;
371 return S_OK;
374 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
375 *ppv = NULL;
376 return E_NOINTERFACE;
379 static ULONG WINAPI ActiveScript_AddRef(IActiveScript *iface)
381 return 2;
384 static ULONG WINAPI ActiveScript_Release(IActiveScript *iface)
386 return 1;
389 static HRESULT WINAPI ActiveScript_SetScriptSite(IActiveScript *iface, IActiveScriptSite *pass)
391 IActiveScriptSiteInterruptPoll *poll;
392 IActiveScriptSiteWindow *window;
393 IActiveScriptSiteDebug *debug;
394 IServiceProvider *service;
395 ICanHandleException *canexception;
396 LCID lcid;
397 HRESULT hres;
399 CHECK_EXPECT(SetScriptSite);
401 ok(pass != NULL, "pass == NULL\n");
403 hres = IActiveScriptSite_QueryInterface(pass, &IID_IActiveScriptSiteInterruptPoll, (void**)&poll);
404 ok(hres == E_NOINTERFACE, "Got IActiveScriptSiteInterruptPoll interface: %08x\n", hres);
406 hres = IActiveScriptSite_GetLCID(pass, &lcid);
407 ok(hres == S_OK, "GetLCID failed: %08x\n", hres);
409 hres = IActiveScriptSite_OnStateChange(pass, (state = SCRIPTSTATE_INITIALIZED));
410 ok(hres == E_NOTIMPL, "OnStateChange failed: %08x\n", hres);
412 hres = IActiveScriptSite_QueryInterface(pass, &IID_IActiveScriptSiteDebug, (void**)&debug);
413 todo_wine
414 ok(hres == S_OK, "IActiveScriptSiteDebug not supported: %08x\n", hres);
415 if (SUCCEEDED(hres))
416 IActiveScriptSiteDebug_Release(debug);
418 hres = IActiveScriptSite_QueryInterface(pass, &IID_ICanHandleException, (void**)&canexception);
419 ok(hres == E_NOINTERFACE, "Got IID_ICanHandleException interface: %08x\n", hres);
421 hres = IActiveScriptSite_QueryInterface(pass, &IID_IServiceProvider, (void**)&service);
422 ok(hres == S_OK, "Could not get IServiceProvider interface: %08x\n", hres);
423 if (SUCCEEDED(hres))
424 IServiceProvider_Release(service);
426 hres = IActiveScriptSite_QueryInterface(pass, &IID_IActiveScriptSiteWindow, (void**)&window);
427 ok(hres == S_OK, "Could not get IActiveScriptSiteWindow interface: %08x\n", hres);
428 if (window)
429 IActiveScriptSiteWindow_Release(window);
431 if (site)
432 IActiveScriptSite_Release(site);
433 site = pass;
434 IActiveScriptSite_AddRef(site);
436 return S_OK;
439 static HRESULT WINAPI ActiveScript_GetScriptSite(IActiveScript *iface, REFIID riid, void **ppv)
441 ok(0, "unexpected call\n");
442 return E_NOTIMPL;
445 static HRESULT WINAPI ActiveScript_SetScriptState(IActiveScript *iface, SCRIPTSTATE ss)
447 switch(ss)
449 case SCRIPTSTATE_INITIALIZED:
450 CHECK_EXPECT(SetScriptState_INITIALIZED);
451 break;
452 case SCRIPTSTATE_UNINITIALIZED:
453 CHECK_EXPECT(SetScriptState_UNINITIALIZED);
454 break;
455 case SCRIPTSTATE_STARTED:
456 CHECK_EXPECT(SetScriptState_STARTED);
457 break;
458 default:
459 ok(0, "unexpected call, state %u\n", ss);
462 return S_OK;
465 static HRESULT WINAPI ActiveScript_GetScriptState(IActiveScript *iface, SCRIPTSTATE *pssState)
467 ok(0, "unexpected call\n");
468 return E_NOTIMPL;
471 static HRESULT WINAPI ActiveScript_Close(IActiveScript *iface)
473 CHECK_EXPECT(Close);
474 if (site)
476 IActiveScriptSite_Release(site);
477 site = NULL;
479 return S_OK;
482 static HRESULT WINAPI ActiveScript_AddNamedItem(IActiveScript *iface, LPCOLESTR name, DWORD flags)
484 if (!wcscmp(name, L"scriptlet"))
486 CHECK_EXPECT(AddNamedItem_scriptlet);
487 ok(flags == (SCRIPTITEM_ISVISIBLE|SCRIPTITEM_GLOBALMEMBERS), "got flags %#x\n", flags);
489 else if (!wcscmp(name, L"globals"))
491 CHECK_EXPECT(AddNamedItem_globals);
492 ok(flags == SCRIPTITEM_ISVISIBLE, "got flags %#x\n", flags);
494 else
496 ok(0, "got name %s\n", wine_dbgstr_w(name));
497 return E_FAIL;
499 return S_OK;
502 static HRESULT WINAPI ActiveScript_AddTypeLib(IActiveScript *iface, REFGUID rguidTypeLib,
503 DWORD dwMajor, DWORD dwMinor, DWORD dwFlags)
505 ok(0, "unexpected call\n");
506 return E_NOTIMPL;
509 static HRESULT WINAPI ActiveScript_GetScriptDispatch(IActiveScript *iface, LPCOLESTR item_name,
510 IDispatch **ppdisp)
512 CHECK_EXPECT(GetScriptDispatch);
513 ok(!item_name, "item name %s\n", wine_dbgstr_w(item_name));
514 IDispatch_AddRef(*ppdisp = (IDispatch*)&script_global);
515 return S_OK;
518 static HRESULT WINAPI ActiveScript_GetCurrentScriptThreadID(IActiveScript *iface,
519 SCRIPTTHREADID *pstridThread)
521 ok(0, "unexpected call\n");
522 return E_NOTIMPL;
525 static HRESULT WINAPI ActiveScript_GetScriptThreadID(IActiveScript *iface,
526 DWORD dwWin32ThreadId, SCRIPTTHREADID *pstidThread)
528 ok(0, "unexpected call\n");
529 return E_NOTIMPL;
532 static HRESULT WINAPI ActiveScript_GetScriptThreadState(IActiveScript *iface,
533 SCRIPTTHREADID stidThread, SCRIPTTHREADSTATE *pstsState)
535 ok(0, "unexpected call\n");
536 return E_NOTIMPL;
539 static HRESULT WINAPI ActiveScript_InterruptScriptThread(IActiveScript *iface,
540 SCRIPTTHREADID stidThread, const EXCEPINFO *pexcepinfo, DWORD dwFlags)
542 ok(0, "unexpected call\n");
543 return E_NOTIMPL;
546 static HRESULT WINAPI ActiveScript_Clone(IActiveScript *iface, IActiveScript **ppscript)
548 CHECK_EXPECT(Clone);
550 if (support_clone)
552 *ppscript = iface;
553 return S_OK;
556 if (parse_flags == SCRIPTTEXT_ISVISIBLE) return E_NOTIMPL;
558 CHECK_CALLED(CreateInstance);
559 CHECK_CALLED(QI_IActiveScriptParse);
560 CHECK_CALLED(InitNew);
561 CHECK_CALLED(SetScriptSite);
562 CHECK_CALLED(ParseScriptText);
563 CHECK_CALLED(SetScriptState_UNINITIALIZED);
565 SET_EXPECT(CreateInstance);
566 SET_EXPECT(QI_IActiveScriptParse);
567 SET_EXPECT(InitNew);
568 SET_EXPECT(SetScriptSite);
569 SET_EXPECT(AddNamedItem_scriptlet);
570 SET_EXPECT(AddNamedItem_globals);
571 SET_EXPECT(GetScriptDispatch);
572 SET_EXPECT(GetDispID_vbAddOne);
573 SET_EXPECT(GetDispID_wtTest);
574 SET_EXPECT(GetDispID_get_gsProp);
575 SET_EXPECT(GetDispID_put_gsProp);
576 SET_EXPECT(SetScriptState_STARTED);
577 SET_EXPECT(ParseScriptText);
579 parse_flags = SCRIPTTEXT_ISVISIBLE;
580 return E_NOTIMPL;
583 static const IActiveScriptVtbl ActiveScriptVtbl = {
584 ActiveScript_QueryInterface,
585 ActiveScript_AddRef,
586 ActiveScript_Release,
587 ActiveScript_SetScriptSite,
588 ActiveScript_GetScriptSite,
589 ActiveScript_SetScriptState,
590 ActiveScript_GetScriptState,
591 ActiveScript_Close,
592 ActiveScript_AddNamedItem,
593 ActiveScript_AddTypeLib,
594 ActiveScript_GetScriptDispatch,
595 ActiveScript_GetCurrentScriptThreadID,
596 ActiveScript_GetScriptThreadID,
597 ActiveScript_GetScriptThreadState,
598 ActiveScript_InterruptScriptThread,
599 ActiveScript_Clone
602 static IActiveScript ActiveScript = { &ActiveScriptVtbl };
604 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
606 *ppv = NULL;
608 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) {
609 *ppv = iface;
610 return S_OK;
613 if(IsEqualGUID(&IID_IMarshal, riid) || IsEqualGUID(&IID_IClassFactoryEx, riid))
614 return E_NOINTERFACE;
616 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
617 return E_NOINTERFACE;
620 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
622 return 2;
625 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
627 return 1;
630 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
632 CHECK_EXPECT(CreateInstance);
634 ok(!outer, "outer = %p\n", outer);
635 ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
636 *ppv = &ActiveScript;
637 return S_OK;
640 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
642 ok(0, "unexpected call\n");
643 return S_OK;
646 static const IClassFactoryVtbl ClassFactoryVtbl = {
647 ClassFactory_QueryInterface,
648 ClassFactory_AddRef,
649 ClassFactory_Release,
650 ClassFactory_CreateInstance,
651 ClassFactory_LockServer
654 static IClassFactory script_cf = { &ClassFactoryVtbl };
656 static BOOL init_key(const char *key_name, const char *def_value, BOOL init)
658 HKEY hkey;
659 DWORD res;
661 if(!init) {
662 RegDeleteKeyA(HKEY_CLASSES_ROOT, key_name);
663 return TRUE;
666 res = RegCreateKeyA(HKEY_CLASSES_ROOT, key_name, &hkey);
667 if(res != ERROR_SUCCESS)
668 return FALSE;
670 if(def_value)
671 res = RegSetValueA(hkey, NULL, REG_SZ, def_value, strlen(def_value));
673 RegCloseKey(hkey);
675 return res == ERROR_SUCCESS;
678 static BOOL register_script_engine(BOOL init)
680 DWORD regid;
681 HRESULT hres;
683 if (!init_key("WTScript\\CLSID", TESTSCRIPT_CLSID, init)) return FALSE;
684 if (!init) return TRUE;
686 hres = CoRegisterClassObject(&CLSID_TestScript, (IUnknown *)&script_cf,
687 CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &regid);
688 ok(hres == S_OK, "Could not register script engine: %08x\n", hres);
689 return TRUE;
692 static WCHAR *get_test_file(const char *res_name)
694 WCHAR path[MAX_PATH], buffer[MAX_PATH], *ret;
695 const char *data;
696 HANDLE handle;
697 DWORD size;
698 HRSRC src;
699 BOOL res;
701 src = FindResourceA(NULL, res_name, (const char *)40);
702 ok(src != NULL, "Could not find resource %s\n", res_name);
703 size = SizeofResource(NULL, src);
704 data = LoadResource(NULL, src);
706 GetTempPathW(ARRAY_SIZE(path), path);
707 GetTempFileNameW(path, L"wsc", 0, buffer);
708 handle = CreateFileW(buffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
709 ok(handle != INVALID_HANDLE_VALUE, "failed to create temp file\n");
711 res = WriteFile(handle, data, size, &size, NULL);
712 ok(res, "WriteFile failed: %u\n", GetLastError());
714 res = CloseHandle(handle);
715 ok(res, "CloseHandle failed: %u\n", GetLastError());
717 size = (wcslen(buffer) + 1) * sizeof(WCHAR);
718 ret = heap_alloc(size);
719 memcpy(ret, buffer, size);
720 return ret;
723 #define test_key_value(a,b) test_key_value_(a,b,__LINE__)
724 static void test_key_value_(const char *key_name, const char *expect, unsigned line)
726 char buf[512];
727 LONG size = sizeof(buf);
728 LSTATUS status;
729 status = RegQueryValueA(HKEY_CLASSES_ROOT, key_name, buf, &size);
730 ok_(__FILE__,line)(!status, "RegQueryValueA failed: %u\n", status);
731 if (*expect == '*')
732 ok_(__FILE__,line)(size >= strlen(expect) + 1 && !strcmp(buf + size - strlen(expect), expect + 1),
733 "Unexpected value \"%s\", expected \"%s\"\n", buf, expect);
734 else
735 ok_(__FILE__,line)(size == strlen(expect) + 1 && !memicmp(buf, expect, size),
736 "Unexpected value \"%s\", expected \"%s\"\n", buf, expect);
739 static void test_key_deleted(const char *key_name)
741 HKEY key;
742 LSTATUS status;
743 status = RegOpenKeyA(HKEY_CLASSES_ROOT, key_name, &key);
744 ok(status == ERROR_FILE_NOT_FOUND, "RegOpenKey(\"%s\") returned %u\n", key_name, status);
747 static void register_script_object(BOOL do_register, const WCHAR *file_name)
749 HRESULT hres;
751 parse_flags = SCRIPTTEXT_ISPERSISTENT | SCRIPTTEXT_ISVISIBLE;
753 SET_EXPECT(CreateInstance);
754 SET_EXPECT(QI_IActiveScriptParse);
755 SET_EXPECT(InitNew);
756 SET_EXPECT(SetScriptSite);
757 SET_EXPECT(ParseScriptText);
758 SET_EXPECT(SetScriptState_UNINITIALIZED);
759 SET_EXPECT(Close);
760 hres = pDllInstall(do_register, file_name);
761 CHECK_CALLED(CreateInstance);
762 CHECK_CALLED(QI_IActiveScriptParse);
763 CHECK_CALLED(InitNew);
764 CHECK_CALLED(SetScriptSite);
765 CHECK_CALLED(ParseScriptText);
766 CHECK_CALLED(SetScriptState_UNINITIALIZED);
767 CHECK_CALLED(Close);
768 ok(hres == S_OK, "DllInstall failed: %08x\n", hres);
770 if (do_register)
772 test_key_value("CLSID\\" CLSID_STR, "WineTest object");
773 test_key_value("CLSID\\" CLSID_STR "\\InprocServer32", "*\\scrobj.dll");
774 test_key_value("CLSID\\" CLSID_STR "\\ProgID", "WineTest.1.23");
775 test_key_value("CLSID\\" CLSID_STR "\\VersionIndependentProgID", "WineTest");
776 test_key_value("WineTest", "WineTest object");
777 test_key_value("WineTest\\CLSID", CLSID_STR);
778 test_key_value("WineTest.1.23", "WineTest object");
779 test_key_value("WineTest.1.23\\CLSID", CLSID_STR);
781 else
783 test_key_deleted("CLSID\\" CLSID_STR);
784 test_key_deleted("WineTest");
785 test_key_deleted("WineTest.1.23");
789 static void test_create_object(void)
791 DISPID vb_add_one_id, js_add_two_id, wt_test_id, wt_gsprop_id, id;
792 DISPID id_propput = DISPID_PROPERTYPUT;
793 IDispatchEx *dispex;
794 IClassFactory *cf;
795 IDispatch *disp;
796 IUnknown *unk;
797 DISPPARAMS dp;
798 EXCEPINFO ei;
799 VARIANT v, r;
800 BSTR str;
801 HRESULT hres;
803 hres = CoGetClassObject(&CLSID_WineTest, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, NULL,
804 &IID_IClassFactory, (void**)&cf);
805 ok(hres == S_OK, "Could not get class factory: %08x\n", hres);
807 parse_flags = SCRIPTTEXT_ISPERSISTENT | SCRIPTTEXT_ISVISIBLE;
809 /* CreateInstance creates two script engine instances. The first one is for validation
810 * and is created once per class factry. Then, when object instance is created, it tries
811 * to clone that or create a new instance from scratch.
812 * We don't implement Clone in tests, but we use it to check already called functions
813 * and set new expected once.
815 SET_EXPECT(CreateInstance);
816 SET_EXPECT(QI_IActiveScriptParse);
817 SET_EXPECT(InitNew);
818 SET_EXPECT(SetScriptSite);
819 SET_EXPECT(ParseScriptText);
820 SET_EXPECT(SetScriptState_UNINITIALIZED);
821 SET_EXPECT(Clone);
822 hres = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void**)&unk);
823 ok(hres == S_OK, "Could not create scriptlet instance: %08x\n", hres);
824 CHECK_CALLED(Clone);
825 CHECK_CALLED(CreateInstance);
826 CHECK_CALLED(QI_IActiveScriptParse);
827 CHECK_CALLED(InitNew);
828 CHECK_CALLED(SetScriptSite);
829 CHECK_CALLED(AddNamedItem_scriptlet);
830 CHECK_CALLED(AddNamedItem_globals);
831 CHECK_CALLED(GetScriptDispatch);
832 todo_wine
833 CHECK_CALLED(GetDispID_vbAddOne);
834 CHECK_CALLED(GetDispID_wtTest);
835 CHECK_CALLED(GetDispID_get_gsProp);
836 CHECK_CALLED(GetDispID_put_gsProp);
837 CHECK_CALLED(SetScriptState_STARTED);
838 CHECK_CALLED(ParseScriptText);
840 hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
841 ok(hres == S_OK, "Could not get IDispatch iface: %08x\n", hres);
843 IDispatch_Release(disp);
845 hres = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
846 ok(hres == S_OK, "Could not get IDispatch iface: %08x\n", hres);
848 str = SysAllocString(L"vbAddOne");
849 hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseSensitive, &vb_add_one_id);
850 ok(hres == S_OK, "Could not get vkAddOne id: %08x\n", hres);
851 SysFreeString(str);
853 str = SysAllocString(L"jsAddTwo");
854 hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseSensitive, &js_add_two_id);
855 ok(hres == S_OK, "Could not get jsAddTwo id: %08x\n", hres);
856 SysFreeString(str);
858 str = SysAllocString(L"wtTest");
859 hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseSensitive, &wt_test_id);
860 ok(hres == S_OK, "Could not get wtTest id: %08x\n", hres);
861 SysFreeString(str);
863 str = SysAllocString(L"gsProp");
864 hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseSensitive, &wt_gsprop_id);
865 ok(hres == S_OK, "Could not get wtTest id: %08x\n", hres);
866 SysFreeString(str);
868 str = SysAllocString(L"vbaddone");
869 hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseSensitive, &id);
870 ok(hres == DISP_E_UNKNOWNNAME, "invalid case returned: %08x\n", hres);
871 SysFreeString(str);
873 str = SysAllocString(L"vbaddone");
874 hres = IDispatchEx_GetDispID(dispex, str, 0, &id);
875 ok(hres == DISP_E_UNKNOWNNAME, "invalid case returned: %08x\n", hres);
876 SysFreeString(str);
878 str = SysAllocString(L"vbaddone");
879 hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id);
880 ok(hres == S_OK, "case insensitive returned: %08x\n", hres);
881 ok(id == vb_add_one_id, "id = %u, expected %u\n", id, vb_add_one_id);
882 SysFreeString(str);
884 memset(&ei, 0, sizeof(ei));
885 memset(&dp, 0, sizeof(dp));
886 V_VT(&v) = VT_I4;
887 V_I4(&v) = 2;
888 V_VT(&r) = VT_ERROR;
889 dp.cArgs = 1;
890 dp.rgvarg = &v;
891 hres = IDispatchEx_InvokeEx(dispex, vb_add_one_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &r, &ei, NULL);
892 ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
893 ok(V_VT(&r) == VT_I4, "V_VT(r) = %d\n", V_VT(&r));
894 ok(V_I4(&r) == 3, "V_I4(r) = %d\n", V_I4(&r));
896 memset(&ei, 0, sizeof(ei));
897 memset(&dp, 0, sizeof(dp));
898 V_VT(&v) = VT_I4;
899 V_I4(&v) = 4;
900 V_VT(&r) = VT_ERROR;
901 dp.cArgs = 1;
902 dp.rgvarg = &v;
903 hres = IDispatchEx_InvokeEx(dispex, js_add_two_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &r, &ei, NULL);
904 ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
905 ok(V_VT(&r) == VT_I4, "V_VT(r) = %d\n", V_VT(&r));
906 ok(V_I4(&r) == 6, "V_I4(r) = %d\n", V_I4(&r));
908 memset(&ei, 0, sizeof(ei));
909 memset(&dp, 0, sizeof(dp));
910 V_VT(&v) = VT_I4;
911 V_I4(&v) = 4;
912 V_VT(&r) = VT_ERROR;
913 dp.cArgs = 1;
914 dp.rgvarg = &v;
915 SET_EXPECT(InvokeEx);
916 hres = IDispatchEx_InvokeEx(dispex, wt_test_id, 0x100, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &r, &ei, (void*)0xdeadbeef);
917 ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
918 CHECK_CALLED(InvokeEx);
919 ok(V_VT(&r) == VT_BOOL, "V_VT(r) = %d\n", V_VT(&r));
920 ok(V_BOOL(&r) == VARIANT_TRUE, "V_I4(r) = %d\n", V_I4(&r));
922 memset(&ei, 0, sizeof(ei));
923 memset(&dp, 0, sizeof(dp));
924 V_VT(&r) = VT_ERROR;
925 SET_EXPECT(InvokeEx);
926 hres = IDispatchEx_InvokeEx(dispex, wt_test_id, 0x100, DISPATCH_METHOD, &dp, &r, &ei, (void*)0xdeadbeef);
927 ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
928 CHECK_CALLED(InvokeEx);
929 ok(V_VT(&r) == VT_BOOL, "V_VT(r) = %d\n", V_VT(&r));
930 ok(V_BOOL(&r) == VARIANT_TRUE, "V_I4(r) = %d\n", V_I4(&r));
932 memset(&ei, 0, sizeof(ei));
933 memset(&dp, 0, sizeof(dp));
934 V_VT(&v) = VT_I4;
935 V_I4(&v) = 4;
936 V_VT(&r) = VT_ERROR;
937 dp.cArgs = 1;
938 dp.rgvarg = &v;
939 SET_EXPECT(InvokeEx_get_gsProp);
940 hres = IDispatchEx_InvokeEx(dispex, wt_gsprop_id, 0, DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dp, &r, &ei, NULL);
941 ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
942 CHECK_CALLED(InvokeEx_get_gsProp);
943 ok(V_VT(&r) == VT_BOOL, "V_VT(r) = %d\n", V_VT(&r));
944 ok(V_BOOL(&r) == VARIANT_TRUE, "V_I4(r) = %d\n", V_I4(&r));
946 memset(&ei, 0, sizeof(ei));
947 memset(&dp, 0, sizeof(dp));
948 V_VT(&v) = VT_I4;
949 V_I4(&v) = 4;
950 V_VT(&r) = VT_ERROR;
951 dp.cArgs = 1;
952 dp.rgdispidNamedArgs = &id_propput;
953 dp.rgvarg = &v;
954 dp.cNamedArgs = 1;
955 SET_EXPECT(InvokeEx_put_gsProp);
956 hres = IDispatchEx_InvokeEx(dispex, wt_gsprop_id, 0, DISPATCH_PROPERTYPUT, &dp, &r, &ei, NULL);
957 ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
958 CHECK_CALLED(InvokeEx_put_gsProp);
959 ok(V_VT(&r) == VT_BOOL, "V_VT(r) = %d\n", V_VT(&r));
960 ok(V_BOOL(&r) == VARIANT_FALSE, "V_I4(r) = %d\n", V_I4(&r));
962 hres = IDispatchEx_InvokeEx(dispex, wt_test_id, 0x100, DISPATCH_PROPERTYGET, &dp, &r, &ei, (void*)0xdeadbeef);
963 ok(hres == DISP_E_MEMBERNOTFOUND, "InvokeEx returned: %08x\n", hres);
965 hres = IDispatchEx_InvokeEx(dispex, 0xdeadbeef, 0, DISPATCH_METHOD, &dp, &r, &ei, (void*)0xdeadbeef);
966 ok(hres == DISP_E_MEMBERNOTFOUND, "InvokeEx returned: %08x\n", hres);
968 hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, 0, DISPATCH_METHOD, &dp, &r, &ei, (void*)0xdeadbeef);
969 ok(hres == DISP_E_MEMBERNOTFOUND, "InvokeEx returned: %08x\n", hres);
971 IDispatchEx_Release(dispex);
973 SET_EXPECT(SetScriptState_UNINITIALIZED);
974 SET_EXPECT(Close);
975 IUnknown_Release(unk);
976 CHECK_CALLED(SetScriptState_UNINITIALIZED);
977 CHECK_CALLED(Close);
979 parse_flags = SCRIPTTEXT_ISVISIBLE;
981 SET_EXPECT(Clone);
982 SET_EXPECT(CreateInstance);
983 SET_EXPECT(QI_IActiveScriptParse);
984 SET_EXPECT(InitNew);
985 SET_EXPECT(SetScriptSite);
986 SET_EXPECT(AddNamedItem_scriptlet);
987 SET_EXPECT(AddNamedItem_globals);
988 SET_EXPECT(GetScriptDispatch);
989 SET_EXPECT(GetDispID_vbAddOne);
990 SET_EXPECT(GetDispID_wtTest);
991 SET_EXPECT(GetDispID_get_gsProp);
992 SET_EXPECT(GetDispID_put_gsProp);
993 SET_EXPECT(SetScriptState_STARTED);
994 SET_EXPECT(ParseScriptText);
995 hres = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void**)&unk);
996 ok(hres == S_OK, "Could not create scriptlet instance: %08x\n", hres);
997 CHECK_CALLED(Clone);
998 CHECK_CALLED(CreateInstance);
999 CHECK_CALLED(QI_IActiveScriptParse);
1000 CHECK_CALLED(InitNew);
1001 CHECK_CALLED(SetScriptSite);
1002 CHECK_CALLED(AddNamedItem_scriptlet);
1003 CHECK_CALLED(AddNamedItem_globals);
1004 CHECK_CALLED(GetScriptDispatch);
1005 todo_wine
1006 CHECK_CALLED(GetDispID_vbAddOne);
1007 CHECK_CALLED(GetDispID_wtTest);
1008 CHECK_CALLED(GetDispID_get_gsProp);
1009 CHECK_CALLED(GetDispID_put_gsProp);
1010 CHECK_CALLED(SetScriptState_STARTED);
1011 CHECK_CALLED(ParseScriptText);
1013 SET_EXPECT(SetScriptState_UNINITIALIZED);
1014 SET_EXPECT(Close);
1015 IUnknown_Release(unk);
1016 CHECK_CALLED(SetScriptState_UNINITIALIZED);
1017 CHECK_CALLED(Close);
1019 support_clone = TRUE;
1020 SET_EXPECT(Clone);
1021 SET_EXPECT(QI_IActiveScriptParse);
1022 SET_EXPECT(SetScriptSite);
1023 SET_EXPECT(AddNamedItem_scriptlet);
1024 SET_EXPECT(AddNamedItem_globals);
1025 SET_EXPECT(GetScriptDispatch);
1026 SET_EXPECT(GetDispID_vbAddOne);
1027 SET_EXPECT(GetDispID_wtTest);
1028 SET_EXPECT(GetDispID_get_gsProp);
1029 SET_EXPECT(GetDispID_put_gsProp);
1030 SET_EXPECT(SetScriptState_STARTED);
1031 hres = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void**)&unk);
1032 ok(hres == S_OK, "Could not create scriptlet instance: %08x\n", hres);
1033 CHECK_CALLED(Clone);
1034 CHECK_CALLED(QI_IActiveScriptParse);
1035 CHECK_CALLED(SetScriptSite);
1036 CHECK_CALLED(AddNamedItem_scriptlet);
1037 CHECK_CALLED(AddNamedItem_globals);
1038 CHECK_CALLED(GetScriptDispatch);
1039 todo_wine
1040 CHECK_CALLED(GetDispID_vbAddOne);
1041 CHECK_CALLED(GetDispID_wtTest);
1042 CHECK_CALLED(GetDispID_get_gsProp);
1043 CHECK_CALLED(GetDispID_put_gsProp);
1044 CHECK_CALLED(SetScriptState_STARTED);
1046 SET_EXPECT(SetScriptState_UNINITIALIZED);
1047 SET_EXPECT(Close);
1048 IUnknown_Release(unk);
1049 CHECK_CALLED(SetScriptState_UNINITIALIZED);
1050 CHECK_CALLED(Close);
1052 SET_EXPECT(Close);
1053 IClassFactory_Release(cf);
1054 CHECK_CALLED(Close);
1057 START_TEST(scrobj)
1059 HMODULE scrobj_module;
1060 WCHAR *test_file;
1061 HRESULT hres;
1063 hres = CoInitialize(NULL);
1064 ok(hres == S_OK, "CoInitialize failed: %08x\n", hres);
1066 scrobj_module = LoadLibraryA("scrobj.dll");
1067 ok(scrobj_module != NULL, "Could not load scrobj.dll\n");
1069 pDllInstall = (void *)GetProcAddress(scrobj_module, "DllInstall");
1070 ok(pDllInstall != NULL, "DllInstall not found in scrobj.dll\n");
1072 if (register_script_engine(TRUE))
1074 test_file = get_test_file("scrobj.wsc");
1076 register_script_object(TRUE, test_file);
1077 test_create_object();
1078 register_script_object(FALSE, test_file);
1080 register_script_engine(FALSE);
1081 heap_free(test_file);
1083 else
1084 skip("Could not register script engine\n");
1086 CoUninitialize();