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.

397 lines
11 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: dllinit.c *
  3. * *
  4. * Contains the GDI library initialization routines. *
  5. * *
  6. * Created: 07-Nov-1990 13:30:31 *
  7. * Author: Eric Kutter [erick] *
  8. * *
  9. * Copyright (c) 1990-1999 Microsoft Corporation *
  10. \**************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. #include "glsup.h"
  14. extern PVOID pAFRTNodeList;
  15. extern VOID vSetCheckDBCSTrailByte(DWORD dwCodePage);
  16. NTSTATUS GdiProcessSetup();
  17. VOID GdiProcessShutdown();
  18. #ifdef LANGPACK
  19. #include "winuserp.h"
  20. #endif
  21. HBRUSH ghbrDCBrush;
  22. HPEN ghbrDCPen;
  23. BOOL gbWOW64 = FALSE;
  24. /******************************Public*Routine******************************\
  25. * GdiDllInitialize *
  26. * *
  27. * This is the init procedure for GDI.DLL, which is called each time a new *
  28. * process links to it. *
  29. * *
  30. * History: *
  31. * Thu 30-May-1991 18:08:00 -by- Charles Whitmer [chuckwh] *
  32. * Added Local Handle Table initialization. *
  33. \**************************************************************************/
  34. #if defined(_GDIPLUS_)
  35. //
  36. // The following are globals kept in 'gre':
  37. //
  38. extern PGDI_SHARED_MEMORY gpGdiSharedMemory;
  39. extern PENTRY gpentHmgr;
  40. extern PDEVCAPS gpGdiDevCaps;
  41. #endif
  42. PGDI_SHARED_MEMORY pGdiSharedMemory = NULL;
  43. PENTRY pGdiSharedHandleTable = NULL;
  44. PDEVCAPS pGdiDevCaps = NULL;
  45. W32PID gW32PID;
  46. UINT guintAcp;
  47. UINT guintDBCScp;
  48. PGDIHANDLECACHE pGdiHandleCache;
  49. BOOL gbFirst = TRUE;
  50. #ifdef LANGPACK
  51. BOOL gbLpk = FALSE;
  52. FPLPKEXTEXTOUT fpLpkExtTextOut;
  53. FPLPKGETCHARACTERPLACEMENT fpLpkGetCharacterPlacement;
  54. FPLPKGETTEXTEXTENTEXPOINT fpLpkGetTextExtentExPoint;
  55. FPLPKUSEGDIWIDTHCACHE fpLpkUseGDIWidthCache;
  56. VOID GdiInitializeLanguagePack(DWORD);
  57. #endif
  58. NTSTATUS GdiDllInitialize(
  59. PVOID pvDllHandle,
  60. ULONG ulReason)
  61. {
  62. NTSTATUS Status = STATUS_SUCCESS;
  63. INT i;
  64. PTEB pteb = NtCurrentTeb();
  65. switch (ulReason)
  66. {
  67. case DLL_PROCESS_ATTACH:
  68. DisableThreadLibraryCalls(pvDllHandle);
  69. //
  70. // force the kernel to initialize. This should be done last
  71. // since ClientThreadSetup is going to get called before this returns.
  72. //
  73. if (NtGdiInit() != TRUE)
  74. {
  75. return(STATUS_NO_MEMORY);
  76. }
  77. Status = GdiProcessSetup();
  78. ghbrDCBrush = GetStockObject (DC_BRUSH);
  79. ghbrDCPen = GetStockObject (DC_PEN);
  80. #ifdef BUILD_WOW6432
  81. gbWOW64 = TRUE;
  82. #endif
  83. break;
  84. case DLL_PROCESS_DETACH:
  85. GdiProcessShutdown();
  86. break;
  87. }
  88. return(Status);
  89. }
  90. /******************************Public*Routine******************************\
  91. * GdiProcessSetup()
  92. *
  93. * This gets called from two places. Once at dll init time and another when
  94. * USER gets called back when the kernel initializes itself for this process.
  95. * It is only after the kernel is initialized that the GdiSharedHandleTable
  96. * is available but the other globals need to be setup right away.
  97. *
  98. * History:
  99. * 11-Sep-1995 -by- Eric Kutter [erick]
  100. * Wrote it.
  101. \**************************************************************************/
  102. NTSTATUS GdiProcessSetup()
  103. {
  104. NTSTATUS Status = STATUS_SUCCESS;
  105. PTEB pteb = NtCurrentTeb();
  106. // who ever calls this first needs to initialize the global variables.
  107. if (gbFirst)
  108. {
  109. //
  110. // Initialize the GL metafile support semaphore
  111. //
  112. Status = (NTSTATUS)INITIALIZECRITICALSECTION(&semGlLoad);
  113. if (!NT_SUCCESS(Status))
  114. {
  115. WARNING("InitializeCriticalSection failed\n");
  116. return(Status);
  117. }
  118. //
  119. // Initialize the local semaphore and reserve the Local Handle Table
  120. // for the process.
  121. //
  122. Status = (NTSTATUS)INITIALIZECRITICALSECTION(&semLocal);
  123. if (!NT_SUCCESS(Status))
  124. {
  125. WARNING("InitializeCriticalSection failed\n");
  126. return(Status);
  127. }
  128. //
  129. // Initialize critical sections for ICM
  130. //
  131. Status = (NTSTATUS)INITIALIZECRITICALSECTION(&semListIcmInfo);
  132. if (!NT_SUCCESS(Status))
  133. {
  134. WARNING("InitializeCriticalSection failed\n");
  135. return(Status);
  136. }
  137. Status = (NTSTATUS)INITIALIZECRITICALSECTION(&semColorTransformCache);
  138. if (!NT_SUCCESS(Status))
  139. {
  140. WARNING("InitializeCriticalSection failed\n");
  141. return(Status);
  142. }
  143. Status = (NTSTATUS)INITIALIZECRITICALSECTION(&semColorSpaceCache);
  144. if (!NT_SUCCESS(Status))
  145. {
  146. WARNING("InitializeCriticalSection failed\n");
  147. return(Status);
  148. }
  149. //
  150. // Initialize critical section for UMPD
  151. //
  152. Status = (NTSTATUS)INITIALIZECRITICALSECTION(&semUMPD);
  153. if (!NT_SUCCESS(Status))
  154. {
  155. WARNING("InitializeCriticalSection failed\n");
  156. return(Status);
  157. }
  158. pAFRTNodeList = NULL;
  159. guintAcp = GetACP();
  160. if(IS_ANY_DBCS_CODEPAGE(guintAcp))
  161. {
  162. // if the default code page is a DBCS code page then set guintACP to 1252
  163. // since we want to compute client wide widths for SBCS fonts for code page
  164. // 1252 in addition to DBCS fonts for the default code page
  165. vSetCheckDBCSTrailByte(guintAcp);
  166. guintDBCScp = guintAcp;
  167. guintAcp = 1252;
  168. }
  169. else
  170. {
  171. guintDBCScp = 0xFFFFFFFF; // assume this will never be a valid CP
  172. }
  173. #ifdef FE_SB
  174. fFontAssocStatus = NtGdiQueryFontAssocInfo(NULL);
  175. #endif
  176. // assign unique process ID
  177. gW32PID = (W32PID)((ULONG)((ULONG_PTR)pteb->ClientId.UniqueProcess & PID_BITS));
  178. #ifdef LANGPACK
  179. if(((PGDI_SHARED_MEMORY) NtCurrentPebShared()->GdiSharedHandleTable)->dwLpkShapingDLLs)
  180. {
  181. GdiInitializeLanguagePack(
  182. ((PGDI_SHARED_MEMORY)
  183. NtCurrentPebShared()->GdiSharedHandleTable)->dwLpkShapingDLLs);
  184. }
  185. #endif
  186. gbFirst = FALSE;
  187. //
  188. // ICM has not been initialized
  189. //
  190. ghICM = NULL;
  191. InitializeListHead(&ListIcmInfo);
  192. InitializeListHead(&ListCachedColorSpace);
  193. InitializeListHead(&ListCachedColorTransform);
  194. }
  195. // The pshared handle table needs to be set everytime this routine gets
  196. // called in case the PEB doesn't have it yet for the first.
  197. #if !defined(_GDIPLUS_)
  198. pGdiSharedMemory = (PGDI_SHARED_MEMORY) NtCurrentPebShared()->GdiSharedHandleTable;
  199. pGdiSharedHandleTable = pGdiSharedMemory->aentryHmgr;
  200. pGdiDevCaps = &pGdiSharedMemory->DevCaps;
  201. if (GetAppCompatFlags2(VER40) & GACF2_NOBATCHING)
  202. {
  203. GdiBatchLimit = 0;
  204. }
  205. else
  206. {
  207. GdiBatchLimit = (NtCurrentPebShared()->GdiDCAttributeList) & 0xff;
  208. }
  209. pGdiHandleCache = (PGDIHANDLECACHE)(&NtCurrentPebShared()->GdiHandleBuffer[0]);
  210. #else
  211. pGdiSharedMemory = gpGdiSharedMemory;
  212. pGdiSharedHandleTable = gpentHmgr;
  213. pGdiDevCaps = gpGdiDevCaps;
  214. //
  215. // Be sure to disable batching and handle caching.
  216. //
  217. GdiBatchLimit = 0;
  218. pGdiHandleCache = NULL;
  219. #endif
  220. // @@@ Add TrueType fonts
  221. #if defined(_GDIPLUS_)
  222. AddFontResourceW(L"arial.ttf");
  223. AddFontResourceW(L"cour.ttf");
  224. #endif // _GDIPLUS_
  225. return(Status);
  226. }
  227. /******************************Public*Routine******************************\
  228. * GdiProcessShutdown()
  229. *
  230. * Historically, gdi32.dll has allowed process termination to release the
  231. * user-mode resources. However, some apps may use LoadLibrary/FreeLibrary
  232. * to hook gdi32.dll, in which case the FreeLibrary will not free any of
  233. * the resources.
  234. *
  235. * As a system component, we should do a good job and cleanup after ourselves
  236. * instead of relying on process termination.
  237. *
  238. \**************************************************************************/
  239. VOID GdiProcessShutdown()
  240. {
  241. if (gbWOW64)
  242. {
  243. vUMPDWow64Shutdown();
  244. }
  245. DELETECRITICALSECTION(&semUMPD);
  246. DELETECRITICALSECTION(&semColorSpaceCache);
  247. DELETECRITICALSECTION(&semColorTransformCache);
  248. DELETECRITICALSECTION(&semListIcmInfo);
  249. DELETECRITICALSECTION(&semLocal);
  250. DELETECRITICALSECTION(&semGlLoad);
  251. }
  252. #ifdef LANGPACK
  253. VOID GdiInitializeLanguagePack(DWORD dwLpkShapingDLLs)
  254. {
  255. FPLPKINITIALIZE fpLpkInitialize;
  256. HANDLE hLpk = LoadLibraryW(L"LPK.DLL");
  257. if (hLpk != NULL)
  258. {
  259. FARPROC fpUser[4];
  260. fpLpkInitialize = (FPLPKINITIALIZE)
  261. GetProcAddress(hLpk,"LpkInitialize");
  262. fpLpkExtTextOut = (FPLPKEXTEXTOUT)
  263. GetProcAddress(hLpk,"LpkExtTextOut");
  264. fpLpkGetCharacterPlacement = (FPLPKGETCHARACTERPLACEMENT)
  265. GetProcAddress(hLpk,"LpkGetCharacterPlacement");
  266. fpLpkGetTextExtentExPoint = (FPLPKGETTEXTEXTENTEXPOINT)
  267. GetProcAddress(hLpk,"LpkGetTextExtentExPoint");
  268. fpLpkUseGDIWidthCache = (FPLPKUSEGDIWIDTHCACHE)
  269. GetProcAddress(hLpk,"LpkUseGDIWidthCache");
  270. fpUser[LPK_TABBED_TEXT_OUT] =
  271. GetProcAddress(hLpk,"LpkTabbedTextOut");
  272. fpUser[LPK_PSM_TEXT_OUT] =
  273. GetProcAddress(hLpk,"LpkPSMTextOut");
  274. fpUser[LPK_DRAW_TEXT_EX] =
  275. GetProcAddress(hLpk,"LpkDrawTextEx");
  276. fpUser[LPK_EDIT_CONTROL] =
  277. GetProcAddress(hLpk,"LpkEditControl");
  278. if(fpLpkInitialize &&
  279. fpLpkExtTextOut &&
  280. fpLpkGetCharacterPlacement &&
  281. fpLpkGetTextExtentExPoint &&
  282. fpLpkUseGDIWidthCache &&
  283. fpUser[LPK_TABBED_TEXT_OUT] &&
  284. fpUser[LPK_PSM_TEXT_OUT] &&
  285. fpUser[LPK_DRAW_TEXT_EX] &&
  286. fpUser[LPK_EDIT_CONTROL])
  287. {
  288. if((*fpLpkInitialize)(dwLpkShapingDLLs))
  289. {
  290. gbLpk = TRUE;
  291. InitializeLpkHooks(fpUser);
  292. }
  293. else
  294. {
  295. WARNING("gdi32: LPK initialization routine return FALSE\n");
  296. FreeLibrary(hLpk);
  297. }
  298. }
  299. else
  300. {
  301. WARNING("gdi32: one or more require LPK functions missing\n");
  302. FreeLibrary(hLpk);
  303. }
  304. }
  305. else
  306. {
  307. WARNING("gdi32: unable to load LPK\n");
  308. }
  309. }
  310. #endif