Zebediah Figura : ole32: Always grab a reference to apt in CoGetClassObject().
Alexandre Julliard
julliard at winehq.org
Mon Apr 9 15:41:10 CDT 2018
Module: wine
Branch: master
Commit: 6af0e50f3691e76d4d8b85e43561fb9e527a240e
URL: https://source.winehq.org/git/wine.git/?a=commit;h=6af0e50f3691e76d4d8b85e43561fb9e527a240e
Author: Zebediah Figura <z.figura12 at gmail.com>
Date: Wed Mar 28 21:01:58 2018 -0500
ole32: Always grab a reference to apt in CoGetClassObject().
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ole32/compobj.c | 26 +++++++++++++++++---------
dlls/ole32/compobj_private.h | 1 +
2 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c
index fc8587b..50ac6d3 100644
--- a/dlls/ole32/compobj.c
+++ b/dlls/ole32/compobj.c
@@ -1162,9 +1162,17 @@ DWORD apartment_release(struct apartment *apt)
ret = InterlockedDecrement(&apt->refs);
TRACE("%s: after = %d\n", wine_dbgstr_longlong(apt->oxid), ret);
+
+ if (apt->being_destroyed)
+ {
+ LeaveCriticalSection(&csApartment);
+ return ret;
+ }
+
/* destruction stuff that needs to happen under csApartment CS */
if (ret == 0)
{
+ apt->being_destroyed = TRUE;
if (apt == MTA) MTA = NULL;
else if (apt == MainApartment) MainApartment = NULL;
list_remove(&apt->entry);
@@ -2981,7 +2989,6 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject(
IUnknown *regClassObject;
HRESULT hres = E_UNEXPECTED;
APARTMENT *apt;
- BOOL release_apt = FALSE;
TRACE("CLSID: %s,IID: %s\n", debugstr_guid(rclsid), debugstr_guid(iid));
@@ -2990,14 +2997,15 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject(
*ppv = NULL;
- if (!(apt = COM_CurrentApt()))
+ if ((apt = COM_CurrentApt()))
+ apartment_addref(apt);
+ else
{
if (!(apt = apartment_find_mta()))
{
ERR("apartment not initialised\n");
return CO_E_NOTINITIALIZED;
}
- release_apt = TRUE;
}
if (pServerInfo) {
@@ -3009,7 +3017,7 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject(
{
if (IsEqualCLSID(rclsid, &CLSID_InProcFreeMarshaler))
{
- if (release_apt) apartment_release(apt);
+ apartment_release(apt);
return FTMarshalCF_Create(iid, ppv);
}
if (IsEqualCLSID(rclsid, &CLSID_GlobalOptions))
@@ -3035,7 +3043,7 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject(
hres = get_inproc_class_object(apt, &clsreg, &comclass->clsid, iid, !(dwClsContext & WINE_CLSCTX_DONT_HOST), ppv);
ReleaseActCtx(data.hActCtx);
- if (release_apt) apartment_release(apt);
+ apartment_release(apt);
return hres;
}
}
@@ -3056,7 +3064,7 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject(
* is good since we are not returning it in the "out" parameter.
*/
IUnknown_Release(regClassObject);
- if (release_apt) apartment_release(apt);
+ apartment_release(apt);
return hres;
}
@@ -3091,7 +3099,7 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject(
* other types */
if (SUCCEEDED(hres))
{
- if (release_apt) apartment_release(apt);
+ apartment_release(apt);
return hres;
}
}
@@ -3127,11 +3135,11 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject(
* other types */
if (SUCCEEDED(hres))
{
- if (release_apt) apartment_release(apt);
+ apartment_release(apt);
return hres;
}
}
- if (release_apt) apartment_release(apt);
+ apartment_release(apt);
/* Next try out of process */
if (CLSCTX_LOCAL_SERVER & dwClsContext)
diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h
index 9e65c3e..12413f7 100644
--- a/dlls/ole32/compobj_private.h
+++ b/dlls/ole32/compobj_private.h
@@ -142,6 +142,7 @@ struct apartment
DWORD host_apt_tid; /* thread ID of apartment hosting objects of differing threading model (CS cs) */
HWND host_apt_hwnd; /* handle to apartment window of host apartment (CS cs) */
LocalServer *local_server; /* A marshallable object exposing local servers (CS cs) */
+ BOOL being_destroyed; /* is currently being destroyed */
/* FIXME: OIDs should be given out by RPCSS */
OID oidc; /* object ID counter, starts at 1, zero is invalid OID (CS cs) */
More information about the wine-cvs
mailing list