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.
 
 
 
 
 
 

285 lines
8.2 KiB

/********************************************************************
*
* Module Name : lpk_init.cxx
*
* The module handles the Dll entry point and intialization routines.
*
* Created : Oct 21, 1996
* Author : Samer Arafeh [samera]
*
* Copyright (c) 1996, Microsoft Corporation. All rights reserved.
*
**********************************************************************/
#include "precomp.hxx"
/***************************************************************************\
* FindStartOfString
*
* Searches the unicode res string for the specified pattern.
*
* History:
* 2-Jan-1998 SamerA Created.
\***************************************************************************/
PWSTR FindStartOfString(
PWSTR pwszToFind,
ULONG uLenToFind,
PWSTR pResourceData,
ULONG uSearchLen)
{
ULONG i=0,j=0;
PWSTR pwszMatch=pResourceData ;
if ( uLenToFind > uSearchLen ) {
return NULL;
}
while ( i<uSearchLen ) {
if ( (pwszToFind[j] == pwszMatch[i]) &&
((uSearchLen-i+1) >= uLenToFind ) ) {
while ( j<uLenToFind ) {
if ( pwszToFind[j] != pwszMatch[i] ) {
j=0;
break;
}
++j;
++i;
}
if (j == uLenToFind) {
//
// Clear NULLs
//
while ( pwszMatch[i] == L'\0' )
++i;
return &pwszMatch[i];
}
continue;
}
++i;
}
return NULL;
}
/***************************************************************************\
* LpkCheckForMirrorSignature
*
* Reetreives a pointer to the version resource section of the
* current executable. It checks if the 'FileDescription' field
* contains double LRM at the beginning to indicate a localized Mirrored
* App that requires mirroring. If signature is found, then
* SetProcessDefaultLayout is automatically called to apply mirroring for
* the current process.
*
* History:
* 2-Jan-1998 SamerA Created.
\***************************************************************************/
BOOL LpkCheckForMirrorSignature( void )
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
PVOID pImageBase,pResourceData;
PIMAGE_RESOURCE_DATA_ENTRY pImageResource;
ULONG uResourceSize;
ULONG_PTR resIdPath[ 3 ];
WCHAR *pwchDescritpion;
WCHAR wchVersionVar[] = L"FileDescription";
//
// Get the current executable handle
//
pImageBase = NtCurrentPeb()->ImageBaseAddress;
if ( NULL == pImageBase ) {
return NT_SUCCESS(status);
}
//
// Find the version resource. Search for neutral resource, this way
// the MUI resource redirection code is activated, and the MUI
// resource will be selected, if available.
//
resIdPath[0] = (ULONG_PTR) RT_VERSION ;
resIdPath[1] = (ULONG_PTR) 1;
resIdPath[2] = (ULONG_PTR) MAKELANGID( LANG_NEUTRAL , SUBLANG_NEUTRAL );
// try {
//
// Bug #246044 WeiWu 12/07/00
// Due to #173609 bug fix, resource loader no longer by default redirects
// version resource searching to MUI alternative modules
// So, we have to use LDR_FIND_RESOURCE_LANGUAGE_REDIRECT_VERSION to force version redirection
//
status = LdrFindResourceEx_U(
LDR_FIND_RESOURCE_LANGUAGE_REDIRECT_VERSION,
pImageBase,
resIdPath,
3,
&pImageResource
);
// }
// except( EXCEPTION_EXECUTE_HANDLER )
// {
// status = GetExceptionCode();
// }
if ( NT_SUCCESS(status) ) {
//
// Load the resource into memory
//
// try {
status = LdrAccessResource( pImageBase ,
pImageResource,
&pResourceData,
&uResourceSize
);
// }
// except( EXCEPTION_EXECUTE_HANDLER )
// {
// status = GetExceptionCode();
// }
if ( NT_SUCCESS(status) ) {
//
// Now we have the Version Info of the current
// executable.
//
// Let's read the FileDescription and check
// if this image needs to be mirrored by
// calling NtUserSetProcessDefaultLayout()
//
pwchDescritpion = FindStartOfString( wchVersionVar ,
(sizeof(wchVersionVar)/sizeof(WCHAR)) ,
(WCHAR*)pResourceData ,
uResourceSize/sizeof(WCHAR));
if ( pwchDescritpion &&
(0x200e == pwchDescritpion[0]) &&
(0x200e == pwchDescritpion[1]) ) {
SetProcessDefaultLayout( LAYOUT_RTL );
}
}
}
//
// return status of operation
//
return NT_SUCCESS(status);
}
/*************************************************************
*
* LPK Dll Initialization Routines
*
**************************************************************/
/**********************************************************************
LpkDllInitialize( HANDLE hDll , DWORD dwReason , PVOID pvSituation )
hDll : Handle to Dll
dwReason : Process attach, thread attach, ...etc
pvSituation : Load-time or Run-time Dynalink
This is the initialization procedure called when LPK.DLL gets loaded
into a process address space
History :
Oct 21, 1996 -by- Samer Arafeh [samera]
***********************************************************************/
extern "C" BOOL LpkDllInitialize(HINSTANCE hDll, DWORD dwReason, PVOID pvSituation)
{
BOOL bRet = TRUE ;
UNREFERENCED_PARAMETER(pvSituation) ;
switch( dwReason )
{
/* Process Attachment : when a process first maps the LPK.DLL to its address space,
do the one time initialization. */
case DLL_PROCESS_ATTACH:
{
// Disable calling our DLL when new threads are created within the process
// context that we are mapped in. This is a useful optimization since
// we are not handlling DLL_THREAD_ATTACH
DisableThreadLibraryCalls( hDll ) ;
LpkPresent(); // Tell Uniscribe that the LPK is present.
}
break ;
case DLL_THREAD_ATTACH:
break ;
case DLL_THREAD_DETACH:
break ;
case DLL_PROCESS_DETACH:
break ;
}
return bRet ;
}
//////////////////////////////////////////////////////////////////////////////
// GDI32 will call this function at loading time and should return TRUE //
//////////////////////////////////////////////////////////////////////////////
BOOL LpkInitialize (DWORD dwLPKShapingDLLs) {
HRESULT hr;
hr = ScriptGetProperties(&g_ppScriptProperties, &g_iMaxScript);
if (FAILED(hr)) {
return FALSE;
}
// InitNLS is returning true any way, but I prefered to stay checking it just in case
// somebody changed the code indise it.
if (!InitNLS()) {
return FALSE;
}
// in case of low memory InitializeCriticalSectionAndSpinCount return FALSE.
// we didn't use InitializeCriticalSection because it may throw exception in the low memory
// condition and should be catched be try-except block.
if (!InitializeCriticalSectionAndSpinCount(&csFontIdCache, 0))
{
return FALSE;
}
LpkCheckForMirrorSignature();
g_dwLoadedShapingDLLs = dwLPKShapingDLLs;
// We don't call the GDI intialization for the font linking here because in the CSRSS
// process the LPK intailization will be done before the Gre GDI intailization.
g_iUseFontLinking = -1;
g_ACP = GetACP();
// Prepare the FontID cache.
g_cCachedFontsID = 0; // # of cahced font ID.
g_pCurrentAvailablePos = 0; // where can we cache next font ID.
return TRUE;
}