From 98aa713fa7d3284aa773eba0ec35d6c4d5a259ce Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Thu, 20 Sep 2012 14:02:16 +1000 Subject: [PATCH] scrrun: Add Scripting.Dictionary interface. --- dlls/scrrun/Makefile.in | 1 + dlls/scrrun/dictionary.c | 345 +++++++++++++++++++++++++++++++++++++++++ dlls/scrrun/scrrun.c | 15 ++ dlls/scrrun/scrrun_private.h | 2 + dlls/scrrun/tests/Makefile.in | 1 + dlls/scrrun/tests/dictionary.c | 102 ++++++++++++ 6 files changed, 466 insertions(+) create mode 100644 dlls/scrrun/dictionary.c create mode 100644 dlls/scrrun/tests/dictionary.c diff --git a/dlls/scrrun/Makefile.in b/dlls/scrrun/Makefile.in index f6dcf623182..d8d71b26773 100644 --- a/dlls/scrrun/Makefile.in +++ b/dlls/scrrun/Makefile.in @@ -2,6 +2,7 @@ MODULE = scrrun.dll IMPORTS = uuid oleaut32 C_SRCS = \ + dictionary.c \ filesystem.c \ scrrun.c diff --git a/dlls/scrrun/dictionary.c b/dlls/scrrun/dictionary.c new file mode 100644 index 00000000000..a02c957075d --- /dev/null +++ b/dlls/scrrun/dictionary.c @@ -0,0 +1,345 @@ +/* + * Copyright (C) 2012 Alistair Leslie-Hughes + * + * 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 + +#include "config.h" +#include + +#include "windef.h" +#include "winbase.h" +#include "ole2.h" +#include "dispex.h" +#include "scrrun.h" +#include "scrrun_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(scrrun); + +typedef struct +{ + IDictionary IDictionary_iface; + + LONG ref; +} dictionary; + +static inline dictionary *impl_from_IDictionary(IDictionary *iface) +{ + return CONTAINING_RECORD(iface, dictionary, IDictionary_iface); +} + +static HRESULT WINAPI dictionary_QueryInterface(IDictionary *iface, REFIID riid, void **obj) +{ + dictionary *This = impl_from_IDictionary(iface); + TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), obj); + + *obj = NULL; + + if(IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IDispatch) || + IsEqualIID(riid, &IID_IDictionary)) + { + *obj = &This->IDictionary_iface; + } + else if ( IsEqualGUID( riid, &IID_IDispatchEx )) + { + TRACE("Interface IDispatchEx not supported - returning NULL\n"); + *obj = NULL; + return E_NOINTERFACE; + } + else if ( IsEqualGUID( riid, &IID_IObjectWithSite )) + { + TRACE("Interface IObjectWithSite not supported - returning NULL\n"); + *obj = NULL; + return E_NOINTERFACE; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + + IDictionary_AddRef(iface); + return S_OK; +} + +static ULONG WINAPI dictionary_AddRef(IDictionary *iface) +{ + dictionary *This = impl_from_IDictionary(iface); + TRACE("(%p)\n", This); + + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI dictionary_Release(IDictionary *iface) +{ + dictionary *This = impl_from_IDictionary(iface); + LONG ref; + + TRACE("(%p)\n", This); + + ref = InterlockedDecrement(&This->ref); + if(ref == 0) + { + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + +static HRESULT WINAPI dictionary_GetTypeInfoCount(IDictionary *iface, UINT *pctinfo) +{ + dictionary *This = impl_from_IDictionary(iface); + + TRACE("(%p)->()\n", This); + + *pctinfo = 1; + return S_OK; +} + +static HRESULT WINAPI dictionary_GetTypeInfo(IDictionary *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) +{ + dictionary *This = impl_from_IDictionary(iface); + + TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); + return get_typeinfo(IDictionary_tid, ppTInfo); +} + +static HRESULT WINAPI dictionary_GetIDsOfNames(IDictionary *iface, REFIID riid, LPOLESTR *rgszNames, + UINT cNames, LCID lcid, DISPID *rgDispId) +{ + dictionary *This = impl_from_IDictionary(iface); + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId); + + hr = get_typeinfo(IDictionary_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI dictionary_Invoke(IDictionary *iface, DISPID dispIdMember, REFIID riid, + LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + dictionary *This = impl_from_IDictionary(iface); + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), + lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + + hr = get_typeinfo(IDictionary_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke(typeinfo, &iface, dispIdMember, wFlags, + pDispParams, pVarResult, pExcepInfo, puArgErr); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI dictionary_putref_Item(IDictionary *iface, VARIANT *Key, VARIANT *pRetItem) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->(%p %p)\n", This, Key, pRetItem); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dictionary_put_Item(IDictionary *iface, VARIANT *Key, VARIANT *pRetItem) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->(%p %p)\n", This, Key, pRetItem); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dictionary_get_Item(IDictionary *iface, VARIANT *Key, VARIANT *pRetItem) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->(%p %p)\n", This, Key, pRetItem ); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dictionary_Add(IDictionary *iface, VARIANT *Key, VARIANT *Item) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->(%p %p)\n", This, Key, Item); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dictionary_get_Count(IDictionary *iface, LONG *pCount) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->(%p)\n", This, pCount); + + *pCount = 0; + + return S_OK; +} + +static HRESULT WINAPI dictionary_Exists(IDictionary *iface, VARIANT *Key, VARIANT_BOOL *pExists) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->(%p %p)\n", This, Key, pExists); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dictionary_Items(IDictionary *iface, VARIANT *pItemsArray) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->(%p)\n", This, pItemsArray); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dictionary_put_Key(IDictionary *iface, VARIANT *Key, VARIANT *rhs) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->(%p %p)\n", This, Key, rhs); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dictionary_Keys(IDictionary *iface, VARIANT *pKeysArray) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->(%p)\n", This, pKeysArray); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dictionary_Remove(IDictionary *iface, VARIANT *Key) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->(%p)\n", This, Key); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dictionary_RemoveAll(IDictionary *iface) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->()\n", This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dictionary_put_CompareMode(IDictionary *iface, CompareMethod pcomp) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->()\n", This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dictionary_get_CompareMode(IDictionary *iface, CompareMethod *pcomp) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->(%p)\n", This, pcomp); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dictionary__NewEnum(IDictionary *iface, IUnknown **ppunk) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->(%p)\n", This, ppunk); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dictionary_get_HashVal(IDictionary *iface, VARIANT *Key, VARIANT *HashVal) +{ + dictionary *This = impl_from_IDictionary(iface); + + FIXME("(%p)->(%p %p)\n", This, Key, HashVal); + + return E_NOTIMPL; +} + + +static const struct IDictionaryVtbl dictionary_vtbl = +{ + dictionary_QueryInterface, + dictionary_AddRef, + dictionary_Release, + dictionary_GetTypeInfoCount, + dictionary_GetTypeInfo, + dictionary_GetIDsOfNames, + dictionary_Invoke, + dictionary_putref_Item, + dictionary_put_Item, + dictionary_get_Item, + dictionary_Add, + dictionary_get_Count, + dictionary_Exists, + dictionary_Items, + dictionary_put_Key, + dictionary_Keys, + dictionary_Remove, + dictionary_RemoveAll, + dictionary_put_CompareMode, + dictionary_get_CompareMode, + dictionary__NewEnum, + dictionary_get_HashVal +}; + +HRESULT WINAPI Dictionary_CreateInstance(IClassFactory *factory,IUnknown *outer,REFIID riid, void **obj) +{ + dictionary *This; + + TRACE("(%p)\n", obj); + + *obj = NULL; + + This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); + if(!This) return E_OUTOFMEMORY; + + This->IDictionary_iface.lpVtbl = &dictionary_vtbl; + This->ref = 1; + + *obj = &This->IDictionary_iface; + + return S_OK; +} diff --git a/dlls/scrrun/scrrun.c b/dlls/scrrun/scrrun.c index d5ea3696616..932d124cb89 100644 --- a/dlls/scrrun/scrrun.c +++ b/dlls/scrrun/scrrun.c @@ -85,13 +85,24 @@ static const struct IClassFactoryVtbl scrruncf_vtbl = scrruncf_LockServer }; +static const struct IClassFactoryVtbl dictcf_vtbl = +{ + scrruncf_QueryInterface, + scrruncf_AddRef, + scrruncf_Release, + Dictionary_CreateInstance, + scrruncf_LockServer +}; + static IClassFactory FileSystemFactory = { &scrruncf_vtbl }; +static IClassFactory DictionaryFactory = { &dictcf_vtbl }; static ITypeLib *typelib; static ITypeInfo *typeinfos[LAST_tid]; static REFIID tid_ids[] = { &IID_NULL, + &IID_IDictionary, &IID_IFileSystem3, }; @@ -198,6 +209,10 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) TRACE("(CLSID_WshShell %s %p)\n", debugstr_guid(riid), ppv); return IClassFactory_QueryInterface(&FileSystemFactory, riid, ppv); } + else if(IsEqualGUID(&CLSID_Dictionary, rclsid)) { + TRACE("(CLSID_WshShell %s %p)\n", debugstr_guid(riid), ppv); + return IClassFactory_QueryInterface(&DictionaryFactory, riid, ppv); + } FIXME("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); return CLASS_E_CLASSNOTAVAILABLE; diff --git a/dlls/scrrun/scrrun_private.h b/dlls/scrrun/scrrun_private.h index fc700a6cac0..07788310473 100644 --- a/dlls/scrrun/scrrun_private.h +++ b/dlls/scrrun/scrrun_private.h @@ -19,10 +19,12 @@ #define _SCRRUN_PRIVATE_H extern HRESULT WINAPI FileSystem_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN; +extern HRESULT WINAPI Dictionary_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN; typedef enum tid_t { NULL_tid, + IDictionary_tid, IFileSystem3_tid, LAST_tid } tid_t; diff --git a/dlls/scrrun/tests/Makefile.in b/dlls/scrrun/tests/Makefile.in index 326eb1a56af..d9d1679ad86 100644 --- a/dlls/scrrun/tests/Makefile.in +++ b/dlls/scrrun/tests/Makefile.in @@ -2,6 +2,7 @@ TESTDLL = scrrun.dll IMPORTS = ole32 shlwapi uuid oleaut32 C_SRCS = \ + dictionary.c \ filesystem.c IDL_H_SRCS = scrrun.idl diff --git a/dlls/scrrun/tests/dictionary.c b/dlls/scrrun/tests/dictionary.c new file mode 100644 index 00000000000..e28bbb18cab --- /dev/null +++ b/dlls/scrrun/tests/dictionary.c @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2012 Alistair Leslie-Hughes + * + * 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 +#include + +#include "windows.h" +#include "ole2.h" +#include "oleauto.h" +#include "dispex.h" + +#include "wine/test.h" + +#include "scrrun.h" + +static void test_interfaces(void) +{ + static const WCHAR key_add[] = {'a', 0}; + static const WCHAR key_add_value[] = {'a', 0}; + static const WCHAR key_non_exist[] = {'b', 0}; + HRESULT hr; + IDispatch *disp; + IDispatchEx *dispex; + IDictionary *dict; + IObjectWithSite *site; + VARIANT key, value; + VARIANT_BOOL exists; + LONG count = 0; + + hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, + &IID_IDispatch, (void**)&disp); + if(FAILED(hr)) { + win_skip("Could not create FileSystem object: %08x\n", hr); + return; + } + + VariantInit(&key); + VariantInit(&value); + + hr = IDispatch_QueryInterface(disp, &IID_IDictionary, (void**)&dict); + ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK); + + hr = IDispatch_QueryInterface(disp, &IID_IObjectWithSite, (void**)&site); + ok(hr == E_NOINTERFACE, "got 0x%08x, expected 0x%08x\n", hr, E_NOINTERFACE); + + hr = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); + ok(hr == E_NOINTERFACE, "got 0x%08x, expected 0x%08x\n", hr, E_NOINTERFACE); + + V_VT(&key) = VT_BSTR; + V_BSTR(&key) = SysAllocString(key_add); + V_VT(&value) = VT_BSTR; + V_BSTR(&value) = SysAllocString(key_add_value); + hr = IDictionary_Add(dict, &key, &value); + todo_wine ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK); + VariantClear(&value); + + exists = VARIANT_FALSE; + hr = IDictionary_Exists(dict, &key, &exists); + todo_wine ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK); + todo_wine ok(exists == VARIANT_TRUE, "Expected TRUE but got FALSE.\n"); + VariantClear(&key); + + exists = VARIANT_TRUE; + V_VT(&key) = VT_BSTR; + V_BSTR(&key) = SysAllocString(key_non_exist); + hr = IDictionary_Exists(dict, &key, &exists); + todo_wine ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK); + todo_wine ok(exists == VARIANT_FALSE, "Expected FALSE but got TRUE.\n"); + VariantClear(&key); + + hr = IDictionary_get_Count(dict, &count); + ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK); + todo_wine ok(count == 1, "got %d, expected 1\n", count); + + IDictionary_Release(dict); + IDispatch_Release(disp); +} + +START_TEST(dictionary) +{ + CoInitialize(NULL); + + test_interfaces(); + + + CoUninitialize(); +} -- 2.11.4.GIT