|
1 // Copyright (c) 1995-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 the License "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 // e32test\dll\t_tdlla.cpp |
|
15 // Overview: |
|
16 // Test static data in DLLs |
|
17 // API Information: |
|
18 // RLibrary |
|
19 // Details: |
|
20 // - Test statically linked DLLs with static data and verify results. |
|
21 // - Load a dynamically loadable DLL, check DLL data, verify results. |
|
22 // - Load a dynamically loadable DLL in another thread, check DLL data, |
|
23 // verify results. |
|
24 // - Load a DLL that is statically linked to the test process, check |
|
25 // DLL data, verify results. |
|
26 // - Load in a different thread a DLL that is statically linked to the |
|
27 // test process, check DLL data, verify results. |
|
28 // Platforms/Drives/Compatibility: |
|
29 // All. |
|
30 // Assumptions/Requirement/Pre-requisites: |
|
31 // Failures and causes: |
|
32 // Base Port information: |
|
33 // |
|
34 // |
|
35 |
|
36 #include <e32test.h> |
|
37 #include <e32svr.h> |
|
38 |
|
39 #include "../mmu/mmudetect.h" |
|
40 |
|
41 LOCAL_D RTest test(_L("T_TDLLA")); |
|
42 TInt InitialisedData=0x7c99103b; |
|
43 TInt ZeroInitialisedData[32]; |
|
44 |
|
45 IMPORT_C TInt Function3(); |
|
46 IMPORT_C TInt Function4(); |
|
47 IMPORT_C void SetDll3Data(TInt); |
|
48 IMPORT_C TInt GetDll3Data(); |
|
49 |
|
50 _LIT(KExeCommandLine,"2"); |
|
51 _LIT(KDll1Name,"T_DLLA1"); |
|
52 _LIT(KDll2Name,"T_DLLA2"); |
|
53 _LIT(KDll3Name,"T_DLLA3"); |
|
54 |
|
55 typedef TFullName& (*PFRFN)(); |
|
56 TFullName& DllA1ProcessName(RLibrary lib) |
|
57 { |
|
58 |
|
59 PFRFN f=(PFRFN)lib.Lookup(3); |
|
60 return (*f)(); |
|
61 } |
|
62 |
|
63 TFullName& DllA1ThreadName(RLibrary lib) |
|
64 { |
|
65 |
|
66 PFRFN f=(PFRFN)lib.Lookup(4); |
|
67 return (*f)(); |
|
68 } |
|
69 |
|
70 void Kick(RThread aThread) |
|
71 { |
|
72 TRequestStatus s; |
|
73 TRequestStatus* pS=&s; |
|
74 aThread.RequestComplete(pS,0); |
|
75 } |
|
76 |
|
77 RSemaphore gThreadSem; |
|
78 TInt Thread1(TAny* a) |
|
79 { |
|
80 TInt r=KErrNone; |
|
81 const TDesC& name=*(const TDesC*)a; |
|
82 RLibrary lib; |
|
83 r=lib.Load(name); |
|
84 if (r!=KErrNone) |
|
85 return r; |
|
86 gThreadSem.Signal(); |
|
87 User::WaitForAnyRequest(); |
|
88 lib.Close(); |
|
89 return KErrNone; |
|
90 } |
|
91 |
|
92 TInt Thread2(TAny* a) |
|
93 { |
|
94 TInt r=KErrNone; |
|
95 const TDesC& name=*(const TDesC*)a; |
|
96 RLibrary lib; |
|
97 r=lib.Load(name); |
|
98 if (r!=KErrNone) |
|
99 return r; |
|
100 gThreadSem.Signal(); |
|
101 User::WaitForAnyRequest(); |
|
102 return KErrNone; |
|
103 } |
|
104 |
|
105 LOCAL_D TInt ProcessEntryCount=0; |
|
106 LOCAL_D TInt ExportCallCount=0; |
|
107 EXPORT_C void ExportedFunction() |
|
108 { |
|
109 ++ExportCallCount; |
|
110 } |
|
111 |
|
112 void SpawnExe() |
|
113 { |
|
114 #ifdef __EPOC32__ |
|
115 test.Printf(_L("SpawnExe()\n")); |
|
116 if (User::CommandLineLength()!=0) |
|
117 { |
|
118 test.Printf(_L("This is second EXE\n")); |
|
119 return; |
|
120 } |
|
121 RProcess p; |
|
122 TInt r=p.Create(RProcess().FileName(), KExeCommandLine); |
|
123 test(r==KErrNone); |
|
124 TFullName aFullName = p.FullName(); |
|
125 test.Printf(_L("Second EXE: %S\n"),&aFullName); |
|
126 TRequestStatus s; |
|
127 p.Logon(s); |
|
128 p.Resume(); |
|
129 User::WaitForRequest(s); |
|
130 TExitCategoryName aExitCategory = p.ExitCategory(); |
|
131 test.Printf(_L("Second EXE: %d,%d,%S\n"),p.ExitType(),p.ExitReason(),&aExitCategory); |
|
132 CLOSE_AND_WAIT(p); |
|
133 #endif |
|
134 } |
|
135 |
|
136 GLDEF_C TInt E32Main() |
|
137 // |
|
138 // Test static data in dlls |
|
139 // |
|
140 { |
|
141 |
|
142 // Turn off evil lazy dll unloading |
|
143 RLoader l; |
|
144 test(l.Connect()==KErrNone); |
|
145 test(l.CancelLazyDllUnload()==KErrNone); |
|
146 l.Close(); |
|
147 |
|
148 test(InitialisedData==0x7c99103b); |
|
149 ++InitialisedData; |
|
150 TInt i; |
|
151 for (i=0; i<31; ++i) |
|
152 test(ZeroInitialisedData[i]==0); |
|
153 for (i=0; i<31; ++i) |
|
154 ZeroInitialisedData[i]=(i+487)*(i+487); |
|
155 if (++ProcessEntryCount!=1) |
|
156 User::Panic(_L("PROC_REENT"),ProcessEntryCount); |
|
157 |
|
158 test.Title(); |
|
159 test.Start(_L("Test statically linked dlls with static data")); |
|
160 |
|
161 test(Function3()==3); |
|
162 test(Function4()==4); |
|
163 SetDll3Data(101); |
|
164 test(GetDll3Data()==101); |
|
165 SetDll3Data(105); |
|
166 test(GetDll3Data()==105); |
|
167 |
|
168 test.Next(_L("Load T_DLLA1")); |
|
169 |
|
170 RLibrary lib; |
|
171 TInt r=lib.Load(KDll1Name); |
|
172 test(r==KErrNone); |
|
173 TLibraryFunction f=lib.Lookup(1); |
|
174 test((*f)()==KErrNone); |
|
175 f=lib.Lookup(2); |
|
176 test((*f)()==1); |
|
177 |
|
178 test.Printf(_L("DLLA1 Process Name %S\n"),&DllA1ProcessName(lib)); |
|
179 test.Printf(_L("DLLA1 Thread Name %S\n"),&DllA1ThreadName(lib)); |
|
180 test(DllA1ProcessName(lib)==RProcess().FullName()); |
|
181 test(DllA1ThreadName(lib)==RThread().FullName()); |
|
182 |
|
183 test.Next(_L("Unload")); |
|
184 lib.Close(); |
|
185 |
|
186 test.Next(_L("Load again")); |
|
187 r=lib.Load(KDll1Name); |
|
188 test(r==KErrNone); |
|
189 test.Next(_L("Check Dll data")); |
|
190 f=lib.Lookup(1); |
|
191 test((*f)()==KErrNone); |
|
192 f=lib.Lookup(2); |
|
193 test((*f)()==1); |
|
194 test((*f)()==2); |
|
195 test((*f)()==3); |
|
196 test.Next(_L("Close")); |
|
197 lib.Close(); |
|
198 |
|
199 test.Next(_L("Loading T_DLLA1 again in another thread")); |
|
200 r=gThreadSem.CreateLocal(0); |
|
201 RThread t; |
|
202 r=t.Create(_L("Thread1"), Thread1, KDefaultStackSize, NULL, (TAny*)&KDll1Name); |
|
203 test(r==KErrNone); |
|
204 t.SetPriority(EPriorityMore); |
|
205 TRequestStatus stat; |
|
206 t.Logon(stat); |
|
207 t.Resume(); |
|
208 gThreadSem.Wait(); |
|
209 |
|
210 test.Next(_L("Load again")); |
|
211 r=lib.Load(KDll1Name); |
|
212 test(r==KErrNone); |
|
213 test.Printf(_L("DLLA1 Process Name %S\n"),&DllA1ProcessName(lib)); |
|
214 test.Printf(_L("DLLA1 Thread Name %S\n"),&DllA1ThreadName(lib)); |
|
215 test(DllA1ProcessName(lib)==RProcess().FullName()); |
|
216 test(DllA1ThreadName(lib)==t.FullName()); |
|
217 test.Next(_L("Check Dll data")); |
|
218 f=lib.Lookup(1); |
|
219 test((*f)()==KErrNone); |
|
220 f=lib.Lookup(2); |
|
221 test((*f)()==1); |
|
222 test((*f)()==2); |
|
223 test((*f)()==3); |
|
224 |
|
225 Kick(t); |
|
226 User::WaitForRequest(stat); |
|
227 test(stat==KErrNone); |
|
228 test(t.ExitType()==EExitKill); |
|
229 |
|
230 SpawnExe(); |
|
231 |
|
232 test.Printf(_L("DLLA1 Process Name %S\n"),&DllA1ProcessName(lib)); |
|
233 test.Printf(_L("DLLA1 Thread Name %S\n"),&DllA1ThreadName(lib)); |
|
234 test(DllA1ProcessName(lib)==RProcess().FullName()); |
|
235 test(DllA1ThreadName(lib)==t.FullName()); |
|
236 test((*f)()==4); |
|
237 test((*f)()==5); |
|
238 test((*f)()==6); |
|
239 |
|
240 CLOSE_AND_WAIT(t); |
|
241 test.Next(_L("Close")); |
|
242 lib.Close(); |
|
243 |
|
244 test.Next(_L("Load a dll that this process is statically linked to")); |
|
245 r=lib.Load(KDll3Name); |
|
246 test.Printf(_L("Returns %d\n"),r); |
|
247 test(r==KErrNone); |
|
248 test(GetDll3Data()==105); |
|
249 |
|
250 test.Next(_L("Close it")); |
|
251 lib.Close(); |
|
252 test(GetDll3Data()==105); |
|
253 |
|
254 test.Next(_L("Load a dll that is statically linked to this process")); |
|
255 test(ExportCallCount==0); |
|
256 r=lib.Load(KDll2Name); |
|
257 test(r==KErrNone); |
|
258 test(InitialisedData==0x7c99103c); |
|
259 for (i=0; i<31; ++i) |
|
260 test(ZeroInitialisedData[i]==(i+487)*(i+487)); |
|
261 test(ExportCallCount==1); |
|
262 test.Next(_L("Close it")); |
|
263 lib.Close(); |
|
264 test(ExportCallCount==2); |
|
265 |
|
266 test.Next(_L("Load it in a different thread")); |
|
267 r=t.Create(_L("Thread1"), Thread1, KDefaultStackSize, NULL, (TAny*)&KDll2Name); |
|
268 test(r==KErrNone); |
|
269 t.SetPriority(EPriorityMore); |
|
270 t.Logon(stat); |
|
271 t.Resume(); |
|
272 gThreadSem.Wait(); |
|
273 test(ExportCallCount==3); |
|
274 Kick(t); |
|
275 User::WaitForRequest(stat); |
|
276 test(stat==KErrNone); |
|
277 test(t.ExitType()==EExitKill); |
|
278 test(ExportCallCount==4); |
|
279 CLOSE_AND_WAIT(t); |
|
280 |
|
281 r=t.Create(_L("Thread2"), Thread2, KDefaultStackSize, NULL, (TAny*)&KDll2Name); |
|
282 test(r==KErrNone); |
|
283 t.SetPriority(EPriorityMore); |
|
284 t.Logon(stat); |
|
285 t.Resume(); |
|
286 gThreadSem.Wait(); |
|
287 test(ExportCallCount==5); |
|
288 SpawnExe(); |
|
289 Kick(t); |
|
290 User::WaitForRequest(stat); |
|
291 test(stat==KErrNone); |
|
292 test(t.ExitType()==EExitKill); |
|
293 test(ExportCallCount==6); |
|
294 CLOSE_AND_WAIT(t); |
|
295 |
|
296 test.Next(_L("Test loading twice")); |
|
297 RDebug::Print(_L("Loading T_DLLA1.DLL")); |
|
298 r=lib.Load(KDll1Name); |
|
299 test(r==KErrNone); |
|
300 f=lib.Lookup(1); |
|
301 test((*f)()==KErrNone); |
|
302 f=lib.Lookup(2); |
|
303 test((*f)()==1); |
|
304 test(DllA1ProcessName(lib)==RProcess().FullName()); |
|
305 test(DllA1ThreadName(lib)==RThread().FullName()); |
|
306 RLibrary lib2; |
|
307 RDebug::Print(_L("Loading T_DLLA1.DLL again")); |
|
308 r=lib2.Load(KDll1Name); |
|
309 test(r==KErrNone); |
|
310 f=lib2.Lookup(2); |
|
311 test((*f)()==2); |
|
312 test(DllA1ProcessName(lib2)==RProcess().FullName()); |
|
313 test(DllA1ThreadName(lib2)==RThread().FullName()); |
|
314 |
|
315 test.Next(_L("Close One")); |
|
316 RDebug::Print(_L("Closing T_DLLA1")); |
|
317 lib.Close(); |
|
318 f=lib2.Lookup(2); |
|
319 test((*f)()==3); |
|
320 test(DllA1ProcessName(lib2)==RProcess().FullName()); |
|
321 test(DllA1ThreadName(lib2)==RThread().FullName()); |
|
322 |
|
323 test.Next(_L("Close Two")); |
|
324 RDebug::Print(_L("Closing T_DLLA1 again")); |
|
325 lib2.Close(); |
|
326 test(GetDll3Data()==105); |
|
327 |
|
328 test.End(); |
|
329 return(KErrNone); |
|
330 } |
|
331 |