wbemdisp: Implement ISwbemObject::GetIDsOfNames.
This commit is contained in:
parent
c245fb66f8
commit
e992df727a
|
@ -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;
|
||||
}
|
||||
|
||||
return get_typeinfo( ISWbemObject_tid, info );
|
||||
#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;
|
||||
}
|
||||
|
||||
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 );
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue