Module: wine Branch: master Commit: efd0eead07b81ea01abbbcb97ba3cd7536448f4a URL: http://source.winehq.org/git/wine.git/?a=commit;h=efd0eead07b81ea01abbbcb97b...
Author: Jacek Caban jacek@codeweavers.com Date: Thu Nov 15 11:21:57 2012 +0100
atl: Properly fail on an aggregation attempt.
---
dlls/atl/registrar.c | 49 ++++++++++++++++++++++++++++++------------- dlls/atl/tests/registrar.c | 12 ++++++++++ 2 files changed, 46 insertions(+), 15 deletions(-)
diff --git a/dlls/atl/registrar.c b/dlls/atl/registrar.c index 7b1fe30..028f35e 100644 --- a/dlls/atl/registrar.c +++ b/dlls/atl/registrar.c @@ -698,21 +698,22 @@ static const IRegistrarVtbl RegistrarVtbl = { Registrar_ResourceUnregister, };
-static HRESULT Registrar_create(const IUnknown *pUnkOuter, REFIID riid, void **ppvObject) +/* Exported only by newer ATL versions */ +static HRESULT AtlCreateRegistrar(IRegistrar **ret) { - Registrar *ret; + Registrar *registrar;
- if(!IsEqualGUID(&IID_IUnknown, riid) && !IsEqualGUID(&IID_IRegistrar, riid)) - return E_NOINTERFACE; + registrar = HeapAlloc(GetProcessHeap(), 0, sizeof(*registrar)); + if(!registrar) + return E_OUTOFMEMORY;
- ret = HeapAlloc(GetProcessHeap(), 0, sizeof(Registrar)); - ret->IRegistrar_iface.lpVtbl = &RegistrarVtbl; - ret->ref = 1; - ret->rep = NULL; - *ppvObject = ret; + registrar->IRegistrar_iface.lpVtbl = &RegistrarVtbl; + registrar->ref = 1; + registrar->rep = NULL;
InterlockedIncrement(&dll_count);
+ *ret = ®istrar->IRegistrar_iface; return S_OK; }
@@ -746,10 +747,25 @@ static ULONG WINAPI RegistrarCF_Release(IClassFactory *iface) }
static HRESULT WINAPI RegistrarCF_CreateInstance(IClassFactory *iface, LPUNKNOWN pUnkOuter, - REFIID riid, void **ppvObject) + REFIID riid, void **ppv) { - TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppvObject); - return Registrar_create(pUnkOuter, riid, ppvObject); + IRegistrar *registrar; + HRESULT hres; + + TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv); + + if(pUnkOuter) { + *ppv = NULL; + return CLASS_E_NOAGGREGATION; + } + + hres = AtlCreateRegistrar(®istrar); + if(FAILED(hres)) + return hres; + + hres = IRegistrar_QueryInterface(registrar, riid, ppv); + IRegistrar_Release(registrar); + return hres; }
static HRESULT WINAPI RegistrarCF_LockServer(IClassFactory *iface, BOOL lock) @@ -801,10 +817,13 @@ static HRESULT do_register_dll_server(IRegistrar *pRegistrar, LPCOLESTR wszDll, static const WCHAR wszModule[] = {'M','O','D','U','L','E',0}; static const WCHAR wszRegistry[] = {'R','E','G','I','S','T','R','Y',0};
- if (pRegistrar) + if(pRegistrar) { registrar = pRegistrar; - else - Registrar_create(NULL, &IID_IRegistrar, (void**)®istrar); + }else { + hres = AtlCreateRegistrar(®istrar); + if(FAILED(hres)) + return hres; + }
IRegistrar_AddReplacement(registrar, wszModule, wszDll);
diff --git a/dlls/atl/tests/registrar.c b/dlls/atl/tests/registrar.c index 9c5dd23..1b1c797 100644 --- a/dlls/atl/tests/registrar.c +++ b/dlls/atl/tests/registrar.c @@ -135,11 +135,23 @@ static void test_registrar(void) IRegistrar_Release(registrar); }
+static void test_aggregation(void) +{ + IUnknown *unk = (IUnknown*)0xdeadbeef; + HRESULT hres; + + hres = CoCreateInstance(&CLSID_Registrar, (IUnknown*)0xdeadbeef, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, + &IID_IUnknown, (void**)&unk); + ok(hres == CLASS_E_NOAGGREGATION, "CoCreateInstance failed: %08x, expected CLASS_E_NOAGGREGATION\n", hres); + ok(!unk, "unk = %p\n", unk); +} + START_TEST(registrar) { CoInitialize(NULL);
test_registrar(); + test_aggregation();
CoUninitialize(); }