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