|
1 // Copyright (c) 2003-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 // TestServer - server implementation |
|
15 // |
|
16 // |
|
17 |
|
18 #include "e32std.h" |
|
19 #include "SmokeTestSecureFSserver.h" |
|
20 #include <f32file.h> |
|
21 |
|
22 TRequestStatus aStatus; |
|
23 TRequestStatus* aSt = &aStatus; |
|
24 |
|
25 |
|
26 inline CTestSecureFSshutdown::CTestSecureFSshutdown() |
|
27 :CTimer(-1) |
|
28 {CActiveScheduler::Add(this);} |
|
29 inline void CTestSecureFSshutdown::ConstructL() |
|
30 {CTimer::ConstructL();} |
|
31 inline void CTestSecureFSshutdown::Start() |
|
32 {After(KMyShutdownDelay);} |
|
33 |
|
34 inline CTestSecureFSserver::CTestSecureFSserver() |
|
35 :CServer2(0,ESharableSessions) |
|
36 {} |
|
37 |
|
38 inline CTestSecureFSSession::CTestSecureFSSession() |
|
39 {} |
|
40 inline CTestSecureFSserver& CTestSecureFSSession::Server() |
|
41 {return *static_cast<CTestSecureFSserver*>(const_cast<CServer2*>(CSession2::Server()));} |
|
42 inline TBool CTestSecureFSSession::ReceivePending() const |
|
43 {return !iReceive.IsNull();} |
|
44 |
|
45 // |
|
46 |
|
47 void CTestSecureFSSession::CreateL() |
|
48 // |
|
49 // 2nd phase construct for sessions - called by the CServer framework |
|
50 // |
|
51 { |
|
52 //RDebug::Print(_L("Server::CTestSecureFSSession::CreateL - start")); |
|
53 |
|
54 Server().AddSession(); |
|
55 //RDebug::Print(_L("Server::CTestSecureFSSession::CreateL - end")); |
|
56 } |
|
57 |
|
58 CTestSecureFSSession::~CTestSecureFSSession() |
|
59 { |
|
60 Server().DropSession(); |
|
61 } |
|
62 |
|
63 void CTestSecureFSSession::Send(const TDesC& aMessage) |
|
64 // |
|
65 // Deliver the message to the client, truncating if required |
|
66 // If the write fails, panic the client, not the sender |
|
67 // |
|
68 { |
|
69 if (ReceivePending()) |
|
70 { |
|
71 TPtrC m(aMessage); |
|
72 if (iReceive.Int1()<aMessage.Length()) |
|
73 m.Set(m.Left(iReceive.Int1())); |
|
74 TInt r=iReceive.Write(0,m); |
|
75 if (r==KErrNone) |
|
76 iReceive.Complete(KErrNone); |
|
77 else |
|
78 PanicClient(iReceive,EPanicBadDescriptor); |
|
79 } |
|
80 } |
|
81 |
|
82 void CTestSecureFSSession::ServiceL(const RMessage2& aMessage) |
|
83 // |
|
84 // Handle a client request. |
|
85 // Leaving is handled by CMyServer::ServiceError() which reports |
|
86 // the error code to the client |
|
87 // |
|
88 { |
|
89 TInt result = KErrNone; |
|
90 |
|
91 switch (aMessage.Function()) |
|
92 { |
|
93 case ETestIpcSetHomeTime: |
|
94 DoSetHomeTime(aMessage); |
|
95 break; |
|
96 |
|
97 case ETestIpcDeleteFile: |
|
98 result = DoDeleteFileL(aMessage); |
|
99 break; |
|
100 |
|
101 case ETestIpcKillProcess: |
|
102 DoKillProcess(aMessage); |
|
103 break; |
|
104 |
|
105 case ETestIpcChangeLocale: |
|
106 result = DoChangeLocale(aMessage); |
|
107 break; |
|
108 |
|
109 case ETestIpcCheckForFile: |
|
110 result = DoCheckForFile(aMessage); |
|
111 break; |
|
112 |
|
113 case ETestIpcCopyFile: |
|
114 result = DoCopyFile(aMessage); |
|
115 break; |
|
116 |
|
117 case ETestIpcSetUpFbs: |
|
118 DoSetUpFbs(); |
|
119 break; |
|
120 |
|
121 default: |
|
122 PanicClient(aMessage,EPanicIllegalFunction); |
|
123 break; |
|
124 } |
|
125 aMessage.Complete(result); |
|
126 } |
|
127 |
|
128 // |
|
129 |
|
130 void CTestSecureFSSession::DoSetHomeTime(const RMessage2& aMessage) |
|
131 { |
|
132 TPckgBuf<TTime> pckg; |
|
133 aMessage.Read(0,pckg); |
|
134 User::SetHomeTime(pckg()); |
|
135 } |
|
136 |
|
137 TInt CTestSecureFSSession::DoDeleteFileL(const RMessage2& aMessage) |
|
138 { |
|
139 RFs fs; |
|
140 TFileName* const fileName=new(ELeave) TFileName; |
|
141 CleanupStack::PushL(fileName); |
|
142 User::LeaveIfError(fs.Connect()); |
|
143 |
|
144 CleanupClosePushL(fs); |
|
145 aMessage.ReadL(0,*fileName); |
|
146 TInt err=fs.Delete(*fileName); |
|
147 if (!(err==KErrNone || err==KErrNotFound || err==KErrPathNotFound)) // ignore not found error |
|
148 { |
|
149 User::Leave(err); |
|
150 } |
|
151 CleanupStack::PopAndDestroy(&fs); |
|
152 CleanupStack::PopAndDestroy(fileName); |
|
153 return err; |
|
154 } |
|
155 |
|
156 void CTestSecureFSSession::DoKillProcess(const RMessage2& aMessage) |
|
157 { |
|
158 TFullName* name = new(ELeave) TFullName; |
|
159 CleanupStack::PushL(name); |
|
160 |
|
161 aMessage.ReadL(0,*name); |
|
162 TFindProcess* finder = new (ELeave) TFindProcess(*name); |
|
163 CleanupStack::PushL(finder); |
|
164 RProcess* process = new (ELeave) RProcess; |
|
165 CleanupStack::PushL(process); |
|
166 |
|
167 if (finder->Next(*name) == KErrNone) |
|
168 { |
|
169 if (process->Open(*name) == KErrNone) |
|
170 { |
|
171 process->Kill(KErrNone); |
|
172 } |
|
173 } |
|
174 |
|
175 if (process != NULL) |
|
176 { |
|
177 process->Close(); |
|
178 } |
|
179 CleanupStack::PopAndDestroy(process); |
|
180 CleanupStack::PopAndDestroy(finder); |
|
181 CleanupStack::PopAndDestroy(name); |
|
182 } |
|
183 |
|
184 |
|
185 TInt CTestSecureFSSession::DoChangeLocale(const RMessage2& aMessage) |
|
186 { |
|
187 TBuf<50> locname; |
|
188 TInt result; |
|
189 aMessage.ReadL(0,locname); |
|
190 |
|
191 result = UserSvr::ChangeLocale(locname); |
|
192 |
|
193 return result; |
|
194 } |
|
195 |
|
196 TInt CTestSecureFSSession::DoCheckForFile(const RMessage2& aMessage) |
|
197 { |
|
198 RFs fs; |
|
199 TInt err; |
|
200 TFileName* const fileName=new(ELeave) TFileName; |
|
201 CleanupStack::PushL(fileName); |
|
202 User::LeaveIfError(fs.Connect()); |
|
203 |
|
204 CleanupClosePushL(fs); |
|
205 aMessage.ReadL(0,*fileName); |
|
206 |
|
207 TUint attribs; |
|
208 err=fs.Att(*fileName, attribs); |
|
209 fs.Close(); |
|
210 |
|
211 CleanupStack::PopAndDestroy(&fs); |
|
212 CleanupStack::PopAndDestroy(fileName); |
|
213 return err; |
|
214 |
|
215 } |
|
216 |
|
217 TInt CTestSecureFSSession::DoCopyFile(const RMessage2& aMessage) |
|
218 { |
|
219 |
|
220 RFs fs; |
|
221 TInt result; |
|
222 |
|
223 User::LeaveIfError(fs.Connect()); |
|
224 CleanupClosePushL(fs); |
|
225 |
|
226 TFileName fileSource; |
|
227 TFileName fileDest; |
|
228 |
|
229 aMessage.ReadL(0,fileSource); |
|
230 aMessage.ReadL(1,fileDest); |
|
231 |
|
232 CFileMan* fileMan = NULL; |
|
233 |
|
234 fileMan = CFileMan::NewL(fs); |
|
235 CleanupStack::PushL( fileMan ); |
|
236 |
|
237 fs.MkDirAll(fileDest); |
|
238 result = fileMan->Copy( fileSource, fileDest, CFileMan::EOverWrite ); |
|
239 |
|
240 User::LeaveIfError(fs.Connect()); |
|
241 fs.SetAtt(fileDest,KEntryAttNormal,KEntryAttReadOnly); |
|
242 fs.Close(); |
|
243 |
|
244 CleanupStack::PopAndDestroy(fileMan); |
|
245 CleanupStack::PopAndDestroy(&fs); |
|
246 return result; |
|
247 |
|
248 } |
|
249 |
|
250 void CTestSecureFSSession::DoSetUpFbs() |
|
251 { |
|
252 // FbsStartup(); |
|
253 // User::LeaveIfError( RFbsSession::Connect() ); |
|
254 // CleanupStack::PushL( TCleanupItem( TCleanupOperation(&RFbsSession::Disconnect ), NULL ) ); |
|
255 } |
|
256 |
|
257 // |
|
258 |
|
259 void CTestSecureFSSession::ServiceError(const RMessage2& aMessage,TInt aError) |
|
260 // |
|
261 // Handle an error from CMySession::ServiceL() |
|
262 // A bad descriptor error implies a badly programmed client, so panic it; |
|
263 // otherwise use the default handling (report the error to the client) |
|
264 // |
|
265 { |
|
266 if (aError==KErrBadDescriptor) |
|
267 PanicClient(aMessage,EPanicBadDescriptor); |
|
268 CSession2::ServiceError(aMessage,aError); |
|
269 } |
|
270 |
|
271 void CTestSecureFSshutdown::RunL() |
|
272 // |
|
273 // Initiate server exit when the timer expires |
|
274 // |
|
275 { |
|
276 CActiveScheduler::Stop(); |
|
277 } |
|
278 |
|
279 CServer2* CTestSecureFSserver::NewLC() |
|
280 { |
|
281 CTestSecureFSserver* self=new(ELeave) CTestSecureFSserver; |
|
282 CleanupStack::PushL(self); |
|
283 self->ConstructL(); |
|
284 return self; |
|
285 } |
|
286 |
|
287 void CTestSecureFSserver::ConstructL() |
|
288 // |
|
289 // 2nd phase construction - ensure the timer and server objects are running |
|
290 // |
|
291 { |
|
292 StartL(KTestServerName); |
|
293 iShutdown.ConstructL(); |
|
294 // ensure that the server still exits even if the 1st client fails to connect |
|
295 iShutdown.Start(); |
|
296 } |
|
297 |
|
298 |
|
299 CSession2* CTestSecureFSserver::NewSessionL(const TVersion&,const RMessage2&) const |
|
300 // |
|
301 // Cretae a new client session. This should really check the version number. |
|
302 // |
|
303 { |
|
304 return new(ELeave) CTestSecureFSSession(); |
|
305 } |
|
306 |
|
307 void CTestSecureFSserver::AddSession() |
|
308 // |
|
309 // A new session is being created |
|
310 // Cancel the shutdown timer if it was running |
|
311 // |
|
312 { |
|
313 ++iSessionCount; |
|
314 iShutdown.Cancel(); |
|
315 } |
|
316 |
|
317 void CTestSecureFSserver::DropSession() |
|
318 // |
|
319 // A session is being destroyed |
|
320 // Start the shutdown timer if it is the last session. |
|
321 // |
|
322 { |
|
323 if (--iSessionCount==0) |
|
324 iShutdown.Start(); |
|
325 } |
|
326 |
|
327 void CTestSecureFSserver::Send(const TDesC& aMessage) |
|
328 // |
|
329 // Pass on the signal to all clients |
|
330 // |
|
331 { |
|
332 iSessionIter.SetToFirst(); |
|
333 CSession2* s; |
|
334 while ((s=iSessionIter++)!=0) |
|
335 static_cast<CTestSecureFSSession*>(s)->Send(aMessage); |
|
336 } |
|
337 |
|
338 void PanicClient(const RMessage2& aMessage,TTestPanic aPanic) |
|
339 // |
|
340 // RMessage::Panic() also completes the message. This is: |
|
341 // (a) important for efficient cleanup within the kernel |
|
342 // (b) a problem if the message is completed a second time |
|
343 // |
|
344 { |
|
345 _LIT(KPanic,"TestServer"); |
|
346 aMessage.Panic(KPanic,aPanic); |
|
347 } |
|
348 |
|
349 |
|
350 |
|
351 /** |
|
352 Perform all server initialisation, in particular creation of the |
|
353 scheduler and server and then run the scheduler |
|
354 */ |
|
355 |
|
356 static void RunServerL() |
|
357 { |
|
358 // naming the server thread after the server helps to debug panics |
|
359 User::LeaveIfError(RThread::RenameMe(KTestServerName)); |
|
360 // create and install the active scheduler we need |
|
361 CActiveScheduler* s=new(ELeave) CActiveScheduler; |
|
362 CleanupStack::PushL(s); |
|
363 CActiveScheduler::Install(s); |
|
364 CTestSecureFSserver::NewLC(); // create the server (leave it on the cleanup stack) |
|
365 RProcess::Rendezvous(KErrNone); |
|
366 CActiveScheduler::Start(); |
|
367 CleanupStack::PopAndDestroy(2); // Cleanup the server and scheduler |
|
368 } |
|
369 |
|
370 |
|
371 |
|
372 |
|
373 TInt E32Main() |
|
374 // |
|
375 // Server process entry-point |
|
376 // |
|
377 { |
|
378 __UHEAP_MARK; |
|
379 // |
|
380 RDebug::Print(_L("Server::E32Main Version 0.0.0")); |
|
381 CTrapCleanup* cleanup=CTrapCleanup::New(); |
|
382 TInt r=KErrNoMemory; |
|
383 if (cleanup) |
|
384 { |
|
385 TRAP(r,RunServerL()); |
|
386 delete cleanup; |
|
387 } |
|
388 // |
|
389 __UHEAP_MARKEND; |
|
390 return r; |
|
391 } |
|
392 |
|
393 |