Hans Leidekker : wbemdisp: Implement ISWbemObjectSet::get__NewEnum.
Alexandre Julliard
julliard at wine.codeweavers.com
Wed Jan 14 14:35:42 CST 2015
Module: wine
Branch: master
Commit: c245fb66f89da61818b743e1f1df9b00343968dc
URL: http://source.winehq.org/git/wine.git/?a=commit;h=c245fb66f89da61818b743e1f1df9b00343968dc
Author: Hans Leidekker <hans at codeweavers.com>
Date: Wed Jan 14 15:36:16 2015 +0100
wbemdisp: Implement ISWbemObjectSet::get__NewEnum.
---
dlls/wbemdisp/locator.c | 156 +++++++++++++++++++++++++++++++++++++++--
dlls/wbemdisp/tests/wbemdisp.c | 69 ++++++++++++++++++
2 files changed, 221 insertions(+), 4 deletions(-)
diff --git a/dlls/wbemdisp/locator.c b/dlls/wbemdisp/locator.c
index 9731630..c3103fa 100644
--- a/dlls/wbemdisp/locator.c
+++ b/dlls/wbemdisp/locator.c
@@ -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;
diff --git a/dlls/wbemdisp/tests/wbemdisp.c b/dlls/wbemdisp/tests/wbemdisp.c
index 8c0b628..863115b 100644
--- a/dlls/wbemdisp/tests/wbemdisp.c
+++ b/dlls/wbemdisp/tests/wbemdisp.c
@@ -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 );
}
More information about the wine-cvs
mailing list