|
1 /* |
|
2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * TestUtil - server implementation |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 /** |
|
23 @file |
|
24 @test |
|
25 @internalComponent |
|
26 */ |
|
27 |
|
28 #include "testutilserver.h" |
|
29 #include "testutilsession.h" |
|
30 #include "testutilclientserver.h" |
|
31 |
|
32 // Timer implementation |
|
33 CGenericTimer* CGenericTimer::NewL(MTimeoutClient& aClient) |
|
34 { |
|
35 CGenericTimer* self = new(ELeave) CGenericTimer(aClient); |
|
36 CleanupStack::PushL(self); |
|
37 self->ConstructL(); // calls CTimer::Construct |
|
38 CleanupStack::Pop(self); |
|
39 return self; |
|
40 } |
|
41 |
|
42 CGenericTimer::CGenericTimer(MTimeoutClient& aClient) |
|
43 : CTimer(-1), iClient(aClient) |
|
44 { |
|
45 CActiveScheduler::Add(this); |
|
46 } |
|
47 |
|
48 void CGenericTimer::RunL() |
|
49 { |
|
50 // When the timeout expires, then call the client's handler |
|
51 iClient.HandleTimeout(); |
|
52 }; |
|
53 |
|
54 // file detector implementation |
|
55 CTestFileDetector* CTestFileDetector::NewL(const RMessage2& aMessage, RFs& aFs) |
|
56 { |
|
57 CTestFileDetector* self = new (ELeave) CTestFileDetector(aMessage, aFs); |
|
58 CleanupStack::PushL(self); |
|
59 self->ConstructL(); |
|
60 CleanupStack::Pop(self); |
|
61 return self; |
|
62 } |
|
63 |
|
64 CTestFileDetector::CTestFileDetector(const RMessage2& aMessage, RFs& aFs) |
|
65 :CActive(EPriorityNormal), iFs(aFs), iMessage(aMessage) |
|
66 { |
|
67 iTimeInterval = iMessage.Int1(); |
|
68 CActiveScheduler::Add(this); |
|
69 } |
|
70 |
|
71 CTestFileDetector::~CTestFileDetector() |
|
72 { |
|
73 Cancel(); |
|
74 delete iTimer; |
|
75 delete iFileName; |
|
76 } |
|
77 |
|
78 void CTestFileDetector::ConstructL() |
|
79 { |
|
80 if (iTimeInterval!=0) |
|
81 { |
|
82 iTimer=CGenericTimer::NewL(*this); |
|
83 } |
|
84 iFileName = CTestUtilSessionCommon::AllocateInputBufferLC(iMessage, 0); |
|
85 CleanupStack::Pop(); |
|
86 } |
|
87 |
|
88 void CTestFileDetector::DetectFile() |
|
89 { |
|
90 if (!iTimer) |
|
91 { |
|
92 CheckAndComplete(); |
|
93 } |
|
94 else |
|
95 { |
|
96 TEntry entry; |
|
97 TInt err=iFs.Entry(iFileName->Des(), entry); |
|
98 if (err == KErrNone) |
|
99 { |
|
100 TPckgC<TBool> exists(ETrue); |
|
101 iMessage.WriteL(2, exists); |
|
102 iMessage.Complete(KErrNone); |
|
103 } |
|
104 else |
|
105 { |
|
106 iTimer->After(iTimeInterval*1000); |
|
107 iFs.NotifyChange(ENotifyFile, |
|
108 iStatus, |
|
109 iFileName->Des()); |
|
110 SetActive(); |
|
111 } |
|
112 } |
|
113 } |
|
114 |
|
115 void CTestFileDetector::RunL() |
|
116 { |
|
117 if (iTimer) |
|
118 { |
|
119 iTimer->Cancel(); |
|
120 } |
|
121 CheckAndComplete(); |
|
122 } |
|
123 |
|
124 void CTestFileDetector::DoCancel() |
|
125 { |
|
126 iFs.NotifyChangeCancel(iStatus); |
|
127 } |
|
128 |
|
129 void CTestFileDetector::HandleTimeout() |
|
130 { |
|
131 Cancel(); |
|
132 CheckAndComplete(); |
|
133 } |
|
134 |
|
135 void CTestFileDetector::CheckAndComplete() |
|
136 { |
|
137 TEntry entry; |
|
138 TInt err=iFs.Entry(iFileName->Des(), entry); |
|
139 if (err == KErrNone) |
|
140 { |
|
141 TPckgC<TBool> exists(ETrue); |
|
142 iMessage.WriteL(2, exists); |
|
143 iMessage.Complete(KErrNone); |
|
144 } |
|
145 else if (err == KErrNotFound |
|
146 || err == KErrPathNotFound |
|
147 || err == KErrNotReady |
|
148 || err == KErrCorrupt) |
|
149 { |
|
150 TPckgC<TBool> exists(EFalse); |
|
151 iMessage.WriteL(2, exists); |
|
152 iMessage.Complete(KErrNone); |
|
153 } |
|
154 else |
|
155 { |
|
156 iMessage.Complete(err); |
|
157 } |
|
158 } |
|
159 |
|
160 // CTestUtilSession Implementation |
|
161 CTestUtilSession::CTestUtilSession() |
|
162 { |
|
163 } |
|
164 |
|
165 CTestUtilSession::~CTestUtilSession() |
|
166 { |
|
167 Server().DropSession(); |
|
168 for (TInt i = 0;i < iLockedFileHandles.Count(); i++) |
|
169 { |
|
170 iLockedFileHandles[i].Close(); |
|
171 } |
|
172 iLockedFileHandles.Close(); |
|
173 |
|
174 delete iFileWatcher; |
|
175 delete iDetector; |
|
176 } |
|
177 |
|
178 void CTestUtilSession::CreateL() |
|
179 { |
|
180 Server().AddSession(); |
|
181 } |
|
182 |
|
183 _LIT(KBP, ":\\"); |
|
184 _LIT(KFAT,"Fat"); |
|
185 |
|
186 void CTestUtilSession::ServiceL(const RMessage2& aMessage) |
|
187 { |
|
188 switch (aMessage.Function()) |
|
189 { |
|
190 case ECopy: |
|
191 { |
|
192 HBufC* source = CTestUtilSessionCommon::AllocateInputBufferLC(aMessage,0); |
|
193 HBufC* destination = CTestUtilSessionCommon::AllocateInputBufferLC(aMessage,1); |
|
194 |
|
195 TInt err = Server().FileMan().Copy(*source, *destination, CFileMan::ERecurse | CFileMan::EOverWrite); |
|
196 if (err == KErrNone) |
|
197 { |
|
198 // Turn off the read only attributes |
|
199 TTime time(0); // must specify 0, or a valid time, otherwise sets time to a random value and causes -6/-21 errors |
|
200 err = Server().FileMan().Attribs(*destination, 0, KEntryAttReadOnly, time, CFileMan::ERecurse); |
|
201 } |
|
202 |
|
203 CleanupStack::PopAndDestroy(destination); |
|
204 CleanupStack::PopAndDestroy(source); |
|
205 |
|
206 aMessage.Complete(err); |
|
207 break; |
|
208 } |
|
209 case EMove: |
|
210 { |
|
211 HBufC* source = CTestUtilSessionCommon::AllocateInputBufferLC(aMessage,0); |
|
212 HBufC* destination = CTestUtilSessionCommon::AllocateInputBufferLC(aMessage,1); |
|
213 |
|
214 TInt err = Server().FS().Rename(*source,*destination); |
|
215 if (err == KErrNone) |
|
216 { |
|
217 // Turn off the read only attributes |
|
218 TTime time(0); // must specify 0, or a valid time, otherwise sets time to a random value and causes -6/-21 errors |
|
219 err = Server().FileMan().Attribs(*destination, 0, KEntryAttReadOnly, time, CFileMan::ERecurse); |
|
220 } |
|
221 |
|
222 CleanupStack::PopAndDestroy(destination); |
|
223 CleanupStack::PopAndDestroy(source); |
|
224 |
|
225 aMessage.Complete(err); |
|
226 break; |
|
227 } |
|
228 case EDelete: |
|
229 { |
|
230 HBufC* fileName = CTestUtilSessionCommon::AllocateInputBufferLC(aMessage,0); |
|
231 TEntry entry; |
|
232 TInt err = Server().FS().Entry(*fileName, entry); |
|
233 if (err == KErrNone) |
|
234 { |
|
235 if (entry.IsDir()) |
|
236 { |
|
237 TPath pathName(*fileName); |
|
238 if (pathName[pathName.Length() - 1] != KPathDelimiter) |
|
239 { |
|
240 pathName.Append(KPathDelimiter); |
|
241 } |
|
242 err = Server().FileMan().RmDir(pathName); |
|
243 } |
|
244 else |
|
245 { |
|
246 err = Server().FS().Delete(*fileName); |
|
247 } |
|
248 } |
|
249 CleanupStack::PopAndDestroy(fileName); |
|
250 |
|
251 aMessage.Complete(err); |
|
252 break; |
|
253 } |
|
254 case ERmDir: |
|
255 { |
|
256 HBufC* fileName = CTestUtilSessionCommon::AllocateInputBufferLC(aMessage,0); |
|
257 TParsePtrC parsePtr(*fileName); |
|
258 if(parsePtr.IsRoot()) |
|
259 { |
|
260 User::Leave(KErrAccessDenied); |
|
261 } |
|
262 TInt err = Server().FileMan().RmDir(*fileName); |
|
263 CleanupStack::PopAndDestroy(fileName); |
|
264 |
|
265 aMessage.Complete(err); |
|
266 break; |
|
267 } |
|
268 case EMkDirAll: |
|
269 { |
|
270 HBufC* fileName = CTestUtilSessionCommon::AllocateInputBufferLC(aMessage,0); |
|
271 TInt err = Server().FS().MkDirAll(*fileName); |
|
272 CleanupStack::PopAndDestroy(fileName); |
|
273 |
|
274 aMessage.Complete(err); |
|
275 break; |
|
276 } |
|
277 case EFileExists: |
|
278 { |
|
279 delete iDetector; |
|
280 iDetector=CTestFileDetector::NewL(aMessage, |
|
281 Server().FS()); |
|
282 iDetector->DetectFile(); |
|
283 break; |
|
284 } |
|
285 case ELock: |
|
286 { |
|
287 HBufC* fileName = CTestUtilSessionCommon::AllocateInputBufferLC(aMessage,0); |
|
288 RFile lockFile; |
|
289 TInt err = lockFile.Open(Server().FS(), *fileName, EFileWrite); |
|
290 if (err == KErrNone) |
|
291 iLockedFileHandles.Append(lockFile); |
|
292 |
|
293 CleanupStack::PopAndDestroy(fileName); |
|
294 aMessage.Complete(err); |
|
295 break; |
|
296 } |
|
297 case EUnlock: |
|
298 { |
|
299 HBufC* fileName = CTestUtilSessionCommon::AllocateInputBufferLC(aMessage,0); |
|
300 TInt err = KErrNotFound; |
|
301 TFileName lockedFileName; |
|
302 for (TInt i = 0; i < iLockedFileHandles.Count() && err;i++) |
|
303 { |
|
304 TInt err2 = iLockedFileHandles[i].FullName(lockedFileName); |
|
305 User::LeaveIfError(err2); |
|
306 if (lockedFileName.MatchF(*fileName) != KErrNotFound) |
|
307 { |
|
308 iLockedFileHandles[i].Close(); |
|
309 iLockedFileHandles.Remove(i); |
|
310 err = KErrNone; |
|
311 } |
|
312 } |
|
313 CleanupStack::PopAndDestroy(fileName); |
|
314 aMessage.Complete(err); |
|
315 break; |
|
316 } |
|
317 case EFormat: |
|
318 { |
|
319 TInt drive = aMessage.Int0(); |
|
320 TBool formatFatOnly = aMessage.Int1(); |
|
321 TChar aDriveChar; |
|
322 User::LeaveIfError(Server().FS().DriveToChar(drive, aDriveChar)); |
|
323 TBuf<3> bfDrv; |
|
324 bfDrv.Append(aDriveChar); |
|
325 bfDrv.Append(KBP); |
|
326 |
|
327 RFormat format; |
|
328 TInt count; |
|
329 User::LeaveIfError(format.Open(Server().FS(), bfDrv, EHighDensity, count)); |
|
330 CleanupClosePushL(format); |
|
331 |
|
332 if (formatFatOnly) |
|
333 { |
|
334 User::LeaveIfError(format.Next(count)); |
|
335 } |
|
336 else |
|
337 { |
|
338 while (count > 0) |
|
339 { |
|
340 User::LeaveIfError(format.Next(count)); |
|
341 } |
|
342 } |
|
343 |
|
344 CleanupStack::PopAndDestroy(&format); |
|
345 aMessage.Complete(KErrNone); |
|
346 break; |
|
347 } |
|
348 case EMount: |
|
349 { |
|
350 TInt drive = aMessage.Int0(); |
|
351 User::LeaveIfError(Server().FS().Connect()); |
|
352 //Mount the drive synchronizely to make sure the drive is ready for the next operation |
|
353 User::LeaveIfError(Server().FS().MountFileSystem(KFAT, drive, ETrue)); |
|
354 aMessage.Complete(KErrNone); |
|
355 break; |
|
356 } |
|
357 case EUnMount: |
|
358 { |
|
359 TInt drive = aMessage.Int0(); |
|
360 TFileName fsName; |
|
361 User::LeaveIfError(Server().FS().FileSystemName(fsName, drive)); |
|
362 User::LeaveIfError(Server().FS().DismountFileSystem(fsName, drive)); |
|
363 aMessage.Complete(KErrNone); |
|
364 break; |
|
365 } |
|
366 case ESetReadOnly: |
|
367 { |
|
368 HBufC* fileName = CTestUtilSessionCommon::AllocateInputBufferLC(aMessage,0); |
|
369 TInt setReadOnly = aMessage.Int1(); |
|
370 TUint setmask; |
|
371 TUint clearmask; |
|
372 if (setReadOnly) |
|
373 { |
|
374 // Setting read only attribute |
|
375 setmask = KEntryAttReadOnly; |
|
376 clearmask = 0; |
|
377 } |
|
378 else |
|
379 { |
|
380 // Clearing read only attribute |
|
381 setmask = 0; |
|
382 clearmask = KEntryAttReadOnly; |
|
383 } |
|
384 |
|
385 // Turn off the read only attributes |
|
386 TTime time(0); |
|
387 TInt err = Server().FileMan().Attribs(*fileName, setmask, clearmask, time); |
|
388 CleanupStack::PopAndDestroy(fileName); |
|
389 aMessage.Complete(err); |
|
390 break; |
|
391 } |
|
392 case EGetFileHandle: |
|
393 { |
|
394 HBufC* fileName = CTestUtilSessionCommon::AllocateInputBufferLC(aMessage,0); |
|
395 RFile file; |
|
396 CleanupClosePushL(file); |
|
397 User::LeaveIfError(file.Open(Server().FS(), *fileName, EFileRead | EFileShareReadersOnly)); |
|
398 User::LeaveIfError(file.TransferToClient(aMessage, 1)); |
|
399 CleanupStack::PopAndDestroy(2, fileName); // file |
|
400 break; |
|
401 } |
|
402 case EWatchFile: |
|
403 { |
|
404 if (iFileWatcher) |
|
405 { |
|
406 if (iFileWatcher->IsActive()) |
|
407 { |
|
408 aMessage.Complete(KErrServerBusy); |
|
409 break; |
|
410 } |
|
411 else |
|
412 { |
|
413 delete iFileWatcher; |
|
414 iFileWatcher = NULL; |
|
415 } |
|
416 } |
|
417 // Create a new file watcher for this session |
|
418 iFileWatcher = CFileWatcher::NewL(Server().FS(), aMessage); |
|
419 break; |
|
420 } |
|
421 case EWatchFileCancel: |
|
422 { |
|
423 if (iFileWatcher) |
|
424 { |
|
425 iFileWatcher->Cancel(); |
|
426 aMessage.Complete(KErrNone); |
|
427 } |
|
428 else |
|
429 { |
|
430 // No file watch request to cancel! |
|
431 aMessage.Complete(KErrNotReady); |
|
432 } |
|
433 break; |
|
434 } |
|
435 case EGetNumFiles: |
|
436 { |
|
437 HBufC* dirPath = CTestUtilSessionCommon::AllocateInputBufferLC(aMessage,0); |
|
438 CDir* dirContents = NULL; |
|
439 |
|
440 User::LeaveIfError(Server().FS().GetDir(*dirPath, KEntryAttNormal, ESortNone, dirContents)); |
|
441 TPckg<TInt> numFiles(dirContents->Count()); |
|
442 |
|
443 delete dirContents; |
|
444 aMessage.WriteL(1, numFiles); |
|
445 aMessage.Complete(KErrNone); |
|
446 CleanupStack::PopAndDestroy(dirPath); |
|
447 break; |
|
448 } |
|
449 default: |
|
450 { |
|
451 PanicClient(aMessage,EPanicIllegalFunction); |
|
452 break; |
|
453 } |
|
454 } |
|
455 } |
|
456 |
|
457 void CTestUtilSession::ServiceError(const RMessage2& aMessage,TInt aError) |
|
458 { |
|
459 if (aError==KErrBadDescriptor) |
|
460 PanicClient(aMessage,EPanicBadDescriptor); |
|
461 CSession2::ServiceError(aMessage,aError); |
|
462 } |
|
463 // End of file |