Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/wbemdisp/locator.c | 51 ++++++++++++++++++++++------------ dlls/wbemdisp/tests/wbemdisp.c | 11 ++++++++ 2 files changed, 45 insertions(+), 17 deletions(-)
diff --git a/dlls/wbemdisp/locator.c b/dlls/wbemdisp/locator.c index 619f7e5c67f..9e191c07b49 100644 --- a/dlls/wbemdisp/locator.c +++ b/dlls/wbemdisp/locator.c @@ -43,9 +43,11 @@ static WCHAR *heap_strdupW( const WCHAR *src ) return dst; }
-static HRESULT EnumVARIANT_create( IEnumWbemClassObject *, IEnumVARIANT ** ); +struct services; + +static HRESULT EnumVARIANT_create( struct services *, IEnumWbemClassObject *, IEnumVARIANT ** ); static HRESULT ISWbemSecurity_create( ISWbemSecurity ** ); -static HRESULT SWbemObject_create( IWbemClassObject *, ISWbemObject ** ); +static HRESULT SWbemObject_create( struct services *, IWbemClassObject *, ISWbemObject ** );
enum type_id { @@ -513,6 +515,13 @@ static HRESULT SWbemPropertySet_create( IWbemClassObject *wbem_object, ISWbemPro return S_OK; }
+struct services +{ + ISWbemServices ISWbemServices_iface; + LONG refs; + IWbemServices *services; +}; + struct member { BSTR name; @@ -529,6 +538,7 @@ struct object UINT nb_members; DISPID last_dispid; DISPID last_dispid_method; + struct services *services; };
struct methodset @@ -706,7 +716,7 @@ static HRESULT WINAPI method_get_InParameters( IWbemClassObject_Release( in_sign ); if (SUCCEEDED(hr)) { - hr = SWbemObject_create( instance, params ); + hr = SWbemObject_create( method->set->object->services, instance, params ); IWbemClassObject_Release( instance ); } } @@ -995,6 +1005,7 @@ static ULONG WINAPI object_Release(
TRACE( "destroying %p\n", object ); IWbemClassObject_Release( object->object ); + ISWbemServices_Release( &object->services->ISWbemServices_iface ); for (i = 0; i < object->nb_members; i++) SysFreeString( object->members[i].name ); heap_free( object->members ); heap_free( object ); @@ -1557,7 +1568,8 @@ static const ISWbemObjectVtbl object_vtbl = object_get_Security_ };
-static HRESULT SWbemObject_create( IWbemClassObject *wbem_object, ISWbemObject **obj ) +static HRESULT SWbemObject_create( struct services *services, IWbemClassObject *wbem_object, + ISWbemObject **obj ) { struct object *object;
@@ -1572,6 +1584,8 @@ static HRESULT SWbemObject_create( IWbemClassObject *wbem_object, ISWbemObject * object->nb_members = 0; object->last_dispid = DISPID_BASE; object->last_dispid_method = DISPID_BASE_METHOD; + object->services = services; + ISWbemServices_AddRef( &object->services->ISWbemServices_iface );
*obj = &object->ISWbemObject_iface; TRACE( "returning iface %p\n", *obj ); @@ -1584,6 +1598,7 @@ struct objectset LONG refs; IEnumWbemClassObject *objectenum; LONG count; + struct services *services; };
static inline struct objectset *impl_from_ISWbemObjectSet( @@ -1608,6 +1623,7 @@ static ULONG WINAPI objectset_Release( { TRACE( "destroying %p\n", objectset ); IEnumWbemClassObject_Release( objectset->objectenum ); + ISWbemServices_Release( &objectset->services->ISWbemServices_iface ); heap_free( objectset ); } return refs; @@ -1725,7 +1741,7 @@ static HRESULT WINAPI objectset_get__NewEnum( hr = IEnumWbemClassObject_Clone( objectset->objectenum, &objectenum ); if (FAILED( hr )) return hr;
- hr = EnumVARIANT_create( objectenum, (IEnumVARIANT **)pUnk ); + hr = EnumVARIANT_create( objectset->services, objectenum, (IEnumVARIANT **)pUnk ); IEnumWbemClassObject_Release( objectenum ); return hr; } @@ -1824,7 +1840,8 @@ static LONG get_object_count( IEnumWbemClassObject *iter ) return count; }
-static HRESULT SWbemObjectSet_create( IEnumWbemClassObject *wbem_objectenum, ISWbemObjectSet **obj ) +static HRESULT SWbemObjectSet_create( struct services *services, IEnumWbemClassObject *wbem_objectenum, + ISWbemObjectSet **obj ) { struct objectset *objectset;
@@ -1836,6 +1853,8 @@ static HRESULT SWbemObjectSet_create( IEnumWbemClassObject *wbem_objectenum, ISW objectset->objectenum = wbem_objectenum; IEnumWbemClassObject_AddRef( objectset->objectenum ); objectset->count = get_object_count( objectset->objectenum ); + objectset->services = services; + ISWbemServices_AddRef( &services->ISWbemServices_iface );
*obj = &objectset->ISWbemObjectSet_iface; TRACE( "returning iface %p\n", *obj ); @@ -1847,6 +1866,7 @@ struct enumvar IEnumVARIANT IEnumVARIANT_iface; LONG refs; IEnumWbemClassObject *objectenum; + struct services *services; };
static inline struct enumvar *impl_from_IEnumVARIANT( @@ -1871,6 +1891,7 @@ static ULONG WINAPI enumvar_Release( { TRACE( "destroying %p\n", enumvar ); IEnumWbemClassObject_Release( enumvar->objectenum ); + ISWbemServices_Release( &enumvar->services->ISWbemServices_iface ); heap_free( enumvar ); } return refs; @@ -1913,7 +1934,7 @@ static HRESULT WINAPI enumvar_Next( IEnumVARIANT *iface, ULONG celt, VARIANT *va ISWbemObject *sobj; HRESULT hr;
- hr = SWbemObject_create( obj, &sobj ); + hr = SWbemObject_create( enumvar->services, obj, &sobj ); IWbemClassObject_Release( obj ); if (FAILED( hr )) return hr;
@@ -1959,7 +1980,8 @@ static const struct IEnumVARIANTVtbl enumvar_vtbl = enumvar_Clone };
-static HRESULT EnumVARIANT_create( IEnumWbemClassObject *objectenum, IEnumVARIANT **obj ) +static HRESULT EnumVARIANT_create( struct services *services, IEnumWbemClassObject *objectenum, + IEnumVARIANT **obj ) { struct enumvar *enumvar;
@@ -1968,19 +1990,14 @@ static HRESULT EnumVARIANT_create( IEnumWbemClassObject *objectenum, IEnumVARIAN enumvar->refs = 1; enumvar->objectenum = objectenum; IEnumWbemClassObject_AddRef( enumvar->objectenum ); + enumvar->services = services; + ISWbemServices_AddRef( &services->ISWbemServices_iface );
*obj = &enumvar->IEnumVARIANT_iface; TRACE( "returning iface %p\n", *obj ); return S_OK; }
-struct services -{ - ISWbemServices ISWbemServices_iface; - LONG refs; - IWbemServices *services; -}; - static inline struct services *impl_from_ISWbemServices( ISWbemServices *iface ) { @@ -2127,7 +2144,7 @@ static HRESULT WINAPI services_Get( hr = IWbemServices_GetObject( services->services, strObjectPath, iFlags, NULL, &obj, NULL ); if (hr != S_OK) return hr;
- hr = SWbemObject_create( obj, objWbemObject ); + hr = SWbemObject_create( services, obj, objWbemObject ); IWbemClassObject_Release( obj ); return hr; } @@ -2256,7 +2273,7 @@ static HRESULT WINAPI services_ExecQuery( hr = IWbemServices_ExecQuery( services->services, strQueryLanguage, strQuery, iFlags, NULL, &iter ); if (hr != S_OK) return hr;
- hr = SWbemObjectSet_create( iter, objWbemObjectSet ); + hr = SWbemObjectSet_create( services, iter, objWbemObjectSet ); IEnumWbemClassObject_Release( iter ); return hr; } diff --git a/dlls/wbemdisp/tests/wbemdisp.c b/dlls/wbemdisp/tests/wbemdisp.c index c38a0f14c9b..bf44f62329a 100644 --- a/dlls/wbemdisp/tests/wbemdisp.c +++ b/dlls/wbemdisp/tests/wbemdisp.c @@ -279,6 +279,15 @@ static void test_ParseDisplayName(void) IParseDisplayName_Release( displayname ); }
+#define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__) +static void _expect_ref(IUnknown* obj, ULONG ref, int line) +{ + ULONG rc; + IUnknown_AddRef(obj); + rc = IUnknown_Release(obj); + ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc); +} + static void test_locator(void) { HRESULT hr; @@ -307,12 +316,14 @@ static void test_locator(void) SysFreeString( root_bstr ); SysFreeString( host_bstr );
+ EXPECT_REF( services, 1 ); query_bstr = SysAllocString( L"Select ProcessorId from Win32_Processor" ); lang_bstr = SysAllocString( L"WQL" ); hr = ISWbemServices_ExecQuery( services, query_bstr, lang_bstr, wbemFlagForwardOnly, NULL, &object_set); ok( hr == S_OK, "got %x\n", hr ); SysFreeString( lang_bstr ); SysFreeString( query_bstr ); + EXPECT_REF( services, 2 );
hr = ISWbemLocator_get_Security_( locator, &security ); ok( hr == S_OK, "got %x\n", hr );
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/wbemdisp/locator.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-)
diff --git a/dlls/wbemdisp/locator.c b/dlls/wbemdisp/locator.c index 9e191c07b49..926a4e88e63 100644 --- a/dlls/wbemdisp/locator.c +++ b/dlls/wbemdisp/locator.c @@ -1414,14 +1414,36 @@ static HRESULT WINAPI object_ReferencesAsync_(
static HRESULT WINAPI object_ExecMethod_( ISWbemObject *iface, - BSTR strMethodName, - IDispatch *objWbemInParameters, - LONG iFlags, - IDispatch *objWbemNamedValueSet, - ISWbemObject **objWbemOutParameters ) + BSTR method, + IDispatch *in_params, + LONG flags, + IDispatch *valueset, + ISWbemObject **out_params ) { - FIXME( "\n" ); - return E_NOTIMPL; + struct object *object = impl_from_ISWbemObject( iface ); + VARIANT path; + HRESULT hr; + + TRACE( "%p, %s, %p, %#x, %p, %p\n", object, debugstr_w(method), in_params, flags, valueset, out_params ); + + V_VT( &path ) = VT_EMPTY; + hr = IWbemClassObject_Get( object->object, L"__PATH", 0, &path, NULL, NULL ); + if (SUCCEEDED(hr)) + { + if (V_VT( &path ) != VT_BSTR) + { + WARN( "Unexpected object path value type.\n" ); + VariantClear( &path ); + return E_UNEXPECTED; + } + + hr = ISWbemServices_ExecMethod( &object->services->ISWbemServices_iface, V_BSTR( &path ), method, + in_params, flags, valueset, out_params ); + + VariantClear( &path ); + } + + return hr; }
static HRESULT WINAPI object_ExecMethodAsync_(
Signed-off-by: Hans Leidekker hans@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/wbemdisp/locator.c | 50 ++++++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 8 deletions(-)
diff --git a/dlls/wbemdisp/locator.c b/dlls/wbemdisp/locator.c index 926a4e88e63..867a19c1ab2 100644 --- a/dlls/wbemdisp/locator.c +++ b/dlls/wbemdisp/locator.c @@ -1590,6 +1590,18 @@ static const ISWbemObjectVtbl object_vtbl = object_get_Security_ };
+static struct object *unsafe_object_impl_from_IDispatch(IDispatch *iface) +{ + if (!iface) + return NULL; + if (iface->lpVtbl != (IDispatchVtbl *)&object_vtbl) + { + FIXME( "External implementations are not supported.\n" ); + return NULL; + } + return CONTAINING_RECORD(iface, struct object, ISWbemObject_iface); +} + static HRESULT SWbemObject_create( struct services *services, IWbemClassObject *wbem_object, ISWbemObject **obj ) { @@ -2412,15 +2424,37 @@ static HRESULT WINAPI services_ExecNotificationQueryAsync(
static HRESULT WINAPI services_ExecMethod( ISWbemServices *iface, - BSTR strObjectPath, - BSTR strMethodName, - IDispatch *objWbemInParameters, - LONG iFlags, - IDispatch *objWbemNamedValueSet, - ISWbemObject **objWbemOutParameters ) + BSTR path, + BSTR method, + IDispatch *in_sparams, + LONG flags, + IDispatch *valueset, + ISWbemObject **out_sparams ) { - FIXME( "\n" ); - return E_NOTIMPL; + struct services *services = impl_from_ISWbemServices( iface ); + IWbemClassObject *out_params = NULL; + struct object *in_params; + HRESULT hr; + + TRACE( "%p, %s, %s, %p, %#x, %p, %p\n", services, debugstr_w(path), debugstr_w(method), in_sparams, + flags, valueset, out_sparams ); + + in_params = unsafe_object_impl_from_IDispatch( in_sparams ); + out_params = NULL; + + if (valueset) + FIXME("Named value set is unused\n"); + + hr = IWbemServices_ExecMethod( services->services, path, method, flags, NULL, in_params ? in_params->object : NULL, + out_sparams ? &out_params : NULL, NULL ); + + if (SUCCEEDED(hr) && out_params) + { + hr = SWbemObject_create( services, out_params, out_sparams ); + IWbemClassObject_Release( out_params ); + } + + return hr; }
static HRESULT WINAPI services_ExecMethodAsync(
Signed-off-by: Hans Leidekker hans@codeweavers.com
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=86228
Your paranoid android.
=== build (build log) ===
error: patch failed: dlls/wbemdisp/locator.c:43 Task: Patch failed to apply
On 3/1/21 10:25 AM, Marvin wrote:
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=86228
Your paranoid android.
=== build (build log) ===
error: patch failed: dlls/wbemdisp/locator.c:43 Task: Patch failed to apply |+ ../bin/build/Build.pl patch.diff exe64:exe32 Applying patch wine:HEAD=35e43ccf1b42e9f67d7765753f0c3ef8cf102c46 + git apply --verbose /home/winetest/tools/testbot/var/../var/staging/patch.diff Checking patch dlls/wbemdisp/locator.c... error: while searching for: return dst; } static HRESULT EnumVARIANT_create( IEnumWbemClassObject *, IEnumVARIANT ** ); static HRESULT ISWbemSecurity_create( ISWbemSecurity ** ); static HRESULT SWbemObject_create( IWbemClassObject *, ISWbemObject ** ); enum type_id { error: patch failed: dlls/wbemdisp/locator.c:43 error: dlls/wbemdisp/locator.c: patch does not apply Checking patch dlls/wbemdisp/tests/wbemdisp.c... Task: Patch failed to apply|
This HEAD is from before 6.3 tag. Yet, somehow patches 2 and 3 are reported to apply fine.