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@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
492a9653f5
commit
6db5a3a11f
|
@ -489,10 +489,12 @@ static HRESULT SWbemPropertySet_create( IWbemClassObject *wbem_object, ISWbemPro
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DISPID_BASE 0x1800000
|
#define DISPID_BASE 0x1800000
|
||||||
|
#define DISPID_BASE_METHOD 0x1000000
|
||||||
|
|
||||||
struct member
|
struct member
|
||||||
{
|
{
|
||||||
BSTR name;
|
BSTR name;
|
||||||
|
BOOL is_method;
|
||||||
DISPID dispid;
|
DISPID dispid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -504,6 +506,7 @@ struct object
|
||||||
struct member *members;
|
struct member *members;
|
||||||
UINT nb_members;
|
UINT nb_members;
|
||||||
DISPID last_dispid;
|
DISPID last_dispid;
|
||||||
|
DISPID last_dispid_method;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct object *impl_from_ISWbemObject(
|
static inline struct object *impl_from_ISWbemObject(
|
||||||
|
@ -585,41 +588,83 @@ static HRESULT WINAPI object_GetTypeInfo(
|
||||||
|
|
||||||
static HRESULT init_members( struct object *object )
|
static HRESULT init_members( struct object *object )
|
||||||
{
|
{
|
||||||
LONG bound, i;
|
IWbemClassObject *sig_in, *sig_out;
|
||||||
SAFEARRAY *sa;
|
LONG i = 0, count = 0;
|
||||||
|
BSTR name;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
if (object->members) return S_OK;
|
if (object->members) return S_OK;
|
||||||
|
|
||||||
hr = IWbemClassObject_GetNames( object->object, NULL, 0, NULL, &sa );
|
hr = IWbemClassObject_BeginEnumeration( object->object, 0 );
|
||||||
if (FAILED( hr )) return hr;
|
if (SUCCEEDED( hr ))
|
||||||
hr = SafeArrayGetUBound( sa, 1, &bound );
|
|
||||||
if (FAILED( hr ))
|
|
||||||
{
|
{
|
||||||
SafeArrayDestroy( sa );
|
while (IWbemClassObject_Next( object->object, 0, NULL, NULL, NULL, NULL ) == S_OK) count++;
|
||||||
return hr;
|
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 );
|
while (IWbemClassObject_NextMethod( object->object, 0, &name, &sig_in, &sig_out ) == S_OK)
|
||||||
return E_OUTOFMEMORY;
|
{
|
||||||
|
count++;
|
||||||
|
SysFreeString( name );
|
||||||
|
IWbemClassObject_Release( sig_in );
|
||||||
|
IWbemClassObject_Release( sig_out );
|
||||||
}
|
}
|
||||||
for (i = 0; i <= bound; i++)
|
IWbemClassObject_EndMethodEnumeration( object->object );
|
||||||
|
}
|
||||||
|
|
||||||
|
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 );
|
while (IWbemClassObject_Next( object->object, 0, &name, NULL, NULL, NULL ) == S_OK)
|
||||||
if (FAILED( hr ))
|
|
||||||
{
|
{
|
||||||
for (i--; i >= 0; i--) SysFreeString( object->members[i].name );
|
object->members[i].name = name;
|
||||||
SafeArrayDestroy( sa );
|
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) );
|
||||||
|
}
|
||||||
|
IWbemClassObject_EndEnumeration( object->object );
|
||||||
|
}
|
||||||
|
|
||||||
|
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 );
|
heap_free( object->members );
|
||||||
object->members = NULL;
|
object->members = NULL;
|
||||||
return E_OUTOFMEMORY;
|
object->nb_members = 0;
|
||||||
}
|
return E_FAIL;
|
||||||
object->members[i].dispid = 0;
|
|
||||||
}
|
|
||||||
object->nb_members = bound + 1;
|
|
||||||
SafeArrayDestroy( sa );
|
|
||||||
return S_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static DISPID get_member_dispid( struct object *object, const WCHAR *name )
|
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 (!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;
|
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),
|
TRACE( "%p, %x, %s, %u, %x, %p, %p, %p, %p\n", object, member, debugstr_guid(riid),
|
||||||
lcid, flags, params, result, excep_info, arg_err );
|
lcid, flags, params, result, excep_info, arg_err );
|
||||||
|
|
||||||
if (member <= DISPID_BASE)
|
if (member <= DISPID_BASE_METHOD)
|
||||||
{
|
{
|
||||||
hr = get_typeinfo( ISWbemObject_tid, &typeinfo );
|
hr = get_typeinfo( ISWbemObject_tid, &typeinfo );
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
|
@ -1044,6 +1095,7 @@ static HRESULT SWbemObject_create( IWbemClassObject *wbem_object, ISWbemObject *
|
||||||
object->members = NULL;
|
object->members = NULL;
|
||||||
object->nb_members = 0;
|
object->nb_members = 0;
|
||||||
object->last_dispid = DISPID_BASE;
|
object->last_dispid = DISPID_BASE;
|
||||||
|
object->last_dispid_method = DISPID_BASE_METHOD;
|
||||||
|
|
||||||
*obj = &object->ISWbemObject_iface;
|
*obj = &object->ISWbemObject_iface;
|
||||||
TRACE( "returning iface %p\n", *obj );
|
TRACE( "returning iface %p\n", *obj );
|
||||||
|
|
|
@ -48,6 +48,11 @@ static void test_ParseDisplayName(void)
|
||||||
static const WCHAR name4[] =
|
static const WCHAR name4[] =
|
||||||
{'w','i','n','m','g','m','t','s',':','\\','\\','.','\\','r','o','o','t','\\','c','i','m','v','2',':',
|
{'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};
|
'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
|
static const struct
|
||||||
{
|
{
|
||||||
const WCHAR *name;
|
const WCHAR *name;
|
||||||
|
@ -241,6 +246,36 @@ static void test_ParseDisplayName(void)
|
||||||
IMoniker_Release( moniker );
|
IMoniker_Release( moniker );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
IBindCtx_Release(ctx);
|
||||||
IParseDisplayName_Release( displayname );
|
IParseDisplayName_Release( displayname );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue