combase: Move initialisation functions.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
48bd5461ed
commit
ee080a423a
|
@ -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.@)
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.@]
|
||||
*
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue