[2/2] scrrun:Add Scripting.Dictionary interface

Alistair Leslie-Hughes leslie_alistair at hotmail.com
Tue Sep 18 22:25:22 CDT 2012


Hi,


Changelog:
     scrrun: Add Scripting.Dictionary interface


Best Regards
  Alistair Leslie-Hughes
-------------- next part --------------
>From 7c911fb57913afdfebd64bb9f4727011c19ad5c0 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
Date: Sun, 23 Sep 2012 12:51:11 +1000
Subject: [PATCH] Add Scripting.Dictionary interface
To: wine-patches <wine-patches at winehq.org>

---
 dlls/scrrun/Makefile.in        |    1 +
 dlls/scrrun/dictionary.c       |  345 ++++++++++++++++++++++++++++++++++++++++
 dlls/scrrun/scrrun.c           |    6 +
 dlls/scrrun/scrrun_private.h   |    2 +
 dlls/scrrun/tests/Makefile.in  |    2 +
 dlls/scrrun/tests/dictionary.c |  102 ++++++++++++
 6 files changed, 458 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 f6dcf62..d8d71b2 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 0000000..f6a4f8f
--- /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 <stdarg.h>
+
+#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 create_dictionary(REFIID riid, LPVOID *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 2558b30..04c9424 100644
--- a/dlls/scrrun/scrrun.c
+++ b/dlls/scrrun/scrrun.c
@@ -143,6 +143,7 @@ static ITypeInfo *typeinfos[LAST_tid];
 
 static REFIID tid_ids[] = {
     &IID_NULL,
+    &IID_IDictionary,
     &IID_IFileSystem3,
 };
 
@@ -264,6 +265,11 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
         This->pfnCreateInstance = &create_filesystem;
         This->clsid = IID_IFileSystem3;
     }
+    else if(IsEqualGUID(&CLSID_Dictionary, rclsid)) {
+        TRACE("(CLSID_Dictionary %s %p)\n", debugstr_guid(riid), ppv);
+        This->pfnCreateInstance = &create_dictionary;
+        This->clsid = IID_IDictionary;
+    }
 
     if(This->pfnCreateInstance != NULL)
     {
diff --git a/dlls/scrrun/scrrun_private.h b/dlls/scrrun/scrrun_private.h
index 100f4c0..ab307ee 100644
--- a/dlls/scrrun/scrrun_private.h
+++ b/dlls/scrrun/scrrun_private.h
@@ -19,10 +19,12 @@
 #define _SCRRUN_PRIVATE_H
 
 extern HRESULT create_filesystem(REFIID riid, LPVOID *ppv) DECLSPEC_HIDDEN;
+extern HRESULT create_dictionary(REFIID riid, LPVOID *ppv) 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 326eb1a..03b1a82 100644
--- a/dlls/scrrun/tests/Makefile.in
+++ b/dlls/scrrun/tests/Makefile.in
@@ -1,7 +1,9 @@
+
 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 0000000..e28bbb1
--- /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 <stdio.h>
+
+#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();
+}
-- 
1.7.9.5



More information about the wine-patches mailing list