ole32: Revoke registered class objects when the apartment they were registered in is destroyed, not when the last CoUninitialize is called.
This commit is contained in:
parent
4cbca9ac3a
commit
d76ab14479
|
@ -77,7 +77,7 @@ HINSTANCE OLE32_hInstance = 0; /* FIXME: make static ... */
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static HRESULT COM_GetRegisteredClassObject(REFCLSID rclsid, DWORD dwClsContext, LPUNKNOWN* ppUnk);
|
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 HRESULT get_inproc_class_object(HKEY hkeydll, REFCLSID rclsid, REFIID riid, void **ppv);
|
||||||
|
|
||||||
static APARTMENT *MTA; /* protected by csApartment */
|
static APARTMENT *MTA; /* protected by csApartment */
|
||||||
|
@ -121,6 +121,7 @@ typedef struct tagRegisteredClass
|
||||||
{
|
{
|
||||||
struct list entry;
|
struct list entry;
|
||||||
CLSID classIdentifier;
|
CLSID classIdentifier;
|
||||||
|
OXID apartment_id;
|
||||||
LPUNKNOWN classObject;
|
LPUNKNOWN classObject;
|
||||||
DWORD runContext;
|
DWORD runContext;
|
||||||
DWORD connectFlags;
|
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));
|
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
|
/* no locking is needed for this apartment, because no other thread
|
||||||
* can access it at this point */
|
* can access it at this point */
|
||||||
|
|
||||||
|
@ -955,9 +959,6 @@ void WINAPI CoUninitialize(void)
|
||||||
|
|
||||||
RunningObjectTableImpl_UnInitialize();
|
RunningObjectTableImpl_UnInitialize();
|
||||||
|
|
||||||
/* Release the references to the registered class objects */
|
|
||||||
COM_RevokeAllClasses();
|
|
||||||
|
|
||||||
/* This will free the loaded COM Dlls */
|
/* This will free the loaded COM Dlls */
|
||||||
CoFreeAllLibraries();
|
CoFreeAllLibraries();
|
||||||
|
|
||||||
|
@ -1621,6 +1622,21 @@ static HRESULT COM_GetRegisteredClassObject(
|
||||||
return hr;
|
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.@]
|
* CoRegisterClassObject [OLE32.@]
|
||||||
*
|
*
|
||||||
|
@ -1657,6 +1673,7 @@ HRESULT WINAPI CoRegisterClassObject(
|
||||||
RegisteredClass* newClass;
|
RegisteredClass* newClass;
|
||||||
LPUNKNOWN foundObject;
|
LPUNKNOWN foundObject;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
APARTMENT *apt;
|
||||||
|
|
||||||
TRACE("(%s,%p,0x%08x,0x%08x,%p)\n",
|
TRACE("(%s,%p,0x%08x,0x%08x,%p)\n",
|
||||||
debugstr_guid(rclsid),pUnk,dwClsContext,flags,lpdwRegister);
|
debugstr_guid(rclsid),pUnk,dwClsContext,flags,lpdwRegister);
|
||||||
|
@ -1664,7 +1681,8 @@ HRESULT WINAPI CoRegisterClassObject(
|
||||||
if ( (lpdwRegister==0) || (pUnk==0) )
|
if ( (lpdwRegister==0) || (pUnk==0) )
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
if (!COM_CurrentApt())
|
apt = COM_CurrentApt();
|
||||||
|
if (!apt)
|
||||||
{
|
{
|
||||||
ERR("COM was not initialized\n");
|
ERR("COM was not initialized\n");
|
||||||
return CO_E_NOTINITIALIZED;
|
return CO_E_NOTINITIALIZED;
|
||||||
|
@ -1699,6 +1717,7 @@ HRESULT WINAPI CoRegisterClassObject(
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
newClass->classIdentifier = *rclsid;
|
newClass->classIdentifier = *rclsid;
|
||||||
|
newClass->apartment_id = apt->oxid;
|
||||||
newClass->runContext = dwClsContext;
|
newClass->runContext = dwClsContext;
|
||||||
newClass->connectFlags = flags;
|
newClass->connectFlags = flags;
|
||||||
newClass->pMarshaledData = NULL;
|
newClass->pMarshaledData = NULL;
|
||||||
|
@ -2384,20 +2403,6 @@ HRESULT WINAPI CoFileTimeNow( FILETIME *lpFileTime )
|
||||||
return S_OK;
|
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.@]
|
* CoLockObjectExternal [OLE32.@]
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue