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.

413 lines
10 KiB

  1. //
  2. // dllmain.cpp
  3. //
  4. #include "private.h"
  5. #include "globals.h"
  6. #include "tim.h"
  7. #include "imelist.h"
  8. #include "utb.h"
  9. #include "dam.h"
  10. #include "catmgr.h"
  11. #include "nuimgr.h"
  12. #include "profiles.h"
  13. #include "internat.h"
  14. #include "acp2anch.h"
  15. #include "cicmutex.h"
  16. #include "strary.h"
  17. #include "range.h"
  18. #include "compart.h"
  19. #include "marshal.h"
  20. #include "timlist.h"
  21. #include "gcompart.h"
  22. #include "mui.h"
  23. #include "anchoref.h"
  24. #include "hotkey.h"
  25. #include "lbaddin.h"
  26. extern "C" BOOL WINAPI _CRT_INIT(HINSTANCE, DWORD, LPVOID);
  27. extern HINSTANCE g_hOle32;
  28. extern CCicCriticalSectionStatic g_csDelayLoad;;
  29. #ifdef DEBUG
  30. void dbg_RangeDump(ITfRange *pRange);
  31. #endif
  32. extern void UninitThread(void);
  33. extern void RegisterMarshalWndClass();
  34. CCicMutex g_mutexLBES;
  35. CCicMutex g_mutexCompart;
  36. CCicMutex g_mutexAsm;
  37. CCicMutex g_mutexLayouts;
  38. CCicMutex g_mutexTMD;
  39. extern void UninitLayoutMappedFile();
  40. char g_szAsmListCache[MAX_PATH];
  41. char g_szTimListCache[MAX_PATH];
  42. char g_szLayoutsCache[MAX_PATH];
  43. //
  44. // Hack for Office10 BVT.
  45. //
  46. // MSACCESS 10 Debug version (CMallocSpy) shows MsgBox after DLL is detached
  47. // from process.
  48. // Showing MsgBox calls window Hook so Hook entry is called then.
  49. // Need to check the DLL was already detached.
  50. //
  51. BOOL g_fDllProcessDetached = FALSE;
  52. DWORD g_dwThreadDllMain = 0;
  53. void InitStaticHooks();
  54. BOOL g_bOnWow64;
  55. BOOL gf_CRT_INIT = FALSE;
  56. BOOL gfSharedMemory = FALSE;
  57. //+---------------------------------------------------------------------------
  58. //
  59. // ProcessAttach
  60. //
  61. //----------------------------------------------------------------------------
  62. BOOL ProcessAttach(HINSTANCE hInstance)
  63. {
  64. CcshellGetDebugFlags();
  65. Perf_Init();
  66. #ifdef DEBUG
  67. //
  68. // Do you know how to link non-used function??
  69. //
  70. dbg_RangeDump(NULL);
  71. #endif
  72. #ifndef NOCLIB
  73. gf_CRT_INIT = TRUE;
  74. #endif
  75. if (!g_cs.Init())
  76. return FALSE;
  77. if (!g_csInDllMain.Init())
  78. return FALSE;
  79. if (!g_csDelayLoad.Init())
  80. return FALSE;
  81. g_bOnWow64 = RunningOnWow64();
  82. Dbg_MemInit( ! g_bOnWow64 ? TEXT("MSCTF") : TEXT("MSCTF(wow64)"), g_rgPerfObjCounters);
  83. g_hInst = hInstance;
  84. g_hklDefault = GetKeyboardLayout(0);
  85. g_dwTLSIndex = TlsAlloc();
  86. if (g_dwTLSIndex == TLS_OUT_OF_INDEXES)
  87. return FALSE;
  88. g_msgPrivate = RegisterWindowMessage(TEXT("MSUIM.Msg.Private"));
  89. if (!g_msgPrivate)
  90. return FALSE;
  91. g_msgSetFocus = RegisterWindowMessage(TEXT("MSUIM.Msg.SetFocus"));
  92. if (!g_msgSetFocus)
  93. return FALSE;
  94. g_msgThreadTerminate = RegisterWindowMessage(TEXT("MSUIM.Msg.ThreadTerminate"));
  95. if (!g_msgThreadTerminate)
  96. return FALSE;
  97. g_msgThreadItemChange = RegisterWindowMessage(TEXT("MSUIM.Msg.ThreadItemChange"));
  98. if (!g_msgThreadItemChange)
  99. return FALSE;
  100. g_msgLBarModal = RegisterWindowMessage(TEXT("MSUIM.Msg.LangBarModal"));
  101. if (!g_msgLBarModal)
  102. return FALSE;
  103. g_msgRpcSendReceive = RegisterWindowMessage(TEXT("MSUIM.Msg.RpcSendReceive"));
  104. if (!g_msgRpcSendReceive)
  105. return FALSE;
  106. g_msgThreadMarshal = RegisterWindowMessage(TEXT("MSUIM.Msg.ThreadMarshal"));
  107. if (!g_msgThreadMarshal)
  108. return FALSE;
  109. g_msgCheckThreadInputIdel = RegisterWindowMessage(TEXT("MSUIM.Msg.CheckThreadInputIdel"));
  110. if (!g_msgCheckThreadInputIdel)
  111. return FALSE;
  112. g_msgStubCleanUp = RegisterWindowMessage(TEXT("MSUIM.Msg.StubCleanUp"));
  113. if (!g_msgStubCleanUp)
  114. return FALSE;
  115. g_msgShowFloating = RegisterWindowMessage(TEXT("MSUIM.Msg.ShowFloating"));
  116. if (!g_msgShowFloating)
  117. return FALSE;
  118. g_msgLBUpdate = RegisterWindowMessage(TEXT("MSUIM.Msg.LBUpdate"));
  119. if (!g_msgLBUpdate)
  120. return FALSE;
  121. g_msgNuiMgrDirtyUpdate = RegisterWindowMessage(TEXT("MSUIM.Msg.MuiMgrDirtyUpdate"));
  122. if (!g_msgNuiMgrDirtyUpdate)
  123. return FALSE;
  124. InitOSVer();
  125. //
  126. // get imm32's hmodule.
  127. //
  128. InitDelayedLibs();
  129. InitUniqueString();
  130. g_SharedMemory.BaseInit();
  131. if (!g_SharedMemory.Start())
  132. return FALSE;
  133. gfSharedMemory = TRUE;
  134. InitAppCompatFlags();
  135. InitCUASFlag();
  136. g_rglbes = new CStructArray<LBAREVENTSINKLOCAL>;
  137. if (!g_rglbes)
  138. return FALSE;
  139. RegisterMarshalWndClass();
  140. GetDesktopUniqueNameArray(TEXT("CTF.AsmListCache.FMP"), g_szAsmListCache);
  141. GetDesktopUniqueNameArray(TEXT("CTF.TimListCache.FMP"), g_szTimListCache);
  142. GetDesktopUniqueNameArray(TEXT("CTF.LayoutsCache.FMP"), g_szLayoutsCache);
  143. TCHAR ach[MAX_PATH];
  144. GetDesktopUniqueNameArray(TEXT("CTF.LBES.Mutex"), ach);
  145. CCicSecAttr sa;
  146. if (!g_mutexLBES.Init(sa, ach))
  147. return FALSE;
  148. GetDesktopUniqueNameArray(TEXT("CTF.Compart.Mutex"), ach);
  149. if (!g_mutexCompart.Init(sa, ach))
  150. return FALSE;
  151. GetDesktopUniqueNameArray(TEXT("CTF.Asm.Mutex"), ach);
  152. if (!g_mutexAsm.Init(sa, ach))
  153. return FALSE;
  154. GetDesktopUniqueNameArray(TEXT("CTF.Layouts.Mutex"), ach);
  155. if (!g_mutexLayouts.Init(sa, ach))
  156. return FALSE;
  157. GetDesktopUniqueNameArray(TEXT("CTF.TMD.Mutex"), ach);
  158. if (!g_mutexTMD.Init(sa, ach))
  159. return FALSE;
  160. InitLangChangeHotKey();
  161. CRange::_InitClass();
  162. CAnchorRef::_InitClass();
  163. dbg_InitMarshalTimeOut();
  164. MuiLoadResource(hInstance, TEXT("msctf.dll"));
  165. CheckAnchorStores();
  166. return TRUE;
  167. }
  168. //+---------------------------------------------------------------------------
  169. //
  170. // ProcessDetach
  171. //
  172. //----------------------------------------------------------------------------
  173. void ProcessDetach(HINSTANCE hInstance)
  174. {
  175. #ifndef NOCLIB
  176. if (gf_CRT_INIT)
  177. {
  178. #endif
  179. if (gfSharedMemory)
  180. {
  181. //
  182. // If _Module.m_nLockCnt != 0, then TFUninitLib() doesn't calls from DllUninit().
  183. // So critical section of g_csIMLib never deleted.
  184. //
  185. if (DllRefCount() != 0)
  186. {
  187. TFUninitLib();
  188. }
  189. CRange::_UninitClass();
  190. CAnchorRef::_UninitClass();
  191. MuiClearResource();
  192. }
  193. UninitINAT();
  194. CDispAttrGuidCache::StaticUnInit();
  195. UninitThread();
  196. //
  197. // clean up all marshal window in this thread.
  198. //
  199. CThreadMarshalWnd::ClearMarshalWndProc(GetCurrentProcessId());
  200. TF_UninitThreadSystem();
  201. UninitProcess();
  202. if (g_dwTLSIndex != TLS_OUT_OF_INDEXES)
  203. TlsFree(g_dwTLSIndex);
  204. g_dwTLSIndex = TLS_OUT_OF_INDEXES;
  205. if (g_rglbes)
  206. delete g_rglbes;
  207. g_rglbes = NULL;
  208. g_gcomplist.CleanUp();
  209. g_timlist.CleanUp();
  210. Dbg_MemUninit();
  211. g_cs.Delete();
  212. g_csInDllMain.Delete();
  213. g_csDelayLoad.Delete();
  214. if (gfSharedMemory)
  215. {
  216. g_mutexLBES.Uninit();
  217. g_mutexCompart.Uninit();
  218. g_mutexAsm.Uninit();
  219. //
  220. // call UninitLayoutMappedFile before uninitializing the mutex.
  221. //
  222. UninitLayoutMappedFile();
  223. g_mutexLayouts.Uninit();
  224. g_mutexTMD.Uninit();
  225. InitStaticHooks(); // must happen before we uninit shared memory
  226. g_SharedMemory.Close();
  227. }
  228. g_SharedMemory.Finalize();
  229. #ifndef NOCLIB
  230. }
  231. if (g_fDllProcessDetached)
  232. {
  233. // why were we called twice?
  234. Assert(0);
  235. }
  236. #endif
  237. Assert(DllRefCount() == 0); // leaked something?
  238. g_fDllProcessDetached = TRUE;
  239. }
  240. //+---------------------------------------------------------------------------
  241. //
  242. // DllMain
  243. //
  244. //----------------------------------------------------------------------------
  245. BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID pvReserved)
  246. {
  247. BOOL bRet = TRUE;
  248. g_dwThreadDllMain = GetCurrentThreadId();
  249. switch (dwReason)
  250. {
  251. case DLL_PROCESS_ATTACH:
  252. //
  253. // Now real DllEntry point is _DllMainCRTStartup.
  254. // _DllMainCRTStartup does not call our DllMain(DLL_PROCESS_DETACH)
  255. // if our DllMain(DLL_PROCESS_ATTACH) fails.
  256. // So we have to clean this up.
  257. //
  258. if (!ProcessAttach(hInstance))
  259. {
  260. ProcessDetach(hInstance);
  261. bRet = FALSE;
  262. break;
  263. }
  264. //
  265. // fall thru
  266. //
  267. //
  268. // to call TF_InitThreadSystem(), make sure we have not initialized
  269. // timlist yet.
  270. //
  271. Assert(!g_timlist.IsInitialized());
  272. case DLL_THREAD_ATTACH:
  273. TF_InitThreadSystem();
  274. break;
  275. case DLL_THREAD_DETACH:
  276. UninitThread();
  277. TF_UninitThreadSystem();
  278. break;
  279. case DLL_PROCESS_DETACH:
  280. ProcessDetach(hInstance);
  281. break;
  282. }
  283. g_dwThreadDllMain = 0;
  284. return bRet;
  285. }
  286. #ifdef DEBUG
  287. //+---------------------------------------------------------------------------
  288. //
  289. // dbg_RangeDump
  290. //
  291. //----------------------------------------------------------------------------
  292. void dbg_RangeDump(ITfRange *pRange)
  293. {
  294. WCHAR ach[256];
  295. ULONG cch;
  296. char ch[256];
  297. ULONG cch1 = ARRAYSIZE(ch);
  298. if (!pRange)
  299. return;
  300. pRange->GetText(BACKDOOR_EDIT_COOKIE, 0, ach, ARRAYSIZE(ach), &cch);
  301. ach[cch] = L'\0';
  302. TraceMsg(TF_GENERAL, "dbg_RangeDump");
  303. TraceMsg(TF_GENERAL, "\tpRange: %x", (UINT_PTR)pRange);
  304. cch1 = WideCharToMultiByte(CP_ACP, 0, ach, -1, ch, sizeof(ch)-1, NULL, NULL);
  305. ch[cch1] = '\0';
  306. TraceMsg(TF_GENERAL, "\t%s", ch);
  307. char sz[512];
  308. sz[0] = '\0';
  309. for (UINT i = 0; i < cch; i++)
  310. {
  311. StringCchPrintf(sz, ARRAYSIZE(sz), "%s%04x ", sz, ach[i]);
  312. }
  313. TraceMsg(TF_GENERAL, "\t%s", sz);
  314. }
  315. #endif