Synchronize access to the s_COMLockCount, firstRegisteredClass,
openDllList in compobj.
This commit is contained in:
parent
a2ae982978
commit
aad36bcd59
|
@ -123,7 +123,7 @@ WORD Table_ETask[62];
|
|||
* decreased every time CoUninitialize is called. When it hits 0, the COM
|
||||
* libraries are freed
|
||||
*/
|
||||
static ULONG s_COMLockCount = 0;
|
||||
static LONG s_COMLockCount = 0;
|
||||
|
||||
/*
|
||||
* This linked list contains the list of registered class objects. These
|
||||
|
@ -143,6 +143,7 @@ typedef struct tagRegisteredClass
|
|||
struct tagRegisteredClass* nextClass;
|
||||
} RegisteredClass;
|
||||
|
||||
static CRITICAL_SECTION csRegisteredClassList;
|
||||
static RegisteredClass* firstRegisteredClass = NULL;
|
||||
|
||||
/* this open DLL table belongs in a per process table, but my guess is that
|
||||
|
@ -154,6 +155,7 @@ typedef struct tagOpenDll {
|
|||
struct tagOpenDll *next;
|
||||
} OpenDll;
|
||||
|
||||
static CRITICAL_SECTION csOpenDllList;
|
||||
static OpenDll *openDllList = NULL; /* linked list of open dlls */
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -167,6 +169,21 @@ static HRESULT COM_GetRegisteredClassObject(REFCLSID rclsid,
|
|||
static void COM_RevokeAllClasses();
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Initialize/Uninitialize critical sections.
|
||||
*/
|
||||
void COMPOBJ_InitProcess( void )
|
||||
{
|
||||
InitializeCriticalSection( &csRegisteredClassList );
|
||||
InitializeCriticalSection( &csOpenDllList );
|
||||
}
|
||||
|
||||
void COMPOBJ_UninitProcess( void )
|
||||
{
|
||||
DeleteCriticalSection( &csRegisteredClassList );
|
||||
DeleteCriticalSection( &csOpenDllList );
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* CoBuildVersion [COMPOBJ.1]
|
||||
* CoBuildVersion [OLE32.4]
|
||||
|
@ -254,14 +271,17 @@ HRESULT WINAPI CoInitializeEx(
|
|||
/*
|
||||
* 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 (s_COMLockCount==0)
|
||||
if (InterlockedExchangeAdd(&s_COMLockCount,1)==0)
|
||||
{
|
||||
/*
|
||||
* Initialize the various COM libraries and data structures.
|
||||
*/
|
||||
TRACE("() - Initializing the COM libraries\n");
|
||||
|
||||
|
||||
RunningObjectTableImpl_Initialize();
|
||||
|
||||
hr = S_OK;
|
||||
|
@ -269,11 +289,6 @@ HRESULT WINAPI CoInitializeEx(
|
|||
else
|
||||
hr = S_FALSE;
|
||||
|
||||
/*
|
||||
* Crank-up that lock count.
|
||||
*/
|
||||
s_COMLockCount++;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
@ -298,18 +313,16 @@ void WINAPI CoUninitialize16(void)
|
|||
*/
|
||||
void WINAPI CoUninitialize(void)
|
||||
{
|
||||
LONG lCOMRefCnt;
|
||||
TRACE("()\n");
|
||||
|
||||
/*
|
||||
* Decrease the reference count.
|
||||
*/
|
||||
s_COMLockCount--;
|
||||
|
||||
/*
|
||||
* If we are back to 0 locks on the COM library, make sure we free
|
||||
* all the associated data structures.
|
||||
*/
|
||||
if (s_COMLockCount==0)
|
||||
lCOMRefCnt = InterlockedExchangeAdd(&s_COMLockCount,-1);
|
||||
if (lCOMRefCnt==1)
|
||||
{
|
||||
/*
|
||||
* Release the various COM libraries and data structures.
|
||||
|
@ -331,7 +344,12 @@ void WINAPI CoUninitialize(void)
|
|||
* This will free list of external references to COM objects.
|
||||
*/
|
||||
COM_ExternalLockFreeList();
|
||||
}
|
||||
|
||||
}
|
||||
else if (lCOMRefCnt<1) {
|
||||
ERR( "CoUninitialize() - not CoInitialized.\n" );
|
||||
InterlockedExchangeAdd(&s_COMLockCount,1); /* restore the lock count. */
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -973,8 +991,11 @@ static HRESULT COM_GetRegisteredClassObject(
|
|||
DWORD dwClsContext,
|
||||
LPUNKNOWN* ppUnk)
|
||||
{
|
||||
HRESULT hr = S_FALSE;
|
||||
RegisteredClass* curClass;
|
||||
|
||||
EnterCriticalSection( &csRegisteredClassList );
|
||||
|
||||
/*
|
||||
* Sanity check
|
||||
*/
|
||||
|
@ -1004,7 +1025,8 @@ static HRESULT COM_GetRegisteredClassObject(
|
|||
|
||||
IUnknown_AddRef(curClass->classObject);
|
||||
|
||||
return S_OK;
|
||||
hr = S_OK;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1013,10 +1035,12 @@ static HRESULT COM_GetRegisteredClassObject(
|
|||
curClass = curClass->nextClass;
|
||||
}
|
||||
|
||||
end:
|
||||
LeaveCriticalSection( &csRegisteredClassList );
|
||||
/*
|
||||
* If we get to here, we haven't found our class.
|
||||
*/
|
||||
return S_FALSE;
|
||||
return hr;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -1050,7 +1074,7 @@ HRESULT WINAPI CoRegisterClassObject(
|
|||
if ( (lpdwRegister==0) || (pUnk==0) )
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the cookie (out parameter)
|
||||
|
@ -1081,7 +1105,10 @@ HRESULT WINAPI CoRegisterClassObject(
|
|||
* unique.
|
||||
*/
|
||||
newClass = HeapAlloc(GetProcessHeap(), 0, sizeof(RegisteredClass));
|
||||
if ( newClass == NULL )
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
EnterCriticalSection( &csRegisteredClassList );
|
||||
/*
|
||||
* Initialize the node.
|
||||
*/
|
||||
|
@ -1100,6 +1127,8 @@ HRESULT WINAPI CoRegisterClassObject(
|
|||
|
||||
firstRegisteredClass = newClass;
|
||||
|
||||
LeaveCriticalSection( &csRegisteredClassList );
|
||||
|
||||
/*
|
||||
* Assign the out parameter (cookie)
|
||||
*/
|
||||
|
@ -1121,11 +1150,14 @@ HRESULT WINAPI CoRegisterClassObject(
|
|||
HRESULT WINAPI CoRevokeClassObject(
|
||||
DWORD dwRegister)
|
||||
{
|
||||
HRESULT hr = E_INVALIDARG;
|
||||
RegisteredClass** prevClassLink;
|
||||
RegisteredClass* curClass;
|
||||
|
||||
TRACE("(%08lx)\n",dwRegister);
|
||||
|
||||
EnterCriticalSection( &csRegisteredClassList );
|
||||
|
||||
/*
|
||||
* Iterate through the whole list and try to match the cookie.
|
||||
*/
|
||||
|
@ -1151,11 +1183,12 @@ HRESULT WINAPI CoRevokeClassObject(
|
|||
|
||||
/*
|
||||
* Free the memory used by the chain node.
|
||||
*/
|
||||
*/
|
||||
HeapFree(GetProcessHeap(), 0, curClass);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
hr = S_OK;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* Step to the next class in the list.
|
||||
|
@ -1164,10 +1197,12 @@ HRESULT WINAPI CoRevokeClassObject(
|
|||
curClass = curClass->nextClass;
|
||||
}
|
||||
|
||||
end:
|
||||
LeaveCriticalSection( &csRegisteredClassList );
|
||||
/*
|
||||
* If we get to here, we haven't found our class.
|
||||
*/
|
||||
return E_INVALIDARG;
|
||||
return hr;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -1513,6 +1548,8 @@ void WINAPI CoFreeLibrary(HINSTANCE hLibrary)
|
|||
OpenDll *ptr, *prev;
|
||||
OpenDll *tmp;
|
||||
|
||||
EnterCriticalSection( &csOpenDllList );
|
||||
|
||||
/* lookup library in linked list */
|
||||
prev = NULL;
|
||||
for (ptr = openDllList; ptr != NULL; ptr=ptr->next) {
|
||||
|
@ -1524,7 +1561,7 @@ void WINAPI CoFreeLibrary(HINSTANCE hLibrary)
|
|||
|
||||
if (ptr == NULL) {
|
||||
/* shouldn't happen if user passed in a valid hLibrary */
|
||||
return;
|
||||
goto end;
|
||||
}
|
||||
/* assert: ptr points to the library entry to free */
|
||||
|
||||
|
@ -1539,7 +1576,8 @@ void WINAPI CoFreeLibrary(HINSTANCE hLibrary)
|
|||
HeapFree(GetProcessHeap(), 0, ptr);
|
||||
prev->next = tmp;
|
||||
}
|
||||
|
||||
end:
|
||||
LeaveCriticalSection( &csOpenDllList );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1550,11 +1588,15 @@ void WINAPI CoFreeAllLibraries(void)
|
|||
{
|
||||
OpenDll *ptr, *tmp;
|
||||
|
||||
EnterCriticalSection( &csOpenDllList );
|
||||
|
||||
for (ptr = openDllList; ptr != NULL; ) {
|
||||
tmp=ptr->next;
|
||||
CoFreeLibrary(ptr->hLibrary);
|
||||
ptr = tmp;
|
||||
}
|
||||
|
||||
LeaveCriticalSection( &csOpenDllList );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1569,6 +1611,8 @@ void WINAPI CoFreeUnusedLibraries(void)
|
|||
typedef HRESULT(*DllCanUnloadNowFunc)(void);
|
||||
DllCanUnloadNowFunc DllCanUnloadNow;
|
||||
|
||||
EnterCriticalSection( &csOpenDllList );
|
||||
|
||||
for (ptr = openDllList; ptr != NULL; ) {
|
||||
DllCanUnloadNow = (DllCanUnloadNowFunc)
|
||||
GetProcAddress(ptr->hLibrary, "DllCanUnloadNow");
|
||||
|
@ -1582,6 +1626,8 @@ void WINAPI CoFreeUnusedLibraries(void)
|
|||
ptr=ptr->next;
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection( &csOpenDllList );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -1662,6 +1708,8 @@ HINSTANCE WINAPI CoLoadLibrary(LPOLESTR lpszLibName, BOOL bAutoFree)
|
|||
if (!bAutoFree)
|
||||
return hLibrary;
|
||||
|
||||
EnterCriticalSection( &csOpenDllList );
|
||||
|
||||
if (openDllList == NULL) {
|
||||
/* empty list -- add first node */
|
||||
openDllList = (OpenDll*)HeapAlloc(GetProcessHeap(),0, sizeof(OpenDll));
|
||||
|
@ -1685,6 +1733,8 @@ HINSTANCE WINAPI CoLoadLibrary(LPOLESTR lpszLibName, BOOL bAutoFree)
|
|||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection( &csOpenDllList );
|
||||
|
||||
return hLibrary;
|
||||
}
|
||||
|
||||
|
@ -1786,10 +1836,14 @@ HRESULT WINAPI OLE32_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
|
|||
*/
|
||||
static void COM_RevokeAllClasses()
|
||||
{
|
||||
EnterCriticalSection( &csRegisteredClassList );
|
||||
|
||||
while (firstRegisteredClass!=0)
|
||||
{
|
||||
CoRevokeClassObject(firstRegisteredClass->dwCookie);
|
||||
}
|
||||
|
||||
LeaveCriticalSection( &csRegisteredClassList );
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -22,9 +22,11 @@ BOOL WINAPI OLE32_DllEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImp
|
|||
switch(fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
OLE32_hInstance = hinstDLL;
|
||||
COMPOBJ_InitProcess();
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
COMPOBJ_UninitProcess();
|
||||
OLE32_hInstance = 0;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -5,4 +5,7 @@
|
|||
|
||||
extern HINSTANCE OLE32_hInstance;
|
||||
|
||||
void COMPOBJ_InitProcess( void );
|
||||
void COMPOBJ_UninitProcess( void );
|
||||
|
||||
#endif /* __WINE_OLE32_MAIN_H */
|
||||
|
|
Loading…
Reference in New Issue