|
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 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 // |
|
15 |
|
16 #include "sc_std.h" |
|
17 |
|
18 |
|
19 const TInt KMajorVersionNumber=1; |
|
20 const TInt KMinorVersionNumber=1; |
|
21 |
|
22 _LIT(KRofsName,"Rofs"); |
|
23 |
|
24 #ifdef __WINS__ |
|
25 _LIT(KRomName,"Win32"); |
|
26 #else |
|
27 _LIT(KRomName,"Rom"); |
|
28 #endif |
|
29 |
|
30 _LIT(KCompositeName,"Composite"); |
|
31 |
|
32 |
|
33 static void Fault(TCompFault aFault) |
|
34 // |
|
35 // Report a fault in the composite file system. |
|
36 // |
|
37 { |
|
38 User::Panic(_L("COMPFILESYS"),aFault); |
|
39 } |
|
40 |
|
41 |
|
42 CCompFileSystem::CCompFileSystem() |
|
43 { |
|
44 __PRINT1(_L("CCompFileSystem()[0x%x]"), this); |
|
45 } |
|
46 |
|
47 |
|
48 CCompFileSystem::~CCompFileSystem() |
|
49 { |
|
50 __PRINT1(_L("~CCompFileSystem()[0x%x]"),this); |
|
51 if (iMount) |
|
52 { |
|
53 iMount->NullCompFileSystem(); |
|
54 } |
|
55 } |
|
56 |
|
57 |
|
58 TInt CCompFileSystem::Install() |
|
59 // |
|
60 // Install the file system |
|
61 // |
|
62 { |
|
63 __PRINT1(_L("CCompFileSystem::Install()[0x%x]"), this); |
|
64 iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KF32BuildVersionNumber); |
|
65 return(SetName(&KCompositeName)); |
|
66 } |
|
67 |
|
68 |
|
69 CMountCB* CCompFileSystem::NewMountL() const |
|
70 // |
|
71 // Create a new mount control block |
|
72 // |
|
73 { |
|
74 __PRINT1(_L("CCompFileSystem::NewMountL()[0x%x]"), this); |
|
75 |
|
76 // Composite FS is a singleton, and can only have one mount. |
|
77 // If it already exists, just return the existin one. |
|
78 if (iMount == NULL) |
|
79 { |
|
80 ((CCompFileSystem*)this)->iMount = new(ELeave) CCompMountCB((CCompFileSystem *)this); |
|
81 TRAPD(err,iMount->NewRomMountL()); |
|
82 if(err!=KErrNone) |
|
83 { |
|
84 iMount->Close(); |
|
85 User::Leave(err); |
|
86 } |
|
87 } |
|
88 |
|
89 __PRINT1(_L(" created CCompMountCB:0x%x"),iMount); |
|
90 |
|
91 return (iMount); |
|
92 } |
|
93 |
|
94 |
|
95 CFileCB* CCompFileSystem::NewFileL() const |
|
96 // |
|
97 // Create a new file |
|
98 // |
|
99 { |
|
100 __PRINT(_L("CCompFileSystem::NewFileL()")); |
|
101 CFileCB* pFile=new(ELeave) CCompFileCB; |
|
102 __PRINT1(_L("file at 0x%x"),pFile); |
|
103 return(pFile); |
|
104 } |
|
105 |
|
106 |
|
107 CDirCB* CCompFileSystem::NewDirL() const |
|
108 // |
|
109 // create a new directory lister |
|
110 // |
|
111 { |
|
112 __PRINT(_L("CCompFileSystem::NewDirL()")); |
|
113 |
|
114 CCompDirCB* pDir=new (ELeave) CCompDirCB; |
|
115 |
|
116 CleanupStack::PushL(pDir); |
|
117 |
|
118 TInt count = iMount->iMounts.Count(); |
|
119 TInt r=KErrNone; |
|
120 |
|
121 for(TInt idx=0; idx<count; idx++) |
|
122 { |
|
123 TRAPD(err, r=pDir->iDirs.Append(iMount->iMounts[idx].iFs->NewDirL())); |
|
124 if(err!= KErrNone || r != KErrNone) |
|
125 { |
|
126 pDir->Close(); |
|
127 User::Leave(err == KErrNone ? r : err); |
|
128 } |
|
129 } |
|
130 |
|
131 CleanupStack::Pop(pDir); |
|
132 |
|
133 __PRINT1(_L("dir at 0x%x"),pDir); |
|
134 return(pDir); |
|
135 } |
|
136 |
|
137 |
|
138 CFormatCB* CCompFileSystem::NewFormatL() const |
|
139 // |
|
140 // Create a new media formatter |
|
141 // |
|
142 { |
|
143 User::Leave(KErrAccessDenied); |
|
144 return(NULL); |
|
145 } |
|
146 |
|
147 |
|
148 void CCompFileSystem::DriveInfo(TDriveInfo& anInfo,TInt /*aDriveNumber*/) const |
|
149 // |
|
150 // Return drive info |
|
151 // |
|
152 { |
|
153 __PRINT(_L("CCompFileSystem::DriveInfo()")); |
|
154 anInfo.iMediaAtt=KMediaAttWriteProtected; |
|
155 anInfo.iDriveAtt=KDriveAttRom|KDriveAttInternal; |
|
156 anInfo.iType=EMediaRom; |
|
157 } |
|
158 |
|
159 |
|
160 TInt CCompFileSystem::DefaultPath(TDes& /*aPath*/) const |
|
161 // |
|
162 // Return the initial default path. |
|
163 // |
|
164 { |
|
165 Fault(ECompFsDefaultPath); |
|
166 return(KErrNone); |
|
167 } |
|
168 |
|
169 |
|
170 CFileSystem* CCompFileSystem::NewL() |
|
171 // |
|
172 // |
|
173 // |
|
174 { |
|
175 __PRINT(_L("CCompFileSystem::NewL()")); |
|
176 CCompFileSystem* pFs = new(ELeave) CCompFileSystem; |
|
177 |
|
178 __PRINT1(_L("CompFs=0x%x"),pFs); |
|
179 return (pFs); |
|
180 } |
|
181 |
|
182 CCompMountCB::~CCompMountCB() |
|
183 // |
|
184 // |
|
185 // |
|
186 { |
|
187 __PRINT1(_L("~CCompMountCB() this=0x%x"),this); |
|
188 |
|
189 |
|
190 for(TInt mount=iMounts.Count(); mount--;) |
|
191 iMounts[mount].iMount->Close(); |
|
192 |
|
193 iMounts.Close(); |
|
194 |
|
195 if (iFileSystem) |
|
196 { |
|
197 iFileSystem->NullMount(); |
|
198 } |
|
199 } |
|
200 |
|
201 void CCompMountCB::NewRomMountL() |
|
202 // |
|
203 // Creates a new ROM mount, and adds it to the list. |
|
204 // |
|
205 { |
|
206 CFileSystem* romFs= GetFileSystem(KRomName); |
|
207 if(!romFs) |
|
208 { |
|
209 User::Leave(KErrNotFound); |
|
210 } |
|
211 |
|
212 CMountCB* romMount = romFs->NewMountL(); |
|
213 User::LeaveIfError(iMounts.Append(TCompMount(romFs,romMount))); |
|
214 } |
|
215 |
|
216 |
|
217 |
|
218 void CCompMountCB::MountL(TBool aForceMount) |
|
219 // |
|
220 // Mount a media. Only allowed to leave with KErrNoMemory,KErrNotReady,KErrCorrupt,KErrUnknown. |
|
221 // |
|
222 // |
|
223 { |
|
224 __PRINT(_L("CCompMountCB::MountL()")); |
|
225 // First mount rom |
|
226 RomMount()->SetDrive(&Drive()); |
|
227 RomMount()->MountL(aForceMount); |
|
228 |
|
229 // Mounts count starts at 1, as ROMFS starts in slot one. |
|
230 // If its still 1 on mount, then no mounts have been added. |
|
231 // To maintain compatibility with the previous version of this API, |
|
232 // (where you couldn't specifically add mounts) in this case we mount |
|
233 // ROFS by default. |
|
234 // (There would be little point mounting it with only one FS) |
|
235 |
|
236 if (iMounts.Count()==1) |
|
237 { |
|
238 CFileSystem* rofsFs = GetFileSystem(KRofsName); |
|
239 if(!rofsFs) |
|
240 User::Leave(KErrUnknown); |
|
241 |
|
242 AddFsToCompositeMount(rofsFs); |
|
243 } |
|
244 |
|
245 SetVolumeName(_L("RomDrive").AllocL()); |
|
246 |
|
247 // combine sizes |
|
248 for(TInt mount=iMounts.Count(); mount--;) |
|
249 iSize+= iMounts[mount].iMount->Size(); |
|
250 |
|
251 // no need to update iUniqueID since 0 in both rom and rofs |
|
252 } |
|
253 |
|
254 |
|
255 TInt CCompMountCB::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput) |
|
256 { |
|
257 // aInterfaceId : If EAddFsToCompositeMount, method mounts a media and adds to CompFS. |
|
258 // : Local drive mapping for this mount's drive (CompFS's) |
|
259 // should be alterd to indicate the local drive to be added. |
|
260 // aIntput : CFileSystem* for the mount to be added. |
|
261 // aInterFace : Unused. |
|
262 switch(aInterfaceId) |
|
263 { |
|
264 case CMountCB::EFileAccessor: |
|
265 ((CMountCB::MFileAccessor*&) aInterface) = this; |
|
266 return KErrNone; |
|
267 |
|
268 case EAddFsToCompositeMount: |
|
269 return(AddFsToCompositeMount((CFileSystem*) aInput)); |
|
270 |
|
271 case CMountCB::ELocalBufferSupport: |
|
272 { |
|
273 CCompFileCB* file = (CCompFileCB*) aInput; |
|
274 return file?file->TrueFile()->Mount().LocalBufferSupport():KErrNone; |
|
275 } |
|
276 |
|
277 default: |
|
278 return (CMountCB::GetInterface(aInterfaceId,aInterface,aInput)); |
|
279 } |
|
280 } |
|
281 |
|
282 /** |
|
283 Mounts a media with the provided filesystem and adds to the composite mount. |
|
284 Local drive mapping for this mount's drive (CompFS's) should be altered to indicate the local drive to be added. |
|
285 */ |
|
286 TInt CCompMountCB::AddFsToCompositeMount(CFileSystem* aFileSystem) |
|
287 { |
|
288 __PRINT1(_L("CCompMountCB::AddFsToCompositeMount(0x%x)"), aFileSystem); |
|
289 |
|
290 CMountCB* newMount=NULL; |
|
291 TRAPD(err,newMount = aFileSystem->NewMountL()); |
|
292 if (err==KErrNone) |
|
293 { |
|
294 newMount->InitL(Drive(), aFileSystem); |
|
295 TRAP(err,newMount->MountL(EFalse)); |
|
296 if (err==KErrNone) |
|
297 { |
|
298 err = iMounts.Append(TCompMount(aFileSystem,newMount)); |
|
299 if (err!=KErrNone) |
|
300 return err; |
|
301 |
|
302 TInt r = newMount->AddToCompositeMount(iMounts.Count()-1); |
|
303 |
|
304 if(r == KErrNotSupported) |
|
305 r = KErrNone; |
|
306 |
|
307 return r; |
|
308 } |
|
309 |
|
310 } |
|
311 |
|
312 return err; |
|
313 } |
|
314 |
|
315 TInt CCompMountCB::ReMount() |
|
316 // |
|
317 // Try and remount this media. |
|
318 // |
|
319 { |
|
320 return(0); |
|
321 } |
|
322 |
|
323 |
|
324 void CCompMountCB::Dismounted() |
|
325 // |
|
326 // Dummy implementation of pure virtual function |
|
327 // |
|
328 {} |
|
329 |
|
330 |
|
331 void CCompMountCB::VolumeL(TVolumeInfo& aVolume) const |
|
332 // |
|
333 // |
|
334 // Return the volume info. |
|
335 // |
|
336 { |
|
337 __PRINT(_L("CCompMountCB::VolumeL()")); |
|
338 aVolume.iFree=0; |
|
339 } |
|
340 |
|
341 |
|
342 void CCompMountCB::SetVolumeL(TDes& /*aName*/) |
|
343 // |
|
344 // |
|
345 // Set the volume label. |
|
346 // |
|
347 { |
|
348 User::Leave(KErrAccessDenied); |
|
349 } |
|
350 |
|
351 void CCompMountCB::MkDirL(const TDesC& /*aName*/) |
|
352 // |
|
353 // Make a directory. |
|
354 // |
|
355 { |
|
356 User::Leave(KErrAccessDenied); |
|
357 } |
|
358 |
|
359 void CCompMountCB::RmDirL(const TDesC& /*aName*/) |
|
360 // |
|
361 // Remove a directory. |
|
362 // |
|
363 { |
|
364 User::Leave(KErrAccessDenied); |
|
365 } |
|
366 |
|
367 void CCompMountCB::DeleteL(const TDesC& /*aName*/) |
|
368 // |
|
369 // Delete a file. |
|
370 // |
|
371 { |
|
372 User::Leave(KErrAccessDenied); |
|
373 } |
|
374 |
|
375 void CCompMountCB::RenameL(const TDesC& /*anOldName*/,const TDesC& /*anNewName*/) |
|
376 // |
|
377 // Rename a file or directory. |
|
378 // |
|
379 { |
|
380 User::Leave(KErrAccessDenied); |
|
381 } |
|
382 |
|
383 void CCompMountCB::ReplaceL(const TDesC& /*anOldName*/,const TDesC& /*anNewName*/) |
|
384 // |
|
385 // Atomic replace. |
|
386 // |
|
387 { |
|
388 User::Leave(KErrAccessDenied); |
|
389 } |
|
390 |
|
391 |
|
392 void CCompMountCB::EntryL(const TDesC& aName,TEntry& anEntry) const |
|
393 // |
|
394 // Get entry details. |
|
395 // |
|
396 { |
|
397 __PRINT(_L("CCompMountCB::EntryL()")); |
|
398 TInt lesserErr = KErrNone; |
|
399 TInt err = KErrPathNotFound; |
|
400 TInt idx = iMounts.Count(); |
|
401 |
|
402 // Look for entry on each mount, until it finds one, starting at the top. |
|
403 while(idx--) |
|
404 { |
|
405 TRAP(err, iMounts[idx].iMount->EntryL(aName,anEntry)); |
|
406 |
|
407 // There will often be more then one error encountered when trying |
|
408 // to find an entry. If the entry is not found on any mount, but it |
|
409 // did find its path, it should not return a path error. |
|
410 // To ensure this, the last non-path related error must be remembered. |
|
411 if ((err != KErrPathNotFound) && (err != KErrPathHidden)) |
|
412 lesserErr=err; |
|
413 |
|
414 // It can stop looking for the entry when it either finds it |
|
415 // or discovers its hidden. (ie An error other then NotFound) |
|
416 if((err != KErrNotFound) && (err != KErrPathNotFound)) |
|
417 break; |
|
418 } |
|
419 |
|
420 if (err!=KErrNone) |
|
421 User::Leave(lesserErr?lesserErr:err); |
|
422 } |
|
423 |
|
424 |
|
425 void CCompMountCB::SetEntryL(const TDesC& /*aName*/,const TTime& /*aTime*/,TUint /*aSetAttMask*/,TUint /*aClearAttMask*/) |
|
426 // |
|
427 // Set entry details. |
|
428 // |
|
429 { |
|
430 User::Leave(KErrAccessDenied); |
|
431 } |
|
432 |
|
433 |
|
434 static TInt InitFile(CFileCB* aCompFile, CFileCB* aTrueFile,CMountCB* aRealMount,TUint8 aQueOffset) |
|
435 // |
|
436 // Initialise the true file object with values set in the composite file object |
|
437 // by TDrive |
|
438 // |
|
439 { |
|
440 TRAPD(r,aTrueFile->InitL(&aCompFile->Drive(),&aCompFile->Drive(),aCompFile->FileName().Des().AllocL() ) ); |
|
441 if(r!=KErrNone) |
|
442 return(r); |
|
443 |
|
444 aTrueFile->SetMount(aRealMount); |
|
445 aTrueFile->SetShare(aCompFile->Share()); |
|
446 r=aTrueFile->Mount().Open(); |
|
447 if(r==KErrNone) |
|
448 { |
|
449 // destructor for CFileCB only calls close on the mount if iMountLink set |
|
450 TDblQue<CFileCB>* pQue=(TDblQue<CFileCB>*)((TUint8*)aRealMount+aQueOffset); |
|
451 pQue->AddLast(*aTrueFile); |
|
452 } |
|
453 return(r); |
|
454 } |
|
455 |
|
456 |
|
457 void CCompMountCB::FileOpenL(const TDesC& aName,TUint aMode,TFileOpen anOpen,CFileCB* aFile) |
|
458 // |
|
459 // Open a file on the current mount. |
|
460 // |
|
461 { |
|
462 __PRINT1(_L("CCompMountCB::FileOpenL() %S"), &aName); |
|
463 |
|
464 |
|
465 TInt err = KErrPathNotFound; |
|
466 TInt lesserErr = KErrNone; |
|
467 CFileCB* pTrueFile = NULL; |
|
468 TInt idx = iMounts.Count(); |
|
469 |
|
470 // Look for file on each mount, until it finds one, starting at the top. |
|
471 while(idx--) |
|
472 { |
|
473 CMountCB* mount = iMounts[idx].iMount; |
|
474 pTrueFile = iMounts[idx].iFs->NewFileL(); |
|
475 TUint8 offset=(TUint8)(((TUint8*)&iMountQ-(TUint8*)this)); |
|
476 err = InitFile(aFile,pTrueFile,mount,offset); |
|
477 |
|
478 if(err == KErrNone) |
|
479 TRAP(err, mount->FileOpenL(aName,aMode,anOpen,pTrueFile)); |
|
480 |
|
481 __PRINT2(_L("opening file on mount %d [err=%d]"),idx,err); |
|
482 |
|
483 // If success, stop looking. |
|
484 if (err == KErrNone) |
|
485 break; |
|
486 |
|
487 // Not opened, so use Close() to cause file object to be deleted |
|
488 pTrueFile->Close(); |
|
489 |
|
490 // If the file is not found on any mount, but it did find its path, |
|
491 // it should not return a path error. |
|
492 // To ensure this, the last non-path related error must be remembered. |
|
493 if ((err != KErrPathNotFound) && (err != KErrPathHidden)) |
|
494 lesserErr=err; |
|
495 |
|
496 // Stop search if error other than file cannot be found. |
|
497 // A common error for this will be one of the hidden errors. |
|
498 // Note that for these, the lesser error calculation above |
|
499 // is still needed for these. |
|
500 if(err != KErrNotFound && err != KErrPathNotFound) |
|
501 break; |
|
502 } |
|
503 |
|
504 if (err!=KErrNone) |
|
505 User::Leave(lesserErr?lesserErr:err); |
|
506 |
|
507 aFile->SetSize(pTrueFile->Size()); |
|
508 aFile->SetAtt(pTrueFile->Att()); |
|
509 aFile->SetModified(pTrueFile->Modified()); |
|
510 ((CCompFileCB*)aFile)->SetTrueFile(pTrueFile); |
|
511 } |
|
512 |
|
513 |
|
514 TInt CCompMountCB::GetFileUniqueId(const TDesC& /* aName */, TInt64& aUniqueId) |
|
515 { |
|
516 // Get unique identifier for the file - for Composite File System will just return zero |
|
517 aUniqueId = MAKE_TINT64(0,0); |
|
518 return KErrNone; |
|
519 } |
|
520 |
|
521 TInt CCompMountCB::Spare3(TInt /*aVal*/, TAny* /*aPtr1*/, TAny* /*aPtr2*/) |
|
522 { |
|
523 return KErrNotSupported; |
|
524 } |
|
525 |
|
526 TInt CCompMountCB::Spare2(TInt /*aVal*/, TAny* /*aPtr1*/, TAny* /*aPtr2*/) |
|
527 { |
|
528 return KErrNotSupported; |
|
529 } |
|
530 |
|
531 TInt CCompMountCB::Spare1(TInt /*aVal*/, TAny* /*aPtr1*/, TAny* /*aPtr2*/) |
|
532 { |
|
533 return KErrNotSupported; |
|
534 } |
|
535 |
|
536 |
|
537 |
|
538 static void SetAtt(CDirCB* aDir,TUint8 aOffset,TUint aValue) |
|
539 // |
|
540 // |
|
541 // |
|
542 { |
|
543 TUint8* pA=(TUint8*)aDir+aOffset; |
|
544 *(TUint*)pA=aValue; |
|
545 } |
|
546 |
|
547 |
|
548 static void SetUid(CDirCB* aDir,TUint8 aOffset,TUidType aValue) |
|
549 // |
|
550 // |
|
551 // |
|
552 { |
|
553 TUint8* pU=(TUint8*)aDir+aOffset; |
|
554 *(TUidType*)pU=aValue; |
|
555 } |
|
556 |
|
557 |
|
558 TInt CCompDirCB::InitDir(CDirCB* aTrg,CMountCB* aMount) |
|
559 // |
|
560 // |
|
561 // |
|
562 { |
|
563 TRAPD(r,aTrg->InitL(&Drive())); |
|
564 if(r!=KErrNone) |
|
565 return(r); |
|
566 aTrg->SetMount(aMount); |
|
567 r=aTrg->Mount().Open(); |
|
568 if(r!=KErrNone) |
|
569 { |
|
570 aTrg->SetMount(NULL); |
|
571 return(r); |
|
572 } |
|
573 SetAtt(aTrg,(TUint8)((TUint8*)&iAtt-(TUint8*)this),iAtt); |
|
574 SetUid(aTrg,(TUint8)((TUint8*)&iUidType-(TUint8*)this),iUidType); |
|
575 aTrg->Mount().DecLock(); |
|
576 return(KErrNone); |
|
577 } |
|
578 |
|
579 |
|
580 void CCompMountCB::DirOpenL(const TDesC& aName,CDirCB* aDir) |
|
581 // |
|
582 // Open a directory on the current mount. |
|
583 // |
|
584 { |
|
585 __PRINT(_L("CCompMountCB::DirOpenL()")); |
|
586 CCompDirCB* pD=(CCompDirCB*)aDir; |
|
587 pD->iMatch=aName.AllocL(); |
|
588 |
|
589 TInt err = KErrPathNotFound; |
|
590 TInt idx = iMounts.Count(); |
|
591 TBool anyFound = EFalse; |
|
592 pD->iCurrentDir = -1; |
|
593 |
|
594 while(idx) // Open dir on every mount it exists. |
|
595 { |
|
596 idx--; |
|
597 CDirCB* theDir = pD->iDirs[idx]; |
|
598 CMountCB* theMount = iMounts[idx].iMount; |
|
599 err = pD->InitDir(theDir, theMount); |
|
600 if(err == KErrNone) |
|
601 TRAP(err, theMount->DirOpenL(aName,theDir)); |
|
602 |
|
603 if(err == KErrNone) |
|
604 { |
|
605 if(!anyFound) |
|
606 { |
|
607 anyFound = ETrue; |
|
608 pD->iCurrentDir = idx; |
|
609 } |
|
610 continue; |
|
611 } |
|
612 |
|
613 pD->iDirs[idx]->Close(); // deletes object |
|
614 pD->iDirs[idx] = NULL; |
|
615 |
|
616 if (err == KErrPathHidden) |
|
617 { |
|
618 // Dont look for anythng below this hidden dir. |
|
619 break; |
|
620 } |
|
621 else if (err != KErrPathNotFound) |
|
622 { |
|
623 // An unexpected error - make it report this to caller! |
|
624 anyFound = EFalse; |
|
625 break; |
|
626 } |
|
627 } |
|
628 |
|
629 // If we broke before bottom, close the remaining |
|
630 while (idx--) |
|
631 { |
|
632 pD->iDirs[idx]->Close(); |
|
633 pD->iDirs[idx] = NULL; |
|
634 } |
|
635 |
|
636 // If we didnt find anythng at all, or some other error, leave. |
|
637 if(!anyFound) |
|
638 User::Leave(err); |
|
639 |
|
640 } |
|
641 |
|
642 |
|
643 void CCompMountCB::RawReadL(TInt64 /*aPos*/,TInt /*aLength*/,const TAny* /*aTrg*/,TInt /*anOffset*/,const RMessagePtr2& /*aMessage*/) const |
|
644 // |
|
645 // Read up to aLength data directly |
|
646 // |
|
647 { |
|
648 User::Leave(KErrAccessDenied); |
|
649 } |
|
650 |
|
651 |
|
652 void CCompMountCB::RawWriteL(TInt64 /*aPos*/,TInt /*aLength*/,const TAny* /*aSrc*/,TInt /*anOffset*/,const RMessagePtr2& /*aMessage*/) |
|
653 // |
|
654 // Write aLength data |
|
655 // |
|
656 { |
|
657 User::Leave(KErrAccessDenied); |
|
658 } |
|
659 |
|
660 |
|
661 void CCompMountCB::GetShortNameL(const TDesC& /*aLongName*/,TDes& /*aShortName*/) |
|
662 // |
|
663 // Return the short name associated with aLongName |
|
664 // Assumes all rom names are 8.3 |
|
665 // |
|
666 { |
|
667 User::Leave(KErrNotSupported); |
|
668 } |
|
669 |
|
670 |
|
671 void CCompMountCB::GetLongNameL(const TDesC& /*aShortName*/,TDes& /*aLongName*/) |
|
672 // |
|
673 // Return the short name associated with aLongName |
|
674 // Assumes all rom names are 8.3 |
|
675 // |
|
676 { |
|
677 User::Leave(KErrNotSupported); |
|
678 } |
|
679 |
|
680 |
|
681 void CCompMountCB::IsFileInRom(const TDesC& aFileName,TUint8*& aFileStart) |
|
682 // |
|
683 // Return the address of the file if it is in rom |
|
684 // |
|
685 { |
|
686 __PRINT(_L("CCompMountCB::IsFileInRom()")); |
|
687 TEntry entry; |
|
688 aFileStart=NULL; |
|
689 TInt idx = iMounts.Count(); |
|
690 |
|
691 while(idx--) |
|
692 { |
|
693 TRAPD(r,iMounts[idx].iMount->EntryL(aFileName,entry)); |
|
694 if(r==KErrNone) |
|
695 { |
|
696 // File exists on mount, check whether it is rom-based |
|
697 iMounts[idx].iMount->IsFileInRom(aFileName,aFileStart); |
|
698 break; |
|
699 } |
|
700 else if(r != KErrNotFound && r != KErrPathNotFound) |
|
701 { |
|
702 break; |
|
703 } |
|
704 } |
|
705 } |
|
706 |
|
707 |
|
708 void CCompMountCB::ReadSectionL(const TDesC& aName,TInt aPos,TAny* aTrg,TInt aLength,const RMessagePtr2& aMessage) |
|
709 // |
|
710 // Starting from aPos, read aLength bytes of a file into a Trg, |
|
711 // regardless of lock state |
|
712 // |
|
713 { |
|
714 __PRINT(_L("CCompMountCB::ReadSectionL()")); |
|
715 TInt lesserErr = KErrNone; |
|
716 TInt err = KErrPathNotFound; |
|
717 TInt idx = iMounts.Count(); |
|
718 |
|
719 // Look for file on each mount, until it finds one, starting at the top. |
|
720 while(idx--) |
|
721 { |
|
722 TRAP(err, iMounts[idx].iMount->ReadSectionL(aName,aPos,aTrg,aLength,aMessage)); |
|
723 |
|
724 // If the file is not found on any mount, but it did find its path, |
|
725 // it should not return a path error. |
|
726 // To ensure this, the last non-path related error must be remembered. |
|
727 if ((err != KErrPathNotFound) && (err != KErrPathHidden)) |
|
728 lesserErr=err; |
|
729 |
|
730 // Break if file was found, it was hidden, or some unexpected error |
|
731 // (ie break if file or pathe not found) |
|
732 // Note: If hidden, lesserErr calulation above still needed. |
|
733 if ((err != KErrNotFound) && (err != KErrPathNotFound)) |
|
734 break; |
|
735 } |
|
736 |
|
737 if (err!=KErrNone) |
|
738 User::Leave(lesserErr?lesserErr:err); |
|
739 } |
|
740 |
|
741 |
|
742 CCompFileCB::CCompFileCB() |
|
743 {} |
|
744 |
|
745 |
|
746 CCompFileCB::~CCompFileCB() |
|
747 { |
|
748 __PRINT1(_L("~CCompFileCB()[0x%x]"),this); |
|
749 if(TrueFile()) |
|
750 TrueFile()->Close(); |
|
751 } |
|
752 |
|
753 |
|
754 void CCompFileCB::RenameL(const TDesC& /*aNewName*/) |
|
755 // |
|
756 // Rename the file. |
|
757 // |
|
758 { |
|
759 User::Leave(KErrAccessDenied); |
|
760 } |
|
761 |
|
762 |
|
763 void CCompFileCB::ReadL(TInt aPos,TInt& aLength,const TAny* aDes,const RMessagePtr2& aMessage) |
|
764 // |
|
765 // Read from the file. |
|
766 // |
|
767 { |
|
768 __PRINT(_L("CCompFileCB::ReadL()")); |
|
769 TrueFile()->ReadL(aPos,aLength,aDes,aMessage); |
|
770 } |
|
771 |
|
772 |
|
773 void CCompFileCB::WriteL(TInt /*aPos*/,TInt& /*aLength*/,const TAny* /*aDes*/,const RMessagePtr2& /*aMessage*/) |
|
774 // |
|
775 // Write to the file. |
|
776 // |
|
777 { |
|
778 User::Leave(KErrAccessDenied); |
|
779 } |
|
780 |
|
781 |
|
782 TInt CCompFileCB::Address(TInt& aPos) const |
|
783 // |
|
784 // Return address of the file at aPos |
|
785 // |
|
786 { |
|
787 __PRINT(_L("CCompFileCB::Address()")); |
|
788 return(TrueFile()->Address(aPos)); |
|
789 } |
|
790 |
|
791 |
|
792 void CCompFileCB::SetSizeL(TInt /*aSize*/) |
|
793 // |
|
794 // Set the file size. |
|
795 // |
|
796 { |
|
797 User::Leave(KErrAccessDenied); |
|
798 } |
|
799 |
|
800 |
|
801 void CCompFileCB::SetEntryL(const TTime& /*aTime*/,TUint /*aSetAttMask*/,TUint /*aClearAttMask*/) |
|
802 // |
|
803 // Set the entry's attributes and modified time. |
|
804 // |
|
805 { |
|
806 User::Leave(KErrAccessDenied); |
|
807 } |
|
808 |
|
809 |
|
810 void CCompFileCB::FlushDataL() |
|
811 // |
|
812 // Commit any buffered date to the media. |
|
813 // |
|
814 { |
|
815 User::Leave(KErrAccessDenied); |
|
816 } |
|
817 |
|
818 |
|
819 void CCompFileCB::FlushAllL() |
|
820 // |
|
821 // Commit any buffered date to the media. |
|
822 // |
|
823 { |
|
824 User::Leave(KErrAccessDenied); |
|
825 } |
|
826 |
|
827 |
|
828 TInt CCompFileCB::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput) |
|
829 { |
|
830 if (TrueFile()) |
|
831 return TrueFile()->GetInterface(aInterfaceId, aInterface, aInput); |
|
832 else |
|
833 return KErrNotSupported; |
|
834 } |
|
835 |
|
836 |
|
837 CCompDirCB::CCompDirCB() |
|
838 // |
|
839 // |
|
840 // |
|
841 {} |
|
842 |
|
843 |
|
844 CCompDirCB::~CCompDirCB() |
|
845 // |
|
846 // |
|
847 // |
|
848 { |
|
849 __PRINT1(_L("~CCompDirCB() [0x%x]"),this); |
|
850 for(TInt dir=iDirs.Count(); dir--;) |
|
851 { |
|
852 if (iDirs[dir]) |
|
853 iDirs[dir]->Close(); |
|
854 } |
|
855 iDirs.Close(); |
|
856 delete iMatch; |
|
857 } |
|
858 |
|
859 |
|
860 void CCompDirCB::ReadL(TEntry& anEntry) |
|
861 // |
|
862 // Reads the next directory entry. |
|
863 // |
|
864 { |
|
865 __PRINT(_L("CCompDirCB::ReadL()")); |
|
866 |
|
867 if(Pending()) |
|
868 { |
|
869 CDirCB* pDir = iDirs[iCurrentDir]; |
|
870 pDir->SetPending(ETrue); |
|
871 TRAPD(r,pDir->ReadL(anEntry)); |
|
872 __ASSERT_ALWAYS(r!=KErrEof,Fault(ECompDirReadPending)); |
|
873 SetPending(pDir->Pending()); |
|
874 User::LeaveIfError(r); |
|
875 return; |
|
876 } |
|
877 |
|
878 if(iCurrentDir < 0) |
|
879 User::Leave(KErrEof); |
|
880 |
|
881 TFileName match(*iMatch); |
|
882 TInt namePos=match.LocateReverse(KPathDelimiter)+1; // There is always a path delimiter |
|
883 TPtrC dirName=match.Left(namePos); |
|
884 TFileName filename; |
|
885 TInt err; |
|
886 |
|
887 do |
|
888 { |
|
889 CDirCB* theDir = iDirs[iCurrentDir]; |
|
890 if(theDir) |
|
891 { |
|
892 FOREVER // loop until we can read no more (EOF or other err) |
|
893 // If non-duplicate entry found, it returns. |
|
894 { |
|
895 TRAP(err, theDir->ReadL(anEntry)); |
|
896 |
|
897 if(err != KErrNone) |
|
898 break; |
|
899 |
|
900 __PRINT2(_L("CCompDirCB:: ReadL got = '%S' from dir %d"),&anEntry.iName, iCurrentDir); |
|
901 |
|
902 filename=dirName; |
|
903 filename+=anEntry.iName; |
|
904 |
|
905 if (!IsDuplicate(filename)) |
|
906 return; |
|
907 } |
|
908 |
|
909 // We have either reached EOF for CurrentDir or encounted an error. |
|
910 |
|
911 __PRINT1(_L("CCompDirCB:: ReadL err = %d"),err); |
|
912 |
|
913 if(err != KErrEof) |
|
914 { |
|
915 User::Leave(err); |
|
916 } |
|
917 } |
|
918 } |
|
919 |
|
920 while (iCurrentDir--); |
|
921 |
|
922 User::Leave(KErrEof); |
|
923 } |
|
924 |
|
925 |
|
926 TBool CCompDirCB::IsDuplicate(TFileName& aFilename) |
|
927 // |
|
928 // Is used by ReadL to determine if a file name read is a duplicate of |
|
929 // a filename already read bit it. |
|
930 // |
|
931 { |
|
932 RArray<TCompMount> &mounts = ((CCompMountCB*)&Mount())->iMounts; |
|
933 TInt count = mounts.Count(); |
|
934 TEntry tmpEntry; |
|
935 __PRINT1(_L("theMount->iMounts.Count() = %d"),count); |
|
936 |
|
937 for (TInt idx = iCurrentDir+1; idx < count; idx++) |
|
938 { |
|
939 TRAPD(r, mounts[idx].iMount->EntryL(aFilename,tmpEntry)); |
|
940 |
|
941 if ((r == KErrNone) || (r == KErrHidden) || (r == KErrPathHidden)) |
|
942 { |
|
943 __PRINT1(_L("CCompDirCB:: Duplicate (r=%d)"),r); |
|
944 return (ETrue); |
|
945 } |
|
946 } |
|
947 return (EFalse); |
|
948 } |
|
949 |
|
950 |
|
951 void CCompDirCB::StoreLongEntryNameL(const TDesC& aName) |
|
952 // |
|
953 // Stores the Long Entry Name |
|
954 // |
|
955 { |
|
956 __ASSERT_ALWAYS(iCurrentDir >= 0 && iDirs[iCurrentDir] != NULL, Fault(ECompDirStoreLongEntryNameL)); |
|
957 iDirs[iCurrentDir]->StoreLongEntryNameL(aName); |
|
958 } |
|
959 |
|
960 |
|
961 extern "C" { |
|
962 |
|
963 EXPORT_C CFileSystem* CreateFileSystem() |
|
964 // |
|
965 // Create a new file system |
|
966 // |
|
967 { |
|
968 return(CCompFileSystem::NewL()); |
|
969 } |
|
970 } |
|
971 |