sl@0: // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // Implementation of the FontInjector DLL, only for the emulator. This DLL has sl@0: // writeable static data and should use the EPOCALLOWDLLDATA keyword in the MMP sl@0: // file, but it does not because by default the EKA2 emulator allows global data sl@0: // as long as the constructors do not make executive calls and, in some test sl@0: // cases, there is more than one instance of the test server with this DLL loaded, sl@0: // although it should be in active use by only one process at a time. For more sl@0: // information see the Symbian Developer Library > Symbian OS Guide > Essential sl@0: // idioms > Static data. sl@0: // sl@0: sl@0: #include "fontinjector.h" sl@0: sl@0: #ifdef __WINS__ sl@0: sl@0: template EXPORT_C XVtableInjector::XVtableInjector() sl@0: { sl@0: ASSERT(gObjects.Count() == 0); sl@0: ASSERT(!gShellcode); sl@0: ASSERT(!gOriginalVtable); sl@0: } sl@0: sl@0: template EXPORT_C XVtableInjector::~XVtableInjector() sl@0: { sl@0: for (TInt i = 0; i < gObjects.Count(); ++i) sl@0: { sl@0: *reinterpret_cast(gObjects[i]) = gOriginalVtable; sl@0: } sl@0: gObjects.Close(); sl@0: gShellcode = NULL; sl@0: gOriginalVtable = NULL; sl@0: } sl@0: sl@0: template EXPORT_C TInt XVtableInjector::InjectShellcode(C* aObject, MShellcode* aShellcode) sl@0: { sl@0: if (gShellcode && gShellcode != aShellcode) sl@0: { sl@0: return KErrArgument; sl@0: } sl@0: TInt err = KErrNone; sl@0: if (gObjects.FindInAddressOrder(aObject) == KErrNotFound) sl@0: { sl@0: if (gOriginalVtable && gOriginalVtable != *reinterpret_cast(aObject)) sl@0: { sl@0: return KErrArgument; sl@0: } sl@0: err = gObjects.InsertInAddressOrder(aObject); sl@0: if (err == KErrNone) sl@0: { sl@0: gShellcode = aShellcode; sl@0: gOriginalVtable = *reinterpret_cast(aObject); sl@0: *reinterpret_cast(aObject) = *reinterpret_cast(this); sl@0: } sl@0: } sl@0: return err; sl@0: } sl@0: sl@0: template<> EXPORT_C void XVtableInjector::GetVirtualFunctionName(TInt aIndex, TDes& aName) sl@0: { sl@0: switch (aIndex) sl@0: { sl@0: case 0: sl@0: aName.Copy(_S("CFont::~CFont()")); sl@0: break; sl@0: case 1: sl@0: aName.Copy(_S("CFont::Extension_(TUint, TAny*&, TAny*)")); sl@0: break; sl@0: case 2: sl@0: aName.Copy(_S("CFont::DoTypeUid()")); sl@0: break; sl@0: case 3: sl@0: aName.Copy(_S("CFont::DoHeightInPixels()")); sl@0: break; sl@0: case 4: sl@0: aName.Copy(_S("CFont::DoAscentInPixels()")); sl@0: break; sl@0: case 5: sl@0: aName.Copy(_S("CFont::DoDescentInPixels()")); sl@0: break; sl@0: case 6: sl@0: aName.Copy(_S("CFont::DoCharWidthInPixels(TChar)")); sl@0: break; sl@0: case 7: sl@0: aName.Copy(_S("CFont::DoTextWidthInPixels(const TDesC&)")); sl@0: break; sl@0: case 8: sl@0: aName.Copy(_S("CFont::DoBaselineOffsetInPixels()")); sl@0: break; sl@0: case 9: sl@0: aName.Copy(_S("CFont::DoTextCount(const TDesC&, TInt)")); sl@0: break; sl@0: case 10: sl@0: aName.Copy(_S("CFont::DoTextCount(const TDesC&, TInt, TInt&)")); sl@0: break; sl@0: case 11: sl@0: aName.Copy(_S("CFont::DoMaxCharWidthInPixels()")); sl@0: break; sl@0: case 12: sl@0: aName.Copy(_S("CFont::DoMaxNormalCharWidthInPixels()")); sl@0: break; sl@0: case 13: sl@0: aName.Copy(_S("CFont::DoFontSpecInTwips()")); sl@0: break; sl@0: case 14: sl@0: aName.Copy(_S("CFont::DoGetCharacterData(TUint, TOpenFontCharMetrics&, const TUint8*&, TSize&)")); sl@0: break; sl@0: case 15: sl@0: aName.Copy(_S("CFont::DoGetCharacterPosition(CFont::TPositionParam&)")); sl@0: break; sl@0: case 16: sl@0: aName.Copy(_S("CFont::DoExtendedFunction(TUid, TAny*)")); sl@0: break; sl@0: default: sl@0: aName.Copy(_S("CFont::")); sl@0: } sl@0: } sl@0: sl@0: template<> EXPORT_C void XVtableInjector::GetVirtualFunctionName(TInt aIndex, TDes& aName) sl@0: { sl@0: switch (aIndex) sl@0: { sl@0: case 0: sl@0: aName.Copy(_S("COpenFont::~COpenFont()")); sl@0: break; sl@0: case 1: sl@0: aName.Copy(_S("COpenFont::Extension_(TUint, TAny*&, TAny*)")); sl@0: break; sl@0: case 2: sl@0: aName.Copy(_S("COpenFont::RasterizeL(TInt, TOpenFontGlyphData*)")); sl@0: break; sl@0: case 3: sl@0: aName.Copy(_S("COpenFont::ExtendedInterface(TUid, TAny*&)")); sl@0: break; sl@0: default: sl@0: aName.Format(_L("COpenFont::"), aIndex - 3); sl@0: } sl@0: } sl@0: sl@0: template void XVtableInjector::ObjectDestroyed(TAny* aObject) sl@0: { sl@0: gObjects.Remove(gObjects.FindInAddressOrder(aObject)); sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function000() sl@0: { sl@0: asm { push ecx } sl@0: /* cdecl calling convention */ sl@0: asm { push ecx } sl@0: asm { call ObjectDestroyed } sl@0: asm { add esp, 4 } sl@0: /* thiscall calling convention */ sl@0: asm { mov ecx, gShellcode } sl@0: asm { push 0 } sl@0: asm { mov eax, [ecx] } sl@0: asm { call [eax] } sl@0: /* continue to original function */ sl@0: asm { pop ecx } sl@0: asm { mov eax, gOriginalVtable } sl@0: asm { jmp [eax] } sl@0: } sl@0: sl@0: #define DISPATCH_NTH_VIRTUAL_FUNCTION(n) \ sl@0: asm { push ecx } \ sl@0: /* thiscall calling convention */ \ sl@0: asm { mov ecx, gShellcode } \ sl@0: asm { push n } \ sl@0: asm { mov eax, [ecx] } \ sl@0: asm { call [eax] } \ sl@0: /* continue to original function */ \ sl@0: asm { pop ecx } \ sl@0: asm { mov eax, gOriginalVtable } \ sl@0: asm { jmp [eax + (n * 4)] } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function001() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(1) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function002() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(2) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function003() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(3) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function004() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(4) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function005() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(5) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function006() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(6) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function007() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(7) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function008() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(8) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function009() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(9) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function010() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(10) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function011() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(11) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function012() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(12) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function013() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(13) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function014() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(14) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function015() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(15) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function016() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(16) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function017() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(17) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function018() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(18) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function019() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(19) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function020() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(20) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function021() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(21) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function022() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(22) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function023() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(23) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function024() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(24) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function025() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(25) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function026() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(26) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function027() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(27) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function028() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(28) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function029() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(29) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function030() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(30) sl@0: } sl@0: sl@0: template void __declspec(naked) XVtableInjector::Function031() sl@0: { sl@0: DISPATCH_NTH_VIRTUAL_FUNCTION(31) sl@0: } sl@0: sl@0: template RPointerArray XVtableInjector::gObjects; sl@0: template MShellcode* XVtableInjector::gShellcode = NULL; sl@0: template TAny* XVtableInjector::gOriginalVtable = NULL; sl@0: sl@0: // Explicit instantiation of the injector classes. sl@0: template class XVtableInjector; sl@0: template class XVtableInjector; sl@0: sl@0: #endif // __WINS__