[PATCH 2/6] combase: Move initialisation functions.
Nikolay Sivov
nsivov at codeweavers.com
Thu Aug 27 03:37:45 CDT 2020
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/combase/combase.c | 136 ++++++++++++++++++++++++-
dlls/combase/combase.spec | 5 +-
dlls/combase/combase_private.h | 3 +
dlls/ole32/compobj.c | 179 ---------------------------------
dlls/ole32/ole32.spec | 4 +-
5 files changed, 142 insertions(+), 185 deletions(-)
diff --git a/dlls/combase/combase.c b/dlls/combase/combase.c
index 4ce43717fb4..cddc9e23067 100644
--- a/dlls/combase/combase.c
+++ b/dlls/combase/combase.c
@@ -40,6 +40,13 @@ HINSTANCE hProxyDll;
#define CHARS_IN_GUID 39
+extern void WINAPI DestroyRunningObjectTable(void);
+
+/*
+ * Number of times CoInitialize is called. It is decreased every time CoUninitialize is called. When it hits 0, the COM libraries are freed
+ */
+static LONG com_lockcount;
+
struct comclassredirect_data
{
ULONG size;
@@ -1757,7 +1764,7 @@ HRESULT WINAPI CoRegisterMessageFilter(IMessageFilter *filter, IMessageFilter **
return S_OK;
}
-void WINAPI InternalRevokeAllPSClsids(void)
+static void com_revoke_all_ps_clsids(void)
{
struct registered_ps *cur, *cur2;
@@ -2267,6 +2274,133 @@ void WINAPI DECLSPEC_HOTPATCH CoFreeUnusedLibrariesEx(DWORD unload_delay, DWORD
apartment_freeunusedlibraries(apt, unload_delay);
}
+/*
+ * When locked, don't modify list (unless we add a new head), so that it's
+ * safe to iterate it. Freeing of list entries is delayed and done on unlock.
+ */
+static inline void lock_init_spies(struct tlsdata *tlsdata)
+{
+ tlsdata->spies_lock++;
+}
+
+static void unlock_init_spies(struct tlsdata *tlsdata)
+{
+ struct init_spy *spy, *next;
+
+ if (--tlsdata->spies_lock) return;
+
+ LIST_FOR_EACH_ENTRY_SAFE(spy, next, &tlsdata->spies, struct init_spy, entry)
+ {
+ if (spy->spy) continue;
+ list_remove(&spy->entry);
+ heap_free(spy);
+ }
+}
+
+/******************************************************************************
+ * CoInitializeEx (combase.@)
+ */
+HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(void *reserved, DWORD model)
+{
+ struct tlsdata *tlsdata;
+ struct init_spy *cursor;
+ HRESULT hr;
+
+ TRACE("%p, %#x\n", reserved, model);
+
+ if (reserved)
+ WARN("Unexpected reserved argument %p\n", reserved);
+
+ if (FAILED(hr = com_get_tlsdata(&tlsdata)))
+ return hr;
+
+ if (InterlockedExchangeAdd(&com_lockcount, 1) == 0)
+ TRACE("Initializing the COM libraries\n");
+
+ lock_init_spies(tlsdata);
+ LIST_FOR_EACH_ENTRY(cursor, &tlsdata->spies, struct init_spy, entry)
+ {
+ if (cursor->spy) IInitializeSpy_PreInitialize(cursor->spy, model, tlsdata->inits);
+ }
+ unlock_init_spies(tlsdata);
+
+ hr = enter_apartment(tlsdata, model);
+
+ lock_init_spies(tlsdata);
+ LIST_FOR_EACH_ENTRY(cursor, &tlsdata->spies, struct init_spy, entry)
+ {
+ if (cursor->spy) hr = IInitializeSpy_PostInitialize(cursor->spy, hr, model, tlsdata->inits);
+ }
+ unlock_init_spies(tlsdata);
+
+ return hr;
+}
+
+/***********************************************************************
+ * CoUninitialize (combase.@)
+ */
+void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
+{
+ struct tlsdata *tlsdata;
+ struct init_spy *cursor, *next;
+ LONG lockcount;
+
+ TRACE("\n");
+
+ if (FAILED(com_get_tlsdata(&tlsdata)))
+ return;
+
+ lock_init_spies(tlsdata);
+ LIST_FOR_EACH_ENTRY_SAFE(cursor, next, &tlsdata->spies, struct init_spy, entry)
+ {
+ if (cursor->spy) IInitializeSpy_PreUninitialize(cursor->spy, tlsdata->inits);
+ }
+ unlock_init_spies(tlsdata);
+
+ /* sanity check */
+ if (!tlsdata->inits)
+ {
+ ERR("Mismatched CoUninitialize\n");
+
+ lock_init_spies(tlsdata);
+ LIST_FOR_EACH_ENTRY_SAFE(cursor, next, &tlsdata->spies, struct init_spy, entry)
+ {
+ if (cursor->spy) IInitializeSpy_PostUninitialize(cursor->spy, tlsdata->inits);
+ }
+ unlock_init_spies(tlsdata);
+
+ return;
+ }
+
+ leave_apartment(tlsdata);
+
+ /*
+ * Decrease the reference count.
+ * If we are back to 0 locks on the COM library, make sure we free
+ * all the associated data structures.
+ */
+ lockcount = InterlockedExchangeAdd(&com_lockcount, -1);
+ if (lockcount == 1)
+ {
+ TRACE("Releasing the COM libraries\n");
+
+ com_revoke_all_ps_clsids();
+ DestroyRunningObjectTable();
+ }
+ else if (lockcount < 1)
+ {
+ ERR("Unbalanced lock count %d\n", lockcount);
+ InterlockedExchangeAdd(&com_lockcount, 1);
+ }
+
+ lock_init_spies(tlsdata);
+ LIST_FOR_EACH_ENTRY(cursor, &tlsdata->spies, struct init_spy, entry)
+ {
+ if (cursor->spy) IInitializeSpy_PostUninitialize(cursor->spy, tlsdata->inits);
+ }
+ unlock_init_spies(tlsdata);
+}
+
/***********************************************************************
* DllMain (combase.@)
*/
diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec
index 00aea556d94..01377c8045e 100644
--- a/dlls/combase/combase.spec
+++ b/dlls/combase/combase.spec
@@ -123,7 +123,7 @@
@ stdcall CoGetTreatAsClass(ptr ptr)
@ stdcall CoImpersonateClient()
@ stdcall CoIncrementMTAUsage(ptr) ole32.CoIncrementMTAUsage
-@ stdcall CoInitializeEx(ptr long) ole32.CoInitializeEx
+@ stdcall CoInitializeEx(ptr long)
@ stdcall CoInitializeSecurity(ptr long ptr ptr long long ptr long ptr)
@ stdcall CoInitializeWOW(long long) ole32.CoInitializeWOW
@ stub CoInvalidateRemoteMachineBindings
@@ -163,7 +163,7 @@
@ stdcall CoTaskMemFree(ptr)
@ stdcall CoTaskMemRealloc(ptr long)
@ stub CoTestCancel
-@ stdcall CoUninitialize() ole32.CoUninitialize
+@ stdcall CoUninitialize()
@ stub CoUnloadingWOW
@ stdcall CoUnmarshalHresult(ptr ptr)
@ stdcall CoUnmarshalInterface(ptr ptr ptr) ole32.CoUnmarshalInterface
@@ -268,7 +268,6 @@
@ stub InternalNotifyDDStartOrStop
@ stub InternalOleModalLoopBlockFn
@ stub InternalRegisterWindowPropInterface
-@ stdcall InternalRevokeAllPSClsids()
@ stub InternalReleaseMarshalObjRef
@ stub InternalSTAInvoke
@ stub InternalServerExceptionFilter
diff --git a/dlls/combase/combase_private.h b/dlls/combase/combase_private.h
index 7fe548af593..122522baad5 100644
--- a/dlls/combase/combase_private.h
+++ b/dlls/combase/combase_private.h
@@ -131,6 +131,9 @@ struct stub_manager
BOOL disconnected; /* CoDisconnectObject has been called (CS lock) */
};
+HRESULT WINAPI enter_apartment(struct tlsdata *data, DWORD model);
+void WINAPI leave_apartment(struct tlsdata *data);
+
/* Stub Manager */
ULONG stub_manager_int_release(struct stub_manager *This) DECLSPEC_HIDDEN;
diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c
index 88482392d5e..5afacf3ee3f 100644
--- a/dlls/ole32/compobj.c
+++ b/dlls/ole32/compobj.c
@@ -142,12 +142,6 @@ struct class_reg_data
} u;
};
-/*
- * This lock count counts the number of times CoInitialize is called. It is
- * decreased every time CoUninitialize is called. When it hits 0, the COM
- * libraries are freed
- */
-static LONG s_COMLockCount = 0;
/* Reference count used by CoAddRefServerProcess/CoReleaseServerProcess */
static LONG s_COMServerProcessReferences = 0;
@@ -182,8 +176,6 @@ static CRITICAL_SECTION_DEBUG class_cs_debug =
};
static CRITICAL_SECTION csRegisteredClassList = { &class_cs_debug, -1, 0, 0, 0, 0 };
-extern void WINAPI InternalRevokeAllPSClsids(void);
-
static inline enum comclass_miscfields dvaspect_to_miscfields(DWORD aspect)
{
switch (aspect)
@@ -661,29 +653,6 @@ DWORD WINAPI CoBuildVersion(void)
return (rmm<<16)+rup;
}
-/*
- * When locked, don't modify list (unless we add a new head), so that it's
- * safe to iterate it. Freeing of list entries is delayed and done on unlock.
- */
-static inline void lock_init_spies(struct oletls *info)
-{
- info->spies_lock++;
-}
-
-static void unlock_init_spies(struct oletls *info)
-{
- struct init_spy *spy, *next;
-
- if (--info->spies_lock) return;
-
- LIST_FOR_EACH_ENTRY_SAFE(spy, next, &info->spies, struct init_spy, entry)
- {
- if (spy->spy) continue;
- list_remove(&spy->entry);
- heap_free(spy);
- }
-}
-
/******************************************************************************
* CoInitialize [OLE32.@]
*
@@ -708,154 +677,6 @@ HRESULT WINAPI CoInitialize(LPVOID lpReserved)
return CoInitializeEx(lpReserved, COINIT_APARTMENTTHREADED);
}
-/******************************************************************************
- * CoInitializeEx [OLE32.@]
- *
- * Initializes the COM libraries.
- *
- * PARAMS
- * lpReserved [I] Pointer to IMalloc interface (obsolete, should be NULL).
- * dwCoInit [I] One or more flags from the COINIT enumeration. See notes.
- *
- * RETURNS
- * S_OK if successful,
- * S_FALSE if this function was called already.
- * RPC_E_CHANGED_MODE if a previous call to CoInitializeEx specified another
- * threading model.
- *
- * NOTES
- *
- * The behavior used to set the IMalloc used for memory management is
- * obsolete.
- * The dwCoInit parameter must specify one of the following apartment
- * threading models:
- *| COINIT_APARTMENTTHREADED - A single-threaded apartment (STA).
- *| COINIT_MULTITHREADED - A multi-threaded apartment (MTA).
- * The parameter may also specify zero or more of the following flags:
- *| COINIT_DISABLE_OLE1DDE - Don't use DDE for OLE1 support.
- *| COINIT_SPEED_OVER_MEMORY - Trade memory for speed.
- *
- * SEE ALSO
- * CoUninitialize
- */
-HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
-{
- struct oletls *info = COM_CurrentInfo();
- struct init_spy *cursor;
- HRESULT hr;
-
- TRACE("(%p, %x)\n", lpReserved, (int)dwCoInit);
-
- if (lpReserved!=NULL)
- {
- ERR("(%p, %x) - Bad parameter passed-in %p, must be an old Windows Application\n", lpReserved, (int)dwCoInit, lpReserved);
- }
-
- /*
- * Check the lock count. If this is the first time going through the initialize
- * process, we have to initialize the libraries.
- *
- * And crank-up that lock count.
- */
- if (InterlockedExchangeAdd(&s_COMLockCount,1)==0)
- TRACE("() - Initializing the COM libraries\n");
-
- lock_init_spies(info);
- LIST_FOR_EACH_ENTRY(cursor, &info->spies, struct init_spy, entry)
- {
- if (cursor->spy) IInitializeSpy_PreInitialize(cursor->spy, dwCoInit, info->inits);
- }
- unlock_init_spies(info);
-
- hr = enter_apartment( info, dwCoInit );
-
- lock_init_spies(info);
- LIST_FOR_EACH_ENTRY(cursor, &info->spies, struct init_spy, entry)
- {
- if (cursor->spy) hr = IInitializeSpy_PostInitialize(cursor->spy, hr, dwCoInit, info->inits);
- }
- unlock_init_spies(info);
-
- return hr;
-}
-
-/***********************************************************************
- * CoUninitialize [OLE32.@]
- *
- * This method will decrement the refcount on the current apartment, freeing
- * the resources associated with it if it is the last thread in the apartment.
- * If the last apartment is freed, the function will additionally release
- * any COM resources associated with the process.
- *
- * PARAMS
- *
- * RETURNS
- * Nothing.
- *
- * SEE ALSO
- * CoInitializeEx
- */
-void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
-{
- struct oletls * info = COM_CurrentInfo();
- struct init_spy *cursor, *next;
- LONG lCOMRefCnt;
-
- TRACE("()\n");
-
- /* will only happen on OOM */
- if (!info) return;
-
- lock_init_spies(info);
- LIST_FOR_EACH_ENTRY_SAFE(cursor, next, &info->spies, struct init_spy, entry)
- {
- if (cursor->spy) IInitializeSpy_PreUninitialize(cursor->spy, info->inits);
- }
- unlock_init_spies(info);
-
- /* sanity check */
- if (!info->inits)
- {
- ERR("Mismatched CoUninitialize\n");
-
- lock_init_spies(info);
- LIST_FOR_EACH_ENTRY_SAFE(cursor, next, &info->spies, struct init_spy, entry)
- {
- if (cursor->spy) IInitializeSpy_PostUninitialize(cursor->spy, info->inits);
- }
- unlock_init_spies(info);
-
- return;
- }
-
- leave_apartment( info );
-
- /*
- * Decrease the reference count.
- * If we are back to 0 locks on the COM library, make sure we free
- * all the associated data structures.
- */
- lCOMRefCnt = InterlockedExchangeAdd(&s_COMLockCount,-1);
- if (lCOMRefCnt==1)
- {
- TRACE("() - Releasing the COM libraries\n");
-
- InternalRevokeAllPSClsids();
- DestroyRunningObjectTable();
- }
- else if (lCOMRefCnt<1) {
- ERR( "CoUninitialize() - not CoInitialized.\n" );
- InterlockedExchangeAdd(&s_COMLockCount,1); /* restore the lock count. */
- }
-
- lock_init_spies(info);
- LIST_FOR_EACH_ENTRY(cursor, &info->spies, struct init_spy, entry)
- {
- if (cursor->spy) IInitializeSpy_PostUninitialize(cursor->spy, info->inits);
- }
- unlock_init_spies(info);
-}
-
/******************************************************************************
* CoDisconnectObject [OLE32.@]
*
diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec
index c102bce1776..e80cafd3663 100644
--- a/dlls/ole32/ole32.spec
+++ b/dlls/ole32/ole32.spec
@@ -50,7 +50,7 @@
@ stdcall CoImpersonateClient() combase.CoImpersonateClient
@ stdcall CoIncrementMTAUsage(ptr)
@ stdcall CoInitialize(ptr)
-@ stdcall CoInitializeEx(ptr long)
+@ stdcall CoInitializeEx(ptr long) combase.CoInitializeEx
@ stdcall CoInitializeSecurity(ptr long ptr ptr long long ptr long ptr) combase.CoInitializeSecurity
@ stdcall CoInitializeWOW(long long)
@ stdcall CoIsHandlerConnected(ptr)
@@ -87,7 +87,7 @@
@ stdcall CoTaskMemFree(ptr) combase.CoTaskMemFree
@ stdcall CoTaskMemRealloc(ptr long) combase.CoTaskMemRealloc
@ stdcall CoTreatAsClass(ptr ptr)
-@ stdcall CoUninitialize()
+@ stdcall CoUninitialize() combase.CoUninitialize
@ stub CoUnloadingWOW
@ stdcall CoUnmarshalHresult(ptr ptr) combase.CoUnmarshalHresult
@ stdcall CoUnmarshalInterface(ptr ptr ptr)
--
2.28.0
More information about the wine-devel
mailing list