|
1 // Copyright (c) 1994-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\system\t_env.cpp |
|
15 // Overview: |
|
16 // Test RProcess parameters |
|
17 // API Information: |
|
18 // RProcess |
|
19 // Details: |
|
20 // - Create a thread that causes a variety of panics. Verify that the exit |
|
21 // reason is as expected. |
|
22 // - Create a process that causes a variety of panics. Verify that the results |
|
23 // are as expected. |
|
24 // - Test passing 16 bit and 8 bit descriptors to another process. Verify the |
|
25 // text and other results are as expected. |
|
26 // - Verify that an invalid read of a descriptor by a process causes a panic. |
|
27 // - Test passing zero length data to a separate process works as expected. |
|
28 // - Test that passing each of a mutex, semaphore, file handle and chunk to a |
|
29 // separate process works as expected. |
|
30 // Platforms/Drives/Compatibility: |
|
31 // All. |
|
32 // Assumptions/Requirement/Pre-requisites: |
|
33 // Failures and causes: |
|
34 // Base Port information: |
|
35 // |
|
36 // |
|
37 |
|
38 #include <e32std.h> |
|
39 #include <e32std_private.h> |
|
40 #include <e32test.h> |
|
41 #include <e32panic.h> |
|
42 #include <e32msgqueue.h> |
|
43 #include <d32comm.h> |
|
44 #include <f32file.h> |
|
45 |
|
46 #if defined (__WINS__) |
|
47 #define PDD_NAME _L("ECDRV.PDD") |
|
48 #define LDD_NAME _L("ECOMM.LDD") |
|
49 #else |
|
50 #define PDD_NAME _L("EUART") |
|
51 #define LDD_NAME _L("ECOMM") |
|
52 #endif |
|
53 |
|
54 |
|
55 LOCAL_D RTest test(_L("T_ENV")); |
|
56 |
|
57 |
|
58 _LIT(KProcName, "t_env_child.exe"); |
|
59 _LIT(KThreadName, "t_env_panic_thread"); |
|
60 _LIT(KQueueName, "testqueue"); |
|
61 _LIT(KMutexName, "testmutex"); |
|
62 _LIT(KSemName, "testsemaphore"); |
|
63 _LIT(KChunkName, "testchunk"); |
|
64 _LIT(KFileName, "c:\\testfile"); |
|
65 |
|
66 const TInt KHeapSize=0x2000; |
|
67 |
|
68 |
|
69 |
|
70 class TData |
|
71 { |
|
72 public: |
|
73 TData(TInt aTest, RProcess& aProcess); |
|
74 TInt iTest; |
|
75 RProcess& iProcess; |
|
76 }; |
|
77 |
|
78 TData::TData(TInt aTest, RProcess& aProcess) : iTest(aTest), iProcess(aProcess) |
|
79 { |
|
80 //empty |
|
81 }; |
|
82 |
|
83 |
|
84 class Handles |
|
85 { |
|
86 public: |
|
87 void SetupParameters(RProcess& aNewProcess); |
|
88 Handles(); |
|
89 ~Handles(); |
|
90 void Command(TInt aCommand); |
|
91 |
|
92 public: |
|
93 RMsgQueue<TInt> iCommandQueue; |
|
94 RMsgQueue<TInt> iIntQueue; |
|
95 RMutex iMutex; |
|
96 RSemaphore iSem; |
|
97 RChunk iChunk; |
|
98 RFile iFile; |
|
99 RFs iSession; |
|
100 }; |
|
101 |
|
102 void Handles::Command(TInt aC) |
|
103 { |
|
104 iCommandQueue.SendBlocking(aC); |
|
105 } |
|
106 |
|
107 void Handles::SetupParameters(RProcess& aNewProcess) |
|
108 { |
|
109 aNewProcess.SetParameter(1, iCommandQueue); |
|
110 aNewProcess.SetParameter(2, iIntQueue); |
|
111 aNewProcess.SetParameter(3, iMutex); |
|
112 aNewProcess.SetParameter(4, iSem); |
|
113 aNewProcess.SetParameter(5, iChunk); |
|
114 aNewProcess.SetParameter(7, iSession); |
|
115 aNewProcess.SetParameter(8, iFile); |
|
116 } |
|
117 |
|
118 |
|
119 |
|
120 _LIT8(KTestData,"test data"); |
|
121 |
|
122 Handles::Handles() |
|
123 { |
|
124 TInt ret = iCommandQueue.CreateGlobal(KNullDesC, 10, EOwnerProcess); |
|
125 test(ret == KErrNone); |
|
126 |
|
127 ret = iIntQueue.CreateGlobal(KQueueName,1); |
|
128 test(ret == KErrNone); |
|
129 |
|
130 ret = iMutex.CreateGlobal(KMutexName); |
|
131 test(ret == KErrNone); |
|
132 |
|
133 ret = iSem.CreateGlobal(KSemName,0); |
|
134 test(ret == KErrNone); |
|
135 |
|
136 ret = iChunk.CreateGlobal(KChunkName, 1024, 2048); |
|
137 test(ret == KErrNone); |
|
138 |
|
139 ret = iSession.Connect(); |
|
140 test(ret == KErrNone); |
|
141 |
|
142 ret = iSession.ShareProtected(); |
|
143 test(ret == KErrNone); |
|
144 |
|
145 ret = iFile.Open(iSession, KFileName, EFileStreamText|EFileWrite|EFileShareAny); |
|
146 if (ret == KErrNotFound) // file does not exist - create it |
|
147 ret = iFile.Create(iSession, KFileName, EFileStreamText|EFileWrite|EFileShareAny); |
|
148 test(ret == KErrNone); |
|
149 ret = iFile.Write(0, KTestData); |
|
150 test(ret == KErrNone); |
|
151 } |
|
152 |
|
153 Handles::~Handles() |
|
154 { |
|
155 iCommandQueue.Close(); |
|
156 iIntQueue.Close(); |
|
157 iMutex.Close(); |
|
158 iSem.Close(); |
|
159 iChunk.Close(); |
|
160 iSession.Close(); |
|
161 } |
|
162 |
|
163 |
|
164 LOCAL_C TInt testSetParameterPanics(TAny* aData) |
|
165 { |
|
166 const TData* data = (const TData*)aData; |
|
167 switch (data->iTest) |
|
168 { |
|
169 case 0: //try and pass a non local handle |
|
170 { |
|
171 RMsgQueue<TInt> localMsgQueue; |
|
172 localMsgQueue.CreateLocal(1); |
|
173 data->iProcess.SetParameter(1, localMsgQueue); //should panic with plat security panic |
|
174 break; |
|
175 } |
|
176 |
|
177 case 1: //out of range slot |
|
178 { |
|
179 RMsgQueue<TInt> globalMsgQueue; |
|
180 globalMsgQueue.CreateGlobal(KNullDesC, 1); |
|
181 data->iProcess.SetParameter(-1, globalMsgQueue); //should panic with range error |
|
182 break; |
|
183 } |
|
184 |
|
185 case 2: |
|
186 { |
|
187 RMsgQueue<TInt> globalMsgQueue; |
|
188 globalMsgQueue.CreateGlobal(KNullDesC, 1); |
|
189 data->iProcess.SetParameter(1234, globalMsgQueue); //should panic with range error |
|
190 break; |
|
191 } |
|
192 |
|
193 case 3: //in use |
|
194 { |
|
195 RMsgQueue<TInt> globalMsgQueue; |
|
196 globalMsgQueue.CreateGlobal(KNullDesC, 1); |
|
197 data->iProcess.SetParameter(1, globalMsgQueue); |
|
198 data->iProcess.SetParameter(1, globalMsgQueue); //panic, in use |
|
199 break; |
|
200 } |
|
201 |
|
202 case 4: |
|
203 { |
|
204 TPtrC8 bad((const TUint8*)0xfeed,4); |
|
205 data->iProcess.SetParameter(1, bad); |
|
206 break; |
|
207 } |
|
208 |
|
209 case 5: //slot 0 is for the command line |
|
210 { |
|
211 RMsgQueue<TInt> globalMsgQueue; |
|
212 globalMsgQueue.CreateGlobal(KNullDesC, 1); |
|
213 data->iProcess.SetParameter(0, globalMsgQueue); //panic, in use |
|
214 break; |
|
215 } |
|
216 |
|
217 } |
|
218 return KErrNone; |
|
219 } |
|
220 |
|
221 |
|
222 |
|
223 |
|
224 GLDEF_C TInt E32Main() |
|
225 { |
|
226 |
|
227 test.Title(); |
|
228 test.Start(_L("Process Parameters")); |
|
229 |
|
230 test.Next(_L("Test Panics on a set")); |
|
231 |
|
232 TBool jit = User::JustInTime(); |
|
233 User::SetJustInTime(EFalse); |
|
234 TInt i; |
|
235 RProcess p; |
|
236 TInt ret = p.Create(KProcName, KProcName); |
|
237 test(ret == KErrNone); |
|
238 for (i = 0; i < 6; i++) |
|
239 { |
|
240 test.Printf(_L("panic test number %d\n"), i); |
|
241 TData data(i, p); |
|
242 RThread thread; |
|
243 ret = thread.Create(KThreadName, testSetParameterPanics, KDefaultStackSize, KHeapSize, KHeapSize, &data); |
|
244 test(KErrNone == ret); |
|
245 TRequestStatus stat; |
|
246 thread.Logon(stat); |
|
247 thread.Resume(); |
|
248 User::WaitForRequest(stat); |
|
249 test.Printf(_L("exit type is %d, stat is %d"), thread.ExitType(), stat.Int()); |
|
250 test (thread.ExitType() == EExitPanic); |
|
251 switch (i) |
|
252 { |
|
253 case 0: |
|
254 test (thread.ExitReason() == EPlatformSecurityTrap); |
|
255 break; |
|
256 |
|
257 case 1: |
|
258 case 2: |
|
259 test (thread.ExitReason() == EParameterSlotRange); |
|
260 break; |
|
261 |
|
262 case 3: |
|
263 case 5: |
|
264 test (thread.ExitReason() == EParameterSlotInUse); |
|
265 break; |
|
266 |
|
267 case 4: |
|
268 test (thread.ExitReason() == ECausedException); |
|
269 break; |
|
270 } |
|
271 CLOSE_AND_WAIT(thread); |
|
272 } |
|
273 p.Kill(0); |
|
274 CLOSE_AND_WAIT(p); |
|
275 |
|
276 test.Next(_L("launch panicing process")); |
|
277 |
|
278 |
|
279 Handles h; |
|
280 |
|
281 TRequestStatus stat; |
|
282 for (i = 0; i < 1; i++) |
|
283 { |
|
284 h.Command(i); |
|
285 ret = p.Create(KProcName, KNullDesC); |
|
286 test(ret == KErrNone); |
|
287 p.Logon(stat); |
|
288 h.SetupParameters(p); |
|
289 p.Resume(); |
|
290 User::WaitForRequest(stat); |
|
291 test(p.ExitType()==EExitPanic); |
|
292 test(p.ExitReason()==EParameterSlotRange); |
|
293 CLOSE_AND_WAIT(p); |
|
294 } |
|
295 User::SetJustInTime(jit); |
|
296 |
|
297 test.Next(_L("test 16 bit descriptor")); |
|
298 h.Command(8); |
|
299 ret = p.Create(KProcName, KNullDesC); |
|
300 test(ret == KErrNone); |
|
301 p.Logon(stat); |
|
302 h.SetupParameters(p); |
|
303 p.SetParameter(15, _L("16 bit text")); |
|
304 p.Resume(); |
|
305 User::WaitForRequest(stat); |
|
306 test(p.ExitType()==EExitKill); |
|
307 test(p.ExitReason()==KErrNone); |
|
308 CLOSE_AND_WAIT(p); |
|
309 |
|
310 test.Next(_L("test 8 bit descriptor")); |
|
311 h.Command(9); |
|
312 ret = p.Create(KProcName, KNullDesC); |
|
313 test(ret == KErrNone); |
|
314 p.Logon(stat); |
|
315 h.SetupParameters(p); |
|
316 p.SetParameter(15, _L8("8 bit text")); |
|
317 p.Resume(); |
|
318 User::WaitForRequest(stat); |
|
319 test(p.ExitType()==EExitKill); |
|
320 test(p.ExitReason()==KErrNone); |
|
321 CLOSE_AND_WAIT(p); |
|
322 |
|
323 |
|
324 test.Next(_L("test bad read of descriptor")); |
|
325 h.Command(10); |
|
326 ret = p.Create(KProcName, KNullDesC); |
|
327 test(ret == KErrNone); |
|
328 p.Logon(stat); |
|
329 h.SetupParameters(p); |
|
330 p.SetParameter(15, _L8("aa")); |
|
331 p.Resume(); |
|
332 User::WaitForRequest(stat); |
|
333 test(p.ExitType()==EExitPanic); |
|
334 test(p.ExitReason()==ECausedException); |
|
335 CLOSE_AND_WAIT(p); |
|
336 |
|
337 test.Next(_L("test zero length data")); |
|
338 h.Command(11); |
|
339 ret = p.Create(KProcName, KNullDesC); |
|
340 test(ret == KErrNone); |
|
341 p.Logon(stat); |
|
342 h.SetupParameters(p); |
|
343 p.SetParameter(15, KNullDesC); |
|
344 p.Resume(); |
|
345 User::WaitForRequest(stat); |
|
346 test(p.ExitType()==EExitKill); |
|
347 test(p.ExitReason()==KErrNone); |
|
348 CLOSE_AND_WAIT(p); |
|
349 |
|
350 test.Next(_L("test reserved command line")); |
|
351 h.Command(12); |
|
352 ret = p.Create(KProcName, KNullDesC); |
|
353 test(ret == KErrNone); |
|
354 p.Logon(stat); |
|
355 h.SetupParameters(p); |
|
356 p.Resume(); |
|
357 User::WaitForRequest(stat); |
|
358 test(p.ExitType()==EExitKill); |
|
359 test(p.ExitReason()==KErrNone); |
|
360 CLOSE_AND_WAIT(p); |
|
361 |
|
362 |
|
363 test.Next(_L("test mutex")); |
|
364 h.Command(4); |
|
365 ret = p.Create(KProcName, KNullDesC); |
|
366 test(ret == KErrNone); |
|
367 p.Logon(stat); |
|
368 h.SetupParameters(p); |
|
369 p.Resume(); |
|
370 User::WaitForRequest(stat); |
|
371 test(p.ExitType()==EExitKill); |
|
372 test(p.ExitReason()==KErrNone); |
|
373 CLOSE_AND_WAIT(p); |
|
374 |
|
375 |
|
376 test.Next(_L("test semaphore")); |
|
377 h.Command(5); |
|
378 ret = p.Create(KProcName, KNullDesC); |
|
379 test(ret == KErrNone); |
|
380 p.Logon(stat); |
|
381 h.SetupParameters(p); |
|
382 p.Resume(); |
|
383 User::WaitForRequest(stat); |
|
384 test(p.ExitType()==EExitKill); |
|
385 test(p.ExitReason()==KErrNone); |
|
386 CLOSE_AND_WAIT(p); |
|
387 |
|
388 test.Next(_L("test file handle")); |
|
389 h.Command(6); |
|
390 ret = p.Create(KProcName, KNullDesC); |
|
391 test(ret == KErrNone); |
|
392 p.Logon(stat); |
|
393 h.SetupParameters(p); |
|
394 p.Resume(); |
|
395 User::WaitForRequest(stat); |
|
396 test(p.ExitType()==EExitKill); |
|
397 test(p.ExitReason()==KErrNone); |
|
398 CLOSE_AND_WAIT(p); |
|
399 |
|
400 test.Next(_L("test chunk")); |
|
401 h.Command(7); |
|
402 ret = p.Create(KProcName, KNullDesC); |
|
403 test(ret == KErrNone); |
|
404 p.Logon(stat); |
|
405 h.SetupParameters(p); |
|
406 p.Resume(); |
|
407 User::WaitForRequest(stat); |
|
408 test(p.ExitType()==EExitKill); |
|
409 test(p.ExitReason()==KErrNone); |
|
410 CLOSE_AND_WAIT(p); |
|
411 |
|
412 test.End(); |
|
413 return 0; |
|
414 } |