|
|
/********************************************************************
* * 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; }
|