/******************************************************************** * * 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= uLenToFind ) ) { while ( jImageBaseAddress; 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; }