259 lines
6.1 KiB
C++
259 lines
6.1 KiB
C++
#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 <crtfree.h>
|
|
|
|
#define _WINDLL
|
|
#include <atlimpl.cpp>
|
|
|
|
#include <shlwapi.h> // 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;
|
|
}
|