Leaked source code of windows server 2003
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.

625 lines
18 KiB

  1. // --------------------------------------------------------------------------------
  2. // Dllmain.cpp
  3. // Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  4. // Steven J. Bailey
  5. // --------------------------------------------------------------------------------
  6. #include "pch.hxx"
  7. #include <shfusion.h>
  8. #define DEFINE_STRING_CONSTANTS
  9. #define DEFINE_STRCONST
  10. #define DEFINE_PROPSYMBOLS
  11. #define DEFINE_TRIGGERS
  12. #include "mimeole.h"
  13. #include "symcache.h"
  14. #include "strconst.h"
  15. #include "htmlstr.h"
  16. #include "thorsspi.h"
  17. #include "sicily.h"
  18. #include "ixputil.h"
  19. #include "olealloc.h"
  20. #include "smime.h"
  21. #include "objheap.h"
  22. #include "internat.h"
  23. #include "icoint.h"
  24. #include "msoert.h"
  25. #include "dllmain.h"
  26. #include "mhtmlurl.h"
  27. #include "mlang.h"
  28. #include <lookup.h>
  29. #include "shared.h"
  30. #include "shlwapi.h"
  31. #include "demand.h"
  32. #include "fontcash.h"
  33. #include "util.h"
  34. #include "resource.h"
  35. #include "../imnxport/asynconn.h"
  36. // --------------------------------------------------------------------------------
  37. // Globals - Object count and lock count
  38. // --------------------------------------------------------------------------------
  39. CRITICAL_SECTION g_csDllMain={0};
  40. CRITICAL_SECTION g_csRAS={0};
  41. CRITICAL_SECTION g_csCounter={0};
  42. CRITICAL_SECTION g_csMLANG={0};
  43. CRITICAL_SECTION g_csCSAPI3T1={0};
  44. BOOL g_fAttached = FALSE;
  45. DWORD g_dwCounter=0; // boundary/cid/mid ratchet
  46. LONG g_cRef=0;
  47. LONG g_cLock=0;
  48. HINSTANCE g_hInst=NULL;
  49. HINSTANCE g_hLocRes=NULL;
  50. CMimeInternational *g_pInternat=NULL;
  51. BOOL g_fWinsockInit=FALSE;
  52. DWORD g_dwSysPageSize;
  53. UINT CF_HTML=0;
  54. UINT CF_INETMSG=0;
  55. UINT CF_RFC822=0;
  56. CMimeAllocator * g_pMoleAlloc=NULL;
  57. LPINETCSETINFO g_pDefBodyCset=NULL;
  58. LPINETCSETINFO g_pDefHeadCset=NULL;
  59. LPSYMBOLCACHE g_pSymCache=NULL;
  60. IMalloc *g_pMalloc=NULL;
  61. HINSTANCE g_hinstMLANG=NULL;
  62. HINSTANCE g_hinstRAS=NULL;
  63. HINSTANCE g_hinstCSAPI3T1=NULL;
  64. LPMHTMLURLCACHE g_pUrlCache=NULL;
  65. BOOL g_fCanEditBiDi=FALSE;
  66. DWORD g_dwCompatMode=0;
  67. IF_DEBUG(DWORD TAG_SSPI=0);
  68. SYSTEM_INFO g_SystemInfo={0};
  69. OSVERSIONINFO g_OSInfo={0};
  70. ULONG g_ulUpperCentury = 0;
  71. ULONG g_ulY2kThreshold = 2029;
  72. IFontCache *g_lpIFontCache=NULL;
  73. HCERTSTORE g_hCachedStoreMy = NULL;
  74. HCERTSTORE g_hCachedStoreAddressBook = NULL;
  75. LPSRVIGNORABLEERROR g_pSrvErrRoot = NULL;
  76. BOOL fIsNT5() { return((g_OSInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) && (g_OSInfo.dwMajorVersion >= 5)); }
  77. // --------------------------------------------------------------------------------
  78. // Debug Globals
  79. // --------------------------------------------------------------------------------
  80. #ifdef DEBUG
  81. DWORD dwDOUTLevel=0;
  82. DWORD dwDOUTLMod=0;
  83. DWORD dwDOUTLModLevel=0;
  84. #endif
  85. #ifdef WIN16
  86. // --------------------------------------------------------------------------------
  87. // From main.c of the build
  88. // --------------------------------------------------------------------------------
  89. extern "C" { void FreeGlobalVars(); };
  90. #endif
  91. #ifdef SMIME_V3
  92. STDAPI EssRegisterServer(void);
  93. BOOL WINAPI EssASNDllMain(HMODULE hInst, ULONG ulReason, LPVOID lpv);
  94. #endif // SMIME_V3
  95. HRESULT GetDllPathName(WCHAR **ppszW);
  96. // These lines should be hardcoded! (YST)
  97. static const TCHAR sc_szLangDll[] = "INETRES.DLL";
  98. // --------------------------------------------------------------------------------
  99. // GetDllMajorVersion
  100. // --------------------------------------------------------------------------------
  101. STDAPI_(OEDLLVERSION) GetDllMajorVersion(void)
  102. {
  103. return OEDLL_VERSION_CURRENT;
  104. }
  105. extern BOOL CanEditBiDi(void);
  106. // --------------------------------------------------------------------------------
  107. // InitGlobalVars
  108. // --------------------------------------------------------------------------------
  109. void InitGlobalVars(void)
  110. {
  111. // Locals
  112. SYSTEM_INFO rSystemInfo;
  113. TCHAR szY2kThreshold[16];
  114. TCHAR rgch[MAX_PATH];
  115. HKEY hkey = NULL;
  116. HRESULT hr;
  117. DWORD cb;
  118. // Initialize Global Critical Sections
  119. InitializeCriticalSection(&g_csDllMain);
  120. InitializeCriticalSection(&g_csRAS);
  121. InitializeCriticalSection(&g_csCounter);
  122. InitializeCriticalSection(&g_csMLANG);
  123. InitializeCriticalSection(&g_csCSAPI3T1);
  124. g_fAttached = TRUE;
  125. // This for the winsock multi-thread hostname lookup
  126. InitLookupCache();
  127. // Get System & OS Info
  128. GetPCAndOSTypes(&g_SystemInfo, &g_OSInfo);
  129. g_dwSysPageSize = g_SystemInfo.dwPageSize;
  130. // Create OLE Task Memory Allocator
  131. CoGetMalloc(1, &g_pMalloc);
  132. Assert(g_pMalloc);
  133. // Create our global allocator
  134. g_pMoleAlloc = new CMimeAllocator;
  135. Assert(g_pMoleAlloc);
  136. // Security Initialize
  137. SecurityInitialize();
  138. // Initialize Demand-loaded Libs
  139. InitDemandLoadedLibs();
  140. // INit crit sect
  141. g_pSymCache = new CPropertySymbolCache;
  142. Assert(g_pSymCache);
  143. // Initialize the Symbol Table
  144. SideAssert(SUCCEEDED(g_pSymCache->Init()));
  145. // Init Body Object Heap
  146. InitObjectHeaps();
  147. // Init International
  148. InitInternational();
  149. // Init ActiveUrl Cache
  150. g_pUrlCache = new CMimeActiveUrlCache;
  151. Assert(g_pUrlCache);
  152. // Check if the system can edit Bidi documents
  153. g_fCanEditBiDi = CanEditBiDi();
  154. // Register clipboard formats
  155. CF_HTML = RegisterClipboardFormat(STR_CF_HTML);
  156. Assert(CF_HTML != 0);
  157. CF_INETMSG = RegisterClipboardFormat(STR_CF_INETMSG);
  158. Assert(CF_INETMSG != 0);
  159. CF_RFC822 = RegisterClipboardFormat(STR_CF_RFC822);
  160. Assert(CF_RFC822 != 0);
  161. // --- Calculate Y2K cut off information
  162. // See http://officeweb/specs/excel/CYu/nty2k.htm
  163. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, REG_Y2K_THRESHOLD, 0, KEY_READ, &hkey))
  164. {
  165. cb = sizeof(szY2kThreshold);
  166. if(ERROR_SUCCESS == RegQueryValueEx(hkey, "1", NULL, NULL, (LPBYTE)szY2kThreshold, &cb))
  167. {
  168. g_ulY2kThreshold = (ULONG)StrToInt(szY2kThreshold);
  169. }
  170. RegCloseKey(hkey);
  171. }
  172. g_ulUpperCentury = g_ulY2kThreshold / 100;
  173. g_ulY2kThreshold %= 100;
  174. // Create the Font Cache Object
  175. if (NULL == g_lpIFontCache)
  176. {
  177. hr = CFontCache::CreateInstance(NULL, (IUnknown **)&g_lpIFontCache);
  178. if(SUCCEEDED(hr))
  179. {
  180. StrCpyN(rgch, c_szExplorerRegPath, ARRAYSIZE(rgch));
  181. StrCatBuff(rgch, "\\International", ARRAYSIZE(rgch));
  182. hr = g_lpIFontCache->Init(HKEY_CURRENT_USER, rgch, 0);
  183. }
  184. if(FAILED(hr))
  185. {
  186. AthMessageBox(HWND_DESKTOP, MAKEINTRESOURCE(IDS_APPNAME), MAKEINTRESOURCE(idsFontCacheError),
  187. NULL, MB_OK | MB_ICONSTOP);
  188. }
  189. }
  190. }
  191. // --------------------------------------------------------------------------------
  192. // FreeGlobalVars
  193. // --------------------------------------------------------------------------------
  194. void FreeGlobalVars(void)
  195. {
  196. // Server ignorable errors
  197. if(g_pSrvErrRoot)
  198. FreeSrvErr(g_pSrvErrRoot);
  199. // Cache stores
  200. if (g_hCachedStoreMy)
  201. CertCloseStore(g_hCachedStoreMy, 0);
  202. if (g_hCachedStoreAddressBook)
  203. CertCloseStore(g_hCachedStoreAddressBook, 0);
  204. // Release ActiveUrlCache
  205. Assert(g_pUrlCache);
  206. SafeRelease(g_pUrlCache);
  207. // Free Address Info Heap (must be before release of g_pSymCache)
  208. FreeObjectHeaps();
  209. // Release Symbol CAche
  210. Assert(g_pSymCache);
  211. SafeRelease(g_pSymCache);
  212. // Unload RAS Dll
  213. EnterCriticalSection(&g_csRAS);
  214. SafeFreeLibrary(g_hinstRAS);
  215. LeaveCriticalSection(&g_csRAS);
  216. // Uninitialize Security
  217. SSPIUninitialize();
  218. UnloadSecurity();
  219. // Unload S/MIME
  220. CSMime::UnloadAll();
  221. // Must be before UnInitializeWinsock()
  222. DeInitLookupCache();
  223. // Cleanup Winsock
  224. if (g_fWinsockInit)
  225. UnInitializeWinsock();
  226. // Free libraries that demand.cpp loaded
  227. FreeDemandLoadedLibs();
  228. // Free CSAPI3T1
  229. EnterCriticalSection(&g_csCSAPI3T1);
  230. SafeFreeLibrary(g_hinstCSAPI3T1);
  231. LeaveCriticalSection(&g_csCSAPI3T1);
  232. // Free mlang lib
  233. EnterCriticalSection(&g_csMLANG);
  234. SafeFreeLibrary(g_hinstMLANG);
  235. LeaveCriticalSection(&g_csMLANG);
  236. // Release Font Cache
  237. SafeRelease(g_lpIFontCache);
  238. // Release g_pInternat
  239. Assert(g_pInternat);
  240. SafeRelease(g_pInternat);
  241. // Free INETRES.DLL (g_hLocRes)
  242. SafeFreeLibrary(g_hLocRes);
  243. // Delete Global Critical Sections
  244. g_fAttached = FALSE;
  245. DeleteCriticalSection(&g_csCSAPI3T1);
  246. DeleteCriticalSection(&g_csMLANG);
  247. DeleteCriticalSection(&g_csCounter);
  248. DeleteCriticalSection(&g_csRAS);
  249. DeleteCriticalSection(&g_csDllMain);
  250. // Release Global Memory allocator
  251. SafeRelease(g_pMoleAlloc);
  252. // Release Global Memory allocator
  253. SafeRelease(g_pMalloc);
  254. //Don't SafeRelease() anything after here, as the allocator has been Released()
  255. #ifdef WIN16
  256. // Need uninitialize it to clean the ole garbage.
  257. CoUninitialize();
  258. #endif // WIN16
  259. }
  260. #ifndef WIN16
  261. // --------------------------------------------------------------------------------
  262. // Win32 Dll Entry Point
  263. // --------------------------------------------------------------------------------
  264. EXTERN_C BOOL WINAPI DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved)
  265. {
  266. // Handle Attach - detach reason
  267. switch (dwReason)
  268. {
  269. case DLL_PROCESS_ATTACH:
  270. SHFusionInitialize(NULL);
  271. #ifdef DEBUG
  272. dwDOUTLevel=GetPrivateProfileInt("Debug", "ICLevel", 0, "athena.ini");
  273. dwDOUTLMod=GetPrivateProfileInt("Debug", "Mod", 0, "athena.ini");
  274. dwDOUTLModLevel=GetPrivateProfileInt("Debug", "ModLevel", 0, "athena.ini");
  275. TAG_SSPI = GetDebugTraceTagMask("InetCommSSPI", TAG_SSPI);
  276. #endif
  277. g_hInst = hInst;
  278. g_hLocRes = LoadLangDll(g_hInst, c_szInetResDll, fIsNT5());
  279. if(g_hLocRes == NULL)
  280. {
  281. Assert(FALSE);
  282. return FALSE;
  283. }
  284. InitGlobalVars();
  285. SideAssert(DisableThreadLibraryCalls(hInst));
  286. #ifdef SMIME_V3
  287. if (!EssASNDllMain(hInst, dwReason, lpReserved)) {
  288. return FALSE;
  289. }
  290. #endif // SMIME_V3
  291. break;
  292. case DLL_PROCESS_DETACH:
  293. #ifdef SMIME_V3
  294. if (!EssASNDllMain(hInst, dwReason, lpReserved)) {
  295. return FALSE;
  296. }
  297. #endif // SMIME_V3
  298. FreeGlobalVars();
  299. SHFusionUninitialize();
  300. break;
  301. }
  302. // Done
  303. return TRUE;
  304. }
  305. #else
  306. // --------------------------------------------------------------------------------
  307. // Win16 Dll Entry Point
  308. // --------------------------------------------------------------------------------
  309. BOOL FAR PASCAL LibMain (HINSTANCE hDll, WORD wDataSeg, WORD cbHeapSize, LPSTR lpszCmdLine)
  310. {
  311. // Win16 specific
  312. CoInitialize(NULL);
  313. // Set global instance handle
  314. g_hInst = hDll;
  315. // Initialize Global Variables
  316. InitGlobalVars();
  317. #ifdef DEBUG
  318. dwDOUTLevel=GetPrivateProfileInt("Debug", "ICLevel", 0, "athena.ini");
  319. dwDOUTLMod=GetPrivateProfileInt("Debug", "Mod", 0, "athena.ini");
  320. dwDOUTLModLevel=GetPrivateProfileInt("Debug", "ModLevel", 0, "athena.ini");
  321. #endif
  322. // Done
  323. return TRUE;
  324. }
  325. #endif // !WIN16
  326. // --------------------------------------------------------------------------------
  327. // DwCounterNext
  328. // --------------------------------------------------------------------------------
  329. DWORD DwCounterNext(void)
  330. {
  331. EnterCriticalSection(&g_csCounter);
  332. DWORD dwCounter = g_dwCounter++;
  333. LeaveCriticalSection(&g_csCounter);
  334. return dwCounter;
  335. }
  336. // --------------------------------------------------------------------------------
  337. // DllAddRef
  338. // --------------------------------------------------------------------------------
  339. ULONG DllAddRef(void)
  340. {
  341. TraceCall("DllAddRef");
  342. return (ULONG)InterlockedIncrement(&g_cRef);
  343. }
  344. // --------------------------------------------------------------------------------
  345. // DllRelease
  346. // --------------------------------------------------------------------------------
  347. ULONG DllRelease(void)
  348. {
  349. TraceCall("DllRelease");
  350. return (ULONG)InterlockedDecrement(&g_cRef);
  351. }
  352. // --------------------------------------------------------------------------------
  353. // DllCanUnloadNow
  354. // --------------------------------------------------------------------------------
  355. STDAPI DllCanUnloadNow(void)
  356. {
  357. // Tracing
  358. TraceCall("DllCanUnloadNow");
  359. if(!g_fAttached) // critacal sections was deleted (or not created): we defently can be unloaded
  360. return S_OK;
  361. // Thread Safety
  362. EnterCriticalSection(&g_csDllMain);
  363. // Trace This
  364. // DebugTrace("DllCanUnloadNow: %s - Reference Count: %d, LockServer Count: %d\n", __FILE__, g_cRef, g_cLock);
  365. // Can We Unload
  366. HRESULT hr = (0 == g_cRef && 0 == g_cLock) ? S_OK : S_FALSE;
  367. // Thread Safety
  368. LeaveCriticalSection(&g_csDllMain);
  369. // Done
  370. return hr;
  371. }
  372. // --------------------------------------------------------------------------------
  373. // RegTypeLib
  374. // --------------------------------------------------------------------------------
  375. __inline HRESULT RegTypeLib(HINSTANCE hInstRes)
  376. {
  377. AssertSz(hInstRes, "[ARGS] RegTypeLib: NULL hInstRes");
  378. HRESULT hr = E_FAIL;
  379. CHAR szDll[MAX_PATH];
  380. WCHAR wszDll[MAX_PATH];
  381. GetModuleFileName(hInstRes, szDll, ARRAYSIZE(szDll));
  382. // Convert the module path to Wide-String
  383. if (MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szDll, -1, wszDll, ARRAYSIZE(wszDll)))
  384. {
  385. ITypeLib *pTypeLib;
  386. hr = LoadTypeLib(wszDll, &pTypeLib);
  387. if (SUCCEEDED(hr))
  388. {
  389. // Register the typelib
  390. hr = RegisterTypeLib(pTypeLib, wszDll, NULL);
  391. pTypeLib->Release();
  392. }
  393. }
  394. return hr;
  395. }
  396. // --------------------------------------------------------------------------------
  397. // DllRegisterServer
  398. // --------------------------------------------------------------------------------
  399. STDAPI DllRegisterServer(void)
  400. {
  401. // Locals
  402. HRESULT hr=S_OK;
  403. // Trace
  404. TraceCall("DllRegisterServer");
  405. #ifdef SMIME_V3
  406. // Register the ESS routines
  407. hr = EssRegisterServer();
  408. if (FAILED(hr)) {
  409. return hr;
  410. }
  411. #endif // SMIME_V3
  412. // CallRegInstall and RegTypeLib are in staticRT/shared.cpp
  413. if (SUCCEEDED(hr = CallRegInstall(g_hInst, g_hInst, c_szReg, NULL)))
  414. return RegTypeLib(g_hInst);
  415. else
  416. return hr;
  417. }
  418. // --------------------------------------------------------------------------------
  419. // DllUnregisterServer
  420. // --------------------------------------------------------------------------------
  421. STDAPI DllUnregisterServer(void)
  422. {
  423. // Locals
  424. HRESULT hr=S_OK;
  425. // Trace
  426. TraceCall("DllUnregisterServer");
  427. // UnRegister
  428. IF_FAILEXIT(hr = CallRegInstall(g_hInst, g_hInst, c_szUnReg, NULL));
  429. exit:
  430. // Done
  431. return hr;
  432. }
  433. HRESULT GetTypeLibrary(ITypeLib **ppTypeLib)
  434. {
  435. HRESULT hr;
  436. WCHAR *pszModuleW=0;
  437. hr = GetDllPathName(&pszModuleW);
  438. if (!FAILED(hr))
  439. {
  440. hr = LoadTypeLib(pszModuleW, ppTypeLib);
  441. SafeMemFree(pszModuleW);
  442. }
  443. return hr;
  444. }
  445. HRESULT GetDllPathName(WCHAR **ppszW)
  446. {
  447. HRESULT hr;
  448. TCHAR rgch[MAX_PATH];
  449. WCHAR *pszModuleW=0;
  450. *ppszW=NULL;
  451. if (!GetModuleFileName(g_hInst, rgch, sizeof(rgch)/sizeof(TCHAR)))
  452. return E_FAIL;
  453. *ppszW = PszToUnicode(CP_ACP, rgch);
  454. return *ppszW ? S_OK : E_OUTOFMEMORY;
  455. }
  456. HCERTSTORE
  457. WINAPI
  458. OpenCachedHKCUStore(
  459. IN OUT HCERTSTORE *phStoreCache,
  460. IN LPCWSTR pwszStore
  461. )
  462. {
  463. HCERTSTORE hStore;
  464. // This caching optimization is only supported on WXP
  465. if (g_OSInfo.dwPlatformId != VER_PLATFORM_WIN32_NT ||
  466. g_OSInfo.dwMajorVersion < 5 ||
  467. (g_OSInfo.dwMajorVersion == 5 && g_OSInfo.dwMinorVersion < 1))
  468. {
  469. return CertOpenStore(
  470. CERT_STORE_PROV_SYSTEM_W,
  471. 0,
  472. NULL,
  473. CERT_SYSTEM_STORE_CURRENT_USER |
  474. CERT_STORE_MAXIMUM_ALLOWED_FLAG,
  475. (const void *) pwszStore
  476. );
  477. }
  478. hStore = *phStoreCache;
  479. if (NULL == hStore) {
  480. hStore = CertOpenStore(
  481. CERT_STORE_PROV_SYSTEM_W,
  482. 0,
  483. NULL,
  484. CERT_SYSTEM_STORE_CURRENT_USER |
  485. CERT_STORE_MAXIMUM_ALLOWED_FLAG |
  486. CERT_STORE_SHARE_CONTEXT_FLAG,
  487. (const void *) pwszStore
  488. );
  489. if (hStore) {
  490. HCERTSTORE hPrevStore;
  491. CertControlStore(
  492. hStore,
  493. 0, // dwFlags
  494. CERT_STORE_CTRL_AUTO_RESYNC,
  495. NULL // pvCtrlPara
  496. );
  497. hPrevStore = InterlockedCompareExchangePointer(
  498. phStoreCache, hStore, NULL);
  499. if (hPrevStore) {
  500. CertCloseStore(hStore, 0);
  501. hStore = hPrevStore;
  502. }
  503. }
  504. }
  505. if (hStore)
  506. hStore = CertDuplicateStore(hStore);
  507. return hStore;
  508. }
  509. HCERTSTORE
  510. WINAPI
  511. OpenCachedMyStore()
  512. {
  513. return OpenCachedHKCUStore(&g_hCachedStoreMy, L"My");
  514. }
  515. HCERTSTORE
  516. WINAPI
  517. OpenCachedAddressBookStore()
  518. {
  519. return OpenCachedHKCUStore(&g_hCachedStoreAddressBook, L"AddressBook");
  520. }