From d76ab14479d922aef075d8b05b237bff08e92300 Mon Sep 17 00:00:00 2001 From: Rob Shearman Date: Mon, 7 May 2007 23:57:31 +0100 Subject: [PATCH] ole32: Revoke registered class objects when the apartment they were registered in is destroyed, not when the last CoUninitialize is called. --- dlls/ole32/compobj.c | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c index f90b0eaeaae..b9669f28aab 100644 --- a/dlls/ole32/compobj.c +++ b/dlls/ole32/compobj.c @@ -77,7 +77,7 @@ HINSTANCE OLE32_hInstance = 0; /* FIXME: make static ... */ */ static HRESULT COM_GetRegisteredClassObject(REFCLSID rclsid, DWORD dwClsContext, LPUNKNOWN* ppUnk); -static void COM_RevokeAllClasses(void); +static void COM_RevokeAllClasses(struct apartment *apt); static HRESULT get_inproc_class_object(HKEY hkeydll, REFCLSID rclsid, REFIID riid, void **ppv); static APARTMENT *MTA; /* protected by csApartment */ @@ -121,6 +121,7 @@ typedef struct tagRegisteredClass { struct list entry; CLSID classIdentifier; + OXID apartment_id; LPUNKNOWN classObject; DWORD runContext; DWORD connectFlags; @@ -361,6 +362,9 @@ DWORD apartment_release(struct apartment *apt) TRACE("destroying apartment %p, oxid %s\n", apt, wine_dbgstr_longlong(apt->oxid)); + /* Release the references to the registered class objects */ + COM_RevokeAllClasses(apt); + /* no locking is needed for this apartment, because no other thread * can access it at this point */ @@ -955,9 +959,6 @@ void WINAPI CoUninitialize(void) RunningObjectTableImpl_UnInitialize(); - /* Release the references to the registered class objects */ - COM_RevokeAllClasses(); - /* This will free the loaded COM Dlls */ CoFreeAllLibraries(); @@ -1621,6 +1622,21 @@ static HRESULT COM_GetRegisteredClassObject( return hr; } +static void COM_RevokeAllClasses(struct apartment *apt) +{ + RegisteredClass *curClass, *cursor; + + EnterCriticalSection( &csRegisteredClassList ); + + LIST_FOR_EACH_ENTRY_SAFE(curClass, cursor, &RegisteredClassList, RegisteredClass, entry) + { + if (curClass->apartment_id == apt->oxid) + CoRevokeClassObject(curClass->dwCookie); + } + + LeaveCriticalSection( &csRegisteredClassList ); +} + /****************************************************************************** * CoRegisterClassObject [OLE32.@] * @@ -1657,6 +1673,7 @@ HRESULT WINAPI CoRegisterClassObject( RegisteredClass* newClass; LPUNKNOWN foundObject; HRESULT hr; + APARTMENT *apt; TRACE("(%s,%p,0x%08x,0x%08x,%p)\n", debugstr_guid(rclsid),pUnk,dwClsContext,flags,lpdwRegister); @@ -1664,7 +1681,8 @@ HRESULT WINAPI CoRegisterClassObject( if ( (lpdwRegister==0) || (pUnk==0) ) return E_INVALIDARG; - if (!COM_CurrentApt()) + apt = COM_CurrentApt(); + if (!apt) { ERR("COM was not initialized\n"); return CO_E_NOTINITIALIZED; @@ -1699,6 +1717,7 @@ HRESULT WINAPI CoRegisterClassObject( return E_OUTOFMEMORY; newClass->classIdentifier = *rclsid; + newClass->apartment_id = apt->oxid; newClass->runContext = dwClsContext; newClass->connectFlags = flags; newClass->pMarshaledData = NULL; @@ -2384,20 +2403,6 @@ HRESULT WINAPI CoFileTimeNow( FILETIME *lpFileTime ) return S_OK; } -static void COM_RevokeAllClasses(void) -{ - EnterCriticalSection( &csRegisteredClassList ); - - while (list_head(&RegisteredClassList)) - { - RegisteredClass *curClass = LIST_ENTRY(list_head(&RegisteredClassList), - RegisteredClass, entry); - CoRevokeClassObject(curClass->dwCookie); - } - - LeaveCriticalSection( &csRegisteredClassList ); -} - /****************************************************************************** * CoLockObjectExternal [OLE32.@] *