mirror of https://github.com/lianthony/NT4.0
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.
659 lines
15 KiB
659 lines
15 KiB
/******************************Module*Header*******************************\
|
|
* Module Name: init.cxx
|
|
*
|
|
* Engine initialization
|
|
*
|
|
* Copyright (c) 1990-1995 Microsoft Corporation
|
|
\**************************************************************************/
|
|
|
|
#include "precomp.hxx"
|
|
|
|
BOOL bInitFontCache();
|
|
BOOL bInitPALOBJ();
|
|
VOID vInitXLATE();
|
|
VOID vInitDefaultDC();
|
|
BOOL bInitBMOBJ();
|
|
BOOL bInitBRUSHOBJ();
|
|
VOID vInitMapper();
|
|
BOOL bInitFontTables();
|
|
BOOL InitializeScripts();
|
|
|
|
#if defined(_MIPS_)
|
|
extern "C"
|
|
{
|
|
VOID vInitMipsMem();
|
|
|
|
ULONG Gdip64bitDisabled;
|
|
PCOPY_MEM_FN CopyMemFn;
|
|
PFILL_MEM_FN FillMemFn;
|
|
PFILL_MEM_ULONG_FN FillMemUlongFn;
|
|
}
|
|
#endif
|
|
|
|
LONG gProcessHandleQuota = INITIAL_HANDLE_QUOTA;
|
|
PPID_HANDLE_TRACK gpPidHandleList = NULL;
|
|
EFLOATEXT gefDefaultHeightInInches;
|
|
extern USHORT GetLanguageID();
|
|
|
|
// The global font enumeration filter type. It can be set to:
|
|
//
|
|
// FE_FILTER_NONE normal operation, no extra filtering applied
|
|
// FE_FILTER_TRUETYPE only TrueType fonts are enumerated
|
|
|
|
extern ULONG gulFontInformation;
|
|
|
|
USHORT gusLanguageID;
|
|
BOOL gbDBCSCodePage;
|
|
|
|
// 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" NTSTATUS FontDriverQueryRoutine
|
|
(
|
|
IN PWSTR ValueName,
|
|
IN ULONG ValueType,
|
|
IN PVOID ValueData,
|
|
IN ULONG ValueLength,
|
|
IN PVOID Context,
|
|
IN PVOID EntryContext
|
|
);
|
|
|
|
|
|
//
|
|
// Prototypes from halftone
|
|
//
|
|
|
|
extern "C" BOOL PASCAL EnableHalftone(VOID);
|
|
extern "C" VOID PASCAL DisableHalftone(VOID);
|
|
|
|
|
|
/**************************************************************************\
|
|
*
|
|
\**************************************************************************/
|
|
|
|
#ifdef i386
|
|
extern "C" PVOID GDIpLockPrefixTable;
|
|
|
|
//
|
|
// Specify address of kernel32 lock prefixes
|
|
//
|
|
extern "C" IMAGE_LOAD_CONFIG_DIRECTORY _load_config_used = {
|
|
0, // Reserved
|
|
0, // Reserved
|
|
0, // Reserved
|
|
0, // Reserved
|
|
0, // GlobalFlagsClear
|
|
0, // GlobalFlagsSet
|
|
0, // CriticalSectionTimeout (milliseconds)
|
|
0, // DeCommitFreeBlockThreshold
|
|
0, // DeCommitTotalFreeThreshold
|
|
&GDIpLockPrefixTable, // LockPrefixTable
|
|
0, 0, 0, 0, 0, 0, 0 // Reserved
|
|
};
|
|
#endif
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* bEnableFontDriver
|
|
*
|
|
* Enables an internal, statically-linked font driver.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
BOOL bEnableFontDriver(PFN pfnFdEnable, BOOL bTrueType)
|
|
{
|
|
//
|
|
// Load driver.
|
|
//
|
|
|
|
LDEVREF ldr(pfnFdEnable, LDEV_FONT);
|
|
|
|
//
|
|
// Validate the new LDEV
|
|
//
|
|
|
|
if (ldr.bValid())
|
|
{
|
|
//
|
|
// Create the PDEV for this (the PDEV won't have anything in it
|
|
// except the dispatch table.
|
|
//
|
|
|
|
PDEVREF pr(ldr,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
|
|
if (pr.bValid())
|
|
{
|
|
//
|
|
// Create a reference to the PDEV.
|
|
//
|
|
|
|
pr.vKeepIt();
|
|
|
|
//
|
|
// Was it the TrueType driver? We need to keep a global handle to
|
|
// it to support the Win 3.1 TrueType-specific calls.
|
|
//
|
|
|
|
if (bTrueType)
|
|
{
|
|
gppdevTrueType = (PPDEV) pr.hdev();
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
}
|
|
|
|
WARNING("bLoadFontDriver failed\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
/******************************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"
|
|
BOOLEAN
|
|
InitializeGre(VOID)
|
|
{
|
|
//
|
|
// We only want to initialize once. We can detect transition to 0.
|
|
//
|
|
|
|
if (InterlockedDecrement(&CountInit) != 0)
|
|
{
|
|
return(TRUE);
|
|
}
|
|
|
|
#if defined(_MIPS_)
|
|
vInitMipsMem();
|
|
#endif
|
|
|
|
gefDefaultHeightInInches = (LONG) DEFAULT_SCALABLE_FONT_HEIGHT_IN_POINTS;
|
|
gefDefaultHeightInInches /= (LONG) POINTS_PER_INCH;
|
|
|
|
//
|
|
// 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
|
|
if ((gpsemDEBUG = hsemCreate())==NULL)
|
|
{
|
|
WARNING("win32k: unable to initialize gpsemDEBUG\n");
|
|
return(FALSE);
|
|
}
|
|
#endif
|
|
//
|
|
// Create the LDEV\PDEV semaphore.
|
|
//
|
|
|
|
if ((gpsemDriverMgmt = hsemCreate()) == 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.
|
|
|
|
gpsemRFONTList = hsemCreate();
|
|
if (gpsemRFONTList == NULL)
|
|
{
|
|
WARNING("win32k: unable to create gpsemRFONTList\n");
|
|
return FALSE;
|
|
}
|
|
|
|
// Create the WNDOBJ semaphore.
|
|
|
|
gpsemWndobj = hsemCreate();
|
|
if (gpsemWndobj == NULL)
|
|
{
|
|
WARNING("win32k: unable to create gpsemWndobj\n");
|
|
return FALSE;
|
|
}
|
|
|
|
// Create the RFONT list semaphore.
|
|
|
|
gpsemGdiSpool = hsemCreate();
|
|
ASSERTGDI(gpsemGdiSpool != NULL, "gpsemGdiSpool failed to create");
|
|
|
|
// 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);
|
|
ASSERTGDI(ro.bValid(),"invalid hrgnDefault\n");
|
|
|
|
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);
|
|
}
|
|
|
|
// Init the font drivers
|
|
|
|
gppdevTrueType = NULL;
|
|
gcTrueTypeFonts = 0;
|
|
gulFontInformation = 0;
|
|
gusLanguageID = GetLanguageID();
|
|
|
|
USHORT AnsiCodePage, OemCodePage;
|
|
|
|
RtlGetDefaultCodePage(&AnsiCodePage,&OemCodePage);
|
|
|
|
gbDBCSCodePage = (IS_ANY_DBCS_CODEPAGE(AnsiCodePage)) ? TRUE : FALSE;
|
|
|
|
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
|
|
|
|
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) vtfdEnableDriver, FALSE))
|
|
{
|
|
WARNING("GDISRV.DLL could not enable VTFD\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
if (!bEnableFontDriver((PFN) BmfdEnableDriver, FALSE))
|
|
{
|
|
WARNING("GDISRV failed to enable BMFD\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
if (!bEnableFontDriver((PFN) ttfdEnableDriver, TRUE))
|
|
{
|
|
WARNING("GDISRV.DLL could not enable TTFD\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
|
|
// initialize the script names
|
|
|
|
if(!InitializeScripts())
|
|
{
|
|
WARNING("Could not initialize the script names\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 Cache\n"));
|
|
|
|
if (!bInitFontCache())
|
|
{
|
|
WARNING("Font cache parameter intialization failed\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
TRACE_FONT(("GRE: Initializing Font Substitution\n"));
|
|
|
|
//
|
|
// Init font substitution table
|
|
//
|
|
|
|
vInitFontSubTable();
|
|
|
|
//
|
|
// Start up the brush component
|
|
//
|
|
|
|
if (!bInitBRUSHOBJ())
|
|
{
|
|
WARNING("Could not init the brushes\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
//
|
|
// Load default face names for the mapper from the registry
|
|
//
|
|
|
|
vInitMapper();
|
|
|
|
//
|
|
// Enable statically linked halftone library
|
|
//
|
|
|
|
if (!EnableHalftone()) {
|
|
|
|
WARNING("GRE: could not enable halftone\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
#ifdef FE_SB
|
|
vInitializeEUDC();
|
|
#endif
|
|
|
|
//
|
|
// handle track structure init
|
|
//
|
|
|
|
PPID_HANDLE_TRACK pTrackSent = (PPID_HANDLE_TRACK)PALLOCNOZ(sizeof(PID_HANDLE_TRACK), 'gthg');
|
|
|
|
if (pTrackSent)
|
|
{
|
|
pTrackSent->Pid = OBJECT_OWNER_NONE;
|
|
pTrackSent->HandleCount = 0;
|
|
pTrackSent->pNext = pTrackSent;
|
|
pTrackSent->pPrev = pTrackSent;
|
|
gpPidHandleList = pTrackSent;
|
|
}
|
|
else
|
|
{
|
|
WARNING("GRE: could allocate POOL for handle tracking\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
TRACE_INIT(("GRE: Completed Initialization\n"));
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
#if defined(_MIPS_)
|
|
|
|
extern "C" {
|
|
|
|
VOID
|
|
vInitMipsMem(
|
|
VOID
|
|
)
|
|
|
|
{
|
|
//
|
|
// Setup the pointer to the real functions as the default functions.
|
|
//
|
|
|
|
#undef memcpy
|
|
#undef memset
|
|
#undef RtlFillMemoryUlong
|
|
|
|
__declspec(dllimport) void * memcpy(void *, const void *, size_t);
|
|
__declspec(dllimport) void * memset(void *, int, size_t);
|
|
__declspec(dllimport) void RtlFillMemoryUlong(void *, unsigned long, unsigned long);
|
|
|
|
Gdip64bitDisabled = 0;
|
|
CopyMemFn = memcpy;
|
|
FillMemFn = memset;
|
|
FillMemUlongFn = RtlFillMemoryUlong;
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
extern "C"
|
|
NTSTATUS
|
|
FontDriverQueryRoutine
|
|
(
|
|
IN PWSTR ValueName,
|
|
IN ULONG ValueType,
|
|
IN PVOID ValueData,
|
|
IN ULONG ValueLength,
|
|
IN PVOID Context,
|
|
IN PVOID EntryContext
|
|
)
|
|
{
|
|
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);
|
|
|
|
|
|
LDEVREF ldr(FontDriverPath, LDEV_FONT);
|
|
|
|
// Validate the new LDEV
|
|
|
|
if (ldr.bValid())
|
|
{
|
|
// Create the PDEV for this (the PDEV won't have anything in it
|
|
// except the dispatch table.
|
|
|
|
|
|
PDEVREF pr(ldr,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
|
|
if (pr.bValid())
|
|
{
|
|
// Create a reference to the PDEV.
|
|
|
|
pr.vKeepIt();
|
|
|
|
|
|
// Now we will try escape 0x2514. If this is ATM then it will return
|
|
// a DWORD with a version number in the low byte. We use this version
|
|
// to compare against ATM on the server when doing remote printing.
|
|
|
|
DWORD ATMVersion;
|
|
|
|
if(ATMVersion = GreNamedEscape((PWSTR) ValueData,0x2514,0,0,0,0))
|
|
{
|
|
gufiLocalType1Rasterizer.CheckSum = TYPE1_RASTERIZER;
|
|
gufiLocalType1Rasterizer.Index = ATMVersion & 0xFF;
|
|
}
|
|
|
|
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"ProcessHandleQuota");
|
|
|
|
NtStatus = ZwQueryValueKey(hKey,
|
|
&UnicodeValue,
|
|
KeyValuePartialInformation,
|
|
pKeyInfo,
|
|
sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(DWORD),
|
|
&ReturnedLength);
|
|
|
|
if (NT_SUCCESS(NtStatus))
|
|
{
|
|
LONG lHandleQuota = *(PLONG)(&pKeyInfo->Data[0]);
|
|
|
|
if ((lHandleQuota > 0) &&
|
|
(lHandleQuota <= (MAX_HANDLE_COUNT)))
|
|
{
|
|
gProcessHandleQuota = lHandleQuota;
|
|
bRet = TRUE;
|
|
}
|
|
}
|
|
}
|
|
return(bRet);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|