Source code of Windows XP (NT5)
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.

395 lines
9.4 KiB

  1. /*
  2. *
  3. * REINIT.C
  4. *
  5. * Purpose:
  6. * RICHEDIT initialization routines
  7. *
  8. * Copyright (c) 1995-1997, Microsoft Corporation. All rights reserved.
  9. */
  10. #include "_common.h"
  11. #include "_font.h"
  12. #include "_format.h"
  13. #include "_disp.h"
  14. #include "_clasfyc.h"
  15. #include "zmouse.h"
  16. #include "_rtfconv.h"
  17. #include "_ols.h"
  18. #include "_host.h"
  19. // The IA64 linker does not currently handle DELAYLOAD
  20. #include <delayimp.h>
  21. ASSERTDATA
  22. class CTxtEdit;
  23. class CCmbBxWinHost;
  24. extern void ReleaseTypeInfoPtrs();
  25. static char szClassREA[sizeof(RICHEDIT_CLASSA)];
  26. static WCHAR wszClassREW[sizeof(RICHEDIT_CLASSW)/sizeof(WCHAR)];
  27. static WCHAR wszClassLBW[] = LISTBOX_CLASSW;
  28. static WCHAR wszClassCBW[] = COMBOBOX_CLASSW;
  29. #define REGISTERED_LISTBOX 1
  30. #define REGISTERED_COMBOBOX 2
  31. // a critical section for multi-threading support.
  32. CRITICAL_SECTION g_CriticalSection;
  33. HINSTANCE hinstRE = 0;
  34. static BOOL RichFRegisterClass(VOID);
  35. #ifdef DEBUG
  36. BOOL fInDllMain = FALSE; // used to ensure that GDI calls are not made during
  37. // DLL_PROCESS_ATTACH
  38. #endif
  39. void FreeFontCache(); // Defined in font.cpp
  40. void ReleaseOutlineBitmaps(); // Defined in render.cpp
  41. #ifdef DEBUG
  42. void CatchLeaks(void);
  43. #endif
  44. static inline
  45. void WINAPI
  46. OverlayIAT(PImgThunkData pitdDst, PCImgThunkData pitdSrc) {
  47. memcpy(pitdDst, pitdSrc, CountOfImports(pitdDst) * sizeof IMAGE_THUNK_DATA);
  48. }
  49. void OurUnloadDelayLoadedDlls(void)
  50. {
  51. PUnloadInfo pui = __puiHead;
  52. for (;pui;)
  53. {
  54. #if DELAYLOAD_VERSION >= 0x200
  55. if (pui->pidd->rvaUnloadIAT)
  56. {
  57. PCImgDelayDescr pidd = pui->pidd;
  58. HMODULE hmod = *(HMODULE *)((PCHAR)&__ImageBase + pidd->rvaHmod);
  59. OverlayIAT((PImgThunkData) ((PCHAR)&__ImageBase + pidd->rvaIAT),
  60. (PCImgThunkData) ((PCHAR)&__ImageBase + pidd->rvaUnloadIAT));
  61. ::FreeLibrary(hmod);
  62. *(HMODULE *)((PCHAR)&__ImageBase+pidd->rvaHmod) = NULL;
  63. PUnloadInfo puiT = pui->puiNext;
  64. ::LocalFree(pui);
  65. pui = puiT;
  66. }
  67. #else
  68. if (pui->pidd->pUnloadIAT)
  69. {
  70. PCImgDelayDescr pidd = pui->pidd;
  71. HMODULE hmod = *pidd->phmod;
  72. OverlayIAT(pidd->pIAT, pidd->pUnloadIAT);
  73. ::FreeLibrary(hmod);
  74. *pidd->phmod = NULL;
  75. PUnloadInfo puiT = pui->puiNext;
  76. ::LocalFree(pui);
  77. pui = puiT;
  78. }
  79. #endif
  80. }
  81. }
  82. extern "C"
  83. {
  84. #ifdef PEGASUS
  85. BOOL WINAPI DllMain(HANDLE hmod, DWORD dwReason, LPVOID lpvReserved)
  86. #else
  87. BOOL WINAPI DllMain(HMODULE hmod, DWORD dwReason, LPVOID lpvReserved)
  88. #endif
  89. {
  90. DebugMain (hmod, dwReason, lpvReserved);
  91. if(dwReason == DLL_PROCESS_DETACH) // We are unloading
  92. {
  93. DeleteDanglingHosts();
  94. CRTFConverter::FreeFontSubInfo();
  95. FreeFontCache();
  96. DestroyFormatCaches();
  97. ReleaseTypeInfoPtrs();
  98. UninitKinsokuClassify();
  99. // Release various resouces allocated during running...
  100. delete g_pols;
  101. delete g_pusp;
  102. g_pusp = NULL;
  103. ReleaseOutlineBitmaps();
  104. if(hinstRE)
  105. {
  106. #ifndef PEGASUS
  107. UnregisterClassA(szClassREA, hinstRE);
  108. #ifdef RICHED32_BUILD
  109. UnregisterClassA(szClassRE10A, hinstRE);
  110. #endif
  111. #endif
  112. W32->UnregisterClass(wszClassREW, hinstRE);
  113. if (W32->_fRegisteredXBox)
  114. {
  115. // There may be cases where these window classes
  116. // are still in memory in which case UnregisterClass
  117. // will fail. So keep track of that
  118. if (W32->UnregisterClass(wszClassLBW, hinstRE))
  119. W32->_fRegisteredXBox &= ~REGISTERED_LISTBOX;
  120. if (W32->UnregisterClass(wszClassCBW, hinstRE))
  121. W32->_fRegisteredXBox &= ~REGISTERED_COMBOBOX;
  122. }
  123. }
  124. delete W32;
  125. #ifdef DEBUG
  126. CatchLeaks();
  127. #endif
  128. #ifndef _WIN64
  129. OurUnloadDelayLoadedDlls();
  130. #endif
  131. DeleteCriticalSection(&g_CriticalSection);
  132. }
  133. else if(dwReason == DLL_PROCESS_ATTACH) // We have just loaded
  134. {
  135. #ifdef DEBUG
  136. fInDllMain = TRUE;
  137. #endif
  138. InitializeCriticalSection(&g_CriticalSection);
  139. #ifndef DEBUG
  140. DisableThreadLibraryCalls(hmod);
  141. #endif
  142. #ifdef PEGASUS
  143. hinstRE = (HINSTANCE) hmod;
  144. #else
  145. hinstRE = hmod;
  146. #endif
  147. W32 = new CW32System;
  148. WCHAR wszFileName[_MAX_PATH];
  149. CopyMemory(szClassREA, RICHEDIT_CLASSA, sizeof(CERICHEDIT_CLASSA));
  150. CopyMemory(wszClassREW, RICHEDIT_CLASSW, sizeof(CERICHEDIT_CLASSW));
  151. int iLen = W32->GetModuleFileName((HMODULE) hmod, wszFileName, _MAX_PATH);
  152. if (iLen)
  153. {
  154. iLen -= sizeof("riched20.dll") - 1;
  155. if (!lstrcmpi(&wszFileName[iLen] , TEXT("richedce.dll")))
  156. {
  157. // This code allows the dll to be renamed for Win CE.
  158. Assert(sizeof(RICHEDIT_CLASSA) == sizeof(CERICHEDIT_CLASSA));
  159. Assert(sizeof(RICHEDIT_CLASSW) == sizeof(CERICHEDIT_CLASSW));
  160. CopyMemory(szClassREA, CERICHEDIT_CLASSA, sizeof(CERICHEDIT_CLASSA));
  161. CopyMemory(wszClassREW, CERICHEDIT_CLASSW, sizeof(CERICHEDIT_CLASSW));
  162. }
  163. }
  164. if(!RichFRegisterClass())
  165. {
  166. return FALSE;
  167. }
  168. #ifdef DEBUG
  169. fInDllMain = FALSE;
  170. #endif
  171. }
  172. return TRUE;
  173. }
  174. } // extern "C"
  175. /*
  176. * RichFRegisterClass
  177. *
  178. * Purpose:
  179. * registers the window classes used by richedit
  180. *
  181. * Algorithm:
  182. * register two window classes, a Unicode one and an ANSI
  183. * one. This enables clients to optimize their use of
  184. * the edit control w.r.t to ANSI/Unicode data
  185. */
  186. static BOOL RichFRegisterClass(VOID)
  187. {
  188. TRACEBEGIN(TRCSUBSYSHOST, TRCSCOPEINTERN, "RichFRegisterClass");
  189. WNDCLASS wc;
  190. wc.style = CS_DBLCLKS | CS_GLOBALCLASS | CS_PARENTDC;
  191. wc.lpfnWndProc = RichEditWndProc;
  192. wc.cbClsExtra = 0;
  193. wc.cbWndExtra = sizeof(CTxtEdit FAR *);
  194. wc.hInstance = hinstRE;
  195. wc.hIcon = 0;
  196. wc.hCursor = 0;
  197. wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
  198. wc.lpszMenuName = NULL;
  199. wc.lpszClassName = wszClassREW;
  200. if( W32->RegisterREClass(&wc, szClassREA, RichEditANSIWndProc) == NULL )
  201. {
  202. return FALSE;
  203. };
  204. return TRUE;
  205. }
  206. /*
  207. * RichFRegisterClass
  208. *
  209. * Purpose:
  210. * registers the window classes used by REListbox
  211. *
  212. * Algorithm:
  213. * register two window classes, a Unicode one and an ANSI
  214. * one. This enables clients to optimize their use of
  215. * the edit control w.r.t to ANSI/Unicode data
  216. */
  217. extern LRESULT CALLBACK RichListBoxWndProc(HWND, UINT, WPARAM, LPARAM);
  218. extern LRESULT CALLBACK RichComboBoxWndProc(HWND, UINT, WPARAM, LPARAM);
  219. __declspec(dllexport) BOOL WINAPI REExtendedRegisterClass(VOID)
  220. {
  221. TRACEBEGIN(TRCSUBSYSHOST, TRCSCOPEINTERN, "REExtendedRegisterClass");
  222. WNDCLASS wc;
  223. if (!(W32->_fRegisteredXBox & REGISTERED_LISTBOX))
  224. {
  225. // Globally register the listbox
  226. wc.style = CS_DBLCLKS | CS_GLOBALCLASS | CS_PARENTDC;
  227. wc.lpfnWndProc = RichListBoxWndProc;
  228. wc.cbClsExtra = 0;
  229. wc.cbWndExtra = sizeof(CTxtEdit FAR *);
  230. wc.hInstance = hinstRE;
  231. wc.hIcon = 0;
  232. wc.hCursor = 0;
  233. wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
  234. wc.lpszMenuName = NULL;
  235. wc.lpszClassName = wszClassLBW;
  236. if(W32->RegisterREClass(&wc, NULL, NULL))
  237. W32->_fRegisteredXBox |= REGISTERED_LISTBOX;
  238. }
  239. if (!(W32->_fRegisteredXBox & REGISTERED_COMBOBOX))
  240. {
  241. // globally register the combobox
  242. wc.style = CS_DBLCLKS | CS_GLOBALCLASS | CS_PARENTDC | CS_VREDRAW | CS_HREDRAW;
  243. wc.lpfnWndProc = RichComboBoxWndProc;
  244. wc.cbClsExtra = 0;
  245. wc.cbWndExtra = sizeof(CCmbBxWinHost FAR *);
  246. wc.hInstance = hinstRE;
  247. wc.hIcon = 0;
  248. wc.hCursor = 0;
  249. wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
  250. wc.lpszMenuName = NULL;
  251. wc.lpszClassName = wszClassCBW;
  252. if(W32->RegisterREClass(&wc, NULL, NULL))
  253. W32->_fRegisteredXBox |= REGISTERED_COMBOBOX;
  254. }
  255. //Set flag so we unregister the window class
  256. return W32->_fRegisteredXBox;
  257. }
  258. BOOL g_fNoLS = FALSE;
  259. BOOL g_fNoUniscribe = FALSE;
  260. //This is a stub function which we call when we can't find LineServices.
  261. //The stub function needs to be the the first function we call in LS.
  262. LSERR WINAPI LsGetReverseLsimethodsStub(LSIMETHODS *plsim)
  263. {
  264. return lserrOutOfMemory;
  265. }
  266. //Ugly, but good enough
  267. BOOL FIsUniscribeDll (const char *szDll)
  268. {
  269. return (*szDll == 'u' || *szDll == 'U');
  270. }
  271. HRESULT WINAPI ScriptGetPropertiesStub(const SCRIPT_PROPERTIES ***ppSp,int *piNumScripts)
  272. {
  273. return E_FAIL;
  274. }
  275. const SCRIPT_LOGATTR* WINAPI ScriptString_pLogAttrStub(SCRIPT_STRING_ANALYSIS ssa)
  276. {
  277. // USP build 0175 (shipped with IE5 and Office2K) doesnt support this API.
  278. return NULL;
  279. }
  280. // Get Uniscibe's fake entry points
  281. FARPROC WINAPI GetUniscribeStubs(LPCSTR szProcName)
  282. {
  283. if (!lstrcmpiA(szProcName, "ScriptGetProperties"))
  284. return (FARPROC)ScriptGetPropertiesStub;
  285. if (!lstrcmpiA(szProcName, "ScriptString_pLogAttr"))
  286. return (FARPROC)ScriptString_pLogAttrStub;
  287. #ifdef DEBUG
  288. char szAssert[128];
  289. wsprintfA(szAssert, "Uniscribe API =%s= is missing. Fix it NOW!", szProcName);
  290. AssertSz(FALSE, szAssert);
  291. #endif
  292. return (FARPROC)ScriptGetPropertiesStub; // we're dying...
  293. }
  294. #ifndef _WIN64
  295. FARPROC WINAPI DliHook(unsigned dliNotify, PDelayLoadInfo pdli)
  296. {
  297. FARPROC fp = 0;
  298. switch (dliNotify)
  299. {
  300. case dliFailLoadLib:
  301. {
  302. if (FIsUniscribeDll(pdli->szDll))
  303. g_fNoUniscribe = TRUE;
  304. else
  305. g_fNoLS = TRUE;
  306. fp = (FARPROC)(HMODULE)hinstRE;
  307. char szBuf[255];
  308. FormatMessageA(FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
  309. ERROR_MOD_NOT_FOUND,
  310. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  311. (char*)szBuf, sizeof(szBuf), NULL);
  312. CopyMemory(szBuf + lstrlenA(szBuf), " (", 3);
  313. CopyMemory(szBuf + lstrlenA(szBuf), pdli->szDll, lstrlenA(pdli->szDll) + 1);
  314. CopyMemory(szBuf + lstrlenA(szBuf), ")", 2);
  315. MessageBoxA(NULL, szBuf, NULL, MB_ICONEXCLAMATION | MB_TASKMODAL | MB_SETFOREGROUND);
  316. }
  317. break;
  318. case dliFailGetProc:
  319. if (FIsUniscribeDll(pdli->szDll))
  320. fp = (FARPROC)GetUniscribeStubs(pdli->dlp.szProcName);
  321. else
  322. fp = (FARPROC)LsGetReverseLsimethodsStub;
  323. break;
  324. }
  325. return fp;
  326. }
  327. PfnDliHook __pfnDliFailureHook = DliHook;
  328. #endif //!_WIN64