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

/******************************Module*Header*******************************\
* Module Name: dllinit.c *
* *
* Contains the GDI library initialization routines. *
* *
* Created: 07-Nov-1990 13:30:31 *
* Author: Eric Kutter [erick] *
* *
* Copyright (c) 1990-1999 Microsoft Corporation *
\**************************************************************************/
#include "precomp.h"
#pragma hdrstop
#include "glsup.h"
extern PVOID pAFRTNodeList;
extern VOID vSetCheckDBCSTrailByte(DWORD dwCodePage);
NTSTATUS GdiProcessSetup();
VOID GdiProcessShutdown();
#ifdef LANGPACK
#include "winuserp.h"
#endif
HBRUSH ghbrDCBrush;
HPEN ghbrDCPen;
BOOL gbWOW64 = FALSE;
/******************************Public*Routine******************************\
* GdiDllInitialize *
* *
* This is the init procedure for GDI.DLL, which is called each time a new *
* process links to it. *
* *
* History: *
* Thu 30-May-1991 18:08:00 -by- Charles Whitmer [chuckwh] *
* Added Local Handle Table initialization. *
\**************************************************************************/
#if defined(_GDIPLUS_)
//
// The following are globals kept in 'gre':
//
extern PGDI_SHARED_MEMORY gpGdiSharedMemory;
extern PENTRY gpentHmgr;
extern PDEVCAPS gpGdiDevCaps;
#endif
PGDI_SHARED_MEMORY pGdiSharedMemory = NULL;
PENTRY pGdiSharedHandleTable = NULL;
PDEVCAPS pGdiDevCaps = NULL;
W32PID gW32PID;
UINT guintAcp;
UINT guintDBCScp;
PGDIHANDLECACHE pGdiHandleCache;
BOOL gbFirst = TRUE;
#ifdef LANGPACK
BOOL gbLpk = FALSE;
FPLPKEXTEXTOUT fpLpkExtTextOut;
FPLPKGETCHARACTERPLACEMENT fpLpkGetCharacterPlacement;
FPLPKGETTEXTEXTENTEXPOINT fpLpkGetTextExtentExPoint;
FPLPKUSEGDIWIDTHCACHE fpLpkUseGDIWidthCache;
VOID GdiInitializeLanguagePack(DWORD);
#endif
NTSTATUS GdiDllInitialize(
PVOID pvDllHandle,
ULONG ulReason)
{
NTSTATUS Status = STATUS_SUCCESS;
INT i;
PTEB pteb = NtCurrentTeb();
switch (ulReason)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(pvDllHandle);
//
// force the kernel to initialize. This should be done last
// since ClientThreadSetup is going to get called before this returns.
//
if (NtGdiInit() != TRUE)
{
return(STATUS_NO_MEMORY);
}
Status = GdiProcessSetup();
ghbrDCBrush = GetStockObject (DC_BRUSH);
ghbrDCPen = GetStockObject (DC_PEN);
#ifdef BUILD_WOW6432
gbWOW64 = TRUE;
#endif
break;
case DLL_PROCESS_DETACH:
GdiProcessShutdown();
break;
}
return(Status);
}
/******************************Public*Routine******************************\
* GdiProcessSetup()
*
* This gets called from two places. Once at dll init time and another when
* USER gets called back when the kernel initializes itself for this process.
* It is only after the kernel is initialized that the GdiSharedHandleTable
* is available but the other globals need to be setup right away.
*
* History:
* 11-Sep-1995 -by- Eric Kutter [erick]
* Wrote it.
\**************************************************************************/
NTSTATUS GdiProcessSetup()
{
NTSTATUS Status = STATUS_SUCCESS;
PTEB pteb = NtCurrentTeb();
// who ever calls this first needs to initialize the global variables.
if (gbFirst)
{
//
// Initialize the GL metafile support semaphore
//
Status = (NTSTATUS)INITIALIZECRITICALSECTION(&semGlLoad);
if (!NT_SUCCESS(Status))
{
WARNING("InitializeCriticalSection failed\n");
return(Status);
}
//
// Initialize the local semaphore and reserve the Local Handle Table
// for the process.
//
Status = (NTSTATUS)INITIALIZECRITICALSECTION(&semLocal);
if (!NT_SUCCESS(Status))
{
WARNING("InitializeCriticalSection failed\n");
return(Status);
}
//
// Initialize critical sections for ICM
//
Status = (NTSTATUS)INITIALIZECRITICALSECTION(&semListIcmInfo);
if (!NT_SUCCESS(Status))
{
WARNING("InitializeCriticalSection failed\n");
return(Status);
}
Status = (NTSTATUS)INITIALIZECRITICALSECTION(&semColorTransformCache);
if (!NT_SUCCESS(Status))
{
WARNING("InitializeCriticalSection failed\n");
return(Status);
}
Status = (NTSTATUS)INITIALIZECRITICALSECTION(&semColorSpaceCache);
if (!NT_SUCCESS(Status))
{
WARNING("InitializeCriticalSection failed\n");
return(Status);
}
//
// Initialize critical section for UMPD
//
Status = (NTSTATUS)INITIALIZECRITICALSECTION(&semUMPD);
if (!NT_SUCCESS(Status))
{
WARNING("InitializeCriticalSection failed\n");
return(Status);
}
pAFRTNodeList = NULL;
guintAcp = GetACP();
if(IS_ANY_DBCS_CODEPAGE(guintAcp))
{
// if the default code page is a DBCS code page then set guintACP to 1252
// since we want to compute client wide widths for SBCS fonts for code page
// 1252 in addition to DBCS fonts for the default code page
vSetCheckDBCSTrailByte(guintAcp);
guintDBCScp = guintAcp;
guintAcp = 1252;
}
else
{
guintDBCScp = 0xFFFFFFFF; // assume this will never be a valid CP
}
#ifdef FE_SB
fFontAssocStatus = NtGdiQueryFontAssocInfo(NULL);
#endif
// assign unique process ID
gW32PID = (W32PID)((ULONG)((ULONG_PTR)pteb->ClientId.UniqueProcess & PID_BITS));
#ifdef LANGPACK
if(((PGDI_SHARED_MEMORY) NtCurrentPebShared()->GdiSharedHandleTable)->dwLpkShapingDLLs)
{
GdiInitializeLanguagePack(
((PGDI_SHARED_MEMORY)
NtCurrentPebShared()->GdiSharedHandleTable)->dwLpkShapingDLLs);
}
#endif
gbFirst = FALSE;
//
// ICM has not been initialized
//
ghICM = NULL;
InitializeListHead(&ListIcmInfo);
InitializeListHead(&ListCachedColorSpace);
InitializeListHead(&ListCachedColorTransform);
}
// The pshared handle table needs to be set everytime this routine gets
// called in case the PEB doesn't have it yet for the first.
#if !defined(_GDIPLUS_)
pGdiSharedMemory = (PGDI_SHARED_MEMORY) NtCurrentPebShared()->GdiSharedHandleTable;
pGdiSharedHandleTable = pGdiSharedMemory->aentryHmgr;
pGdiDevCaps = &pGdiSharedMemory->DevCaps;
if (GetAppCompatFlags2(VER40) & GACF2_NOBATCHING)
{
GdiBatchLimit = 0;
}
else
{
GdiBatchLimit = (NtCurrentPebShared()->GdiDCAttributeList) & 0xff;
}
pGdiHandleCache = (PGDIHANDLECACHE)(&NtCurrentPebShared()->GdiHandleBuffer[0]);
#else
pGdiSharedMemory = gpGdiSharedMemory;
pGdiSharedHandleTable = gpentHmgr;
pGdiDevCaps = gpGdiDevCaps;
//
// Be sure to disable batching and handle caching.
//
GdiBatchLimit = 0;
pGdiHandleCache = NULL;
#endif
// @@@ Add TrueType fonts
#if defined(_GDIPLUS_)
AddFontResourceW(L"arial.ttf");
AddFontResourceW(L"cour.ttf");
#endif // _GDIPLUS_
return(Status);
}
/******************************Public*Routine******************************\
* GdiProcessShutdown()
*
* Historically, gdi32.dll has allowed process termination to release the
* user-mode resources. However, some apps may use LoadLibrary/FreeLibrary
* to hook gdi32.dll, in which case the FreeLibrary will not free any of
* the resources.
*
* As a system component, we should do a good job and cleanup after ourselves
* instead of relying on process termination.
*
\**************************************************************************/
VOID GdiProcessShutdown()
{
if (gbWOW64)
{
vUMPDWow64Shutdown();
}
DELETECRITICALSECTION(&semUMPD);
DELETECRITICALSECTION(&semColorSpaceCache);
DELETECRITICALSECTION(&semColorTransformCache);
DELETECRITICALSECTION(&semListIcmInfo);
DELETECRITICALSECTION(&semLocal);
DELETECRITICALSECTION(&semGlLoad);
}
#ifdef LANGPACK
VOID GdiInitializeLanguagePack(DWORD dwLpkShapingDLLs)
{
FPLPKINITIALIZE fpLpkInitialize;
HANDLE hLpk = LoadLibraryW(L"LPK.DLL");
if (hLpk != NULL)
{
FARPROC fpUser[4];
fpLpkInitialize = (FPLPKINITIALIZE)
GetProcAddress(hLpk,"LpkInitialize");
fpLpkExtTextOut = (FPLPKEXTEXTOUT)
GetProcAddress(hLpk,"LpkExtTextOut");
fpLpkGetCharacterPlacement = (FPLPKGETCHARACTERPLACEMENT)
GetProcAddress(hLpk,"LpkGetCharacterPlacement");
fpLpkGetTextExtentExPoint = (FPLPKGETTEXTEXTENTEXPOINT)
GetProcAddress(hLpk,"LpkGetTextExtentExPoint");
fpLpkUseGDIWidthCache = (FPLPKUSEGDIWIDTHCACHE)
GetProcAddress(hLpk,"LpkUseGDIWidthCache");
fpUser[LPK_TABBED_TEXT_OUT] =
GetProcAddress(hLpk,"LpkTabbedTextOut");
fpUser[LPK_PSM_TEXT_OUT] =
GetProcAddress(hLpk,"LpkPSMTextOut");
fpUser[LPK_DRAW_TEXT_EX] =
GetProcAddress(hLpk,"LpkDrawTextEx");
fpUser[LPK_EDIT_CONTROL] =
GetProcAddress(hLpk,"LpkEditControl");
if(fpLpkInitialize &&
fpLpkExtTextOut &&
fpLpkGetCharacterPlacement &&
fpLpkGetTextExtentExPoint &&
fpLpkUseGDIWidthCache &&
fpUser[LPK_TABBED_TEXT_OUT] &&
fpUser[LPK_PSM_TEXT_OUT] &&
fpUser[LPK_DRAW_TEXT_EX] &&
fpUser[LPK_EDIT_CONTROL])
{
if((*fpLpkInitialize)(dwLpkShapingDLLs))
{
gbLpk = TRUE;
InitializeLpkHooks(fpUser);
}
else
{
WARNING("gdi32: LPK initialization routine return FALSE\n");
FreeLibrary(hLpk);
}
}
else
{
WARNING("gdi32: one or more require LPK functions missing\n");
FreeLibrary(hLpk);
}
}
else
{
WARNING("gdi32: unable to load LPK\n");
}
}
#endif