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