, CoRegisterClassObject . , CoRegisterInitializeSpy.
CoInitialize[Ex].
IInitializeSpy :
HRESULT CRegisterClassesSpy::PostInitialize(HRESULT hrCoInit, DWORD dwCoInit, DWORD dwNewThreadAptRefs)
{
if (hrCoInit == S_OK && dwNewThreadAptRefs == 1) {
if (dwCoInit == COINIT_APARTMENTTHREADED ||
(dwCoInit == COINIT_MULTITHREADED &&
InterlockedIncrement(&m_MTAThreads) == 1)) {
hrCoInit = RegisterClassObjects();
}
}
return hrCoInit;
}
HRESULT CRegisterClassesSpy::PreUninitialize(DWORD dwCurThreadAptRefs)
{
HRESULT hr = S_OK;
if (dwCurThreadAptRefs == 1) {
APTTYPE aptType;
APTTYPEQUALIFIER aptTypeQualifier;
hr = CoGetApartmentType(&aptType, &aptTypeQualifier);
if (SUCCEEDED(hr) &&
(aptType == APTTYPE_STA ||
aptType == APTTYPE_MAINSTA ||
(aptType == APTTYPE_MTA && InterlockedDecrement(&m_MTAThreads) == 0))) {
hr = RevokeClassObjects();
}
}
return hr;
}
, . (? ?) - DLL.
( ):
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
if (fdwReason == DLL_PROCESS_ATTACH) {
g_tlsIndex = TlsAlloc();
TlsSetValue(g_tlsIndex, HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ULARGE_INTEGER)));
}
if (fdwReason == DLL_PROCESS_ATTACH || fdwReason == DLL_THREAD_ATTACH) {
CRegisterClassesSpy *spy = new CRegisterClassesSpy();
IInitializeSpy *pSpy;
spy->QueryInterface(IID_IInitializeSpy, reinterpret_cast<void**>(&pSpy));
spy->Release();
ULARGE_INTEGER* pCookie = reinterpret_cast<ULARGE_INTEGER*>(TlsGetValue(g_tlsIndex));
CoRegisterInitializeSpy(pSpy, pCookie));
pSpy->Release();
}
else if ((fdwReason == DLL_PROCESS_DETACH && lpReserved == NULL) || fdwReason == DLL_THREAD_DETACH) {
ULARGE_INTEGER* pCookie = reinterpret_cast<ULARGE_INTEGER*>(TlsGetValue(g_tlsIndex));
CoRevokeInitializeSpy(*pCookie);
}
if (fdwReason == DLL_PROCESS_DETACH && lpReserved == NULL) {
TlsFree(g_tlsIndex);
}
return TRUE;
}
- DLL DllMain (, COM), IInitializeSpy , , , .
, , EXE DLL .
:
PS: factory (, STA), (GIT), - PostInitialize , factory , , factory .