From 798fbd420540310a8c853ec9676cf3490fc880ca Mon Sep 17 00:00:00 2001 From: Giovanni Mascellani Date: Tue, 20 Dec 2022 15:41:19 +0100 Subject: [PATCH] wbemprox: Do not call Release() inside wbemprox_cf_CreateInstance(). The Ubisoft overlay version 135 hot patches and hooks wbem_locator_Release(), but crashes if Release() is called inside CoCreateInstance(), a condition that doesn't appear to happen on Windows. So we try to exhibit the same behavior. --- dlls/wbemprox/main.c | 12 ++---------- dlls/wbemprox/services.c | 8 ++++++-- dlls/wbemprox/wbemlocator.c | 6 +++++- dlls/wbemprox/wbemprox_private.h | 4 ++-- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/dlls/wbemprox/main.c b/dlls/wbemprox/main.c index 20ca1a08530..30363658636 100644 --- a/dlls/wbemprox/main.c +++ b/dlls/wbemprox/main.c @@ -37,7 +37,7 @@ static HINSTANCE instance; struct list *table_list[WBEMPROX_NAMESPACE_LAST]; -typedef HRESULT (*fnCreateInstance)( LPVOID *ppObj ); +typedef HRESULT (*fnCreateInstance)( LPVOID *ppObj, REFIID riid ); typedef struct { @@ -77,8 +77,6 @@ static HRESULT WINAPI wbemprox_cf_CreateInstance( IClassFactory *iface, LPUNKNOW REFIID riid, LPVOID *ppobj ) { wbemprox_cf *This = impl_from_IClassFactory( iface ); - HRESULT r; - IUnknown *punk; TRACE("%p %s %p\n", pOuter, debugstr_guid(riid), ppobj); @@ -87,13 +85,7 @@ static HRESULT WINAPI wbemprox_cf_CreateInstance( IClassFactory *iface, LPUNKNOW if (pOuter) return CLASS_E_NOAGGREGATION; - r = This->pfnCreateInstance( (LPVOID *)&punk ); - if (FAILED(r)) - return r; - - r = IUnknown_QueryInterface( punk, riid, ppobj ); - IUnknown_Release( punk ); - return r; + return This->pfnCreateInstance( ppobj, riid ); } static HRESULT WINAPI wbemprox_cf_LockServer( IClassFactory *iface, BOOL dolock ) diff --git a/dlls/wbemprox/services.c b/dlls/wbemprox/services.c index 6fc05be9f3c..203b0e90784 100644 --- a/dlls/wbemprox/services.c +++ b/dlls/wbemprox/services.c @@ -1058,7 +1058,7 @@ static HRESULT WINAPI wbem_context_Clone( TRACE("%p, %p\n", iface, newcopy); - if (SUCCEEDED(hr = WbemContext_create( (void **)&cloned_context ))) + if (SUCCEEDED(hr = WbemContext_create( (void **)&cloned_context, &IID_IWbemContext ))) { LIST_FOR_EACH_ENTRY( value, &context->values, struct wbem_context_value, entry ) { @@ -1225,12 +1225,16 @@ static const IWbemContextVtbl wbem_context_vtbl = wbem_context_DeleteAll, }; -HRESULT WbemContext_create( void **obj ) +HRESULT WbemContext_create( void **obj, REFIID riid ) { struct wbem_context *context; TRACE("(%p)\n", obj); + if ( !IsEqualGUID( riid, &IID_IWbemContext ) && + !IsEqualGUID( riid, &IID_IUnknown ) ) + return E_NOINTERFACE; + if (!(context = malloc( sizeof(*context) ))) return E_OUTOFMEMORY; context->IWbemContext_iface.lpVtbl = &wbem_context_vtbl; diff --git a/dlls/wbemprox/wbemlocator.c b/dlls/wbemprox/wbemlocator.c index 32408cf6a90..6e5bddea156 100644 --- a/dlls/wbemprox/wbemlocator.c +++ b/dlls/wbemprox/wbemlocator.c @@ -202,12 +202,16 @@ static const IWbemLocatorVtbl wbem_locator_vtbl = wbem_locator_ConnectServer }; -HRESULT WbemLocator_create( LPVOID *ppObj ) +HRESULT WbemLocator_create( LPVOID *ppObj, REFIID riid ) { wbem_locator *wl; TRACE("(%p)\n", ppObj); + if ( !IsEqualGUID( riid, &IID_IWbemLocator ) && + !IsEqualGUID( riid, &IID_IUnknown ) ) + return E_NOINTERFACE; + if (!(wl = malloc( sizeof(*wl) ))) return E_OUTOFMEMORY; wl->IWbemLocator_iface.lpVtbl = &wbem_locator_vtbl; diff --git a/dlls/wbemprox/wbemprox_private.h b/dlls/wbemprox/wbemprox_private.h index 328840e9dfe..4f23a8b8451 100644 --- a/dlls/wbemprox/wbemprox_private.h +++ b/dlls/wbemprox/wbemprox_private.h @@ -246,9 +246,9 @@ void set_variant( VARTYPE, LONGLONG, void *, VARIANT * ) DECLSPEC_HIDDEN; HRESULT create_signature( enum wbm_namespace ns, const WCHAR *, const WCHAR *, enum param_direction, IWbemClassObject ** ) DECLSPEC_HIDDEN; -HRESULT WbemLocator_create(LPVOID *) DECLSPEC_HIDDEN; +HRESULT WbemLocator_create(LPVOID *, REFIID) DECLSPEC_HIDDEN; HRESULT WbemServices_create(const WCHAR *, IWbemContext *, LPVOID *) DECLSPEC_HIDDEN; -HRESULT WbemContext_create(void **) DECLSPEC_HIDDEN; +HRESULT WbemContext_create(void **, REFIID) DECLSPEC_HIDDEN; HRESULT create_class_object(enum wbm_namespace ns, const WCHAR *, IEnumWbemClassObject *, UINT, struct record *, IWbemClassObject **) DECLSPEC_HIDDEN; HRESULT EnumWbemClassObject_create(struct query *, LPVOID *) DECLSPEC_HIDDEN;