Hans Leidekker : wbemdisp: Generate DISPIDs for object methods too.

Alexandre Julliard julliard at winehq.org
Tue Oct 9 16:22:47 CDT 2018


Module: wine
Branch: master
Commit: 6db5a3a11ff26856a4ed8df3b64d1a21d53eb610
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=6db5a3a11ff26856a4ed8df3b64d1a21d53eb610

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Tue Oct  9 15:25:04 2018 +0200

wbemdisp: Generate DISPIDs for object methods too.

Tests based on a patch by Alistair Leslie-Hughes.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=44474
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/wbemdisp/locator.c        | 102 +++++++++++++++++++++++++++++++----------
 dlls/wbemdisp/tests/wbemdisp.c |  35 ++++++++++++++
 2 files changed, 112 insertions(+), 25 deletions(-)

diff --git a/dlls/wbemdisp/locator.c b/dlls/wbemdisp/locator.c
index 1c7f56a..78b81d8 100644
--- a/dlls/wbemdisp/locator.c
+++ b/dlls/wbemdisp/locator.c
@@ -488,11 +488,13 @@ static HRESULT SWbemPropertySet_create( IWbemClassObject *wbem_object, ISWbemPro
     return S_OK;
 }
 
-#define DISPID_BASE 0x1800000
+#define DISPID_BASE         0x1800000
+#define DISPID_BASE_METHOD  0x1000000
 
 struct member
 {
     BSTR name;
+    BOOL is_method;
     DISPID dispid;
 };
 
@@ -504,6 +506,7 @@ struct object
     struct member *members;
     UINT nb_members;
     DISPID last_dispid;
+    DISPID last_dispid_method;
 };
 
 static inline struct object *impl_from_ISWbemObject(
@@ -585,41 +588,83 @@ static HRESULT WINAPI object_GetTypeInfo(
 
 static HRESULT init_members( struct object *object )
 {
-    LONG bound, i;
-    SAFEARRAY *sa;
+    IWbemClassObject *sig_in, *sig_out;
+    LONG i = 0, count = 0;
+    BSTR name;
     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 ))
+    hr = IWbemClassObject_BeginEnumeration( object->object, 0 );
+    if (SUCCEEDED( hr ))
     {
-        SafeArrayDestroy( sa );
-        return hr;
+        while (IWbemClassObject_Next( object->object, 0, NULL, NULL, NULL, NULL ) == S_OK) count++;
+        IWbemClassObject_EndEnumeration( object->object );
     }
-    if (!(object->members = heap_alloc( sizeof(struct member) * (bound + 1) )))
+
+    hr = IWbemClassObject_BeginMethodEnumeration( object->object, 0 );
+    if (SUCCEEDED( hr ))
     {
-        SafeArrayDestroy( sa );
-        return E_OUTOFMEMORY;
+        while (IWbemClassObject_NextMethod( object->object, 0, &name, &sig_in, &sig_out ) == S_OK)
+        {
+            count++;
+            SysFreeString( name );
+            IWbemClassObject_Release( sig_in );
+            IWbemClassObject_Release( sig_out );
+        }
+        IWbemClassObject_EndMethodEnumeration( object->object );
     }
-    for (i = 0; i <= bound; i++)
+
+    if (!(object->members = heap_alloc( sizeof(struct member) * count ))) return E_OUTOFMEMORY;
+
+    hr = IWbemClassObject_BeginEnumeration( object->object, 0 );
+    if (SUCCEEDED( hr ))
     {
-        hr = SafeArrayGetElement( sa, &i, &object->members[i].name );
-        if (FAILED( hr ))
+        while (IWbemClassObject_Next( object->object, 0, &name, NULL, NULL, NULL ) == S_OK)
         {
-            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].name      = name;
+            object->members[i].is_method = FALSE;
+            object->members[i].dispid    = 0;
+            if (++i > count)
+            {
+                IWbemClassObject_EndEnumeration( object->object );
+                goto error;
+            }
+            TRACE( "added property %s\n", debugstr_w(name) );
         }
-        object->members[i].dispid = 0;
+        IWbemClassObject_EndEnumeration( object->object );
     }
-    object->nb_members = bound + 1;
-    SafeArrayDestroy( sa );
+
+    hr = IWbemClassObject_BeginMethodEnumeration( object->object, 0 );
+    if (SUCCEEDED( hr ))
+    {
+        while (IWbemClassObject_NextMethod( object->object, 0, &name, &sig_in, &sig_out ) == S_OK)
+        {
+            object->members[i].name      = name;
+            object->members[i].is_method = TRUE;
+            object->members[i].dispid    = 0;
+            if (++i > count)
+            {
+                IWbemClassObject_EndMethodEnumeration( object->object );
+                goto error;
+            }
+            IWbemClassObject_Release( sig_in );
+            IWbemClassObject_Release( sig_out );
+            TRACE( "added method %s\n", debugstr_w(name) );
+        }
+        IWbemClassObject_EndMethodEnumeration( object->object );
+    }
+
+    object->nb_members = count;
+    TRACE( "added %u members\n", object->nb_members );
     return S_OK;
+
+error:
+    for (--i; i >= 0; i--) SysFreeString( object->members[i].name );
+    heap_free( object->members );
+    object->members = NULL;
+    object->nb_members = 0;
+    return E_FAIL;
 }
 
 static DISPID get_member_dispid( struct object *object, const WCHAR *name )
@@ -629,7 +674,13 @@ static DISPID get_member_dispid( struct object *object, const WCHAR *name )
     {
         if (!strcmpiW( object->members[i].name, name ))
         {
-            if (!object->members[i].dispid) object->members[i].dispid = ++object->last_dispid;
+            if (!object->members[i].dispid)
+            {
+                if (object->members[i].is_method)
+                    object->members[i].dispid = ++object->last_dispid_method;
+                else
+                    object->members[i].dispid = ++object->last_dispid;
+            }
             return object->members[i].dispid;
         }
     }
@@ -701,7 +752,7 @@ static HRESULT WINAPI object_Invoke(
     TRACE( "%p, %x, %s, %u, %x, %p, %p, %p, %p\n", object, member, debugstr_guid(riid),
            lcid, flags, params, result, excep_info, arg_err );
 
-    if (member <= DISPID_BASE)
+    if (member <= DISPID_BASE_METHOD)
     {
         hr = get_typeinfo( ISWbemObject_tid, &typeinfo );
         if (SUCCEEDED(hr))
@@ -1044,6 +1095,7 @@ static HRESULT SWbemObject_create( IWbemClassObject *wbem_object, ISWbemObject *
     object->members = NULL;
     object->nb_members = 0;
     object->last_dispid = DISPID_BASE;
+    object->last_dispid_method = DISPID_BASE_METHOD;
 
     *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 1ce0456..68c0e3b 100644
--- a/dlls/wbemdisp/tests/wbemdisp.c
+++ b/dlls/wbemdisp/tests/wbemdisp.c
@@ -48,6 +48,11 @@ static void test_ParseDisplayName(void)
     static const WCHAR name4[] =
         {'w','i','n','m','g','m','t','s',':','\\','\\','.','\\','r','o','o','t','\\','c','i','m','v','2',':',
          'W','i','n','3','2','_','S','e','r','v','i','c','e',0};
+    static const WCHAR stdregprovW[] =
+        {'w','i','n','m','g','m','t','s',':','\\','\\','.','\\','r','o','o','t','\\','d','e','f','a','u','l','t',':',
+         'S','t','d','R','e','g','P','r','o','v',0};
+    static const WCHAR getstringvalueW[] =
+        {'G','e','t','S','t','r','i','n','g','V','a','l','u','e',0};
     static const struct
     {
         const WCHAR *name;
@@ -242,6 +247,36 @@ static void test_ParseDisplayName(void)
     }
 
     IBindCtx_Release( ctx );
+
+    hr = CreateBindCtx( 0, &ctx );
+    ok( hr == S_OK, "got %x\n", hr );
+
+    str = SysAllocString( stdregprovW );
+    hr = IParseDisplayName_ParseDisplayName( displayname, NULL, str, &eaten, &moniker );
+    ok( hr == S_OK, "got %x\n", hr );
+    SysFreeString( str );
+
+    if (moniker)
+    {
+        ISWbemObject *sobj = NULL;
+        hr = IMoniker_BindToObject( moniker, ctx, NULL, &IID_ISWbemObject, (void **)&sobj );
+        ok( hr == S_OK, "got %x\n",hr );
+        if (sobj)
+        {
+            DISPID dispid = 0xdeadbeef;
+
+            str = SysAllocString( getstringvalueW );
+            hr = ISWbemObject_GetIDsOfNames( sobj, &IID_NULL, &str, 1, english, &dispid );
+            ok( hr == S_OK, "got %x\n", hr );
+            ok( dispid == 0x1000001, "got %x\n", dispid );
+
+            ISWbemObject_Release( sobj );
+            SysFreeString( str );
+        }
+        IMoniker_Release( moniker );
+    }
+
+    IBindCtx_Release(ctx);
     IParseDisplayName_Release( displayname );
 }
 




More information about the wine-cvs mailing list