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.
961 lines
26 KiB
961 lines
26 KiB
/******************************Module*Header*******************************\
|
|
* Module Name: init.cxx
|
|
*
|
|
* Engine initialization
|
|
*
|
|
* Copyright (c) 1990-1999 Microsoft Corporation
|
|
\**************************************************************************/
|
|
|
|
#include "precomp.hxx"
|
|
#include "verifier.hxx"
|
|
#include "winsta.h"
|
|
|
|
extern "C" USHORT gProtocolType;
|
|
|
|
|
|
BOOLEAN gIsTerminalServer;
|
|
|
|
extern BOOL G_fConsole;
|
|
extern BOOL G_fDoubleDpi;
|
|
|
|
|
|
extern "C" BOOL bInitPALOBJ(); // palobj.cxx
|
|
extern "C" VOID vInitXLATE(); // ylateobj.cxx
|
|
extern "C" BOOL bInitBMOBJ(); // surfeng.cxx
|
|
extern "C" BOOL InitializeScripts(); // fontsup.cxx
|
|
extern "C" BOOL bInitICM(); // icmapi.cxx
|
|
extern "C" BOOL bInitFontTables(); // pftobj.cxx
|
|
extern "C" BOOL bInitStockFonts(VOID); // stockfnt.cxx
|
|
extern "C" VOID vInitFontSubTable(); // fontsub.cxx
|
|
extern "C" BOOL bInitBRUSHOBJ(); // brushobj.cxx
|
|
extern "C" VOID vInitMapper(); // fontmap.cxx
|
|
|
|
extern USHORT GetLanguageID();
|
|
|
|
|
|
// Prototypes from font drivers.
|
|
|
|
extern "C" BOOL BmfdEnableDriver(ULONG iEngineVersion,ULONG cj, PDRVENABLEDATA pded);
|
|
|
|
extern "C" BOOL ttfdEnableDriver(ULONG iEngineVersion,ULONG cj, PDRVENABLEDATA pded);
|
|
|
|
extern "C" BOOL vtfdEnableDriver(ULONG iEngineVersion,ULONG cj, PDRVENABLEDATA pded);
|
|
|
|
extern "C" BOOL atmfdEnableDriver(ULONG iEngineVersion,ULONG cj, PDRVENABLEDATA pded);
|
|
|
|
extern "C" NTSTATUS FontDriverQueryRoutine(
|
|
IN PWSTR ValueName,
|
|
IN ULONG ValueType,
|
|
IN PVOID ValueData,
|
|
IN ULONG ValueLength,
|
|
IN PVOID Context,
|
|
IN PVOID EntryContext
|
|
);
|
|
|
|
extern "C" BOOL bRegisterFontServer(VOID);
|
|
extern "C" BOOL bUserModeFontDrivers(VOID);
|
|
|
|
#ifdef LANGPACK
|
|
extern "C" NTSTATUS LpkShapeQueryRoutine(
|
|
IN PWSTR ValueName,
|
|
IN ULONG ValueType,
|
|
IN PVOID ValueData,
|
|
IN ULONG ValueLength,
|
|
IN PVOID Context,
|
|
IN PVOID EntryContext
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// Prototypes from halftone
|
|
//
|
|
|
|
extern "C" BOOL PASCAL EnableHalftone(VOID);
|
|
extern "C" VOID PASCAL DisableHalftone(VOID);
|
|
|
|
//
|
|
// Hydra prototypes
|
|
//
|
|
extern "C" BOOL MultiUserGreCleanupInit();
|
|
extern "C" BOOL GreEngLoadModuleTrackInit();
|
|
|
|
//
|
|
// Functions are located in INIT segment
|
|
//
|
|
#pragma alloc_text(INIT, InitializeGre)
|
|
#pragma alloc_text(INIT, FontDriverQueryRoutine)
|
|
#ifdef LANGPACK
|
|
#pragma alloc_text(INIT, LpkShapeQueryRoutine)
|
|
#endif
|
|
#pragma alloc_text(INIT, bLoadProcessHandleQuota)
|
|
#pragma alloc_text(INIT, bRegisterFontServer)
|
|
|
|
/**************************************************************************\
|
|
*
|
|
\**************************************************************************/
|
|
|
|
#if defined(i386) && !defined(_GDIPLUS_)
|
|
extern "C" PVOID GDIpLockPrefixTable;
|
|
extern "C" PVOID __safe_se_handler_table[]; /* base of safe handler entry table */
|
|
extern "C" BYTE __safe_se_handler_count; /* absolute symbol whose address is
|
|
the count of table entries */
|
|
|
|
//
|
|
// Specify address of kernel32 lock prefixes
|
|
//
|
|
extern "C" IMAGE_LOAD_CONFIG_DIRECTORY _load_config_used = {
|
|
sizeof(_load_config_used), // Reserved
|
|
0, // Reserved
|
|
0, // Reserved
|
|
0, // Reserved
|
|
0, // GlobalFlagsClear
|
|
0, // GlobalFlagsSet
|
|
0, // CriticalSectionTimeout (milliseconds)
|
|
0, // DeCommitFreeBlockThreshold
|
|
0, // DeCommitTotalFreeThreshold
|
|
(ULONG) &GDIpLockPrefixTable, // LockPrefixTable
|
|
0, 0, 0, 0, 0, 0, 0, // Reserved
|
|
0, // & security_cookie
|
|
(ULONG)__safe_se_handler_table,
|
|
(ULONG)&__safe_se_handler_count
|
|
};
|
|
#endif
|
|
|
|
LONG gProcessHandleQuota;
|
|
|
|
#if defined (_X86_)
|
|
BOOL gbMMXProcessor = FALSE;
|
|
#endif
|
|
|
|
extern "C" VOID vConvertCodePageToCharSet(WORD src, DWORD *pfsRet, BYTE *pjRet);
|
|
|
|
VOID vGetJpn98FixPitch();
|
|
|
|
/******************************Public*Routine******************************\
|
|
* bEnableFontDriver
|
|
*
|
|
* Enables an internal, statically-linked font driver.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
BOOL bEnableFontDriver(PFN pfnFdEnable, ULONG fl)
|
|
{
|
|
//
|
|
// Load driver.
|
|
//
|
|
|
|
PLDEV pldev;
|
|
|
|
pldev = ldevLoadInternal(pfnFdEnable, LDEV_FONT);
|
|
|
|
//
|
|
// Validate the new LDEV
|
|
//
|
|
|
|
if (pldev)
|
|
{
|
|
//
|
|
// Create the PDEV for this (the PDEV won't have anything in it
|
|
// except the dispatch table.
|
|
//
|
|
|
|
PDEVOBJ po(pldev,
|
|
NULL, // PDEVMODEW pdriv,
|
|
NULL, // PWSZ pwszLogAddr,
|
|
NULL, // PWSZ pwszDataFile,
|
|
NULL, // PWSZ pwszDeviceName,
|
|
NULL, // HANDLE hSpool,
|
|
NULL // PREMOTETYPEONENODE pRemoteTypeOne,
|
|
);
|
|
|
|
if (po.bValid())
|
|
{
|
|
//
|
|
// Was it the TrueType driver? We need to keep a global handle to
|
|
// it to support the Win 3.1 TrueType-specific calls.
|
|
//
|
|
|
|
if (fl & FNT_TT_DRV )
|
|
{
|
|
gppdevTrueType = (PPDEV) po.hdev();
|
|
}
|
|
|
|
if (fl & FNT_OT_DRV)
|
|
{
|
|
gppdevATMFD = (PPDEV) po.hdev();
|
|
gufiLocalType1Rasterizer.CheckSum = TYPE1_RASTERIZER;
|
|
gufiLocalType1Rasterizer.Index = 0x1;
|
|
}
|
|
|
|
FntCacheHDEV((PPDEV) po.hdev(), fl);
|
|
|
|
po.ppdev->fl |= PDEV_FONTDRIVER;
|
|
|
|
return(TRUE);
|
|
}
|
|
}
|
|
|
|
WARNING("bLoadFontDriver failed\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* bDoubleDpi
|
|
*
|
|
* Read the registry to determine if we should implement our double-the-DPI
|
|
* hack. This functionality was intended as a simple mechanism for the
|
|
* release of Windows 2000 for applications developers to test their
|
|
* applications for conformance with upcoming high-DPI (200 DPI) displays.
|
|
* The problem is that currently only 75 to 100 DPI displays are available,
|
|
* but we know the high DPI displays are coming soon.
|
|
*
|
|
* So we implement this little hack that doubles the effective resolution
|
|
* of the monitor, and down-samples to the display. So if your monitor does
|
|
* 1024x768, we make the system think it's really 2048x1536.
|
|
*
|
|
* Hopefully, this hacky functionality can be removed for the release after
|
|
* Windows 2000, as it's fairly unusable for anything other than simple
|
|
* test purposes.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
BOOL bDoubleDpi(BOOL fConsole)
|
|
{
|
|
HANDLE hkRegistry;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
UNICODE_STRING UnicodeString;
|
|
NTSTATUS status;
|
|
DWORD Length;
|
|
PKEY_VALUE_FULL_INFORMATION Information;
|
|
DWORD dwDoubleDpi;
|
|
|
|
dwDoubleDpi = 0;
|
|
|
|
///For this to success, it must be console session(session 0)
|
|
///Connected locally to physical console.
|
|
|
|
if (fConsole && (gProtocolType == PROTOCOL_CONSOLE))
|
|
{
|
|
RtlInitUnicodeString(&UnicodeString,
|
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\"
|
|
L"Control\\GraphicsDrivers");
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
&UnicodeString,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL);
|
|
|
|
status = ZwOpenKey(&hkRegistry, GENERIC_READ, &ObjectAttributes);
|
|
|
|
if (NT_SUCCESS(status))
|
|
{
|
|
RtlInitUnicodeString(&UnicodeString, L"DoubleDpi");
|
|
|
|
Length = sizeof(KEY_VALUE_FULL_INFORMATION) + sizeof(L"DoubleDpi") +
|
|
sizeof(DWORD);
|
|
|
|
Information = (PKEY_VALUE_FULL_INFORMATION) PALLOCMEM(Length, ' ddG');
|
|
|
|
if (Information)
|
|
{
|
|
status = ZwQueryValueKey(hkRegistry,
|
|
&UnicodeString,
|
|
KeyValueFullInformation,
|
|
Information,
|
|
Length,
|
|
&Length);
|
|
|
|
if (NT_SUCCESS(status))
|
|
{
|
|
dwDoubleDpi = *(LPDWORD) ((((PUCHAR)Information) +
|
|
Information->DataOffset));
|
|
}
|
|
|
|
VFREEMEM(Information);
|
|
}
|
|
|
|
ZwCloseKey(hkRegistry);
|
|
}
|
|
}
|
|
|
|
return(dwDoubleDpi == 1);
|
|
}
|
|
|
|
void vCheckTimeZoneBias()
|
|
{
|
|
HANDLE hkRegistry;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
UNICODE_STRING UnicodeString;
|
|
NTSTATUS status;
|
|
DWORD Length;
|
|
PKEY_VALUE_FULL_INFORMATION Information;
|
|
|
|
RtlInitUnicodeString(&UnicodeString,
|
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\"
|
|
L"Control\\TimeZoneInformation");
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
&UnicodeString,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL);
|
|
|
|
status = ZwOpenKey(&hkRegistry, GENERIC_READ, &ObjectAttributes);
|
|
|
|
if (NT_SUCCESS(status))
|
|
{
|
|
RtlInitUnicodeString(&UnicodeString, L"ActiveTimeBias");
|
|
|
|
Length = sizeof(KEY_VALUE_FULL_INFORMATION) + sizeof(L"ActiveTimeBias") +
|
|
sizeof(DWORD);
|
|
|
|
Information = (PKEY_VALUE_FULL_INFORMATION) PALLOCMEM(Length, 'pmtG');
|
|
|
|
if (Information)
|
|
{
|
|
status = ZwQueryValueKey(hkRegistry,
|
|
&UnicodeString,
|
|
KeyValueFullInformation,
|
|
Information,
|
|
Length,
|
|
&Length);
|
|
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
gbGUISetup = TRUE;
|
|
}
|
|
|
|
VFREEMEM(Information);
|
|
}
|
|
|
|
ZwCloseKey(hkRegistry);
|
|
}
|
|
else
|
|
{
|
|
gbGUISetup = TRUE;
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* InitializeGreCSRSS
|
|
*
|
|
* Initialize the client-server subsystem portion of GDI.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
extern "C" BOOL InitializeGreCSRSS()
|
|
{
|
|
|
|
// Init DirectX graphics driver
|
|
|
|
if (!NT_SUCCESS(DxDdStartupDxGraphics(0,NULL,0,NULL,NULL,gpepCSRSS)))
|
|
{
|
|
WARNING("GRE: could not enable DirectDraw\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
|
|
USHORT AnsiCodePage, OemCodePage;
|
|
|
|
// Init the font drivers
|
|
|
|
gppdevTrueType = NULL;
|
|
gppdevATMFD = NULL;
|
|
gcTrueTypeFonts = 0;
|
|
gulFontInformation = 0;
|
|
gusLanguageID = GetLanguageID();
|
|
|
|
RtlGetDefaultCodePage(&AnsiCodePage,&OemCodePage);
|
|
|
|
vConvertCodePageToCharSet(
|
|
AnsiCodePage,
|
|
&gfsCurSignature,
|
|
&gjCurCharset);
|
|
|
|
gbDBCSCodePage = (IS_ANY_DBCS_CODEPAGE(AnsiCodePage)) ? TRUE : FALSE;
|
|
|
|
InitFNTCache();
|
|
|
|
vCheckTimeZoneBias();
|
|
|
|
//
|
|
// NOTE: we are disabling ATM and vector font drivers for _GDIPLUS_ work
|
|
//
|
|
|
|
#ifndef _GDIPLUS_
|
|
|
|
QueryTable[0].QueryRoutine = FontDriverQueryRoutine;
|
|
QueryTable[0].Flags = 0; // RTL_QUERY_REGISTRY_REQUIRED;
|
|
QueryTable[0].Name = (PWSTR)NULL;
|
|
QueryTable[0].EntryContext = NULL;
|
|
QueryTable[0].DefaultType = REG_NONE;
|
|
QueryTable[0].DefaultData = NULL;
|
|
QueryTable[0].DefaultLength = 0;
|
|
|
|
QueryTable[1].QueryRoutine = NULL;
|
|
QueryTable[1].Flags = 0;
|
|
QueryTable[1].Name = NULL;
|
|
|
|
// Enumerate and initialize all the font drivers.
|
|
|
|
RtlQueryRegistryValues(RTL_REGISTRY_WINDOWS_NT | RTL_REGISTRY_OPTIONAL,
|
|
(PWSTR)L"Font Drivers",
|
|
&QueryTable[0],
|
|
NULL,
|
|
NULL);
|
|
|
|
if (!bEnableFontDriver((PFN) atmfdEnableDriver, FNT_OT_DRV))
|
|
{
|
|
WARNING("GDISRV.DLL could not enable ATMFD stub\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
// also creates ghsemVTFD semaphore
|
|
if (!bEnableFontDriver((PFN) vtfdEnableDriver, FNT_VT_DRV))
|
|
{
|
|
WARNING("GDISRV.DLL could not enable VTFD\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
#endif // !_GDIPLUS_
|
|
|
|
// We need to get the fix pitch registry first
|
|
// This is only JPN platform
|
|
vGetJpn98FixPitch();
|
|
|
|
// also creates ghsemBMFD semaphore
|
|
if (!bEnableFontDriver((PFN) BmfdEnableDriver, FNT_BMP_DRV))
|
|
{
|
|
WARNING("GDISRV failed to enable BMFD\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
if (!bEnableFontDriver((PFN) ttfdEnableDriver, FNT_TT_DRV))
|
|
{
|
|
WARNING("GDISRV.DLL could not enable TTFD\n");
|
|
return(FALSE);
|
|
}
|
|
//
|
|
// Init global public PFT
|
|
//
|
|
|
|
if (!bInitFontTables())
|
|
{
|
|
WARNING("Could not start the global font tables\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
// Initialize LFONT
|
|
//
|
|
|
|
TRACE_FONT(("GRE: Initializing Stock Fonts\n"));
|
|
|
|
if (!bInitStockFonts())
|
|
{
|
|
WARNING("Stock font initialization failed\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
TRACE_FONT(("GRE: Initializing Font Substitution\n"));
|
|
|
|
// Init font substitution table
|
|
|
|
vInitFontSubTable();
|
|
|
|
// Load default face names for the mapper from the registry
|
|
|
|
vInitMapper();
|
|
|
|
if (!bInitializeEUDC())
|
|
{
|
|
WARNING("EUDC initialization failed\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* InitializeGre
|
|
*
|
|
* Initialize the Graphics Engine. This call is made once by USER.
|
|
*
|
|
* History:
|
|
* Thu 29-Oct-1992 -by- Patrick Haluptzok [patrickh]
|
|
* Remove wrappers, unnecesary semaphore use, bogus variables, cleanup.
|
|
*
|
|
* 10-Aug-1990 -by- Donald Sidoroff [donalds]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
LONG CountInit = 1;
|
|
|
|
extern "C" BOOL gbRemoteSession; // as in ntuser\kernel\globals.c
|
|
|
|
extern "C" BOOLEAN InitializeGre(
|
|
VOID)
|
|
{
|
|
#ifdef LANGPACK
|
|
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
|
|
#endif
|
|
|
|
G_fConsole = (BOOL)!gbRemoteSession;
|
|
|
|
G_fDoubleDpi = bDoubleDpi(G_fConsole);
|
|
|
|
//
|
|
// We only want to initialize once. We can detect transition to 0.
|
|
//
|
|
|
|
if (InterlockedDecrement(&CountInit) != 0)
|
|
{
|
|
return(TRUE);
|
|
}
|
|
|
|
#if defined(_GDIPLUS_)
|
|
gIsTerminalServer = FALSE;
|
|
#else
|
|
gIsTerminalServer = !!(SharedUserData->SuiteMask & (1 << TerminalServer));
|
|
#endif
|
|
|
|
if (!MultiUserGreCleanupInit())
|
|
{
|
|
WARNING("InitializeGre: failed to initialize cleanup support\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
// Initialize the GRE DriverVerifier support (see verifier.cxx).
|
|
//
|
|
|
|
VerifierInitialization();
|
|
|
|
//
|
|
// Note that GreEngLoadModuleTrackInit must be called AFTER gIsTerminalServer is set
|
|
// (though it's called regardless of its value), so that the memory allocations will
|
|
// be placed on the hydra tracking list if necessary.
|
|
|
|
if (!GreEngLoadModuleTrackInit())
|
|
{
|
|
WARNING("InitializeGre: failed to initialize EngLoadModule tracking\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
#if TRACE_SURFACE_ALLOCS
|
|
//
|
|
// Initialize SURFACE tracing if requested in registry
|
|
//
|
|
|
|
TRACED_SURFACE::vInit();
|
|
#endif
|
|
|
|
//
|
|
// load registry process quota information
|
|
//
|
|
|
|
|
|
bLoadProcessHandleQuota();
|
|
|
|
//
|
|
// Initialize lots of random stuff including the handle manager.
|
|
//
|
|
|
|
if (!HmgCreate())
|
|
{
|
|
WARNING("HMGR failed to initialize\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
// Initialize REGION time stamp
|
|
//
|
|
|
|
REGION::ulUniqueREGION = 1;
|
|
|
|
#if DBG_CORE
|
|
if ((ghsemDEBUG = GreCreateSemaphore())==NULL)
|
|
{
|
|
WARNING("win32k: unable to initialize ghsemDEBUG\n");
|
|
return(FALSE);
|
|
}
|
|
#endif
|
|
|
|
#if defined(USE_NINEGRID_STATIC)
|
|
if ((gNineGridSem = GreCreateSemaphore())==NULL)
|
|
{
|
|
WARNING("Win32k: unable to initialize gNineGridSem\n");
|
|
return(FALSE);
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// Create the LDEV\PDEV semaphore.
|
|
//
|
|
|
|
if ((ghsemDriverMgmt = GreCreateSemaphore()) == NULL)
|
|
{
|
|
WARNING("win32k: unable to create driver mgmt semaphore\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
// Init the font drivers
|
|
//
|
|
|
|
if (!bInitPathAlloc())
|
|
{
|
|
WARNING("Pathalloc Initialization failed\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
// Create the RFONT list semaphore.
|
|
|
|
ghsemRFONTList = GreCreateSemaphore();
|
|
if (ghsemRFONTList == NULL)
|
|
{
|
|
WARNING("win32k: unable to create ghsemRFONTList\n");
|
|
return FALSE;
|
|
}
|
|
|
|
ghsemCLISERV = GreCreateSemaphore();
|
|
if (ghsemCLISERV == NULL)
|
|
{
|
|
WARNING("win32k: unabel to create ghsemCLISERV\n");
|
|
return( FALSE );
|
|
}
|
|
|
|
if ((ghsemAtmfdInit = GreCreateSemaphore()) == NULL)
|
|
{
|
|
WARNING("win32k: unable to create driver mgmt semaphore\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
// Create the WNDOBJ semaphore.
|
|
|
|
ghsemWndobj = GreCreateSemaphore();
|
|
if (ghsemWndobj == NULL)
|
|
{
|
|
WARNING("win32k: unable to create ghsemWndobj\n");
|
|
return FALSE;
|
|
}
|
|
|
|
// Create the RFONT list semaphore.
|
|
|
|
ghsemGdiSpool = GreCreateSemaphore();
|
|
if(ghsemGdiSpool == NULL)
|
|
{
|
|
WARNING("win32k: unable to create ghsemGdiSpool\n");
|
|
return FALSE;
|
|
}
|
|
|
|
// Create the mode change semaphore.
|
|
|
|
if ((ghsemShareDevLock = GreCreateSemaphore()) == NULL)
|
|
{
|
|
WARNING("win32k: unable to create mode change semaphore\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
// Create the association list mutex.
|
|
|
|
if ((gAssociationListMutex = GreCreateFastMutex()) == NULL)
|
|
{
|
|
WARNING("win32k: unable to create association list mutex\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
// Create a null region as the default region
|
|
|
|
|
|
hrgnDefault = GreCreateRectRgn(0, 0, 0, 0);
|
|
if (hrgnDefault == (HRGN) 0)
|
|
{
|
|
WARNING("hrgnDefault failed to initialize\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
{
|
|
RGNOBJAPI ro(hrgnDefault,TRUE);
|
|
if(!ro.bValid()) {
|
|
WARNING("invalid hrgnDefault\n");
|
|
return FALSE;
|
|
}
|
|
|
|
prgnDefault = ro.prgnGet();
|
|
}
|
|
|
|
// Create a monochrome 1x1 bitmap as the default bitmap
|
|
|
|
|
|
if (!bInitPALOBJ())
|
|
{
|
|
WARNING("bInitPALOBJ failed !\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
vInitXLATE();
|
|
|
|
if (!bInitBMOBJ())
|
|
{
|
|
WARNING("bInitBMOBJ failed !\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
// initialize the script names
|
|
|
|
if(!InitializeScripts())
|
|
{
|
|
WARNING("Could not initialize the script names\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
// Start up the brush component
|
|
//
|
|
|
|
if (!bInitBRUSHOBJ())
|
|
{
|
|
WARNING("Could not init the brushes\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
if (!bInitICM())
|
|
{
|
|
WARNING("Could not init ICM\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
// Enable statically linked halftone library
|
|
//
|
|
|
|
if (!EnableHalftone())
|
|
{
|
|
WARNING("GRE: could not enable halftone\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
// determine if processor supports MMX
|
|
//
|
|
|
|
#if defined (_X86_)
|
|
|
|
gbMMXProcessor = bIsMMXProcessor();
|
|
|
|
#endif
|
|
|
|
TRACE_INIT(("GRE: Completed Initialization\n"));
|
|
|
|
#ifdef _GDIPLUS_
|
|
|
|
gpepCSRSS = PsGetCurrentProcess();
|
|
InitializeGreCSRSS();
|
|
|
|
#endif
|
|
|
|
#ifdef LANGPACK
|
|
QueryTable[0].QueryRoutine = LpkShapeQueryRoutine;
|
|
QueryTable[0].Flags = 0;
|
|
QueryTable[0].Name = (PWSTR)NULL;
|
|
QueryTable[0].EntryContext = NULL;
|
|
QueryTable[0].DefaultType = REG_NONE;
|
|
QueryTable[0].DefaultData = NULL;
|
|
QueryTable[0].DefaultLength = 0;
|
|
|
|
QueryTable[1].QueryRoutine = NULL;
|
|
QueryTable[1].Flags = 0;
|
|
QueryTable[1].Name = NULL;
|
|
|
|
gpGdiSharedMemory->dwLpkShapingDLLs = 0;
|
|
|
|
RtlQueryRegistryValues(RTL_REGISTRY_WINDOWS_NT | RTL_REGISTRY_OPTIONAL,
|
|
(PWSTR)L"LanguagePack",
|
|
&QueryTable[0],
|
|
NULL,
|
|
NULL);
|
|
#endif
|
|
|
|
gpGdiSharedMemory->timeStamp = 1;
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
extern "C" BOOL TellGdiToGetReady()
|
|
{
|
|
ASSERTGDI(gpepCSRSS, "gpepCSRSS\n");
|
|
|
|
return InitializeGreCSRSS();
|
|
}
|
|
|
|
#ifdef LANGPACK
|
|
extern "C"
|
|
NTSTATUS
|
|
LpkShapeQueryRoutine
|
|
(
|
|
IN PWSTR ValueName,
|
|
IN ULONG ValueType,
|
|
IN PVOID ValueData,
|
|
IN ULONG ValueLength,
|
|
IN PVOID Context,
|
|
IN PVOID EntryContext
|
|
)
|
|
{
|
|
if( ValueType == REG_DWORD ) {
|
|
gpGdiSharedMemory->dwLpkShapingDLLs |= (1<<(*((DWORD*)ValueData)));
|
|
}
|
|
|
|
return( STATUS_SUCCESS );
|
|
}
|
|
#endif
|
|
|
|
|
|
extern "C"
|
|
NTSTATUS
|
|
FontDriverQueryRoutine
|
|
(
|
|
IN PWSTR ValueName,
|
|
IN ULONG ValueType,
|
|
IN PVOID ValueData,
|
|
IN ULONG ValueLength,
|
|
IN PVOID Context,
|
|
IN PVOID EntryContext
|
|
)
|
|
{
|
|
PLDEV pldev;
|
|
WCHAR FontDriverPath[MAX_PATH+1];
|
|
|
|
wcscpy(FontDriverPath, L"\\SystemRoot\\System32\\");
|
|
|
|
// guard against some malicious person putting a huge value in here to hose us
|
|
|
|
if((ValueLength / sizeof(WCHAR) <
|
|
MAX_PATH - (sizeof(L"\\SystemRoot\\System32\\") / sizeof(WCHAR))) &&
|
|
(ValueType == REG_SZ))
|
|
{
|
|
wcscat(FontDriverPath, (PWSTR) ValueData);
|
|
|
|
if (_wcsicmp(L"\\SystemRoot\\System32\\atmdrvr.dll", FontDriverPath) == 0 ||
|
|
_wcsicmp(L"\\SystemRoot\\System32\\atmfd.dll", FontDriverPath) == 0)
|
|
{
|
|
//skip old atm font driver (4.0) or (5.0) because it is loaded through stub
|
|
//WARNING("FontDriverQueryRoutine: system has a old version of ATM driver\n");
|
|
}
|
|
else
|
|
{
|
|
pldev = ldevLoadDriver(FontDriverPath, LDEV_FONT);
|
|
|
|
if (pldev)
|
|
{
|
|
// Create the PDEV for this (the PDEV won't have anything in it
|
|
// except the dispatch table.
|
|
|
|
|
|
PDEVOBJ po(pldev,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
|
|
if (po.bValid())
|
|
{
|
|
po.ppdev->fl |= PDEV_FONTDRIVER;
|
|
|
|
FntCacheHDEV((PPDEV) po.hdev(), FNT_DUMMY_DRV);
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
else
|
|
{
|
|
WARNING("win32k.sys could not initialize installable driver\n");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WARNING("win32k.sys could not initialize installable driver\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
return( STATUS_SUCCESS );
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* Read process handle quota
|
|
*
|
|
* Arguments:
|
|
*
|
|
* None
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status
|
|
*
|
|
* History:
|
|
*
|
|
* 3-May-1996 -by- Mark Enstrom [marke]
|
|
*
|
|
\**************************************************************************/
|
|
|
|
BOOL
|
|
bLoadProcessHandleQuota()
|
|
{
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
UNICODE_STRING UnicodeString;
|
|
NTSTATUS NtStatus;
|
|
HANDLE hKey;
|
|
BOOL bRet = FALSE;
|
|
|
|
RtlInitUnicodeString(&UnicodeString,
|
|
L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows");
|
|
|
|
//
|
|
// Open a registry key
|
|
//
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
&UnicodeString,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL);
|
|
|
|
NtStatus = ZwOpenKey(&hKey,
|
|
KEY_ALL_ACCESS,
|
|
&ObjectAttributes);
|
|
|
|
if (NT_SUCCESS(NtStatus))
|
|
{
|
|
UNICODE_STRING UnicodeValue;
|
|
ULONG ReturnedLength;
|
|
UCHAR DataArray[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(DWORD)];
|
|
PKEY_VALUE_PARTIAL_INFORMATION pKeyInfo = (PKEY_VALUE_PARTIAL_INFORMATION)DataArray;
|
|
|
|
RtlInitUnicodeString(&UnicodeValue,
|
|
L"GDIProcessHandleQuota");
|
|
|
|
NtStatus = ZwQueryValueKey(hKey,
|
|
&UnicodeValue,
|
|
KeyValuePartialInformation,
|
|
pKeyInfo,
|
|
sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(DWORD),
|
|
&ReturnedLength);
|
|
|
|
if (NT_SUCCESS(NtStatus))
|
|
{
|
|
gProcessHandleQuota = *(PLONG)(&pKeyInfo->Data[0]);
|
|
} else {
|
|
gProcessHandleQuota = DEFAULT_HANDLE_QUOTA;
|
|
}
|
|
|
|
bRet = TRUE;
|
|
ZwCloseKey(hKey);
|
|
}
|
|
|
|
return(bRet);
|
|
}
|