wbemdisp: Implement ISWbemObjectSet::get__NewEnum.
This commit is contained in:
parent
78433f1164
commit
c245fb66f8
|
@ -36,6 +36,8 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wbemdisp);
|
||||
|
||||
static HRESULT EnumVARIANT_create( ISWbemObjectSet *, IEnumVARIANT ** );
|
||||
|
||||
enum type_id
|
||||
{
|
||||
ISWbemLocator_tid,
|
||||
|
@ -401,8 +403,11 @@ static HRESULT WINAPI objectset_get__NewEnum(
|
|||
ISWbemObjectSet *iface,
|
||||
IUnknown **pUnk )
|
||||
{
|
||||
FIXME( "\n" );
|
||||
return E_NOTIMPL;
|
||||
struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
|
||||
|
||||
TRACE( "%p, %p\n", objectset, pUnk );
|
||||
|
||||
return EnumVARIANT_create( iface, (IEnumVARIANT **)pUnk );
|
||||
}
|
||||
|
||||
static HRESULT WINAPI objectset_Item(
|
||||
|
@ -420,12 +425,20 @@ static HRESULT WINAPI objectset_get_Count(
|
|||
LONG *iCount )
|
||||
{
|
||||
struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
|
||||
LONG count = 0, total = 0;
|
||||
|
||||
TRACE( "%p, %p\n", objectset, iCount );
|
||||
|
||||
*iCount = 0;
|
||||
while (IEnumWbemClassObject_Skip( objectset->objectenum, WBEM_INFINITE, 1 ) == S_OK) count++;
|
||||
|
||||
IEnumWbemClassObject_Reset( objectset->objectenum );
|
||||
while (!IEnumWbemClassObject_Skip( objectset->objectenum, WBEM_INFINITE, 1 )) (*iCount)++;
|
||||
while (IEnumWbemClassObject_Skip( objectset->objectenum, WBEM_INFINITE, 1 ) == S_OK) total++;
|
||||
|
||||
count = total - count;
|
||||
IEnumWbemClassObject_Reset( objectset->objectenum );
|
||||
while (count--) IEnumWbemClassObject_Skip( objectset->objectenum, WBEM_INFINITE, 1 );
|
||||
|
||||
*iCount = total;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -479,6 +492,141 @@ static HRESULT SWbemObjectSet_create( IEnumWbemClassObject *wbem_objectenum, ISW
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
struct enumvar
|
||||
{
|
||||
IEnumVARIANT IEnumVARIANT_iface;
|
||||
LONG refs;
|
||||
ISWbemObjectSet *objectset;
|
||||
};
|
||||
|
||||
static inline struct enumvar *impl_from_IEnumVARIANT(
|
||||
IEnumVARIANT *iface )
|
||||
{
|
||||
return CONTAINING_RECORD( iface, struct enumvar, IEnumVARIANT_iface );
|
||||
}
|
||||
|
||||
static ULONG WINAPI enumvar_AddRef(
|
||||
IEnumVARIANT *iface )
|
||||
{
|
||||
struct enumvar *enumvar = impl_from_IEnumVARIANT( iface );
|
||||
return InterlockedIncrement( &enumvar->refs );
|
||||
}
|
||||
|
||||
static ULONG WINAPI enumvar_Release(
|
||||
IEnumVARIANT *iface )
|
||||
{
|
||||
struct enumvar *enumvar = impl_from_IEnumVARIANT( iface );
|
||||
LONG refs = InterlockedDecrement( &enumvar->refs );
|
||||
if (!refs)
|
||||
{
|
||||
TRACE( "destroying %p\n", enumvar );
|
||||
ISWbemObjectSet_Release( enumvar->objectset );
|
||||
heap_free( enumvar );
|
||||
}
|
||||
return refs;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI enumvar_QueryInterface(
|
||||
IEnumVARIANT *iface,
|
||||
REFIID riid,
|
||||
void **ppvObject )
|
||||
{
|
||||
struct enumvar *enumvar = impl_from_IEnumVARIANT( iface );
|
||||
|
||||
TRACE( "%p %s %p\n", enumvar, debugstr_guid(riid), ppvObject );
|
||||
|
||||
if (IsEqualGUID( riid, &IID_IEnumVARIANT ) ||
|
||||
IsEqualGUID( riid, &IID_IUnknown ))
|
||||
{
|
||||
*ppvObject = enumvar;
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
IEnumVARIANT_AddRef( iface );
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI enumvar_Next( IEnumVARIANT *iface, ULONG celt, VARIANT *var, ULONG *fetched )
|
||||
{
|
||||
struct enumvar *enumvar = impl_from_IEnumVARIANT( iface );
|
||||
struct objectset *objectset = impl_from_ISWbemObjectSet( enumvar->objectset );
|
||||
IWbemClassObject *obj;
|
||||
ULONG count = 0;
|
||||
|
||||
TRACE( "%p, %u, %p, %p\n", iface, celt, var, fetched );
|
||||
|
||||
if (celt) IEnumWbemClassObject_Next( objectset->objectenum, WBEM_INFINITE, 1, &obj, &count );
|
||||
if (count)
|
||||
{
|
||||
ISWbemObject *sobj;
|
||||
HRESULT hr;
|
||||
|
||||
hr = SWbemObject_create( obj, &sobj );
|
||||
IWbemClassObject_Release( obj );
|
||||
if (FAILED( hr )) return hr;
|
||||
|
||||
V_VT( var ) = VT_DISPATCH;
|
||||
V_DISPATCH( var ) = (IDispatch *)sobj;
|
||||
}
|
||||
if (fetched) *fetched = count;
|
||||
return (count < celt) ? S_FALSE : S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI enumvar_Skip( IEnumVARIANT *iface, ULONG celt )
|
||||
{
|
||||
struct enumvar *enumvar = impl_from_IEnumVARIANT( iface );
|
||||
struct objectset *objectset = impl_from_ISWbemObjectSet( enumvar->objectset );
|
||||
|
||||
TRACE( "%p, %u\n", iface, celt );
|
||||
|
||||
return IEnumWbemClassObject_Skip( objectset->objectenum, WBEM_INFINITE, celt );
|
||||
}
|
||||
|
||||
static HRESULT WINAPI enumvar_Reset( IEnumVARIANT *iface )
|
||||
{
|
||||
struct enumvar *enumvar = impl_from_IEnumVARIANT( iface );
|
||||
struct objectset *objectset = impl_from_ISWbemObjectSet( enumvar->objectset );
|
||||
|
||||
TRACE( "%p\n", iface );
|
||||
|
||||
return IEnumWbemClassObject_Reset( objectset->objectenum );
|
||||
}
|
||||
|
||||
static HRESULT WINAPI enumvar_Clone( IEnumVARIANT *iface, IEnumVARIANT **penum )
|
||||
{
|
||||
FIXME( "%p, %p\n", iface, penum );
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static const struct IEnumVARIANTVtbl enumvar_vtbl =
|
||||
{
|
||||
enumvar_QueryInterface,
|
||||
enumvar_AddRef,
|
||||
enumvar_Release,
|
||||
enumvar_Next,
|
||||
enumvar_Skip,
|
||||
enumvar_Reset,
|
||||
enumvar_Clone
|
||||
};
|
||||
|
||||
static HRESULT EnumVARIANT_create( ISWbemObjectSet *objectset, IEnumVARIANT **obj )
|
||||
{
|
||||
struct enumvar *enumvar;
|
||||
|
||||
if (!(enumvar = heap_alloc( sizeof(*enumvar) ))) return E_OUTOFMEMORY;
|
||||
enumvar->IEnumVARIANT_iface.lpVtbl = &enumvar_vtbl;
|
||||
enumvar->refs = 1;
|
||||
enumvar->objectset = objectset;
|
||||
ISWbemObjectSet_AddRef( enumvar->objectset );
|
||||
|
||||
*obj = &enumvar->IEnumVARIANT_iface;
|
||||
TRACE( "returning iface %p\n", *obj );
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
struct services
|
||||
{
|
||||
ISWbemServices ISWbemServices_iface;
|
||||
|
|
|
@ -29,6 +29,7 @@ DEFINE_GUID(CLSID_WINMGMTS,0x172bddf8,0xceea,0x11d1,0x8b,0x05,0x00,0x60,0x08,0x0
|
|||
|
||||
static void test_ParseDisplayName(void)
|
||||
{
|
||||
static const WCHAR biosW[] = {'W','i','n','3','2','_','B','i','o','s',0};
|
||||
static const WCHAR name1[] =
|
||||
{'w','i','n','m','g','m','t','s',':',0};
|
||||
static const WCHAR name2[] =
|
||||
|
@ -90,6 +91,74 @@ static void test_ParseDisplayName(void)
|
|||
}
|
||||
}
|
||||
|
||||
str = SysAllocString( name1 );
|
||||
eaten = 0xdeadbeef;
|
||||
moniker = NULL;
|
||||
hr = IParseDisplayName_ParseDisplayName( displayname, NULL, str, &eaten, &moniker );
|
||||
SysFreeString( str );
|
||||
ok( hr == S_OK, "got %x\n", hr );
|
||||
ok( eaten == lstrlenW(name1), "got %u\n", eaten );
|
||||
if (moniker)
|
||||
{
|
||||
ISWbemServices *services = NULL;
|
||||
|
||||
hr = IMoniker_BindToObject( moniker, ctx, NULL, &IID_IUnknown, (void **)&services );
|
||||
ok( hr == S_OK, "got %x\n", hr );
|
||||
if (services)
|
||||
{
|
||||
ISWbemObjectSet *objectset = NULL;
|
||||
|
||||
str = SysAllocString( biosW );
|
||||
hr = ISWbemServices_InstancesOf( services, str, 0, NULL, &objectset );
|
||||
SysFreeString( str );
|
||||
ok( hr == S_OK, "got %x\n", hr );
|
||||
if (objectset)
|
||||
{
|
||||
hr = ISWbemObjectSet_get__NewEnum( objectset, &obj );
|
||||
ok( hr == S_OK, "got %x\n", hr );
|
||||
if (obj)
|
||||
{
|
||||
IEnumVARIANT *enumvar = NULL;
|
||||
|
||||
hr = IUnknown_QueryInterface( obj, &IID_IEnumVARIANT, (void **)&enumvar );
|
||||
ok( hr == S_OK, "got %x\n", hr );
|
||||
|
||||
if (enumvar)
|
||||
{
|
||||
VARIANT var;
|
||||
ULONG fetched;
|
||||
|
||||
fetched = 0xdeadbeef;
|
||||
hr = IEnumVARIANT_Next( enumvar, 0, &var, &fetched );
|
||||
ok( hr == S_OK, "got %x\n", hr );
|
||||
ok( !fetched, "got %u\n", fetched );
|
||||
|
||||
fetched = 0xdeadbeef;
|
||||
V_VT( &var ) = VT_ERROR;
|
||||
V_ERROR( &var ) = 0xdeadbeef;
|
||||
hr = IEnumVARIANT_Next( enumvar, 1, &var, &fetched );
|
||||
ok( hr == S_OK, "got %x\n", hr );
|
||||
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 ) );
|
||||
VariantClear( &var );
|
||||
|
||||
fetched = 0xdeadbeef;
|
||||
hr = IEnumVARIANT_Next( enumvar, 1, &var, &fetched );
|
||||
ok( hr == S_FALSE, "got %x\n", hr );
|
||||
ok( !fetched, "got %u\n", fetched );
|
||||
|
||||
IEnumVARIANT_Release( enumvar );
|
||||
}
|
||||
IUnknown_Release( obj );
|
||||
}
|
||||
ISWbemObjectSet_Release( objectset );
|
||||
}
|
||||
IUnknown_Release( services );
|
||||
}
|
||||
IMoniker_Release( moniker );
|
||||
}
|
||||
|
||||
IBindCtx_Release( ctx );
|
||||
IParseDisplayName_Release( displayname );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue