Hans Leidekker : wbemdisp: Implement ISwbemObject::GetIDsOfNames.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Jan 14 14:35:42 CST 2015


Module: wine
Branch: master
Commit: e992df727a9bb5b54fbe4df4f1329bcabbb30bbf
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=e992df727a9bb5b54fbe4df4f1329bcabbb30bbf

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Wed Jan 14 15:37:30 2015 +0100

wbemdisp: Implement ISwbemObject::GetIDsOfNames.

---

 dlls/wbemdisp/locator.c        | 90 ++++++++++++++++++++++++++++++++++++++----
 dlls/wbemdisp/tests/wbemdisp.c | 44 ++++++++++++++++++++-
 2 files changed, 125 insertions(+), 9 deletions(-)

diff --git a/dlls/wbemdisp/locator.c b/dlls/wbemdisp/locator.c
index c3103fa..989c610 100644
--- a/dlls/wbemdisp/locator.c
+++ b/dlls/wbemdisp/locator.c
@@ -93,11 +93,22 @@ static HRESULT get_typeinfo( enum type_id tid, ITypeInfo **ret )
     return S_OK;
 }
 
+#define DISPID_BASE 0x1800000
+
+struct member
+{
+    BSTR name;
+    DISPID dispid;
+};
+
 struct object
 {
     ISWbemObject ISWbemObject_iface;
     LONG refs;
     IWbemClassObject *object;
+    struct member *members;
+    UINT nb_members;
+    DISPID last_dispid;
 };
 
 static inline struct object *impl_from_ISWbemObject(
@@ -120,8 +131,12 @@ static ULONG WINAPI object_Release(
     LONG refs = InterlockedDecrement( &object->refs );
     if (!refs)
     {
+        UINT i;
+
         TRACE( "destroying %p\n", object );
         IWbemClassObject_Release( object->object );
+        for (i = 0; i < object->nb_members; i++) SysFreeString( object->members[i].name );
+        heap_free( object->members );
         heap_free( object );
     }
     return refs;
@@ -169,9 +184,63 @@ static HRESULT WINAPI object_GetTypeInfo(
     ITypeInfo **info )
 {
     struct object *object = impl_from_ISWbemObject( iface );
-    TRACE( "%p, %u, %u, %p\n", object, index, lcid, info );
+    FIXME( "%p, %u, %u, %p\n", object, index, lcid, info );
+    return E_NOTIMPL;
+}
+
+#define DISPID_BASE 0x1800000
+
+static HRESULT init_members( struct object *object )
+{
+    LONG bound, i;
+    SAFEARRAY *sa;
+    HRESULT hr;
+
+    if (object->members) return S_OK;
+
+    hr = IWbemClassObject_GetNames( object->object, NULL, 0, NULL, &sa );
+    if (FAILED( hr )) return hr;
+    hr = SafeArrayGetUBound( sa, 1, &bound );
+    if (FAILED( hr ))
+    {
+        SafeArrayDestroy( sa );
+        return hr;
+    }
+    if (!(object->members = heap_alloc( sizeof(struct member) * (bound + 1) )))
+    {
+        SafeArrayDestroy( sa );
+        return E_OUTOFMEMORY;
+    }
+    for (i = 0; i <= bound; i++)
+    {
+        hr = SafeArrayGetElement( sa, &i, &object->members[i].name );
+        if (FAILED( hr ))
+        {
+            for (i--; i >= 0; i--) SysFreeString( object->members[i].name );
+            SafeArrayDestroy( sa );
+            heap_free( object->members );
+            object->members = NULL;
+            return E_OUTOFMEMORY;
+        }
+        object->members[i].dispid = 0;
+    }
+    object->nb_members = bound + 1;
+    SafeArrayDestroy( sa );
+    return S_OK;
+}
 
-    return get_typeinfo( ISWbemObject_tid, info );
+static DISPID get_member_dispid( struct object *object, const WCHAR *name )
+{
+    UINT i;
+    for (i = 0; i < object->nb_members; i++)
+    {
+        if (!strcmpiW( object->members[i].name, name ))
+        {
+            if (!object->members[i].dispid) object->members[i].dispid = ++object->last_dispid;
+            return object->members[i].dispid;
+        }
+    }
+    return DISPID_UNKNOWN;
 }
 
 static HRESULT WINAPI object_GetIDsOfNames(
@@ -183,20 +252,22 @@ static HRESULT WINAPI object_GetIDsOfNames(
     DISPID *dispid )
 {
     struct object *object = impl_from_ISWbemObject( iface );
-    ITypeInfo *typeinfo;
     HRESULT hr;
+    UINT i;
 
     TRACE( "%p, %s, %p, %u, %u, %p\n", object, debugstr_guid(riid), names, count, lcid, dispid );
 
     if (!names || !count || !dispid) return E_INVALIDARG;
 
-    hr = get_typeinfo( ISWbemObject_tid, &typeinfo );
-    if (SUCCEEDED(hr))
+    hr = init_members( object );
+    if (FAILED( hr )) return hr;
+
+    for (i = 0; i < count; i++)
     {
-        hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid );
-        ITypeInfo_Release( typeinfo );
+        if ((dispid[i] = get_member_dispid( object, names[i] )) == DISPID_UNKNOWN) break;
     }
-    return hr;
+    if (i != count) return DISP_E_UNKNOWNNAME;
+    return S_OK;
 }
 
 static HRESULT WINAPI object_Invoke(
@@ -260,6 +331,9 @@ static HRESULT SWbemObject_create( IWbemClassObject *wbem_object, ISWbemObject *
     object->refs = 1;
     object->object = wbem_object;
     IWbemClassObject_AddRef( object->object );
+    object->members = NULL;
+    object->nb_members = 0;
+    object->last_dispid = DISPID_BASE;
 
     *obj = &object->ISWbemObject_iface;
     TRACE( "returning iface %p\n", *obj );
diff --git a/dlls/wbemdisp/tests/wbemdisp.c b/dlls/wbemdisp/tests/wbemdisp.c
index 863115b..d91e5b8 100644
--- a/dlls/wbemdisp/tests/wbemdisp.c
+++ b/dlls/wbemdisp/tests/wbemdisp.c
@@ -26,10 +26,14 @@
 #include "wine/test.h"
 
 DEFINE_GUID(CLSID_WINMGMTS,0x172bddf8,0xceea,0x11d1,0x8b,0x05,0x00,0x60,0x08,0x06,0xd9,0xb6);
+DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
 
 static void test_ParseDisplayName(void)
 {
     static const WCHAR biosW[] = {'W','i','n','3','2','_','B','i','o','s',0};
+    static const WCHAR manufacturerW[] = {'M','a','n','u','f','a','c','t','u','r','e','r',0};
+    static const WCHAR versionW[] = {'v','e','r','s','i','o','n',0};
+    static const WCHAR nosuchW[] = {'N','o','S','u','c','h',0};
     static const WCHAR name1[] =
         {'w','i','n','m','g','m','t','s',':',0};
     static const WCHAR name2[] =
@@ -54,12 +58,13 @@ static void test_ParseDisplayName(void)
         { name3, S_OK, &IID_ISWbemObject, sizeof(name3)/sizeof(name3[0]) - 1 },
         { name4, S_OK, &IID_ISWbemObject, sizeof(name4)/sizeof(name4[0]) - 1 }
     };
+    LCID english = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
     IParseDisplayName *displayname;
     IBindCtx *ctx;
     IMoniker *moniker;
     IUnknown *obj;
     BSTR str;
-    ULONG i, eaten;
+    ULONG i, eaten, count;
     HRESULT hr;
 
     hr = CoCreateInstance( &CLSID_WINMGMTS, NULL, CLSCTX_INPROC_SERVER, &IID_IParseDisplayName, (void **)&displayname );
@@ -127,6 +132,8 @@ static void test_ParseDisplayName(void)
                     {
                         VARIANT var;
                         ULONG fetched;
+                        IDispatch *dispatch = NULL;
+                        DISPID dispid;
 
                         fetched = 0xdeadbeef;
                         hr = IEnumVARIANT_Next( enumvar, 0, &var, &fetched );
@@ -141,6 +148,41 @@ static void test_ParseDisplayName(void)
                         ok( fetched == 1, "got %u\n", fetched );
                         ok( V_VT( &var ) == VT_DISPATCH, "got %u\n", V_VT( &var ) );
                         ok( V_DISPATCH( &var ) != (IDispatch *)0xdeadbeef, "got %u\n", V_VT( &var ) );
+
+                        dispatch = V_DISPATCH( &var );
+                        count = 0;
+                        hr = IDispatch_GetTypeInfoCount( dispatch, &count );
+                        ok( hr == S_OK, "got %x\n", hr );
+                        ok( count == 1, "got %u\n", count );
+
+                        str = SysAllocString( manufacturerW );
+                        dispid = 0xdeadbeef;
+                        hr = IDispatch_GetIDsOfNames( dispatch, &IID_NULL, &str, 1, english, &dispid );
+                        SysFreeString( str );
+                        ok( hr == S_OK, "got %x\n", hr );
+                        ok( dispid == 0x1800001 || dispid == 0x10b /* win2k */, "got %x\n", dispid );
+
+                        str = SysAllocString( versionW );
+                        dispid = 0xdeadbeef;
+                        hr = IDispatch_GetIDsOfNames( dispatch, &IID_NULL, &str, 1, english, &dispid );
+                        SysFreeString( str );
+                        ok( hr == S_OK, "got %x\n", hr );
+                        ok( dispid == 0x1800002 || dispid == 0x119 /* win2k */, "got %x\n", dispid );
+
+                        str = SysAllocString( nosuchW );
+                        dispid = 0xdeadbeef;
+                        hr = IDispatch_GetIDsOfNames( dispatch, &IID_NULL, &str, 1, english, &dispid );
+                        SysFreeString( str );
+                        ok( hr == DISP_E_UNKNOWNNAME, "got %x\n", hr );
+                        ok( dispid == DISPID_UNKNOWN, "got %x\n", dispid );
+
+                        str = SysAllocString( manufacturerW );
+                        dispid = 0xdeadbeef;
+                        hr = IDispatch_GetIDsOfNames( dispatch, &IID_NULL, &str, 1, english, &dispid );
+                        SysFreeString( str );
+                        ok( hr == S_OK, "got %x\n", hr );
+                        ok( dispid == 0x1800001 || dispid == 0x10b /* win2k */, "got %x\n", dispid );
+
                         VariantClear( &var );
 
                         fetched = 0xdeadbeef;




More information about the wine-cvs mailing list