#include "private.h" #include "mlmain.h" #include "mlstr.h" #include "convobj.h" #include "cpdetect.h" #ifdef NEWMLSTR #include "attrstrw.h" #include "attrstra.h" #include "attrloc.h" #include "util.h" #endif #define DECL_CRTFREE #include #define _WINDLL #include #include // for IsOS() flags BEGIN_OBJECT_MAP(ObjectMap) OBJECT_ENTRY(CLSID_CMultiLanguage, CMultiLanguage) OBJECT_ENTRY(CLSID_CMLangString, CMLStr) OBJECT_ENTRY(CLSID_CMLangConvertCharset, CMLangConvertCharset) #ifdef NEWMLSTR OBJECT_ENTRY(CLSID_CMLStrAttrWStr, CMLStrAttrWStr) OBJECT_ENTRY(CLSID_CMLStrAttrAStr, CMLStrAttrAStr) OBJECT_ENTRY(CLSID_CMLStrAttrLocale, CMLStrAttrLocale) #endif END_OBJECT_MAP() // // Globals // HINSTANCE g_hInst = NULL; HINSTANCE g_hUrlMon = NULL; CRITICAL_SECTION g_cs; CComModule _Module; #ifdef NEWMLSTR CMLAlloc* g_pMalloc; #endif BOOL g_bIsNT5; BOOL g_bIsNT; BOOL g_bIsWin98; UINT g_uACP; // // Build Global Objects // void BuildGlobalObjects(void) { DebugMsg(DM_TRACE, TEXT("BuildGlobalObjects called.")); EnterCriticalSection(&g_cs); // Build CMimeDatabase Object if (NULL == g_pMimeDatabase) g_pMimeDatabase = new CMimeDatabase; #ifdef NEWMLSTR if (NULL == g_pMalloc) g_pMalloc = new CMLAlloc; #endif LeaveCriticalSection(&g_cs); } void FreeGlobalObjects(void) { DebugMsg(DM_TRACE, TEXT("FreeGlobalObjects called.")); // Free CMimeDatabase Object if (NULL != g_pMimeDatabase) { delete g_pMimeDatabase; g_pMimeDatabase = NULL; } #ifdef NEWMLSTR if (NULL != g_pMalloc) { delete g_pMalloc; g_pMalloc = NULL; } #endif // LCDETECT if ( NULL != g_pLCDetect ) { delete (LCDetect *)g_pLCDetect; g_pLCDetect = NULL; } if (NULL != g_pCpMRU) { delete g_pCpMRU; g_pCpMRU = NULL; } if (g_pMimeDatabaseReg) { delete g_pMimeDatabaseReg; g_pMimeDatabaseReg = NULL; } CMLangFontLink_FreeGlobalObjects(); } // // DLL part of the Object // extern "C" BOOL WINAPI DllMain(HMODULE hInstance, DWORD dwReason, LPVOID) { BOOL fRet = TRUE; DebugMsg(DM_TRACE, TEXT("DllMain called. dwReason=0x%08x"), dwReason); switch (dwReason) { LPVOID lpv; case DLL_PROCESS_ATTACH: SHFusionInitializeFromModule(hInstance); InitializeCriticalSection(&g_cs); g_hInst = (HINSTANCE)hInstance; DisableThreadLibraryCalls(g_hInst); _Module.Init(ObjectMap, g_hInst); // HACKHACK (reinerf) - because ATL2.1 bites the big one, we have to malloc some memory // here so that it will cause _Module.m_hHeap to be initialized. They do not init this // member variable in a thread safe manner, so we will alloc and free a small chunk of // memory right now to ensure that the heap is created only once. lpv = malloc(2 * sizeof(CHAR)); if (lpv) { free(lpv); } g_bIsNT5 = staticIsOS(OS_WIN2000ORGREATER); g_bIsNT = staticIsOS(OS_NT); g_bIsWin98 = staticIsOS(OS_WIN98ORGREATER); g_uACP = GetACP(); break; case DLL_PROCESS_DETACH: FreeGlobalObjects(); _Module.Term(); DeleteCriticalSection(&g_cs); if (g_hUrlMon) { FreeLibrary(g_hUrlMon); } SHFusionUninitialize(); break; } return TRUE; } void DllAddRef(void) { _Module.Lock(); } void DllRelease(void) { _Module.Unlock(); } STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppvObj) { DebugMsg(DM_TRACE, TEXT("DllGetClassObject called.")); if (NULL == g_pMimeDatabase) BuildGlobalObjects(); // // See comments in util.cpp NeedToLoadMLangForOutlook() // if (NeedToLoadMLangForOutlook()) LoadLibrary(TEXT("mlang.dll")); return _Module.GetClassObject(rclsid, riid, ppvObj); } STDAPI DllCanUnloadNow(void) { return (_Module.GetLockCount() == 0) ? S_OK : S_FALSE; } // // Self Registration part // #if 0 HRESULT CallRegInstall(LPCSTR szSection) { HRESULT hr = E_FAIL; HINSTANCE hinstAdvPack = LoadLibrary(TEXT("ADVPACK.DLL")); DebugMsg(DM_TRACE, TEXT("CallRegInstall called for %s."), szSection); if (NULL != hinstAdvPack) { REGINSTALL pfnri = (REGINSTALL)GetProcAddress(hinstAdvPack, achREGINSTALL); if (NULL != pfnri) hr = pfnri(g_hInst, szSection, NULL); FreeLibrary(hinstAdvPack); } return hr; } #endif STDAPI DllRegisterServer(void) { HRESULT hr; DebugMsg(DM_TRACE, TEXT("DllRegisterServer called.")); #if 0 HINSTANCE hinstAdvPack = LoadLibrary(TEXT("ADVPACK.DLL")); OSVERSIONINFO osvi; BOOL fRunningOnNT; // Determine which version of NT or Windows we're running on osvi.dwOSVersionInfoSize = sizeof(osvi); GetVersionEx(&osvi); fRunningOnNT = (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId); // Delete any old registration entries, then add the new ones. // Keep ADVPACK.DLL loaded across multiple calls to RegInstall. CallRegInstall("UnReg"); hr = CallRegInstall(fRunningOnNT? "Reg.NT": "Reg"); if (NULL != hinstAdvPack) FreeLibrary(hinstAdvPack); // Need to register TypeLib here ... // Get the full path of this module GetModuleFileName(g_hInst, szModule, ARRAYSIZE(szModule)); // Register our TypeLib MultiByteToWideChar(CP_ACP, 0, szModule, -1, wszTemp, ARRAYSIZE(wszTemp)); hr = LoadTypeLib(wszTemp, &pTypeLib); if (SUCCEEDED(hr)) { hr = RegisterTypeLib(pTypeLib, wszTemp, NULL); pTypeLib->Release(); } #else hr = RegisterServerInfo(); // Legacy registry MIME DB code, keep it for backward compatiblility MimeDatabaseInfo(); #endif return hr; } STDAPI DllUnregisterServer(void) { HRESULT hr; DebugMsg(DM_TRACE, TEXT("DllUnregisterServer called.")); #if 0 hr = CallRegInstall("UnReg"); #else hr = UnregisterServerInfo(); #endif return hr; }