|
1 // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // Implementation of the FontInjector DLL, only for the emulator. This DLL has |
|
15 // writeable static data and should use the EPOCALLOWDLLDATA keyword in the MMP |
|
16 // file, but it does not because by default the EKA2 emulator allows global data |
|
17 // as long as the constructors do not make executive calls and, in some test |
|
18 // cases, there is more than one instance of the test server with this DLL loaded, |
|
19 // although it should be in active use by only one process at a time. For more |
|
20 // information see the Symbian Developer Library > Symbian OS Guide > Essential |
|
21 // idioms > Static data. |
|
22 // |
|
23 |
|
24 #include "fontinjector.h" |
|
25 |
|
26 #ifdef __WINS__ |
|
27 |
|
28 template<class C> EXPORT_C XVtableInjector<C>::XVtableInjector() |
|
29 { |
|
30 ASSERT(gObjects.Count() == 0); |
|
31 ASSERT(!gShellcode); |
|
32 ASSERT(!gOriginalVtable); |
|
33 } |
|
34 |
|
35 template<class C> EXPORT_C XVtableInjector<C>::~XVtableInjector() |
|
36 { |
|
37 for (TInt i = 0; i < gObjects.Count(); ++i) |
|
38 { |
|
39 *reinterpret_cast<TAny**>(gObjects[i]) = gOriginalVtable; |
|
40 } |
|
41 gObjects.Close(); |
|
42 gShellcode = NULL; |
|
43 gOriginalVtable = NULL; |
|
44 } |
|
45 |
|
46 template<class C> EXPORT_C TInt XVtableInjector<C>::InjectShellcode(C* aObject, MShellcode* aShellcode) |
|
47 { |
|
48 if (gShellcode && gShellcode != aShellcode) |
|
49 { |
|
50 return KErrArgument; |
|
51 } |
|
52 TInt err = KErrNone; |
|
53 if (gObjects.FindInAddressOrder(aObject) == KErrNotFound) |
|
54 { |
|
55 if (gOriginalVtable && gOriginalVtable != *reinterpret_cast<TAny**>(aObject)) |
|
56 { |
|
57 return KErrArgument; |
|
58 } |
|
59 err = gObjects.InsertInAddressOrder(aObject); |
|
60 if (err == KErrNone) |
|
61 { |
|
62 gShellcode = aShellcode; |
|
63 gOriginalVtable = *reinterpret_cast<TAny**>(aObject); |
|
64 *reinterpret_cast<TAny**>(aObject) = *reinterpret_cast<TAny**>(this); |
|
65 } |
|
66 } |
|
67 return err; |
|
68 } |
|
69 |
|
70 template<> EXPORT_C void XVtableInjector<CFont>::GetVirtualFunctionName(TInt aIndex, TDes& aName) |
|
71 { |
|
72 switch (aIndex) |
|
73 { |
|
74 case 0: |
|
75 aName.Copy(_S("CFont::~CFont()")); |
|
76 break; |
|
77 case 1: |
|
78 aName.Copy(_S("CFont::Extension_(TUint, TAny*&, TAny*)")); |
|
79 break; |
|
80 case 2: |
|
81 aName.Copy(_S("CFont::DoTypeUid()")); |
|
82 break; |
|
83 case 3: |
|
84 aName.Copy(_S("CFont::DoHeightInPixels()")); |
|
85 break; |
|
86 case 4: |
|
87 aName.Copy(_S("CFont::DoAscentInPixels()")); |
|
88 break; |
|
89 case 5: |
|
90 aName.Copy(_S("CFont::DoDescentInPixels()")); |
|
91 break; |
|
92 case 6: |
|
93 aName.Copy(_S("CFont::DoCharWidthInPixels(TChar)")); |
|
94 break; |
|
95 case 7: |
|
96 aName.Copy(_S("CFont::DoTextWidthInPixels(const TDesC&)")); |
|
97 break; |
|
98 case 8: |
|
99 aName.Copy(_S("CFont::DoBaselineOffsetInPixels()")); |
|
100 break; |
|
101 case 9: |
|
102 aName.Copy(_S("CFont::DoTextCount(const TDesC&, TInt)")); |
|
103 break; |
|
104 case 10: |
|
105 aName.Copy(_S("CFont::DoTextCount(const TDesC&, TInt, TInt&)")); |
|
106 break; |
|
107 case 11: |
|
108 aName.Copy(_S("CFont::DoMaxCharWidthInPixels()")); |
|
109 break; |
|
110 case 12: |
|
111 aName.Copy(_S("CFont::DoMaxNormalCharWidthInPixels()")); |
|
112 break; |
|
113 case 13: |
|
114 aName.Copy(_S("CFont::DoFontSpecInTwips()")); |
|
115 break; |
|
116 case 14: |
|
117 aName.Copy(_S("CFont::DoGetCharacterData(TUint, TOpenFontCharMetrics&, const TUint8*&, TSize&)")); |
|
118 break; |
|
119 case 15: |
|
120 aName.Copy(_S("CFont::DoGetCharacterPosition(CFont::TPositionParam&)")); |
|
121 break; |
|
122 case 16: |
|
123 aName.Copy(_S("CFont::DoExtendedFunction(TUid, TAny*)")); |
|
124 break; |
|
125 default: |
|
126 aName.Copy(_S("CFont::<Unknown Virtual Function>")); |
|
127 } |
|
128 } |
|
129 |
|
130 template<> EXPORT_C void XVtableInjector<COpenFont>::GetVirtualFunctionName(TInt aIndex, TDes& aName) |
|
131 { |
|
132 switch (aIndex) |
|
133 { |
|
134 case 0: |
|
135 aName.Copy(_S("COpenFont::~COpenFont()")); |
|
136 break; |
|
137 case 1: |
|
138 aName.Copy(_S("COpenFont::Extension_(TUint, TAny*&, TAny*)")); |
|
139 break; |
|
140 case 2: |
|
141 aName.Copy(_S("COpenFont::RasterizeL(TInt, TOpenFontGlyphData*)")); |
|
142 break; |
|
143 case 3: |
|
144 aName.Copy(_S("COpenFont::ExtendedInterface(TUid, TAny*&)")); |
|
145 break; |
|
146 default: |
|
147 aName.Format(_L("COpenFont::<Extended Virtual Function %03d>"), aIndex - 3); |
|
148 } |
|
149 } |
|
150 |
|
151 template<class C> void XVtableInjector<C>::ObjectDestroyed(TAny* aObject) |
|
152 { |
|
153 gObjects.Remove(gObjects.FindInAddressOrder(aObject)); |
|
154 } |
|
155 |
|
156 template<class C> void __declspec(naked) XVtableInjector<C>::Function000() |
|
157 { |
|
158 asm { push ecx } |
|
159 /* cdecl calling convention */ |
|
160 asm { push ecx } |
|
161 asm { call ObjectDestroyed } |
|
162 asm { add esp, 4 } |
|
163 /* thiscall calling convention */ |
|
164 asm { mov ecx, gShellcode } |
|
165 asm { push 0 } |
|
166 asm { mov eax, [ecx] } |
|
167 asm { call [eax] } |
|
168 /* continue to original function */ |
|
169 asm { pop ecx } |
|
170 asm { mov eax, gOriginalVtable } |
|
171 asm { jmp [eax] } |
|
172 } |
|
173 |
|
174 #define DISPATCH_NTH_VIRTUAL_FUNCTION(n) \ |
|
175 asm { push ecx } \ |
|
176 /* thiscall calling convention */ \ |
|
177 asm { mov ecx, gShellcode } \ |
|
178 asm { push n } \ |
|
179 asm { mov eax, [ecx] } \ |
|
180 asm { call [eax] } \ |
|
181 /* continue to original function */ \ |
|
182 asm { pop ecx } \ |
|
183 asm { mov eax, gOriginalVtable } \ |
|
184 asm { jmp [eax + (n * 4)] } |
|
185 |
|
186 template<class C> void __declspec(naked) XVtableInjector<C>::Function001() |
|
187 { |
|
188 DISPATCH_NTH_VIRTUAL_FUNCTION(1) |
|
189 } |
|
190 |
|
191 template<class C> void __declspec(naked) XVtableInjector<C>::Function002() |
|
192 { |
|
193 DISPATCH_NTH_VIRTUAL_FUNCTION(2) |
|
194 } |
|
195 |
|
196 template<class C> void __declspec(naked) XVtableInjector<C>::Function003() |
|
197 { |
|
198 DISPATCH_NTH_VIRTUAL_FUNCTION(3) |
|
199 } |
|
200 |
|
201 template<class C> void __declspec(naked) XVtableInjector<C>::Function004() |
|
202 { |
|
203 DISPATCH_NTH_VIRTUAL_FUNCTION(4) |
|
204 } |
|
205 |
|
206 template<class C> void __declspec(naked) XVtableInjector<C>::Function005() |
|
207 { |
|
208 DISPATCH_NTH_VIRTUAL_FUNCTION(5) |
|
209 } |
|
210 |
|
211 template<class C> void __declspec(naked) XVtableInjector<C>::Function006() |
|
212 { |
|
213 DISPATCH_NTH_VIRTUAL_FUNCTION(6) |
|
214 } |
|
215 |
|
216 template<class C> void __declspec(naked) XVtableInjector<C>::Function007() |
|
217 { |
|
218 DISPATCH_NTH_VIRTUAL_FUNCTION(7) |
|
219 } |
|
220 |
|
221 template<class C> void __declspec(naked) XVtableInjector<C>::Function008() |
|
222 { |
|
223 DISPATCH_NTH_VIRTUAL_FUNCTION(8) |
|
224 } |
|
225 |
|
226 template<class C> void __declspec(naked) XVtableInjector<C>::Function009() |
|
227 { |
|
228 DISPATCH_NTH_VIRTUAL_FUNCTION(9) |
|
229 } |
|
230 |
|
231 template<class C> void __declspec(naked) XVtableInjector<C>::Function010() |
|
232 { |
|
233 DISPATCH_NTH_VIRTUAL_FUNCTION(10) |
|
234 } |
|
235 |
|
236 template<class C> void __declspec(naked) XVtableInjector<C>::Function011() |
|
237 { |
|
238 DISPATCH_NTH_VIRTUAL_FUNCTION(11) |
|
239 } |
|
240 |
|
241 template<class C> void __declspec(naked) XVtableInjector<C>::Function012() |
|
242 { |
|
243 DISPATCH_NTH_VIRTUAL_FUNCTION(12) |
|
244 } |
|
245 |
|
246 template<class C> void __declspec(naked) XVtableInjector<C>::Function013() |
|
247 { |
|
248 DISPATCH_NTH_VIRTUAL_FUNCTION(13) |
|
249 } |
|
250 |
|
251 template<class C> void __declspec(naked) XVtableInjector<C>::Function014() |
|
252 { |
|
253 DISPATCH_NTH_VIRTUAL_FUNCTION(14) |
|
254 } |
|
255 |
|
256 template<class C> void __declspec(naked) XVtableInjector<C>::Function015() |
|
257 { |
|
258 DISPATCH_NTH_VIRTUAL_FUNCTION(15) |
|
259 } |
|
260 |
|
261 template<class C> void __declspec(naked) XVtableInjector<C>::Function016() |
|
262 { |
|
263 DISPATCH_NTH_VIRTUAL_FUNCTION(16) |
|
264 } |
|
265 |
|
266 template<class C> void __declspec(naked) XVtableInjector<C>::Function017() |
|
267 { |
|
268 DISPATCH_NTH_VIRTUAL_FUNCTION(17) |
|
269 } |
|
270 |
|
271 template<class C> void __declspec(naked) XVtableInjector<C>::Function018() |
|
272 { |
|
273 DISPATCH_NTH_VIRTUAL_FUNCTION(18) |
|
274 } |
|
275 |
|
276 template<class C> void __declspec(naked) XVtableInjector<C>::Function019() |
|
277 { |
|
278 DISPATCH_NTH_VIRTUAL_FUNCTION(19) |
|
279 } |
|
280 |
|
281 template<class C> void __declspec(naked) XVtableInjector<C>::Function020() |
|
282 { |
|
283 DISPATCH_NTH_VIRTUAL_FUNCTION(20) |
|
284 } |
|
285 |
|
286 template<class C> void __declspec(naked) XVtableInjector<C>::Function021() |
|
287 { |
|
288 DISPATCH_NTH_VIRTUAL_FUNCTION(21) |
|
289 } |
|
290 |
|
291 template<class C> void __declspec(naked) XVtableInjector<C>::Function022() |
|
292 { |
|
293 DISPATCH_NTH_VIRTUAL_FUNCTION(22) |
|
294 } |
|
295 |
|
296 template<class C> void __declspec(naked) XVtableInjector<C>::Function023() |
|
297 { |
|
298 DISPATCH_NTH_VIRTUAL_FUNCTION(23) |
|
299 } |
|
300 |
|
301 template<class C> void __declspec(naked) XVtableInjector<C>::Function024() |
|
302 { |
|
303 DISPATCH_NTH_VIRTUAL_FUNCTION(24) |
|
304 } |
|
305 |
|
306 template<class C> void __declspec(naked) XVtableInjector<C>::Function025() |
|
307 { |
|
308 DISPATCH_NTH_VIRTUAL_FUNCTION(25) |
|
309 } |
|
310 |
|
311 template<class C> void __declspec(naked) XVtableInjector<C>::Function026() |
|
312 { |
|
313 DISPATCH_NTH_VIRTUAL_FUNCTION(26) |
|
314 } |
|
315 |
|
316 template<class C> void __declspec(naked) XVtableInjector<C>::Function027() |
|
317 { |
|
318 DISPATCH_NTH_VIRTUAL_FUNCTION(27) |
|
319 } |
|
320 |
|
321 template<class C> void __declspec(naked) XVtableInjector<C>::Function028() |
|
322 { |
|
323 DISPATCH_NTH_VIRTUAL_FUNCTION(28) |
|
324 } |
|
325 |
|
326 template<class C> void __declspec(naked) XVtableInjector<C>::Function029() |
|
327 { |
|
328 DISPATCH_NTH_VIRTUAL_FUNCTION(29) |
|
329 } |
|
330 |
|
331 template<class C> void __declspec(naked) XVtableInjector<C>::Function030() |
|
332 { |
|
333 DISPATCH_NTH_VIRTUAL_FUNCTION(30) |
|
334 } |
|
335 |
|
336 template<class C> void __declspec(naked) XVtableInjector<C>::Function031() |
|
337 { |
|
338 DISPATCH_NTH_VIRTUAL_FUNCTION(31) |
|
339 } |
|
340 |
|
341 template<class C> RPointerArray<TAny> XVtableInjector<C>::gObjects; |
|
342 template<class C> MShellcode* XVtableInjector<C>::gShellcode = NULL; |
|
343 template<class C> TAny* XVtableInjector<C>::gOriginalVtable = NULL; |
|
344 |
|
345 // Explicit instantiation of the injector classes. |
|
346 template class XVtableInjector<CFont>; |
|
347 template class XVtableInjector<COpenFont>; |
|
348 |
|
349 #endif // __WINS__ |