/* * Copyright 2016 Nikolay Sivov for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #define COBJMACROS #define CONST_VTABLE #include #include #include #include "dispex.h" #include "activscp.h" #include "activdbg.h" #include "objsafe.h" #include "msscript.h" #include "wine/test.h" #define TESTSCRIPT_CLSID "{178fc164-f585-4e24-9c13-4bb7faf80746}" static const GUID CLSID_TestScript = {0x178fc164,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x07,0x46}}; static const WCHAR vbW[] = {'V','B','S','c','r','i','p','t',0}; #ifdef _WIN64 #define CTXARG_T DWORDLONG #define IActiveScriptParseVtbl IActiveScriptParse64Vtbl #define IActiveScriptSiteDebug_Release IActiveScriptSiteDebug64_Release #else #define CTXARG_T DWORD #define IActiveScriptParseVtbl IActiveScriptParse32Vtbl #define IActiveScriptSiteDebug_Release IActiveScriptSiteDebug32_Release #endif #define DEFINE_EXPECT(func) \ static BOOL expect_ ## func = FALSE, called_ ## func = FALSE #define SET_EXPECT(func) \ do { called_ ## func = FALSE; expect_ ## func = TRUE; } while(0) #define CHECK_EXPECT2(func) \ do { \ ok(expect_ ##func, "unexpected call " #func "\n"); \ called_ ## func = TRUE; \ }while(0) #define CHECK_EXPECT(func) \ do { \ CHECK_EXPECT2(func); \ expect_ ## func = FALSE; \ }while(0) #define CHECK_CALLED(func) \ do { \ ok(called_ ## func, "expected " #func "\n"); \ expect_ ## func = called_ ## func = FALSE; \ }while(0) #define CHECK_CALLED_BROKEN(func) \ do { \ ok(called_ ## func || broken(!called_ ## func), "expected " #func "\n"); \ expect_ ## func = called_ ## func = FALSE; \ }while(0) #define CHECK_NOT_CALLED(func) \ do { \ ok(!called_ ## func, "unexpected " #func "\n"); \ expect_ ## func = called_ ## func = FALSE; \ }while(0) #define CLEAR_CALLED(func) \ expect_ ## func = called_ ## func = FALSE DEFINE_EXPECT(CreateInstance); DEFINE_EXPECT(SetInterfaceSafetyOptions); DEFINE_EXPECT(InitNew); DEFINE_EXPECT(Close); DEFINE_EXPECT(SetScriptSite); DEFINE_EXPECT(QI_IActiveScriptParse); DEFINE_EXPECT(SetScriptState_INITIALIZED); DEFINE_EXPECT(AddNamedItem); #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__) static void _expect_ref(IUnknown* obj, ULONG ref, int line) { ULONG rc; IUnknown_AddRef(obj); rc = IUnknown_Release(obj); ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc); } static IActiveScriptSite *site; static SCRIPTSTATE state; static HRESULT WINAPI ActiveScriptParse_QueryInterface(IActiveScriptParse *iface, REFIID riid, void **ppv) { *ppv = NULL; ok(0, "unexpected call\n"); return E_NOINTERFACE; } static ULONG WINAPI ActiveScriptParse_AddRef(IActiveScriptParse *iface) { return 2; } static ULONG WINAPI ActiveScriptParse_Release(IActiveScriptParse *iface) { return 1; } static HRESULT WINAPI ActiveScriptParse_InitNew(IActiveScriptParse *iface) { CHECK_EXPECT(InitNew); return S_OK; } static HRESULT WINAPI ActiveScriptParse_AddScriptlet(IActiveScriptParse *iface, LPCOLESTR pstrDefaultName, LPCOLESTR pstrCode, LPCOLESTR pstrItemName, LPCOLESTR pstrSubItemName, LPCOLESTR pstrEventName, LPCOLESTR pstrDelimiter, CTXARG_T dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags, BSTR *pbstrName, EXCEPINFO *pexcepinfo) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *iface, LPCOLESTR pstrCode, LPCOLESTR pstrItemName, IUnknown *punkContext, LPCOLESTR pstrDelimiter, CTXARG_T dwSourceContextCookie, ULONG ulStartingLine, DWORD dwFlags, VARIANT *pvarResult, EXCEPINFO *pexcepinfo) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static const IActiveScriptParseVtbl ActiveScriptParseVtbl = { ActiveScriptParse_QueryInterface, ActiveScriptParse_AddRef, ActiveScriptParse_Release, ActiveScriptParse_InitNew, ActiveScriptParse_AddScriptlet, ActiveScriptParse_ParseScriptText }; static IActiveScriptParse ActiveScriptParse = { &ActiveScriptParseVtbl }; static HRESULT WINAPI ObjectSafety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv) { *ppv = NULL; ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid)); return E_NOINTERFACE; } static ULONG WINAPI ObjectSafety_AddRef(IObjectSafety *iface) { return 2; } static ULONG WINAPI ObjectSafety_Release(IObjectSafety *iface) { return 1; } static HRESULT WINAPI ObjectSafety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions) { ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid)); return E_NOTIMPL; } static HRESULT WINAPI ObjectSafety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid, DWORD mask, DWORD options) { CHECK_EXPECT(SetInterfaceSafetyOptions); ok(IsEqualGUID(&IID_IActiveScriptParse, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid)); ok(mask == INTERFACESAFE_FOR_UNTRUSTED_DATA, "option mask = %x\n", mask); ok(options == 0, "options = %x\n", options); return S_OK; } static const IObjectSafetyVtbl ObjectSafetyVtbl = { ObjectSafety_QueryInterface, ObjectSafety_AddRef, ObjectSafety_Release, ObjectSafety_GetInterfaceSafetyOptions, ObjectSafety_SetInterfaceSafetyOptions }; static IObjectSafety ObjectSafety = { &ObjectSafetyVtbl }; static HRESULT WINAPI ActiveScript_QueryInterface(IActiveScript *iface, REFIID riid, void **ppv) { *ppv = NULL; if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IActiveScript, riid)) { *ppv = iface; return S_OK; } if(IsEqualGUID(&IID_IObjectSafety, riid)) { *ppv = &ObjectSafety; return S_OK; } if(IsEqualGUID(&IID_IActiveScriptParse, riid)) { CHECK_EXPECT(QI_IActiveScriptParse); *ppv = &ActiveScriptParse; return S_OK; } if(IsEqualGUID(&IID_IActiveScriptGarbageCollector, riid)) return E_NOINTERFACE; ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid)); return E_NOINTERFACE; } static ULONG WINAPI ActiveScript_AddRef(IActiveScript *iface) { return 2; } static ULONG WINAPI ActiveScript_Release(IActiveScript *iface) { return 1; } static HRESULT WINAPI ActiveScript_SetScriptSite(IActiveScript *iface, IActiveScriptSite *pass) { IActiveScriptSiteInterruptPoll *poll; IActiveScriptSiteWindow *window; IActiveScriptSiteDebug *debug; IServiceProvider *service; ICanHandleException *canexpection; LCID lcid; HRESULT hres; CHECK_EXPECT(SetScriptSite); ok(pass != NULL, "pass == NULL\n"); hres = IActiveScriptSite_QueryInterface(pass, &IID_IActiveScriptSiteInterruptPoll, (void**)&poll); ok(hres == E_NOINTERFACE, "Got IActiveScriptSiteInterruptPoll interface: %08x\n", hres); hres = IActiveScriptSite_GetLCID(pass, &lcid); ok(hres == S_OK, "GetLCID failed: %08x\n", hres); hres = IActiveScriptSite_OnStateChange(pass, (state = SCRIPTSTATE_INITIALIZED)); ok(hres == E_NOTIMPL, "OnStateChange failed: %08x\n", hres); hres = IActiveScriptSite_QueryInterface(pass, &IID_IActiveScriptSiteDebug, (void**)&debug); ok(hres == E_NOINTERFACE, "Got IActiveScriptSiteDebug interface: %08x\n", hres); hres = IActiveScriptSite_QueryInterface(pass, &IID_ICanHandleException, (void**)&canexpection); ok(hres == E_NOINTERFACE, "Got IID_ICanHandleException interface: %08x\n", hres); hres = IActiveScriptSite_QueryInterface(pass, &IID_IServiceProvider, (void**)&service); ok(hres == S_OK, "Could not get IServiceProvider interface: %08x\n", hres); IServiceProvider_Release(service); hres = IActiveScriptSite_QueryInterface(pass, &IID_IActiveScriptSiteWindow, (void**)&window); ok(hres == S_OK, "Could not get IActiveScriptSiteWindow interface: %08x\n", hres); IActiveScriptSiteWindow_Release(window); site = pass; IActiveScriptSite_AddRef(site); return S_OK; } static HRESULT WINAPI ActiveScript_GetScriptSite(IActiveScript *iface, REFIID riid, void **ppvObject) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI ActiveScript_SetScriptState(IActiveScript *iface, SCRIPTSTATE ss) { if (ss == SCRIPTSTATE_INITIALIZED) { CHECK_EXPECT(SetScriptState_INITIALIZED); return S_OK; } else ok(0, "unexpected call, state %u\n", ss); return E_NOTIMPL; } static HRESULT WINAPI ActiveScript_GetScriptState(IActiveScript *iface, SCRIPTSTATE *pssState) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI ActiveScript_Close(IActiveScript *iface) { CHECK_EXPECT(Close); return E_NOTIMPL; } static HRESULT WINAPI ActiveScript_AddNamedItem(IActiveScript *iface, LPCOLESTR name, DWORD flags) { static const WCHAR oW[] = {'o',0}; CHECK_EXPECT(AddNamedItem); ok(!lstrcmpW(name, oW), "got name %s\n", wine_dbgstr_w(name)); ok(flags == (SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS), "got flags %#x\n", flags); return S_OK; } static HRESULT WINAPI ActiveScript_AddTypeLib(IActiveScript *iface, REFGUID rguidTypeLib, DWORD dwMajor, DWORD dwMinor, DWORD dwFlags) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI ActiveScript_GetScriptDispatch(IActiveScript *iface, LPCOLESTR pstrItemName, IDispatch **ppdisp) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI ActiveScript_GetCurrentScriptThreadID(IActiveScript *iface, SCRIPTTHREADID *pstridThread) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI ActiveScript_GetScriptThreadID(IActiveScript *iface, DWORD dwWin32ThreadId, SCRIPTTHREADID *pstidThread) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI ActiveScript_GetScriptThreadState(IActiveScript *iface, SCRIPTTHREADID stidThread, SCRIPTTHREADSTATE *pstsState) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI ActiveScript_InterruptScriptThread(IActiveScript *iface, SCRIPTTHREADID stidThread, const EXCEPINFO *pexcepinfo, DWORD dwFlags) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI ActiveScript_Clone(IActiveScript *iface, IActiveScript **ppscript) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static const IActiveScriptVtbl ActiveScriptVtbl = { ActiveScript_QueryInterface, ActiveScript_AddRef, ActiveScript_Release, ActiveScript_SetScriptSite, ActiveScript_GetScriptSite, ActiveScript_SetScriptState, ActiveScript_GetScriptState, ActiveScript_Close, ActiveScript_AddNamedItem, ActiveScript_AddTypeLib, ActiveScript_GetScriptDispatch, ActiveScript_GetCurrentScriptThreadID, ActiveScript_GetScriptThreadID, ActiveScript_GetScriptThreadState, ActiveScript_InterruptScriptThread, ActiveScript_Clone }; static IActiveScript ActiveScript = { &ActiveScriptVtbl }; static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv) { *ppv = NULL; if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) { *ppv = iface; return S_OK; } if(IsEqualGUID(&IID_IMarshal, riid)) return E_NOINTERFACE; ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid)); return E_NOINTERFACE; } static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface) { return 2; } static ULONG WINAPI ClassFactory_Release(IClassFactory *iface) { return 1; } static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv) { CHECK_EXPECT(CreateInstance); ok(!outer, "outer = %p\n", outer); ok(IsEqualGUID(&IID_IActiveScript, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid)); *ppv = &ActiveScript; return S_OK; } static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock) { ok(0, "unexpected call\n"); return S_OK; } static const IClassFactoryVtbl ClassFactoryVtbl = { ClassFactory_QueryInterface, ClassFactory_AddRef, ClassFactory_Release, ClassFactory_CreateInstance, ClassFactory_LockServer }; static IClassFactory script_cf = { &ClassFactoryVtbl }; static BOOL init_key(const char *key_name, const char *def_value, BOOL init) { HKEY hkey; DWORD res; if(!init) { RegDeleteKeyA(HKEY_CLASSES_ROOT, key_name); return TRUE; } res = RegCreateKeyA(HKEY_CLASSES_ROOT, key_name, &hkey); if(res != ERROR_SUCCESS) return FALSE; if(def_value) res = RegSetValueA(hkey, NULL, REG_SZ, def_value, strlen(def_value)); RegCloseKey(hkey); return res == ERROR_SUCCESS; } static BOOL init_registry(BOOL init) { return init_key("TestScript\\CLSID", TESTSCRIPT_CLSID, init) && init_key("CLSID\\"TESTSCRIPT_CLSID"\\Implemented Categories\\{F0B7A1A1-9847-11CF-8F20-00805F2CD064}", NULL, init) && init_key("CLSID\\"TESTSCRIPT_CLSID"\\Implemented Categories\\{F0B7A1A2-9847-11CF-8F20-00805F2CD064}", NULL, init); } static BOOL register_script_engine(void) { DWORD regid; HRESULT hres; if(!init_registry(TRUE)) { init_registry(FALSE); return FALSE; } hres = CoRegisterClassObject(&CLSID_TestScript, (IUnknown *)&script_cf, CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, ®id); ok(hres == S_OK, "Could not register script engine: %08x\n", hres); return TRUE; } static HRESULT WINAPI OleClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **obj) { if (IsEqualIID(riid, &IID_IOleClientSite) || IsEqualIID(riid, &IID_IUnknown)) { *obj = iface; IOleClientSite_AddRef(iface); return S_OK; } *obj = NULL; return E_NOINTERFACE; } static ULONG WINAPI OleClientSite_AddRef(IOleClientSite *iface) { return 2; } static ULONG WINAPI OleClientSite_Release(IOleClientSite *iface) { return 1; } static HRESULT WINAPI OleClientSite_SaveObject(IOleClientSite *iface) { return E_NOTIMPL; } static HRESULT WINAPI OleClientSite_GetMoniker(IOleClientSite *iface, DWORD assign, DWORD which, IMoniker **moniker) { return E_NOTIMPL; } static HRESULT WINAPI OleClientSite_GetContainer(IOleClientSite *iface, IOleContainer **container) { return E_NOTIMPL; } static HRESULT WINAPI OleClientSite_ShowObject(IOleClientSite *iface) { return E_NOTIMPL; } static HRESULT WINAPI OleClientSite_OnShowWindow(IOleClientSite *iface, BOOL show) { return E_NOTIMPL; } static HRESULT WINAPI OleClientSite_RequestNewObjectLayout(IOleClientSite *iface) { return E_NOTIMPL; } static const IOleClientSiteVtbl OleClientSiteVtbl = { OleClientSite_QueryInterface, OleClientSite_AddRef, OleClientSite_Release, OleClientSite_SaveObject, OleClientSite_GetMoniker, OleClientSite_GetContainer, OleClientSite_ShowObject, OleClientSite_OnShowWindow, OleClientSite_RequestNewObjectLayout }; static IOleClientSite testclientsite = { &OleClientSiteVtbl }; static void test_oleobject(void) { DWORD status, dpi_x, dpi_y; IOleClientSite *site; IOleObject *obj; SIZEL extent; HRESULT hr; HDC hdc; hr = CoCreateInstance(&CLSID_ScriptControl, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, &IID_IOleObject, (void**)&obj); ok(hr == S_OK, "got 0x%08x\n", hr); if (0) /* crashes on w2k3 */ hr = IOleObject_GetMiscStatus(obj, DVASPECT_CONTENT, NULL); status = 0; hr = IOleObject_GetMiscStatus(obj, DVASPECT_CONTENT, &status); ok(hr == S_OK, "got 0x%08x\n", hr); ok(status != 0, "got 0x%08x\n", status); hr = IOleObject_SetClientSite(obj, &testclientsite); ok(hr == S_OK, "got 0x%08x\n", hr); if (0) /* crashes on w2k3 */ hr = IOleObject_GetClientSite(obj, NULL); hr = IOleObject_GetClientSite(obj, &site); ok(hr == S_OK, "got 0x%08x\n", hr); ok(site == &testclientsite, "got %p, %p\n", site, &testclientsite); IOleClientSite_Release(site); hr = IOleObject_SetClientSite(obj, NULL); ok(hr == S_OK, "got 0x%08x\n", hr); hr = IOleObject_GetClientSite(obj, &site); ok(hr == S_OK, "got 0x%08x\n", hr); ok(site == NULL, "got %p\n", site); /* extents */ hdc = GetDC(0); dpi_x = GetDeviceCaps(hdc, LOGPIXELSX); dpi_y = GetDeviceCaps(hdc, LOGPIXELSY); ReleaseDC(0, hdc); memset(&extent, 0, sizeof(extent)); hr = IOleObject_GetExtent(obj, DVASPECT_CONTENT, &extent); ok(hr == S_OK, "got 0x%08x\n", hr); ok(extent.cx == MulDiv(38, 2540, dpi_x), "got %d\n", extent.cx); ok(extent.cy == MulDiv(38, 2540, dpi_y), "got %d\n", extent.cy); extent.cx = extent.cy = 0xdeadbeef; hr = IOleObject_GetExtent(obj, DVASPECT_THUMBNAIL, &extent); ok(hr == DV_E_DVASPECT, "got 0x%08x\n", hr); ok(extent.cx == 0xdeadbeef, "got %d\n", extent.cx); ok(extent.cy == 0xdeadbeef, "got %d\n", extent.cy); extent.cx = extent.cy = 0xdeadbeef; hr = IOleObject_GetExtent(obj, DVASPECT_ICON, &extent); ok(hr == DV_E_DVASPECT, "got 0x%08x\n", hr); ok(extent.cx == 0xdeadbeef, "got %d\n", extent.cx); ok(extent.cy == 0xdeadbeef, "got %d\n", extent.cy); extent.cx = extent.cy = 0xdeadbeef; hr = IOleObject_GetExtent(obj, DVASPECT_DOCPRINT, &extent); ok(hr == DV_E_DVASPECT, "got 0x%08x\n", hr); ok(extent.cx == 0xdeadbeef, "got %d\n", extent.cx); ok(extent.cy == 0xdeadbeef, "got %d\n", extent.cy); IOleObject_Release(obj); } static void test_persiststreaminit(void) { IPersistStreamInit *init; HRESULT hr; hr = CoCreateInstance(&CLSID_ScriptControl, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, &IID_IPersistStreamInit, (void**)&init); ok(hr == S_OK, "got 0x%08x\n", hr); IPersistStreamInit_Release(init); } static void test_olecontrol(void) { IOleControl *olecontrol; CONTROLINFO info; HRESULT hr; hr = CoCreateInstance(&CLSID_ScriptControl, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, &IID_IOleControl, (void**)&olecontrol); ok(hr == S_OK, "got 0x%08x\n", hr); memset(&info, 0xab, sizeof(info)); info.cb = sizeof(info); hr = IOleControl_GetControlInfo(olecontrol, &info); ok(hr == S_OK, "got 0x%08x\n", hr); ok(info.hAccel == NULL, "got %p\n", info.hAccel); ok(info.cAccel == 0, "got %d\n", info.cAccel); ok(info.dwFlags == 0xabababab, "got %x\n", info.dwFlags); memset(&info, 0xab, sizeof(info)); info.cb = sizeof(info) - 1; hr = IOleControl_GetControlInfo(olecontrol, &info); ok(hr == S_OK, "got 0x%08x\n", hr); ok(info.hAccel == NULL, "got %p\n", info.hAccel); ok(info.cAccel == 0, "got %d\n", info.cAccel); ok(info.dwFlags == 0xabababab, "got %x\n", info.dwFlags); if (0) /* crashes on win2k3 */ { hr = IOleControl_GetControlInfo(olecontrol, NULL); ok(hr == E_POINTER, "got 0x%08x\n", hr); } IOleControl_Release(olecontrol); } static void test_Language(void) { static const WCHAR jsW[] = {'J','S','c','r','i','p','t',0}; static const WCHAR vb2W[] = {'v','B','s','c','r','i','p','t',0}; static const WCHAR dummyW[] = {'d','u','m','m','y',0}; IScriptControl *sc; HRESULT hr; BSTR str; hr = CoCreateInstance(&CLSID_ScriptControl, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, &IID_IScriptControl, (void**)&sc); ok(hr == S_OK, "got 0x%08x\n", hr); hr = IScriptControl_get_Language(sc, NULL); ok(hr == E_POINTER, "got 0x%08x\n", hr); str = (BSTR)0xdeadbeef; hr = IScriptControl_get_Language(sc, &str); ok(hr == S_OK, "got 0x%08x\n", hr); ok(str == NULL, "got %s\n", wine_dbgstr_w(str)); str = SysAllocString(vbW); hr = IScriptControl_put_Language(sc, str); ok(hr == S_OK, "got 0x%08x\n", hr); SysFreeString(str); str = SysAllocString(vb2W); hr = IScriptControl_put_Language(sc, str); ok(hr == S_OK, "got 0x%08x\n", hr); SysFreeString(str); hr = IScriptControl_get_Language(sc, &str); ok(hr == S_OK, "got 0x%08x\n", hr); ok(!lstrcmpW(str, vbW), "got %s\n", wine_dbgstr_w(str)); SysFreeString(str); str = SysAllocString(dummyW); hr = IScriptControl_put_Language(sc, str); ok(hr == CTL_E_INVALIDPROPERTYVALUE, "got 0x%08x\n", hr); SysFreeString(str); hr = IScriptControl_get_Language(sc, &str); ok(hr == S_OK, "got 0x%08x\n", hr); ok(!lstrcmpW(str, vbW), "got %s\n", wine_dbgstr_w(str)); SysFreeString(str); str = SysAllocString(jsW); hr = IScriptControl_put_Language(sc, str); ok(hr == S_OK, "got 0x%08x\n", hr); SysFreeString(str); hr = IScriptControl_get_Language(sc, &str); ok(hr == S_OK, "got 0x%08x\n", hr); ok(!lstrcmpW(str, jsW), "got %s\n", wine_dbgstr_w(str)); SysFreeString(str); hr = IScriptControl_put_Language(sc, NULL); ok(hr == S_OK, "got 0x%08x\n", hr); hr = IScriptControl_get_Language(sc, &str); ok(hr == S_OK, "got 0x%08x\n", hr); ok(str == NULL, "got %s\n", wine_dbgstr_w(str)); IScriptControl_Release(sc); /* custom script engine */ if (register_script_engine()) { static const WCHAR testscriptW[] = {'t','e','s','t','s','c','r','i','p','t',0}; hr = CoCreateInstance(&CLSID_ScriptControl, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, &IID_IScriptControl, (void**)&sc); ok(hr == S_OK, "got 0x%08x\n", hr); SET_EXPECT(CreateInstance); SET_EXPECT(SetInterfaceSafetyOptions); SET_EXPECT(SetScriptSite); SET_EXPECT(QI_IActiveScriptParse); SET_EXPECT(InitNew); str = SysAllocString(testscriptW); hr = IScriptControl_put_Language(sc, str); ok(hr == S_OK, "got 0x%08x\n", hr); SysFreeString(str); CHECK_CALLED(CreateInstance); CHECK_CALLED(SetInterfaceSafetyOptions); CHECK_CALLED(SetScriptSite); CHECK_CALLED(QI_IActiveScriptParse); CHECK_CALLED(InitNew); hr = IScriptControl_get_Language(sc, &str); todo_wine ok(hr == S_OK, "got 0x%08x\n", hr); if (hr == S_OK) ok(!lstrcmpW(testscriptW, str), "%s\n", wine_dbgstr_w(str)); SysFreeString(str); init_registry(FALSE); SET_EXPECT(Close); IScriptControl_Release(sc); CHECK_CALLED(Close); } else skip("Could not register TestScript engine\n"); } static void test_connectionpoints(void) { IConnectionPointContainer *container, *container2; IConnectionPoint *cp; IScriptControl *sc; HRESULT hr; IID iid; hr = CoCreateInstance(&CLSID_ScriptControl, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, &IID_IScriptControl, (void**)&sc); ok(hr == S_OK, "got 0x%08x\n", hr); EXPECT_REF(sc, 1); hr = IScriptControl_QueryInterface(sc, &IID_IConnectionPointContainer, (void**)&container); ok(hr == S_OK, "got 0x%08x\n", hr); EXPECT_REF(sc, 2); EXPECT_REF(container, 2); hr = IConnectionPointContainer_FindConnectionPoint(container, &IID_IPropertyNotifySink, &cp); ok(hr == S_OK, "got 0x%08x\n", hr); if (0) /* crashes on win2k3 */ { hr = IConnectionPoint_GetConnectionPointContainer(cp, NULL); ok(hr == E_POINTER, "got 0x%08x\n", hr); } hr = IConnectionPoint_GetConnectionInterface(cp, &iid); ok(hr == S_OK, "got 0x%08x\n", hr); ok(IsEqualIID(&iid, &IID_IPropertyNotifySink), "got %s\n", wine_dbgstr_guid(&iid)); hr = IConnectionPoint_GetConnectionPointContainer(cp, &container2); ok(hr == S_OK, "got 0x%08x\n", hr); ok(container2 == container, "got %p, expected %p\n", container2, container); IConnectionPointContainer_Release(container2); IConnectionPoint_Release(cp); hr = IConnectionPointContainer_FindConnectionPoint(container, &DIID_DScriptControlSource, &cp); ok(hr == S_OK, "got 0x%08x\n", hr); if (0) /* crashes on win2k3 */ { hr = IConnectionPoint_GetConnectionPointContainer(cp, NULL); ok(hr == E_POINTER, "got 0x%08x\n", hr); } hr = IConnectionPoint_GetConnectionInterface(cp, &iid); ok(hr == S_OK, "got 0x%08x\n", hr); ok(IsEqualIID(&iid, &DIID_DScriptControlSource), "got %s\n", wine_dbgstr_guid(&iid)); hr = IConnectionPoint_GetConnectionPointContainer(cp, &container2); ok(hr == S_OK, "got 0x%08x\n", hr); ok(container2 == container, "got %p, expected %p\n", container2, container); IConnectionPointContainer_Release(container2); IConnectionPoint_Release(cp); IConnectionPointContainer_Release(container); IScriptControl_Release(sc); } static void test_quickactivate(void) { IScriptControl *sc; IQuickActivate *qa; HRESULT hr; hr = CoCreateInstance(&CLSID_ScriptControl, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, &IID_IScriptControl, (void**)&sc); ok(hr == S_OK, "got 0x%08x\n", hr); hr = IScriptControl_QueryInterface(sc, &IID_IQuickActivate, (void**)&qa); ok(hr == S_OK, "got 0x%08x\n", hr); IQuickActivate_Release(qa); IScriptControl_Release(sc); } static void test_viewobject(void) { DWORD status, aspect, flags; IViewObjectEx *viewex; IScriptControl *sc; IViewObject *view; IAdviseSink *sink; HRESULT hr; hr = CoCreateInstance(&CLSID_ScriptControl, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, &IID_IScriptControl, (void**)&sc); ok(hr == S_OK, "got 0x%08x\n", hr); hr = IScriptControl_QueryInterface(sc, &IID_IViewObject, (void**)&view); ok(hr == S_OK, "got 0x%08x\n", hr); IViewObject_Release(view); hr = IScriptControl_QueryInterface(sc, &IID_IViewObject2, (void**)&view); ok(hr == S_OK, "got 0x%08x\n", hr); sink = (IAdviseSink*)0xdeadbeef; hr = IViewObject_GetAdvise(view, &aspect, &flags, &sink); ok(hr == S_OK, "got 0x%08x\n", hr); ok(aspect == DVASPECT_CONTENT, "got %u\n", aspect); ok(flags == 0, "got %#x\n", flags); ok(sink == NULL, "got %p\n", sink); hr = IViewObject_SetAdvise(view, DVASPECT_CONTENT, 0, NULL); ok(hr == S_OK, "got 0x%08x\n", hr); hr = IViewObject_SetAdvise(view, DVASPECT_THUMBNAIL, 0, NULL); ok(hr == DV_E_DVASPECT, "got 0x%08x\n", hr); hr = IViewObject_SetAdvise(view, DVASPECT_ICON, 0, NULL); ok(hr == DV_E_DVASPECT, "got 0x%08x\n", hr); hr = IViewObject_SetAdvise(view, DVASPECT_DOCPRINT, 0, NULL); ok(hr == DV_E_DVASPECT, "got 0x%08x\n", hr); sink = (IAdviseSink*)0xdeadbeef; hr = IViewObject_GetAdvise(view, &aspect, &flags, &sink); ok(hr == S_OK, "got 0x%08x\n", hr); ok(aspect == DVASPECT_CONTENT, "got %u\n", aspect); ok(flags == 0, "got %#x\n", flags); ok(sink == NULL, "got %p\n", sink); IViewObject_Release(view); hr = IScriptControl_QueryInterface(sc, &IID_IViewObjectEx, (void**)&viewex); ok(hr == S_OK, "got 0x%08x\n", hr); if (0) /* crashes */ hr = IViewObjectEx_GetViewStatus(viewex, NULL); status = 0; hr = IViewObjectEx_GetViewStatus(viewex, &status); ok(hr == S_OK, "got 0x%08x\n", hr); ok(status == VIEWSTATUS_OPAQUE, "got %#x\n", status); IViewObjectEx_Release(viewex); IScriptControl_Release(sc); } static void test_pointerinactive(void) { IPointerInactive *pi; IScriptControl *sc; DWORD policy; HRESULT hr; hr = CoCreateInstance(&CLSID_ScriptControl, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, &IID_IScriptControl, (void**)&sc); ok(hr == S_OK, "got 0x%08x\n", hr); hr = IScriptControl_QueryInterface(sc, &IID_IPointerInactive, (void**)&pi); ok(hr == S_OK, "got 0x%08x\n", hr); if (0) /* crashes w2k3 */ hr = IPointerInactive_GetActivationPolicy(pi, NULL); policy = 123; hr = IPointerInactive_GetActivationPolicy(pi, &policy); ok(hr == S_OK, "got 0x%08x\n", hr); ok(policy == 0, "got %#x\n", policy); IPointerInactive_Release(pi); IScriptControl_Release(sc); } static void test_timeout(void) { IScriptControl *sc; HRESULT hr; LONG val; BSTR str; hr = CoCreateInstance(&CLSID_ScriptControl, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, &IID_IScriptControl, (void**)&sc); ok(hr == S_OK, "got 0x%08x\n", hr); hr = IScriptControl_get_Timeout(sc, NULL); ok(hr == E_POINTER, "got 0x%08x\n", hr); val = 0; hr = IScriptControl_get_Timeout(sc, &val); ok(hr == S_OK, "got 0x%08x\n", hr); ok(val == 10000, "got %d\n", val); hr = IScriptControl_put_Timeout(sc, -1); ok(hr == S_OK, "got 0x%08x\n", hr); val = 0; hr = IScriptControl_get_Timeout(sc, &val); ok(hr == S_OK, "got 0x%08x\n", hr); ok(val == -1, "got %d\n", val); hr = IScriptControl_put_Timeout(sc, -2); ok(hr == CTL_E_INVALIDPROPERTYVALUE, "got 0x%08x\n", hr); val = 0; hr = IScriptControl_get_Timeout(sc, &val); ok(hr == S_OK, "got 0x%08x\n", hr); ok(val == -1, "got %d\n", val); hr = IScriptControl_put_Timeout(sc, 0); ok(hr == S_OK, "got 0x%08x\n", hr); val = 1; hr = IScriptControl_get_Timeout(sc, &val); ok(hr == S_OK, "got 0x%08x\n", hr); ok(val == 0, "got %d\n", val); str = SysAllocString(vbW); hr = IScriptControl_put_Language(sc, str); ok(hr == S_OK, "got 0x%08x\n", hr); SysFreeString(str); val = 1; hr = IScriptControl_get_Timeout(sc, &val); ok(hr == S_OK, "got 0x%08x\n", hr); ok(val == 0, "got %d\n", val); hr = IScriptControl_put_Timeout(sc, 10000); ok(hr == S_OK, "got 0x%08x\n", hr); IScriptControl_Release(sc); } static void test_Reset(void) { IScriptControl *sc; HRESULT hr; BSTR str; hr = CoCreateInstance(&CLSID_ScriptControl, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, &IID_IScriptControl, (void**)&sc); ok(hr == S_OK, "got 0x%08x\n", hr); hr = IScriptControl_Reset(sc); ok(hr == E_FAIL, "got 0x%08x\n", hr); str = SysAllocString(vbW); hr = IScriptControl_put_Language(sc, str); ok(hr == S_OK, "got 0x%08x\n", hr); SysFreeString(str); hr = IScriptControl_Reset(sc); ok(hr == S_OK, "got 0x%08x\n", hr); hr = IScriptControl_get_Language(sc, &str); ok(hr == S_OK, "got 0x%08x\n", hr); ok(!lstrcmpW(str, vbW), "got %s\n", wine_dbgstr_w(str)); SysFreeString(str); IScriptControl_Release(sc); /* custom script engine */ if (register_script_engine()) { static const WCHAR testscriptW[] = {'t','e','s','t','s','c','r','i','p','t',0}; hr = CoCreateInstance(&CLSID_ScriptControl, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, &IID_IScriptControl, (void**)&sc); ok(hr == S_OK, "got 0x%08x\n", hr); SET_EXPECT(CreateInstance); SET_EXPECT(SetInterfaceSafetyOptions); SET_EXPECT(SetScriptSite); SET_EXPECT(QI_IActiveScriptParse); SET_EXPECT(InitNew); str = SysAllocString(testscriptW); hr = IScriptControl_put_Language(sc, str); ok(hr == S_OK, "got 0x%08x\n", hr); SysFreeString(str); SET_EXPECT(SetScriptState_INITIALIZED); hr = IScriptControl_Reset(sc); ok(hr == S_OK, "got 0x%08x\n", hr); CHECK_CALLED(SetScriptState_INITIALIZED); SET_EXPECT(SetScriptState_INITIALIZED); hr = IScriptControl_Reset(sc); ok(hr == S_OK, "got 0x%08x\n", hr); CHECK_CALLED(SetScriptState_INITIALIZED); init_registry(FALSE); SET_EXPECT(Close); IScriptControl_Release(sc); CHECK_CALLED(Close); } else skip("Could not register TestScript engine\n"); } static HRESULT WINAPI disp_QI(IDispatch *iface, REFIID riid, void **obj) { if (IsEqualIID(riid, &IID_IDispatch) || IsEqualIID(riid, &IID_IUnknown)) { *obj = iface; IDispatch_AddRef(iface); return S_OK; } *obj = NULL; return E_NOINTERFACE; } static ULONG WINAPI disp_AddRef(IDispatch *iface) { return 2; } static ULONG WINAPI disp_Release(IDispatch *iface) { return 1; } static HRESULT WINAPI disp_GetTypeInfoCount(IDispatch *iface, UINT *count) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI disp_GetTypeInfo(IDispatch *iface, UINT index, LCID lcid, ITypeInfo **ti) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI disp_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *names, UINT cnames, LCID lcid, DISPID *dispid) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI disp_Invoke(IDispatch *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags, DISPPARAMS *dispparams, VARIANT *result, EXCEPINFO *ei, UINT *arg_err) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static const IDispatchVtbl dispvtbl = { disp_QI, disp_AddRef, disp_Release, disp_GetTypeInfoCount, disp_GetTypeInfo, disp_GetIDsOfNames, disp_Invoke }; static IDispatch testdisp = { &dispvtbl }; static void test_AddObject(void) { static const WCHAR oW[] = {'o',0}; IScriptControl *sc; BSTR str, objname; HRESULT hr; hr = CoCreateInstance(&CLSID_ScriptControl, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, &IID_IScriptControl, (void**)&sc); ok(hr == S_OK, "got 0x%08x\n", hr); objname = SysAllocString(oW); hr = IScriptControl_AddObject(sc, objname, NULL, VARIANT_FALSE); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); hr = IScriptControl_AddObject(sc, objname, &testdisp, VARIANT_FALSE); ok(hr == E_FAIL, "got 0x%08x\n", hr); str = SysAllocString(vbW); hr = IScriptControl_put_Language(sc, str); ok(hr == S_OK, "got 0x%08x\n", hr); SysFreeString(str); hr = IScriptControl_AddObject(sc, objname, &testdisp, VARIANT_TRUE); ok(hr == S_OK, "got 0x%08x\n", hr); hr = IScriptControl_Reset(sc); ok(hr == S_OK, "got 0x%08x\n", hr); hr = IScriptControl_AddObject(sc, objname, &testdisp, VARIANT_TRUE); ok(hr == S_OK, "got 0x%08x\n", hr); IScriptControl_Release(sc); /* custom script engine */ if (register_script_engine()) { static const WCHAR testscriptW[] = {'t','e','s','t','s','c','r','i','p','t',0}; hr = CoCreateInstance(&CLSID_ScriptControl, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, &IID_IScriptControl, (void**)&sc); ok(hr == S_OK, "got 0x%08x\n", hr); SET_EXPECT(CreateInstance); SET_EXPECT(SetInterfaceSafetyOptions); SET_EXPECT(SetScriptSite); SET_EXPECT(QI_IActiveScriptParse); SET_EXPECT(InitNew); str = SysAllocString(testscriptW); hr = IScriptControl_put_Language(sc, str); ok(hr == S_OK, "got 0x%08x\n", hr); SysFreeString(str); hr = IScriptControl_AddObject(sc, objname, NULL, VARIANT_FALSE); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); SET_EXPECT(AddNamedItem); hr = IScriptControl_AddObject(sc, objname, &testdisp, VARIANT_TRUE); ok(hr == S_OK, "got 0x%08x\n", hr); CHECK_CALLED(AddNamedItem); hr = IScriptControl_AddObject(sc, objname, &testdisp, VARIANT_TRUE); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); init_registry(FALSE); SET_EXPECT(Close); IScriptControl_Release(sc); CHECK_CALLED(Close); } else skip("Could not register TestScript engine\n"); SysFreeString(objname); } START_TEST(msscript) { IUnknown *unk; HRESULT hr; CoInitialize(NULL); hr = CoCreateInstance(&CLSID_ScriptControl, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, &IID_IUnknown, (void**)&unk); if (FAILED(hr)) { win_skip("Could not create ScriptControl object: %08x\n", hr); return; } IUnknown_Release(unk); test_oleobject(); test_persiststreaminit(); test_olecontrol(); test_Language(); test_connectionpoints(); test_quickactivate(); test_viewobject(); test_pointerinactive(); test_timeout(); test_Reset(); test_AddObject(); CoUninitialize(); }