|
|
// --------------------------------------------------------------------------------
// Dllmain.cpp
// Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
// Steven J. Bailey
// --------------------------------------------------------------------------------
#include "pch.hxx"
#include <shfusion.h>
#define DEFINE_STRING_CONSTANTS
#define DEFINE_STRCONST
#define DEFINE_PROPSYMBOLS
#define DEFINE_TRIGGERS
#include "mimeole.h"
#include "symcache.h"
#include "strconst.h"
#include "htmlstr.h"
#include "thorsspi.h"
#include "sicily.h"
#include "ixputil.h"
#include "olealloc.h"
#include "smime.h"
#include "objheap.h"
#include "internat.h"
#include "icoint.h"
#include "msoert.h"
#include "dllmain.h"
#include "mhtmlurl.h"
#include "mlang.h"
#include <lookup.h>
#include "shared.h"
#include "shlwapi.h"
#include "demand.h"
#include "fontcash.h"
#include "util.h"
#include "resource.h"
#include "../imnxport/asynconn.h"
// --------------------------------------------------------------------------------
// Globals - Object count and lock count
// --------------------------------------------------------------------------------
CRITICAL_SECTION g_csDllMain={0}; CRITICAL_SECTION g_csRAS={0}; CRITICAL_SECTION g_csCounter={0}; CRITICAL_SECTION g_csMLANG={0}; CRITICAL_SECTION g_csCSAPI3T1={0}; BOOL g_fAttached = FALSE; DWORD g_dwCounter=0; // boundary/cid/mid ratchet
LONG g_cRef=0; LONG g_cLock=0; HINSTANCE g_hInst=NULL; HINSTANCE g_hLocRes=NULL; CMimeInternational *g_pInternat=NULL; BOOL g_fWinsockInit=FALSE; DWORD g_dwSysPageSize; UINT CF_HTML=0; UINT CF_INETMSG=0; UINT CF_RFC822=0; CMimeAllocator * g_pMoleAlloc=NULL; LPINETCSETINFO g_pDefBodyCset=NULL; LPINETCSETINFO g_pDefHeadCset=NULL; LPSYMBOLCACHE g_pSymCache=NULL; IMalloc *g_pMalloc=NULL; HINSTANCE g_hinstMLANG=NULL; HINSTANCE g_hinstRAS=NULL; HINSTANCE g_hinstCSAPI3T1=NULL; LPMHTMLURLCACHE g_pUrlCache=NULL; BOOL g_fCanEditBiDi=FALSE; DWORD g_dwCompatMode=0; IF_DEBUG(DWORD TAG_SSPI=0); SYSTEM_INFO g_SystemInfo={0}; OSVERSIONINFO g_OSInfo={0}; ULONG g_ulUpperCentury = 0; ULONG g_ulY2kThreshold = 2029; IFontCache *g_lpIFontCache=NULL;
HCERTSTORE g_hCachedStoreMy = NULL; HCERTSTORE g_hCachedStoreAddressBook = NULL; LPSRVIGNORABLEERROR g_pSrvErrRoot = NULL;
BOOL fIsNT5() { return((g_OSInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) && (g_OSInfo.dwMajorVersion >= 5)); }
// --------------------------------------------------------------------------------
// Debug Globals
// --------------------------------------------------------------------------------
#ifdef DEBUG
DWORD dwDOUTLevel=0; DWORD dwDOUTLMod=0; DWORD dwDOUTLModLevel=0; #endif
#ifdef WIN16
// --------------------------------------------------------------------------------
// From main.c of the build
// --------------------------------------------------------------------------------
extern "C" { void FreeGlobalVars(); }; #endif
#ifdef SMIME_V3
STDAPI EssRegisterServer(void); BOOL WINAPI EssASNDllMain(HMODULE hInst, ULONG ulReason, LPVOID lpv); #endif // SMIME_V3
HRESULT GetDllPathName(WCHAR **ppszW);
// These lines should be hardcoded! (YST)
static const TCHAR sc_szLangDll[] = "INETRES.DLL";
// --------------------------------------------------------------------------------
// GetDllMajorVersion
// --------------------------------------------------------------------------------
STDAPI_(OEDLLVERSION) GetDllMajorVersion(void) { return OEDLL_VERSION_CURRENT; }
extern BOOL CanEditBiDi(void); // --------------------------------------------------------------------------------
// InitGlobalVars
// --------------------------------------------------------------------------------
void InitGlobalVars(void) { // Locals
SYSTEM_INFO rSystemInfo; TCHAR szY2kThreshold[16]; TCHAR rgch[MAX_PATH]; HKEY hkey = NULL; HRESULT hr; DWORD cb;
// Initialize Global Critical Sections
InitializeCriticalSection(&g_csDllMain); InitializeCriticalSection(&g_csRAS); InitializeCriticalSection(&g_csCounter); InitializeCriticalSection(&g_csMLANG); InitializeCriticalSection(&g_csCSAPI3T1); g_fAttached = TRUE;
// This for the winsock multi-thread hostname lookup
InitLookupCache();
// Get System & OS Info
GetPCAndOSTypes(&g_SystemInfo, &g_OSInfo); g_dwSysPageSize = g_SystemInfo.dwPageSize;
// Create OLE Task Memory Allocator
CoGetMalloc(1, &g_pMalloc); Assert(g_pMalloc);
// Create our global allocator
g_pMoleAlloc = new CMimeAllocator; Assert(g_pMoleAlloc); // Security Initialize
SecurityInitialize();
// Initialize Demand-loaded Libs
InitDemandLoadedLibs();
// INit crit sect
g_pSymCache = new CPropertySymbolCache; Assert(g_pSymCache);
// Initialize the Symbol Table
SideAssert(SUCCEEDED(g_pSymCache->Init()));
// Init Body Object Heap
InitObjectHeaps();
// Init International
InitInternational();
// Init ActiveUrl Cache
g_pUrlCache = new CMimeActiveUrlCache; Assert(g_pUrlCache);
// Check if the system can edit Bidi documents
g_fCanEditBiDi = CanEditBiDi(); // Register clipboard formats
CF_HTML = RegisterClipboardFormat(STR_CF_HTML); Assert(CF_HTML != 0); CF_INETMSG = RegisterClipboardFormat(STR_CF_INETMSG); Assert(CF_INETMSG != 0); CF_RFC822 = RegisterClipboardFormat(STR_CF_RFC822); Assert(CF_RFC822 != 0);
// --- Calculate Y2K cut off information
// See http://officeweb/specs/excel/CYu/nty2k.htm
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, REG_Y2K_THRESHOLD, 0, KEY_READ, &hkey)) { cb = sizeof(szY2kThreshold); if(ERROR_SUCCESS == RegQueryValueEx(hkey, "1", NULL, NULL, (LPBYTE)szY2kThreshold, &cb)) { g_ulY2kThreshold = (ULONG)StrToInt(szY2kThreshold); } RegCloseKey(hkey); }
g_ulUpperCentury = g_ulY2kThreshold / 100; g_ulY2kThreshold %= 100;
// Create the Font Cache Object
if (NULL == g_lpIFontCache) { hr = CFontCache::CreateInstance(NULL, (IUnknown **)&g_lpIFontCache); if(SUCCEEDED(hr)) { StrCpyN(rgch, c_szExplorerRegPath, ARRAYSIZE(rgch)); StrCatBuff(rgch, "\\International", ARRAYSIZE(rgch)); hr = g_lpIFontCache->Init(HKEY_CURRENT_USER, rgch, 0); } if(FAILED(hr)) { AthMessageBox(HWND_DESKTOP, MAKEINTRESOURCE(IDS_APPNAME), MAKEINTRESOURCE(idsFontCacheError), NULL, MB_OK | MB_ICONSTOP); } } }
// --------------------------------------------------------------------------------
// FreeGlobalVars
// --------------------------------------------------------------------------------
void FreeGlobalVars(void) { // Server ignorable errors
if(g_pSrvErrRoot) FreeSrvErr(g_pSrvErrRoot);
// Cache stores
if (g_hCachedStoreMy) CertCloseStore(g_hCachedStoreMy, 0); if (g_hCachedStoreAddressBook) CertCloseStore(g_hCachedStoreAddressBook, 0);
// Release ActiveUrlCache
Assert(g_pUrlCache); SafeRelease(g_pUrlCache);
// Free Address Info Heap (must be before release of g_pSymCache)
FreeObjectHeaps();
// Release Symbol CAche
Assert(g_pSymCache); SafeRelease(g_pSymCache);
// Unload RAS Dll
EnterCriticalSection(&g_csRAS); SafeFreeLibrary(g_hinstRAS); LeaveCriticalSection(&g_csRAS);
// Uninitialize Security
SSPIUninitialize(); UnloadSecurity();
// Unload S/MIME
CSMime::UnloadAll();
// Must be before UnInitializeWinsock()
DeInitLookupCache();
// Cleanup Winsock
if (g_fWinsockInit) UnInitializeWinsock();
// Free libraries that demand.cpp loaded
FreeDemandLoadedLibs();
// Free CSAPI3T1
EnterCriticalSection(&g_csCSAPI3T1); SafeFreeLibrary(g_hinstCSAPI3T1); LeaveCriticalSection(&g_csCSAPI3T1);
// Free mlang lib
EnterCriticalSection(&g_csMLANG); SafeFreeLibrary(g_hinstMLANG); LeaveCriticalSection(&g_csMLANG);
// Release Font Cache
SafeRelease(g_lpIFontCache);
// Release g_pInternat
Assert(g_pInternat); SafeRelease(g_pInternat);
// Free INETRES.DLL (g_hLocRes)
SafeFreeLibrary(g_hLocRes);
// Delete Global Critical Sections
g_fAttached = FALSE; DeleteCriticalSection(&g_csCSAPI3T1); DeleteCriticalSection(&g_csMLANG); DeleteCriticalSection(&g_csCounter); DeleteCriticalSection(&g_csRAS); DeleteCriticalSection(&g_csDllMain);
// Release Global Memory allocator
SafeRelease(g_pMoleAlloc); // Release Global Memory allocator
SafeRelease(g_pMalloc); //Don't SafeRelease() anything after here, as the allocator has been Released()
#ifdef WIN16
// Need uninitialize it to clean the ole garbage.
CoUninitialize(); #endif // WIN16
}
#ifndef WIN16
// --------------------------------------------------------------------------------
// Win32 Dll Entry Point
// --------------------------------------------------------------------------------
EXTERN_C BOOL WINAPI DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved) { // Handle Attach - detach reason
switch (dwReason) { case DLL_PROCESS_ATTACH: SHFusionInitialize(NULL); #ifdef DEBUG
dwDOUTLevel=GetPrivateProfileInt("Debug", "ICLevel", 0, "athena.ini"); dwDOUTLMod=GetPrivateProfileInt("Debug", "Mod", 0, "athena.ini"); dwDOUTLModLevel=GetPrivateProfileInt("Debug", "ModLevel", 0, "athena.ini"); TAG_SSPI = GetDebugTraceTagMask("InetCommSSPI", TAG_SSPI); #endif
g_hInst = hInst; g_hLocRes = LoadLangDll(g_hInst, c_szInetResDll, fIsNT5()); if(g_hLocRes == NULL) { Assert(FALSE); return FALSE; } InitGlobalVars(); SideAssert(DisableThreadLibraryCalls(hInst));
#ifdef SMIME_V3
if (!EssASNDllMain(hInst, dwReason, lpReserved)) { return FALSE; } #endif // SMIME_V3
break;
case DLL_PROCESS_DETACH: #ifdef SMIME_V3
if (!EssASNDllMain(hInst, dwReason, lpReserved)) { return FALSE; } #endif // SMIME_V3
FreeGlobalVars(); SHFusionUninitialize(); break; }
// Done
return TRUE; }
#else
// --------------------------------------------------------------------------------
// Win16 Dll Entry Point
// --------------------------------------------------------------------------------
BOOL FAR PASCAL LibMain (HINSTANCE hDll, WORD wDataSeg, WORD cbHeapSize, LPSTR lpszCmdLine) { // Win16 specific
CoInitialize(NULL);
// Set global instance handle
g_hInst = hDll;
// Initialize Global Variables
InitGlobalVars();
#ifdef DEBUG
dwDOUTLevel=GetPrivateProfileInt("Debug", "ICLevel", 0, "athena.ini"); dwDOUTLMod=GetPrivateProfileInt("Debug", "Mod", 0, "athena.ini"); dwDOUTLModLevel=GetPrivateProfileInt("Debug", "ModLevel", 0, "athena.ini"); #endif
// Done
return TRUE; } #endif // !WIN16
// --------------------------------------------------------------------------------
// DwCounterNext
// --------------------------------------------------------------------------------
DWORD DwCounterNext(void) { EnterCriticalSection(&g_csCounter); DWORD dwCounter = g_dwCounter++; LeaveCriticalSection(&g_csCounter); return dwCounter; }
// --------------------------------------------------------------------------------
// DllAddRef
// --------------------------------------------------------------------------------
ULONG DllAddRef(void) { TraceCall("DllAddRef"); return (ULONG)InterlockedIncrement(&g_cRef); }
// --------------------------------------------------------------------------------
// DllRelease
// --------------------------------------------------------------------------------
ULONG DllRelease(void) { TraceCall("DllRelease"); return (ULONG)InterlockedDecrement(&g_cRef); }
// --------------------------------------------------------------------------------
// DllCanUnloadNow
// --------------------------------------------------------------------------------
STDAPI DllCanUnloadNow(void) { // Tracing
TraceCall("DllCanUnloadNow");
if(!g_fAttached) // critacal sections was deleted (or not created): we defently can be unloaded
return S_OK;
// Thread Safety
EnterCriticalSection(&g_csDllMain);
// Trace This
// DebugTrace("DllCanUnloadNow: %s - Reference Count: %d, LockServer Count: %d\n", __FILE__, g_cRef, g_cLock);
// Can We Unload
HRESULT hr = (0 == g_cRef && 0 == g_cLock) ? S_OK : S_FALSE;
// Thread Safety
LeaveCriticalSection(&g_csDllMain);
// Done
return hr; }
// --------------------------------------------------------------------------------
// RegTypeLib
// --------------------------------------------------------------------------------
__inline HRESULT RegTypeLib(HINSTANCE hInstRes) { AssertSz(hInstRes, "[ARGS] RegTypeLib: NULL hInstRes"); HRESULT hr = E_FAIL; CHAR szDll[MAX_PATH]; WCHAR wszDll[MAX_PATH];
GetModuleFileName(hInstRes, szDll, ARRAYSIZE(szDll));
// Convert the module path to Wide-String
if (MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szDll, -1, wszDll, ARRAYSIZE(wszDll))) { ITypeLib *pTypeLib;
hr = LoadTypeLib(wszDll, &pTypeLib); if (SUCCEEDED(hr)) { // Register the typelib
hr = RegisterTypeLib(pTypeLib, wszDll, NULL); pTypeLib->Release(); } }
return hr; }
// --------------------------------------------------------------------------------
// DllRegisterServer
// --------------------------------------------------------------------------------
STDAPI DllRegisterServer(void) { // Locals
HRESULT hr=S_OK;
// Trace
TraceCall("DllRegisterServer");
#ifdef SMIME_V3
// Register the ESS routines
hr = EssRegisterServer(); if (FAILED(hr)) { return hr; } #endif // SMIME_V3
// CallRegInstall and RegTypeLib are in staticRT/shared.cpp
if (SUCCEEDED(hr = CallRegInstall(g_hInst, g_hInst, c_szReg, NULL))) return RegTypeLib(g_hInst); else return hr;
}
// --------------------------------------------------------------------------------
// DllUnregisterServer
// --------------------------------------------------------------------------------
STDAPI DllUnregisterServer(void) { // Locals
HRESULT hr=S_OK;
// Trace
TraceCall("DllUnregisterServer");
// UnRegister
IF_FAILEXIT(hr = CallRegInstall(g_hInst, g_hInst, c_szUnReg, NULL));
exit: // Done
return hr; }
HRESULT GetTypeLibrary(ITypeLib **ppTypeLib) { HRESULT hr; WCHAR *pszModuleW=0;
hr = GetDllPathName(&pszModuleW); if (!FAILED(hr)) { hr = LoadTypeLib(pszModuleW, ppTypeLib); SafeMemFree(pszModuleW); } return hr; }
HRESULT GetDllPathName(WCHAR **ppszW) { HRESULT hr; TCHAR rgch[MAX_PATH]; WCHAR *pszModuleW=0;
*ppszW=NULL;
if (!GetModuleFileName(g_hInst, rgch, sizeof(rgch)/sizeof(TCHAR))) return E_FAIL; *ppszW = PszToUnicode(CP_ACP, rgch); return *ppszW ? S_OK : E_OUTOFMEMORY; }
HCERTSTORE WINAPI OpenCachedHKCUStore( IN OUT HCERTSTORE *phStoreCache, IN LPCWSTR pwszStore ) { HCERTSTORE hStore;
// This caching optimization is only supported on WXP
if (g_OSInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || g_OSInfo.dwMajorVersion < 5 || (g_OSInfo.dwMajorVersion == 5 && g_OSInfo.dwMinorVersion < 1)) { return CertOpenStore( CERT_STORE_PROV_SYSTEM_W, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_MAXIMUM_ALLOWED_FLAG, (const void *) pwszStore ); }
hStore = *phStoreCache; if (NULL == hStore) { hStore = CertOpenStore( CERT_STORE_PROV_SYSTEM_W, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_MAXIMUM_ALLOWED_FLAG | CERT_STORE_SHARE_CONTEXT_FLAG, (const void *) pwszStore );
if (hStore) { HCERTSTORE hPrevStore;
CertControlStore( hStore, 0, // dwFlags
CERT_STORE_CTRL_AUTO_RESYNC, NULL // pvCtrlPara
);
hPrevStore = InterlockedCompareExchangePointer( phStoreCache, hStore, NULL);
if (hPrevStore) { CertCloseStore(hStore, 0); hStore = hPrevStore; } } }
if (hStore) hStore = CertDuplicateStore(hStore);
return hStore; }
HCERTSTORE WINAPI OpenCachedMyStore() { return OpenCachedHKCUStore(&g_hCachedStoreMy, L"My"); }
HCERTSTORE WINAPI OpenCachedAddressBookStore() { return OpenCachedHKCUStore(&g_hCachedStoreAddressBook, L"AddressBook"); }
|