Source code of Windows XP (NT5)
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
/*****************************************************************************\
FILE: dllmain.cpp
DESCRIPTION: This file will take care of the DLL lifetime.
BryanSt 4/4/2000 (Bryan Starbuck) Copyright (C) Microsoft Corp 2000-2000. All rights reserved. \*****************************************************************************/
#include "priv.h"
extern HANDLE g_hLogFile;
/*****************************************************************************
* * Dynamic Globals. There should be as few of these as possible. * * All access to dynamic globals must be thread-safe. * *****************************************************************************/
ULONG g_cRef = 0; // Global reference count
CRITICAL_SECTION g_csDll; // The shared critical section
#ifdef DEBUG
DWORD g_TlsMem = 0xffffffff; #endif // DEBUG
CComModule _Module;
BEGIN_OBJECT_MAP(ObjectMap) //OBJECT_ENTRY(CLSID_MsgListView, CMsgListView)
END_OBJECT_MAP()
/*****************************************************************************
* * DllAddRef / DllRelease * * Maintain the DLL reference count. * *****************************************************************************/
void DllAddRef(void) { InterlockedIncrement((LPLONG)&g_cRef); }
void DllRelease(void) { InterlockedDecrement((LPLONG)&g_cRef); }
/*****************************************************************************
* * DllGetClassObject * * OLE entry point. Produces an IClassFactory for the indicated GUID. * * The artificial refcount inside DllGetClassObject helps to * avoid the race condition described in DllCanUnloadNow. It's * not perfect, but it makes the race window much smaller. * *****************************************************************************/
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID * ppvObj) { HRESULT hres;
DllAddRef(); if (0)//CLSID_MsgListView == rclsid)
{ hres = _Module.GetClassObject(rclsid, riid, ppvObj); } else { hres = CClassFactory_Create(rclsid, riid, ppvObj); } DllRelease(); return hres; }
/*****************************************************************************
* * DllCanUnloadNow * * OLE entry point. Fail iff there are outstanding refs. * * There is an unavoidable race condition between DllCanUnloadNow * and the creation of a new IClassFactory: Between the time we * return from DllCanUnloadNow() and the caller inspects the value, * another thread in the same process may decide to call * DllGetClassObject, thus suddenly creating an object in this DLL * when there previously was none. * * It is the caller's responsibility to prepare for this possibility; * there is nothing we can do about it. * *****************************************************************************/
STDMETHODIMP DllCanUnloadNow(void) { HRESULT hres;
ENTERCRITICAL;
hres = g_cRef ? S_FALSE : S_OK;
if (S_OK == hres) { hres = (_Module.GetLockCount()==0) ? S_OK : S_FALSE; }
TraceMsg(TF_WMTHEME, "DllCanUnloadNow() returning hres=%#08lx. (S_OK means yes)", hres);
LEAVECRITICAL;
return hres; }
/*
// Table of all window classes we register so we can unregister them
// at DLL unload.
const LPCTSTR c_rgszClasses[] = { // g_cszPopServiceWndClass
};
// Since we are single-binary, we have to play it safe and do
// this cleanup (needed only on NT, but harmless on Win95).
#define UnregisterWindowClasses() \
SHUnregisterClasses(HINST_THISDLL, c_rgszClasses, ARRAYSIZE(c_rgszClasses)) */
/*****************************************************************************
* * Entry32 * * DLL entry point. * * BUGBUG -- On a thread detach, must check if the thread owns any * global timeouts. If so, we must transfer the timeout to another * thread or something. * *****************************************************************************/ STDAPI_(BOOL) DllEntry(HINSTANCE hinst, DWORD dwReason, LPVOID lpReserved) { static s_hresOle = E_FAIL;
switch (dwReason) { case DLL_PROCESS_ATTACH: { #ifdef DEBUG
CcshellGetDebugFlags(); #endif
InitializeCriticalSection(&g_csDll);
g_hinst = hinst; DisableThreadLibraryCalls(hinst); break; }
case DLL_PROCESS_DETACH: { DeleteCriticalSection(&g_csDll); if (INVALID_HANDLE_VALUE != g_hLogFile) { CloseHandle(g_hLogFile); }
break; } } return 1; }
|