[PATCH v2 0/7] MR11724: wbemdisp: Fixes and implementations part 2.
To avoid ending up with three separate `EnumVARIANT` implementations, I made the existing one handle all three. Let me know if they should be separate, and if so I'll change it. -- v2: wbemdisp: Add ISWbemQualifierSet enumerator stub implementation. wbemdisp: Add ISWbemQualifierSet stub implementation. wbemdisp: Implement get ISWbemProperty::Name. https://gitlab.winehq.org/wine/wine/-/merge_requests/11724
From: Conor McCarthy <cmccarthy@codeweavers.com> --- dlls/wbemdisp/locator.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dlls/wbemdisp/locator.c b/dlls/wbemdisp/locator.c index c3ad6fa50a2..5b8558ee5eb 100644 --- a/dlls/wbemdisp/locator.c +++ b/dlls/wbemdisp/locator.c @@ -332,7 +332,7 @@ struct propertyset { ISWbemPropertySet ISWbemPropertySet_iface; LONG refs; - IWbemClassObject *object; + IWbemClassObject *class_object; }; static inline struct propertyset *impl_from_ISWbemPropertySet( @@ -354,7 +354,7 @@ static ULONG WINAPI propertyset_Release( ISWbemPropertySet *iface ) if (!refs) { TRACE( "destroying %p\n", propertyset ); - IWbemClassObject_Release( propertyset->object ); + IWbemClassObject_Release( propertyset->class_object ); free( propertyset ); } return refs; @@ -456,10 +456,10 @@ static HRESULT WINAPI propertyset_Item( ISWbemPropertySet *iface, BSTR name, TRACE( "%p, %s, %#lx, %p\n", propertyset, debugstr_w(name), flags, prop ); - hr = IWbemClassObject_Get( propertyset->object, name, 0, &var, NULL, NULL ); + hr = IWbemClassObject_Get( propertyset->class_object, name, 0, &var, NULL, NULL ); if (SUCCEEDED(hr)) { - hr = SWbemProperty_create( propertyset->object, name, prop ); + hr = SWbemProperty_create( propertyset->class_object, name, prop ); VariantClear( &var ); } return hr; @@ -473,7 +473,7 @@ static HRESULT WINAPI propertyset_get_Count( ISWbemPropertySet *iface, LONG *cou TRACE( "%p, %p\n", propertyset, count ); - hr = IWbemClassObject_Get( propertyset->object, L"__PROPERTY_COUNT", 0, &val, NULL, NULL ); + hr = IWbemClassObject_Get( propertyset->class_object, L"__PROPERTY_COUNT", 0, &val, NULL, NULL ); if (SUCCEEDED(hr)) { *count = V_I4( &val ); @@ -519,8 +519,8 @@ static HRESULT SWbemPropertySet_create( IWbemClassObject *wbem_object, ISWbemPro if (!(propertyset = malloc( sizeof(*propertyset) ))) return E_OUTOFMEMORY; propertyset->ISWbemPropertySet_iface.lpVtbl = &propertyset_vtbl; propertyset->refs = 1; - propertyset->object = wbem_object; - IWbemClassObject_AddRef( propertyset->object ); + propertyset->class_object = wbem_object; + IWbemClassObject_AddRef( propertyset->class_object ); *obj = &propertyset->ISWbemPropertySet_iface; TRACE( "returning iface %p\n", *obj ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11724
From: Conor McCarthy <cmccarthy@codeweavers.com> --- dlls/wbemdisp/locator.c | 147 +++++++++++++++++++++++++++------ dlls/wbemdisp/tests/wbemdisp.c | 4 - 2 files changed, 120 insertions(+), 31 deletions(-) diff --git a/dlls/wbemdisp/locator.c b/dlls/wbemdisp/locator.c index 5b8558ee5eb..cad9d50442a 100644 --- a/dlls/wbemdisp/locator.c +++ b/dlls/wbemdisp/locator.c @@ -50,9 +50,15 @@ static IWbemContext * unsafe_get_context_from_namedvalueset( IDispatch *disp ) return valueset ? valueset->context : NULL; } +enum enum_variant_type +{ + ENUM_OBJECTS, + ENUM_PROPERTIES, +}; + struct services; -static HRESULT EnumVARIANT_create( struct services *, IEnumWbemClassObject *, IEnumVARIANT ** ); +static HRESULT EnumVARIANT_create( enum enum_variant_type, struct services *, void *, IEnumVARIANT ** ); static HRESULT ISWbemSecurity_create( ISWbemSecurity ** ); static HRESULT SWbemObject_create( struct services *, IWbemClassObject *, ISWbemObject ** ); static HRESULT SWbemObjectPath_create( IWbemClassObject *, ISWbemObjectPath ** ); @@ -333,6 +339,7 @@ struct propertyset ISWbemPropertySet ISWbemPropertySet_iface; LONG refs; IWbemClassObject *class_object; + ISWbemObject *object; }; static inline struct propertyset *impl_from_ISWbemPropertySet( @@ -355,6 +362,7 @@ static ULONG WINAPI propertyset_Release( ISWbemPropertySet *iface ) { TRACE( "destroying %p\n", propertyset ); IWbemClassObject_Release( propertyset->class_object ); + ISWbemObject_Release( propertyset->object ); free( propertyset ); } return refs; @@ -443,8 +451,11 @@ static HRESULT WINAPI propertyset_Invoke( ISWbemPropertySet *iface, DISPID membe static HRESULT WINAPI propertyset_get__NewEnum( ISWbemPropertySet *iface, IUnknown **unk ) { - FIXME( "\n" ); - return E_NOTIMPL; + struct propertyset *propertyset = impl_from_ISWbemPropertySet( iface ); + + TRACE( "%p, %p\n", iface, unk ); + + return EnumVARIANT_create( ENUM_PROPERTIES, NULL, propertyset->object, (IEnumVARIANT **)unk ); } static HRESULT WINAPI propertyset_Item( ISWbemPropertySet *iface, BSTR name, @@ -510,17 +521,19 @@ static const ISWbemPropertySetVtbl propertyset_vtbl = propertyset_Remove }; -static HRESULT SWbemPropertySet_create( IWbemClassObject *wbem_object, ISWbemPropertySet **obj ) +static HRESULT SWbemPropertySet_create( IWbemClassObject *wbem_object, ISWbemObject *object, ISWbemPropertySet **obj ) { struct propertyset *propertyset; TRACE( "%p, %p\n", obj, wbem_object ); - if (!(propertyset = malloc( sizeof(*propertyset) ))) return E_OUTOFMEMORY; + if (!(propertyset = calloc( 1, sizeof(*propertyset) ))) return E_OUTOFMEMORY; propertyset->ISWbemPropertySet_iface.lpVtbl = &propertyset_vtbl; propertyset->refs = 1; propertyset->class_object = wbem_object; IWbemClassObject_AddRef( propertyset->class_object ); + propertyset->object = object; + ISWbemObject_AddRef( propertyset->object ); *obj = &propertyset->ISWbemPropertySet_iface; TRACE( "returning iface %p\n", *obj ); @@ -537,6 +550,7 @@ struct services struct member { BSTR name; + BOOL is_system; BOOL is_method; DISPID dispid; CIMTYPE type; @@ -1105,6 +1119,7 @@ static HRESULT init_members( struct object *object ) IWbemClassObject *sig_in, *sig_out; unsigned int i, capacity = 0, count = 0; CIMTYPE type; + LONG flavor; HRESULT hr; BSTR name; @@ -1113,10 +1128,11 @@ static HRESULT init_members( struct object *object ) hr = IWbemClassObject_BeginEnumeration( object->object, 0 ); if (SUCCEEDED( hr )) { - while (IWbemClassObject_Next( object->object, 0, &name, NULL, &type, NULL ) == S_OK) + while (IWbemClassObject_Next( object->object, 0, &name, NULL, &type, &flavor ) == S_OK) { if (!object_reserve_member( object, count + 1, &capacity )) goto error; object->members[count].name = name; + object->members[count].is_system = !!(flavor & WBEM_FLAVOR_ORIGIN_SYSTEM); object->members[count].is_method = FALSE; object->members[count].dispid = 0; object->members[count].type = type; @@ -1133,6 +1149,7 @@ static HRESULT init_members( struct object *object ) { if (!object_reserve_member( object, count + 1, &capacity )) goto error; object->members[count].name = name; + object->members[count].is_system = FALSE; object->members[count].is_method = TRUE; object->members[count].dispid = 0; count++; @@ -1581,9 +1598,14 @@ static HRESULT WINAPI object_get_Qualifiers_( static HRESULT WINAPI object_get_Properties_( ISWbemObject *iface, ISWbemPropertySet **prop_set ) { struct object *object = impl_from_ISWbemObject( iface ); + HRESULT hr; TRACE( "%p, %p\n", object, prop_set ); - return SWbemPropertySet_create( object->object, prop_set ); + + hr = init_members( object ); + if (FAILED( hr )) return hr; + + return SWbemPropertySet_create( object->object, iface, prop_set ); } static HRESULT WINAPI object_get_Methods_( @@ -1842,7 +1864,7 @@ static HRESULT WINAPI objectset_get__NewEnum( hr = IEnumWbemClassObject_Clone( objectset->objectenum, &objectenum ); if (FAILED( hr )) return hr; - hr = EnumVARIANT_create( objectset->services, objectenum, (IEnumVARIANT **)pUnk ); + hr = EnumVARIANT_create( ENUM_OBJECTS, objectset->services, objectenum, (IEnumVARIANT **)pUnk ); IEnumWbemClassObject_Release( objectenum ); return hr; } @@ -1966,8 +1988,17 @@ struct enumvar { IEnumVARIANT IEnumVARIANT_iface; LONG refs; - IEnumWbemClassObject *objectenum; + union + { + struct + { + ISWbemObject *object; + ULONG cursor; + } members; + IEnumWbemClassObject *objectenum; + } u; struct services *services; + enum enum_variant_type enum_type; }; static inline struct enumvar *impl_from_IEnumVARIANT( @@ -1991,8 +2022,11 @@ static ULONG WINAPI enumvar_Release( if (!refs) { TRACE( "destroying %p\n", enumvar ); - IEnumWbemClassObject_Release( enumvar->objectenum ); - ISWbemServices_Release( &enumvar->services->ISWbemServices_iface ); + if (enumvar->enum_type == ENUM_OBJECTS) + IEnumWbemClassObject_Release( enumvar->u.objectenum ); + else + ISWbemObject_Release( enumvar->u.members.object ); + if (enumvar->services) ISWbemServices_Release( &enumvar->services->ISWbemServices_iface ); free( enumvar ); } return refs; @@ -2032,19 +2066,49 @@ static HRESULT WINAPI enumvar_Next( IEnumVARIANT *iface, ULONG celt, VARIANT *va if (!var) return S_FALSE; - if (celt) IEnumWbemClassObject_Next( enumvar->objectenum, WBEM_INFINITE, 1, &obj, &count ); - if (count) + if (enumvar->enum_type == ENUM_OBJECTS) { - ISWbemObject *sobj; - HRESULT hr; + if (celt) IEnumWbemClassObject_Next( enumvar->u.objectenum, WBEM_INFINITE, 1, &obj, &count ); + if (count) + { + ISWbemObject *sobj; + HRESULT hr; - hr = SWbemObject_create( enumvar->services, obj, &sobj ); - IWbemClassObject_Release( obj ); - if (FAILED( hr )) return hr; + hr = SWbemObject_create( enumvar->services, obj, &sobj ); + IWbemClassObject_Release( obj ); + if (FAILED( hr )) return hr; - V_VT( var ) = VT_DISPATCH; - V_DISPATCH( var ) = (IDispatch *)sobj; + V_VT( var ) = VT_DISPATCH; + V_DISPATCH( var ) = (IDispatch *)sobj; + } } + else + { + struct object *object = impl_from_ISWbemObject( enumvar->u.members.object ); + ULONG cursor = enumvar->u.members.cursor; + + for (count = 0; count < celt && cursor < object->nb_members; ++cursor) + { + ISWbemProperty *prop; + HRESULT hr; + + if (object->members[cursor].is_system) continue; + if (object->members[cursor].is_method) continue; + + hr = SWbemProperty_create( object->object, object->members[cursor].name, &prop ); + if (FAILED( hr )) + { + WARN( "Failed to create property, hr %#lx\n", hr ); + break; + } + + V_VT( var + count ) = VT_DISPATCH; + V_DISPATCH( var + count ) = (IDispatch *)prop; + ++count; + } + enumvar->u.members.cursor = cursor; + } + if (fetched) *fetched = count; return (count < celt) ? S_FALSE : S_OK; } @@ -2055,16 +2119,36 @@ static HRESULT WINAPI enumvar_Skip( IEnumVARIANT *iface, ULONG celt ) TRACE( "%p, %lu\n", iface, celt ); - return IEnumWbemClassObject_Skip( enumvar->objectenum, WBEM_INFINITE, celt ); + if (enumvar->enum_type == ENUM_OBJECTS) + return IEnumWbemClassObject_Skip( enumvar->u.objectenum, WBEM_INFINITE, celt ); + else + { + struct object *object = impl_from_ISWbemObject( enumvar->u.members.object ); + + if (enumvar->u.members.cursor + celt < celt || enumvar->u.members.cursor + celt > object->nb_members) + { + enumvar->u.members.cursor = object->nb_members; + return S_FALSE; + } + + enumvar->u.members.cursor += celt; + return S_OK; + } } static HRESULT WINAPI enumvar_Reset( IEnumVARIANT *iface ) { struct enumvar *enumvar = impl_from_IEnumVARIANT( iface ); + HRESULT hr = S_OK; TRACE( "%p\n", iface ); - return IEnumWbemClassObject_Reset( enumvar->objectenum ); + if (enumvar->enum_type == ENUM_OBJECTS) + hr = IEnumWbemClassObject_Reset( enumvar->u.objectenum ); + else + enumvar->u.members.cursor = 0; + + return hr; } static HRESULT WINAPI enumvar_Clone( IEnumVARIANT *iface, IEnumVARIANT **penum ) @@ -2084,18 +2168,27 @@ static const struct IEnumVARIANTVtbl enumvar_vtbl = enumvar_Clone }; -static HRESULT EnumVARIANT_create( struct services *services, IEnumWbemClassObject *objectenum, +static HRESULT EnumVARIANT_create( enum enum_variant_type enum_type, struct services *services, void *object, IEnumVARIANT **obj ) { struct enumvar *enumvar; - if (!(enumvar = malloc( sizeof(*enumvar) ))) return E_OUTOFMEMORY; + if (!(enumvar = calloc( 1, sizeof(*enumvar) ))) return E_OUTOFMEMORY; enumvar->IEnumVARIANT_iface.lpVtbl = &enumvar_vtbl; enumvar->refs = 1; - enumvar->objectenum = objectenum; - IEnumWbemClassObject_AddRef( enumvar->objectenum ); + enumvar->enum_type = enum_type; + if (enum_type == ENUM_OBJECTS) + { + enumvar->u.objectenum = object; + IEnumWbemClassObject_AddRef( enumvar->u.objectenum ); + } + else + { + enumvar->u.members.object = object; + ISWbemObject_AddRef( enumvar->u.members.object ); + } enumvar->services = services; - ISWbemServices_AddRef( &services->ISWbemServices_iface ); + if (services) ISWbemServices_AddRef( &services->ISWbemServices_iface ); *obj = &enumvar->IEnumVARIANT_iface; TRACE( "returning iface %p\n", *obj ); diff --git a/dlls/wbemdisp/tests/wbemdisp.c b/dlls/wbemdisp/tests/wbemdisp.c index 261ff86b4bd..63d35ab0004 100644 --- a/dlls/wbemdisp/tests/wbemdisp.c +++ b/dlls/wbemdisp/tests/wbemdisp.c @@ -289,10 +289,7 @@ static void test_ParseDisplayName(void) ISWbemObject_Release( object ); hr = ISWbemPropertySet_get__NewEnum( props, (IUnknown **)&setenumvar ); - todo_wine ok( hr == S_OK, "got %#lx\n", hr ); - if (hr == S_OK) - { V_VT( vars + ARRAY_SIZE(vars) - 1 ) = VT_ERROR; hr = IEnumVARIANT_Next( setenumvar, ARRAY_SIZE(vars), vars, &fetched ); ok( hr == S_FALSE, "got %#lx\n", hr ); @@ -340,7 +337,6 @@ static void test_ParseDisplayName(void) VariantClear( vars + 1 ); IEnumVARIANT_Release( setenumvar ); IEnumVARIANT_Release( propenumvar ); - } ISWbemPropertySet_Release( props ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11724
From: Conor McCarthy <cmccarthy@codeweavers.com> --- dlls/wbemdisp/locator.c | 2 ++ dlls/wbemdisp/tests/wbemdisp.c | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dlls/wbemdisp/locator.c b/dlls/wbemdisp/locator.c index cad9d50442a..f72143b8c53 100644 --- a/dlls/wbemdisp/locator.c +++ b/dlls/wbemdisp/locator.c @@ -2066,6 +2066,8 @@ static HRESULT WINAPI enumvar_Next( IEnumVARIANT *iface, ULONG celt, VARIANT *va if (!var) return S_FALSE; + for (count = 0; count < celt; ++count) VariantInit( var + count ); + if (enumvar->enum_type == ENUM_OBJECTS) { if (celt) IEnumWbemClassObject_Next( enumvar->u.objectenum, WBEM_INFINITE, 1, &obj, &count ); diff --git a/dlls/wbemdisp/tests/wbemdisp.c b/dlls/wbemdisp/tests/wbemdisp.c index 63d35ab0004..bd719df81b2 100644 --- a/dlls/wbemdisp/tests/wbemdisp.c +++ b/dlls/wbemdisp/tests/wbemdisp.c @@ -294,7 +294,6 @@ static void test_ParseDisplayName(void) hr = IEnumVARIANT_Next( setenumvar, ARRAY_SIZE(vars), vars, &fetched ); ok( hr == S_FALSE, "got %#lx\n", hr ); ok( !!fetched, "got %lu\n", fetched ); - todo_wine ok ( V_VT( vars + ARRAY_SIZE(vars) - 1 ) == VT_EMPTY, "got %u\n", V_VT( vars + ARRAY_SIZE(vars) - 1 ) ); dispname = NULL; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11724
From: Conor McCarthy <cmccarthy@codeweavers.com> --- dlls/wbemdisp/locator.c | 9 ++++++--- dlls/wbemdisp/tests/wbemdisp.c | 4 ---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/dlls/wbemdisp/locator.c b/dlls/wbemdisp/locator.c index f72143b8c53..4ac1dcd978f 100644 --- a/dlls/wbemdisp/locator.c +++ b/dlls/wbemdisp/locator.c @@ -54,6 +54,7 @@ enum enum_variant_type { ENUM_OBJECTS, ENUM_PROPERTIES, + ENUM_METHODS, }; struct services; @@ -933,9 +934,11 @@ static HRESULT WINAPI methodset_get__NewEnum( ISWbemMethodSet *iface, IUnknown **unk ) { - FIXME("\n"); + struct methodset *set = impl_from_ISWbemMethodSet( iface ); - return E_NOTIMPL; + TRACE( "%p, %p\n", iface, unk ); + + return EnumVARIANT_create( ENUM_METHODS, NULL, &set->object->ISWbemObject_iface, (IEnumVARIANT **)unk ); } static HRESULT WINAPI methodset_Item( @@ -2095,7 +2098,7 @@ static HRESULT WINAPI enumvar_Next( IEnumVARIANT *iface, ULONG celt, VARIANT *va HRESULT hr; if (object->members[cursor].is_system) continue; - if (object->members[cursor].is_method) continue; + if (object->members[cursor].is_method != (enumvar->enum_type == ENUM_METHODS)) continue; hr = SWbemProperty_create( object->object, object->members[cursor].name, &prop ); if (FAILED( hr )) diff --git a/dlls/wbemdisp/tests/wbemdisp.c b/dlls/wbemdisp/tests/wbemdisp.c index bd719df81b2..b736a36845f 100644 --- a/dlls/wbemdisp/tests/wbemdisp.c +++ b/dlls/wbemdisp/tests/wbemdisp.c @@ -340,15 +340,11 @@ static void test_ParseDisplayName(void) ISWbemPropertySet_Release( props ); hr = ISWbemMethodSet_get__NewEnum( methods, (IUnknown **)&setenumvar ); - todo_wine ok( hr == S_OK, "got %#lx\n", hr ); - if (hr == S_OK) - { hr = IEnumVARIANT_Next( setenumvar, ARRAY_SIZE(vars), vars, &fetched ); ok( hr == S_FALSE, "got %#lx\n", hr ); ok( !fetched, "got %lu\n", fetched ); IEnumVARIANT_Release( setenumvar ); - } ISWbemMethodSet_Release( methods ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11724
From: Conor McCarthy <cmccarthy@codeweavers.com> --- dlls/wbemdisp/locator.c | 12 ++++++++++-- dlls/wbemdisp/tests/wbemdisp.c | 7 +------ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/dlls/wbemdisp/locator.c b/dlls/wbemdisp/locator.c index 4ac1dcd978f..1ca64956d96 100644 --- a/dlls/wbemdisp/locator.c +++ b/dlls/wbemdisp/locator.c @@ -265,8 +265,16 @@ static HRESULT WINAPI property_put_Value( ISWbemProperty *iface, VARIANT *varVal static HRESULT WINAPI property_get_Name( ISWbemProperty *iface, BSTR *strName ) { - FIXME( "\n" ); - return E_NOTIMPL; + struct property *property = impl_from_ISWbemProperty( iface ); + WCHAR *name; + + TRACE( "%p %p\n", property, strName ); + + if (!(name = SysAllocString( property->name ))) + return E_OUTOFMEMORY; + + *strName = name; + return S_OK; } static HRESULT WINAPI property_get_IsLocal( ISWbemProperty *iface, VARIANT_BOOL *bIsLocal ) diff --git a/dlls/wbemdisp/tests/wbemdisp.c b/dlls/wbemdisp/tests/wbemdisp.c index b736a36845f..59f3a7ccf3b 100644 --- a/dlls/wbemdisp/tests/wbemdisp.c +++ b/dlls/wbemdisp/tests/wbemdisp.c @@ -296,7 +296,6 @@ static void test_ParseDisplayName(void) ok( !!fetched, "got %lu\n", fetched ); ok ( V_VT( vars + ARRAY_SIZE(vars) - 1 ) == VT_EMPTY, "got %u\n", V_VT( vars + ARRAY_SIZE(vars) - 1 ) ); - dispname = NULL; for (i = 0; i < fetched; ++i) { ok( V_VT( vars + i ) == VT_DISPATCH, "got %u\n", V_VT( vars + i ) ); @@ -304,7 +303,6 @@ static void test_ParseDisplayName(void) ok( hr == S_OK, "got %#lx\n", hr ); VariantClear( vars + i ); hr = ISWbemProperty_get_Name( prop, &dispname ); - todo_wine ok( hr == S_OK, "got %#lx\n", hr ); SysFreeString( dispname ); hr = ISWbemProperty_get_Value( prop, &res ); @@ -323,13 +321,10 @@ static void test_ParseDisplayName(void) hr = IEnumVARIANT_Next( setenumvar, 1, vars + 1, &fetched ); ok( hr == S_OK, "got %#lx\n", hr ); hr = ISWbemProperty_get_Name( (ISWbemProperty *)V_DISPATCH(vars), &dispname ); - todo_wine ok( hr == S_OK, "got %#lx\n", hr ); - dispname2 = NULL; hr = ISWbemProperty_get_Name( (ISWbemProperty *)V_DISPATCH(vars + 1), &dispname2 ); - todo_wine ok( hr == S_OK, "got %#lx\n", hr ); - if (dispname) ok( wcscmp( dispname, dispname2 ), "got equal names\n" ); + ok( wcscmp( dispname, dispname2 ), "got equal names\n" ); SysFreeString( dispname ); SysFreeString( dispname2 ); VariantClear( vars ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11724
From: Conor McCarthy <cmccarthy@codeweavers.com> --- dlls/wbemdisp/locator.c | 183 ++++++++++++++++++++++++++++++++- dlls/wbemdisp/tests/wbemdisp.c | 4 - 2 files changed, 181 insertions(+), 6 deletions(-) diff --git a/dlls/wbemdisp/locator.c b/dlls/wbemdisp/locator.c index 1ca64956d96..5b137ea3f61 100644 --- a/dlls/wbemdisp/locator.c +++ b/dlls/wbemdisp/locator.c @@ -63,6 +63,7 @@ static HRESULT EnumVARIANT_create( enum enum_variant_type, struct services *, vo static HRESULT ISWbemSecurity_create( ISWbemSecurity ** ); static HRESULT SWbemObject_create( struct services *, IWbemClassObject *, ISWbemObject ** ); static HRESULT SWbemObjectPath_create( IWbemClassObject *, ISWbemObjectPath ** ); +static HRESULT SWbemQualifierSet_create( ISWbemQualifierSet ** ); enum type_id { @@ -78,6 +79,7 @@ enum type_id ISWbemMethodSet_tid, ISWbemMethod_tid, ISWbemObjectPath_tid, + ISWbemQualifierSet_tid, last_tid }; @@ -98,6 +100,7 @@ static REFIID wbemdisp_tid_id[] = &IID_ISWbemMethodSet, &IID_ISWbemMethod, &IID_ISWbemObjectPath, + &IID_ISWbemQualifierSet, }; static HRESULT get_typeinfo( enum type_id tid, ITypeInfo **ret ) @@ -1602,8 +1605,7 @@ static HRESULT WINAPI object_get_Qualifiers_( ISWbemObject *iface, ISWbemQualifierSet **objWbemQualifierSet ) { - FIXME( "\n" ); - return E_NOTIMPL; + return SWbemQualifierSet_create( objWbemQualifierSet ); } static HRESULT WINAPI object_get_Properties_( ISWbemObject *iface, ISWbemPropertySet **prop_set ) @@ -3641,6 +3643,183 @@ HRESULT SWbemNamedValueSet_create( void **obj ) return hr; } +struct qualifierset +{ + ISWbemQualifierSet ISWbemQualifierSet_iface; + LONG refs; +}; + +static struct qualifierset *impl_from_ISWbemQualifierSet( ISWbemQualifierSet *iface ) +{ + return CONTAINING_RECORD( iface, struct qualifierset, ISWbemQualifierSet_iface ); +} + +static HRESULT WINAPI qualifierset_QueryInterface( ISWbemQualifierSet *iface, REFIID riid, void **ppvObject ) +{ + struct qualifierset *qualifierset = impl_from_ISWbemQualifierSet( iface ); + + TRACE( "%p %s %p\n", qualifierset, debugstr_guid( riid ), ppvObject ); + + if (IsEqualGUID( riid, &IID_ISWbemQualifierSet ) || + IsEqualGUID( riid, &IID_IDispatch ) || + IsEqualGUID( riid, &IID_IUnknown )) + { + *ppvObject = iface; + } + else + { + WARN( "interface %s not implemented\n", debugstr_guid( riid ) ); + *ppvObject = NULL; + return E_NOINTERFACE; + } + + ISWbemQualifierSet_AddRef( iface ); + return S_OK; +} + +static ULONG WINAPI qualifierset_AddRef( ISWbemQualifierSet *iface ) +{ + struct qualifierset *qualifierset = impl_from_ISWbemQualifierSet( iface ); + return InterlockedIncrement( &qualifierset->refs ); +} + +static ULONG WINAPI qualifierset_Release( ISWbemQualifierSet *iface ) +{ + struct qualifierset *qualifierset = impl_from_ISWbemQualifierSet( iface ); + LONG refs = InterlockedDecrement( &qualifierset->refs ); + + if (!refs) + { + TRACE( "destroying %p\n", qualifierset ); + free( qualifierset ); + } + + return refs; +} + +static HRESULT WINAPI qualifierset_GetTypeInfoCount( ISWbemQualifierSet *iface, UINT *count ) +{ + struct qualifierset *qualifierset = impl_from_ISWbemQualifierSet( iface ); + + TRACE( "%p, %p\n", qualifierset, count ); + + *count = 1; + return S_OK; +} + +static HRESULT WINAPI qualifierset_GetTypeInfo( ISWbemQualifierSet *iface, UINT index, LCID lcid, ITypeInfo **info ) +{ + struct qualifierset *qualifierset = impl_from_ISWbemQualifierSet( iface ); + + TRACE( "%p, %u, %#lx, %p\n", qualifierset, index, lcid, info ); + + return get_typeinfo( ISWbemQualifierSet_tid, info ); +} + +static HRESULT WINAPI qualifierset_GetIDsOfNames( ISWbemQualifierSet *iface, REFIID riid, + LPOLESTR *names, UINT count, LCID lcid, DISPID *dispid ) +{ + struct qualifierset *qualifierset = impl_from_ISWbemQualifierSet( iface ); + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE( "%p, %s, %p, %u, %#lx, %p\n", qualifierset, debugstr_guid( riid ), names, count, lcid, dispid ); + + if (!names || !count || !dispid) return E_INVALIDARG; + + hr = get_typeinfo( ISWbemQualifierSet_tid, &typeinfo ); + if (SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid ); + ITypeInfo_Release( typeinfo ); + } + return hr; +} + +static HRESULT WINAPI qualifierset_Invoke( ISWbemQualifierSet *iface, DISPID member, REFIID riid, LCID lcid, + WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *excep_info, UINT *arg_err ) +{ + struct qualifierset *qualifierset = impl_from_ISWbemQualifierSet( iface ); + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE( "%p, %ld, %s, %#lx, %#x, %p, %p, %p, %p\n", qualifierset, member, debugstr_guid( riid ), + lcid, flags, params, result, excep_info, arg_err ); + + hr = get_typeinfo( ISWbemQualifierSet_tid, &typeinfo ); + if (SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke( typeinfo, &qualifierset->ISWbemQualifierSet_iface, member, flags, + params, result, excep_info, arg_err ); + ITypeInfo_Release( typeinfo ); + } + return hr; +} + +static HRESULT WINAPI qualifierset__NewEnum( ISWbemQualifierSet *iface, IUnknown **unk ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI qualifierset_Item( ISWbemQualifierSet *iface, BSTR name, long iFlags, ISWbemQualifier **objWbemQualifier ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI qualifierset_get_Count( ISWbemQualifierSet *iface, long *iCount ) +{ + FIXME( "\n" ); + *iCount = 0; + return S_OK; +} + +static HRESULT WINAPI qualifierset_Add( ISWbemQualifierSet *iface, BSTR strName, VARIANT *varVal, + VARIANT_BOOL bPropagatesToSubclass, VARIANT_BOOL bPropagatesToInstance, VARIANT_BOOL bIsOverridable, + long iFlags, ISWbemQualifier **objWbemQualifier ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI qualifierset_Remove( ISWbemQualifierSet *iface, BSTR strName, long iFlags ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static const ISWbemQualifierSetVtbl qualifierset_vtbl = +{ + qualifierset_QueryInterface, + qualifierset_AddRef, + qualifierset_Release, + qualifierset_GetTypeInfoCount, + qualifierset_GetTypeInfo, + qualifierset_GetIDsOfNames, + qualifierset_Invoke, + qualifierset__NewEnum, + qualifierset_Item, + qualifierset_get_Count, + qualifierset_Add, + qualifierset_Remove, +}; + +static HRESULT SWbemQualifierSet_create( ISWbemQualifierSet **obj ) +{ + struct qualifierset *qualifierset; + + TRACE( "%p\n", obj ); + + if (!(qualifierset = calloc( 1, sizeof(*qualifierset) ))) return E_OUTOFMEMORY; + qualifierset->ISWbemQualifierSet_iface.lpVtbl = &qualifierset_vtbl; + qualifierset->refs = 1; + + *obj = &qualifierset->ISWbemQualifierSet_iface; + TRACE( "returning iface %p\n", *obj ); + return S_OK; +} + struct objectpath { ISWbemObjectPath ISWbemObjectPath_iface; diff --git a/dlls/wbemdisp/tests/wbemdisp.c b/dlls/wbemdisp/tests/wbemdisp.c index 59f3a7ccf3b..aaa0a2d87c3 100644 --- a/dlls/wbemdisp/tests/wbemdisp.c +++ b/dlls/wbemdisp/tests/wbemdisp.c @@ -284,7 +284,6 @@ static void test_ParseDisplayName(void) hr = ISWbemObject_get_Methods_( object, &methods ); ok( hr == S_OK, "got %#lx\n", hr ); hr = ISWbemObject_get_Qualifiers_( object, &quals ); - todo_wine ok( hr == S_OK, "got %#lx\n", hr ); ISWbemObject_Release( object ); @@ -343,8 +342,6 @@ static void test_ParseDisplayName(void) ISWbemMethodSet_Release( methods ); - if (quals) - { hr = ISWbemQualifierSet_get__NewEnum( quals, (IUnknown **)&setenumvar ); todo_wine ok( hr == S_OK, "got %#lx\n", hr ); @@ -360,7 +357,6 @@ static void test_ParseDisplayName(void) } ISWbemQualifierSet_Release( quals ); - } VariantClear( &var ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11724
From: Conor McCarthy <cmccarthy@codeweavers.com> --- dlls/wbemdisp/locator.c | 17 ++++++++++++----- dlls/wbemdisp/tests/wbemdisp.c | 4 ---- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/dlls/wbemdisp/locator.c b/dlls/wbemdisp/locator.c index 5b137ea3f61..08e97585dd8 100644 --- a/dlls/wbemdisp/locator.c +++ b/dlls/wbemdisp/locator.c @@ -55,6 +55,7 @@ enum enum_variant_type ENUM_OBJECTS, ENUM_PROPERTIES, ENUM_METHODS, + ENUM_QUALIFIERS, }; struct services; @@ -2037,7 +2038,7 @@ static ULONG WINAPI enumvar_Release( TRACE( "destroying %p\n", enumvar ); if (enumvar->enum_type == ENUM_OBJECTS) IEnumWbemClassObject_Release( enumvar->u.objectenum ); - else + else if (enumvar->enum_type == ENUM_PROPERTIES || enumvar->enum_type == ENUM_METHODS) ISWbemObject_Release( enumvar->u.members.object ); if (enumvar->services) ISWbemServices_Release( &enumvar->services->ISWbemServices_iface ); free( enumvar ); @@ -2097,6 +2098,10 @@ static HRESULT WINAPI enumvar_Next( IEnumVARIANT *iface, ULONG celt, VARIANT *va V_DISPATCH( var ) = (IDispatch *)sobj; } } + else if (enumvar->enum_type == ENUM_QUALIFIERS) + { + count = 0; + } else { struct object *object = impl_from_ISWbemObject( enumvar->u.members.object ); @@ -2136,6 +2141,8 @@ static HRESULT WINAPI enumvar_Skip( IEnumVARIANT *iface, ULONG celt ) if (enumvar->enum_type == ENUM_OBJECTS) return IEnumWbemClassObject_Skip( enumvar->u.objectenum, WBEM_INFINITE, celt ); + else if (enumvar->enum_type == ENUM_QUALIFIERS) + return S_FALSE; else { struct object *object = impl_from_ISWbemObject( enumvar->u.members.object ); @@ -2160,7 +2167,7 @@ static HRESULT WINAPI enumvar_Reset( IEnumVARIANT *iface ) if (enumvar->enum_type == ENUM_OBJECTS) hr = IEnumWbemClassObject_Reset( enumvar->u.objectenum ); - else + else if (enumvar->enum_type == ENUM_PROPERTIES || enumvar->enum_type == ENUM_METHODS) enumvar->u.members.cursor = 0; return hr; @@ -2197,7 +2204,7 @@ static HRESULT EnumVARIANT_create( enum enum_variant_type enum_type, struct serv enumvar->u.objectenum = object; IEnumWbemClassObject_AddRef( enumvar->u.objectenum ); } - else + else if (enumvar->enum_type == ENUM_PROPERTIES || enumvar->enum_type == ENUM_METHODS) { enumvar->u.members.object = object; ISWbemObject_AddRef( enumvar->u.members.object ); @@ -3758,8 +3765,8 @@ static HRESULT WINAPI qualifierset_Invoke( ISWbemQualifierSet *iface, DISPID mem static HRESULT WINAPI qualifierset__NewEnum( ISWbemQualifierSet *iface, IUnknown **unk ) { - FIXME( "\n" ); - return E_NOTIMPL; + FIXME( "%p %p stub\n", iface, unk ); + return EnumVARIANT_create( ENUM_QUALIFIERS, NULL, NULL, (IEnumVARIANT **)unk ); } static HRESULT WINAPI qualifierset_Item( ISWbemQualifierSet *iface, BSTR name, long iFlags, ISWbemQualifier **objWbemQualifier ) diff --git a/dlls/wbemdisp/tests/wbemdisp.c b/dlls/wbemdisp/tests/wbemdisp.c index aaa0a2d87c3..498e603157c 100644 --- a/dlls/wbemdisp/tests/wbemdisp.c +++ b/dlls/wbemdisp/tests/wbemdisp.c @@ -343,10 +343,7 @@ static void test_ParseDisplayName(void) ISWbemMethodSet_Release( methods ); hr = ISWbemQualifierSet_get__NewEnum( quals, (IUnknown **)&setenumvar ); - todo_wine ok( hr == S_OK, "got %#lx\n", hr ); - if (hr == S_OK) - { hr = IEnumVARIANT_Next( setenumvar, ARRAY_SIZE(vars), vars, &fetched ); ok( hr == S_FALSE, "got %#lx\n", hr ); todo_wine @@ -354,7 +351,6 @@ static void test_ParseDisplayName(void) for (i = 0; i < fetched; ++i) VariantClear( vars + i ); IEnumVARIANT_Release( setenumvar ); - } ISWbemQualifierSet_Release( quals ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11724
This merge request was approved by Hans Leidekker. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11724
participants (3)
-
Conor McCarthy -
Conor McCarthy (@cmccarthy) -
Hans Leidekker (@hans)