os/kernelhwsrv/userlibandfileserver/fileserver/automounter/automounter.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) 1998-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
@file
sl@0
    17
@internalTechnology
sl@0
    18
*/
sl@0
    19
sl@0
    20
#include <e32cmn.h>
sl@0
    21
#include <f32ver.h>
sl@0
    22
#include <u32std.h>
sl@0
    23
#include <f32file.h>
sl@0
    24
sl@0
    25
sl@0
    26
sl@0
    27
#include "filesystem_automounter.h"
sl@0
    28
#include "automounter.h"
sl@0
    29
sl@0
    30
sl@0
    31
//-----------------------------------------------------------------------------
sl@0
    32
sl@0
    33
void Fault(TFault aFault)
sl@0
    34
    {
sl@0
    35
    _LIT(KPanicName, "AutoMounter_fsy");
sl@0
    36
    User::Panic(KPanicName, aFault);
sl@0
    37
    }
sl@0
    38
sl@0
    39
sl@0
    40
//-----------------------------------------------------------------------------
sl@0
    41
sl@0
    42
/**
sl@0
    43
    Factory function, Create a new object of this file system 
sl@0
    44
*/
sl@0
    45
extern "C" 
sl@0
    46
{
sl@0
    47
EXPORT_C CFileSystem* CreateFileSystem()
sl@0
    48
    {
sl@0
    49
    return CAutoMounterFileSystem::New();
sl@0
    50
    }
sl@0
    51
}
sl@0
    52
sl@0
    53
sl@0
    54
//#######################################################################################################################################
sl@0
    55
//#  CAutoMounterFileSystem class implementation
sl@0
    56
//#######################################################################################################################################
sl@0
    57
sl@0
    58
/**
sl@0
    59
    Factory method
sl@0
    60
*/
sl@0
    61
CAutoMounterFileSystem* CAutoMounterFileSystem::New()
sl@0
    62
    {
sl@0
    63
    CAutoMounterFileSystem* pThis = new CAutoMounterFileSystem();
sl@0
    64
    return pThis;
sl@0
    65
    }
sl@0
    66
sl@0
    67
sl@0
    68
CAutoMounterFileSystem::CAutoMounterFileSystem() 
sl@0
    69
    {
sl@0
    70
    __PRINT1(_L("#<<- CAutoMounterFileSystem::CAutoMounterFileSystem() [0x%x]"), this);
sl@0
    71
sl@0
    72
    SetState(EInvalid);
sl@0
    73
    }   
sl@0
    74
sl@0
    75
CAutoMounterFileSystem::~CAutoMounterFileSystem()
sl@0
    76
    {
sl@0
    77
    __PRINT1(_L("#<<- CAutoMounterFileSystem::~CAutoMounterFileSystem() [0x%x]"), this);
sl@0
    78
    }
sl@0
    79
sl@0
    80
//-----------------------------------------------------------------------------
sl@0
    81
sl@0
    82
/**
sl@0
    83
    Install iand initialise file system.
sl@0
    84
*/
sl@0
    85
TInt CAutoMounterFileSystem::Install()
sl@0
    86
    {
sl@0
    87
   
sl@0
    88
    SetState(ENotInitialised);
sl@0
    89
sl@0
    90
    __PRINT1(_L("#<<- CAutoMounterFileSystem::Install() [0x%x]"), this);
sl@0
    91
sl@0
    92
    iVersion=TVersion(KF32MajorVersionNumber,KF32MinorVersionNumber,KF32BuildVersionNumber);
sl@0
    93
sl@0
    94
    InitialiseFileSystem();
sl@0
    95
sl@0
    96
    return SetName(&KFileSystemName_AutoMounter);
sl@0
    97
    }
sl@0
    98
sl@0
    99
sl@0
   100
//-----------------------------------------------------------------------------
sl@0
   101
/** 
sl@0
   102
    Create a new mount control block. 
sl@0
   103
    This method migh be called by the file server in some unusual cases, when the actual mount is needed only temporarily to get access to the 
sl@0
   104
    corresponding media driver. E.g. TDrive::ForceRemountDrive()
sl@0
   105
    Produce the _default_ file system mount
sl@0
   106
*/
sl@0
   107
CMountCB* CAutoMounterFileSystem::NewMountL() const
sl@0
   108
    {
sl@0
   109
    __PRINT1(_L("#<<- CAutoMounterFileSystem::NewMountL() [0x%x]"), this);
sl@0
   110
    ASSERT(State() == EInitialised);
sl@0
   111
sl@0
   112
    __PRINT1(_L("#<<- producing the _default_ filesystem:%S"), &iFSNames[KDefaultFSNo]);
sl@0
   113
sl@0
   114
    CFileSystem* pFS = GetChildFileSystem(KDefaultFSNo);
sl@0
   115
    ASSERT(pFS);
sl@0
   116
sl@0
   117
    return pFS->NewMountL();
sl@0
   118
    }
sl@0
   119
sl@0
   120
//-----------------------------------------------------------------------------
sl@0
   121
/** 
sl@0
   122
    Create a new file. 
sl@0
   123
*/
sl@0
   124
CFileCB* CAutoMounterFileSystem::NewFileL() const
sl@0
   125
    {
sl@0
   126
    __PRINT1(_L("#<<- CAutoMounterFileSystem::NewFileL() [0x%x]"), this);
sl@0
   127
    Fault(EMustNotBeCalled);
sl@0
   128
    return NULL;
sl@0
   129
    }
sl@0
   130
sl@0
   131
//-----------------------------------------------------------------------------
sl@0
   132
/** 
sl@0
   133
    Create a new directory object 
sl@0
   134
*/
sl@0
   135
CDirCB* CAutoMounterFileSystem::NewDirL() const
sl@0
   136
    {
sl@0
   137
    __PRINT1(_L("#<<- CAutoMounterFileSystem::NewDirL() [0x%x]"), this);
sl@0
   138
    Fault(EMustNotBeCalled);
sl@0
   139
    return NULL;
sl@0
   140
    }
sl@0
   141
sl@0
   142
//-----------------------------------------------------------------------------
sl@0
   143
/** 
sl@0
   144
    Create a new media formatter 
sl@0
   145
*/
sl@0
   146
CFormatCB* CAutoMounterFileSystem::NewFormatL() const
sl@0
   147
    {
sl@0
   148
    __PRINT1(_L("#<<- CAutoMounterFileSystem::NewFormatL() [0x%x]"), this);
sl@0
   149
    Fault(EMustNotBeCalled);
sl@0
   150
    return NULL;
sl@0
   151
    }
sl@0
   152
sl@0
   153
sl@0
   154
//-----------------------------------------------------------------------------
sl@0
   155
sl@0
   156
#ifdef _DEBUG
sl@0
   157
/**
sl@0
   158
    Called by File Server before deleting File System object.    
sl@0
   159
*/
sl@0
   160
TInt CAutoMounterFileSystem::Remove()
sl@0
   161
    {
sl@0
   162
    __PRINT1(_L("#<<- CAutoMounterFileSystem::Remove() [0x%x]"), this);
sl@0
   163
    return CFileSystem::Remove();
sl@0
   164
    }
sl@0
   165
sl@0
   166
//-----------------------------------------------------------------------------
sl@0
   167
sl@0
   168
/**
sl@0
   169
*/
sl@0
   170
TBool CAutoMounterFileSystem::QueryVersionSupported(const TVersion& aVer) const
sl@0
   171
    {
sl@0
   172
    __PRINT1(_L("#<<- CAutoMounterFileSystem::QueryVersionSupported() [0x%x]"), this);
sl@0
   173
    return CFileSystem::QueryVersionSupported(aVer);
sl@0
   174
    }
sl@0
   175
sl@0
   176
#endif
sl@0
   177
sl@0
   178
//-----------------------------------------------------------------------------
sl@0
   179
sl@0
   180
/**
sl@0
   181
    Find out if drive extensions are supported. In order to have consistent behaviour, _all_ child 
sl@0
   182
    file systems shall behave the same way.   
sl@0
   183
    
sl@0
   184
    @return ETrue if drive extensions are supported.    
sl@0
   185
*/
sl@0
   186
TBool CAutoMounterFileSystem::IsExtensionSupported() const
sl@0
   187
    {
sl@0
   188
    __PRINT1(_L("#<<- CAutoMounterFileSystem::IsExtensionSupported() [0x%x]"), this);
sl@0
   189
    
sl@0
   190
    ASSERT(State() == EInitialised && iFSNames.Count() > 1);
sl@0
   191
sl@0
   192
sl@0
   193
    //-- in debug mode check file systems compatibility: ALL childs must support this feature
sl@0
   194
    for(TUint i=0; i<iFSNames.Count(); ++i)
sl@0
   195
        {
sl@0
   196
        if( !(GetChildFileSystem(i)->IsExtensionSupported()))
sl@0
   197
            {
sl@0
   198
            DBG_STATEMENT(Fault(EIncompatibleFileSystems));
sl@0
   199
            __PRINT(_L("#<<- ::IsExtensionSupported(): Incompatible file sytems!"));
sl@0
   200
            return EFalse;
sl@0
   201
            }
sl@0
   202
        }
sl@0
   203
sl@0
   204
sl@0
   205
    return ETrue; 
sl@0
   206
    }
sl@0
   207
sl@0
   208
//-----------------------------------------------------------------------------
sl@0
   209
sl@0
   210
/** 
sl@0
   211
    Return the initial default path. 
sl@0
   212
*/
sl@0
   213
TInt CAutoMounterFileSystem::DefaultPath(TDes& aPath) const
sl@0
   214
    {
sl@0
   215
    __PRINT1(_L("#<<- CAutoMounterFileSystem::DefaultPath() [0x%x]"), this);
sl@0
   216
sl@0
   217
    aPath=_L("?:\\");
sl@0
   218
    aPath[0] = (TUint8) RFs::GetSystemDriveChar();
sl@0
   219
    return KErrNone;
sl@0
   220
    }
sl@0
   221
sl@0
   222
sl@0
   223
//-----------------------------------------------------------------------------
sl@0
   224
sl@0
   225
/**
sl@0
   226
    Additional interfaces support.    
sl@0
   227
*/
sl@0
   228
TInt CAutoMounterFileSystem::GetInterface(TInt aInterfaceId, TAny*& aInterface, TAny* aInput)
sl@0
   229
    {
sl@0
   230
sl@0
   231
    __PRINT2(_L("#<<- CAutoMounterFileSystem::GetInterface(id:%d) [0x%x]"), aInterfaceId, this);
sl@0
   232
sl@0
   233
    switch(aInterfaceId)
sl@0
   234
        {
sl@0
   235
        //-- It is this filesystem private interface.
sl@0
   236
        case EExtendedFunctionality:
sl@0
   237
        aInterface = (CFileSystem::MFileSystemExtInterface*)this;
sl@0
   238
        return KErrNone;
sl@0
   239
        
sl@0
   240
        //-- a special case for child filesystems.
sl@0
   241
        //-- ALL of them must respond to this interface query exactly the same way. I.e. It is impossible
sl@0
   242
        //-- to have some of the child FS supporting it and some not.
sl@0
   243
        case EProxyDriveSupport:
sl@0
   244
        return DoProcessProxyDriveSupport();
sl@0
   245
sl@0
   246
sl@0
   247
        default:
sl@0
   248
        //-- This is the request to other (child file system) from the file server
sl@0
   249
        //-- Actually, this part must never be called. File Server shall query the file system interfaces _after_ mounting the concrete FS 
sl@0
   250
        //-- calling TDrive::iCurrentMount->FileSystem().GetInterface() 
sl@0
   251
        ASSERT(0);
sl@0
   252
        return CFileSystem::GetInterface(aInterfaceId, aInterface, aInput);
sl@0
   253
        
sl@0
   254
        }
sl@0
   255
    }
sl@0
   256
sl@0
   257
sl@0
   258
//-----------------------------------------------------------------------------
sl@0
   259
sl@0
   260
/**
sl@0
   261
    Find out if _all_ child file systems support the proxy drive. All childs shall behave exactly the same way.
sl@0
   262
    @return KErrNone if all child file systems support proxy drives, or KErrNotSupported if all of them do not.
sl@0
   263
*/
sl@0
   264
TInt CAutoMounterFileSystem::DoProcessProxyDriveSupport()
sl@0
   265
    {
sl@0
   266
    __PRINT1(_L("#<<- CAutoMounterFileSystem::DoProcessProxyDriveSupport[0x%x]"), this);
sl@0
   267
    ASSERT(State() == EInitialised);
sl@0
   268
sl@0
   269
    const TUint cnt = iFSNames.Count();
sl@0
   270
    ASSERT(cnt > 1);
sl@0
   271
sl@0
   272
    
sl@0
   273
    //-- query the default filesystem #0
sl@0
   274
    const TBool bRes = GetChildFileSystem(KDefaultFSNo)->IsProxyDriveSupported();
sl@0
   275
sl@0
   276
    //-- query the rest of child filesystems
sl@0
   277
    for(TUint i=1; i<cnt; ++i)
sl@0
   278
        {
sl@0
   279
        const TBool b = GetChildFileSystem(i)->IsProxyDriveSupported();
sl@0
   280
sl@0
   281
        if(BoolXOR(b, bRes))
sl@0
   282
            Fault(EIncompatibleFileSystems);
sl@0
   283
        }
sl@0
   284
sl@0
   285
sl@0
   286
    return  bRes ? KErrNone : KErrNotSupported;
sl@0
   287
    }
sl@0
   288
sl@0
   289
//-----------------------------------------------------------------------------
sl@0
   290
/**
sl@0
   291
    Get the child file system name by its index (enumerator).
sl@0
   292
    
sl@0
   293
    @param  aFsNumber   index of the child FS 0...KMaxTInt
sl@0
   294
    @param  aFsName     on success the child file system name will be placed into this buffer  
sl@0
   295
sl@0
   296
    @return KErrNone        if there is a child FS name with index 'aFsNumber' (child FS 'aFsNumber' is supported by automounter)
sl@0
   297
            KErrNotFound    if child FS 'aFsNumber' is not supported
sl@0
   298
*/
sl@0
   299
TInt CAutoMounterFileSystem::GetSupportedFileSystemName(TInt aFsNumber, TDes& aFsName) const
sl@0
   300
    {
sl@0
   301
    __PRINT2(_L("#<<- CAutoMounterFileSystem::GetSupportedFileSystemName[0x%x](%d)"), this, aFsNumber);
sl@0
   302
sl@0
   303
    if(aFsNumber == RFs::KRootFileSystem)
sl@0
   304
        {//-- this is a name query for "root filesystem" or automounter
sl@0
   305
        aFsName = Name(); //-- ourselves
sl@0
   306
        return KErrNone;
sl@0
   307
        }
sl@0
   308
    
sl@0
   309
    //-- this is a query for one of the child filesystems
sl@0
   310
    if((TUint)aFsNumber < iFSNames.Count())
sl@0
   311
        {
sl@0
   312
        aFsName = iFSNames[aFsNumber]; 
sl@0
   313
        return KErrNone;
sl@0
   314
        }
sl@0
   315
sl@0
   316
    
sl@0
   317
    return KErrNotFound;
sl@0
   318
    }
sl@0
   319
sl@0
   320
sl@0
   321
//-----------------------------------------------------------------------------
sl@0
   322
/**
sl@0
   323
    This is the only factory method that can be called by file server for this file system.
sl@0
   324
    In this method the automounter sequentially tries to mount every child and on success produces the corresponding CMountCB object.
sl@0
   325
sl@0
   326
    @param  apDrive         pointer to the TDrive, child FS will need this to access media.
sl@0
   327
    @param  apFileSystem    on return will contain the pointer to the CFileSystem that has produced the proped CMountCB if 
sl@0
   328
                            one of the child file system has recognised the volume.
sl@0
   329
    @param  aForceMount     if ETrue the appropriate child FS (designated by aFsNameHash) will be forcedly mounted on the volume. for volume formatting purposes.
sl@0
   330
    @param  aFsNameHash     if !=0 specifies the file system name, see TVolFormatParam::CalcFSNameHash(). 0 means "file system name is not specified"
sl@0
   331
sl@0
   332
    @return pointer to the constructed CMountCB by one of the child file systems (and pointer to this child FS in apFileSystem)
sl@0
   333
            NULL if it was impossible to produce proper CMountCB object.
sl@0
   334
sl@0
   335
*/
sl@0
   336
CMountCB* CAutoMounterFileSystem::NewMountExL(TDrive* apDrive, CFileSystem** apFileSystem, TBool aForceMount, TUint32 aFsNameHash)
sl@0
   337
    {
sl@0
   338
    __PRINT4(_L("#<<- CAutoMounterFileSystem::NewMountExL[0x%x] drv:%d, ForceMount:%d, FSNameHash:0x%x"), this, apDrive->DriveNumber(), aForceMount, aFsNameHash);
sl@0
   339
sl@0
   340
    ASSERT(State() == EInitialised && apDrive);
sl@0
   341
sl@0
   342
    //-- This method is usually called from the appropriate drive thread; this file system is intended to be bound to
sl@0
   343
    //-- removable drives. Having removable drive runnind in the main file server thread means that something is terribly wrongly configured.
sl@0
   344
    if(apDrive->IsSynchronous())
sl@0
   345
        Fault(EWrongDriveAttributes);
sl@0
   346
sl@0
   347
    if(iFSNames.Count() < 2)
sl@0
   348
        Fault(EWrongConfiguration);
sl@0
   349
sl@0
   350
sl@0
   351
    //-- if aForceMount is true, this means that the TDrive tries mount the filesystem by force for formatting because normal mounting has failed before. 
sl@0
   352
    //-- in our case it means that the file system on the volume hadn't been recognised by any child FS.
sl@0
   353
    //-- aFsNameHash shall designate the file system to be forcedly mounted. Depending on this the appropriat CMounCB object will be produced.
sl@0
   354
    //-- if aFsNameHash is 0, i.e. not provided, this method will fail with KErrNotFound because it is impossible to select appropriat child FS.
sl@0
   355
    if(aForceMount)
sl@0
   356
        {
sl@0
   357
        if(aFsNameHash == 0)
sl@0
   358
            {//-- the file system to mount forcedly is not specified
sl@0
   359
            __PRINT(_L("#<<- Unable to select appropriate child FS for formatting!"));
sl@0
   360
            User::Leave(KErrNotFound);
sl@0
   361
            }
sl@0
   362
        else
sl@0
   363
            {//-- try to find appropriate child FS by its name hash
sl@0
   364
            CFileSystem *pFS = GetChildFileSysteByNameHash(aFsNameHash);
sl@0
   365
            if(!pFS)
sl@0
   366
                {
sl@0
   367
                __PRINT(_L("#<<- no child FS found by its name hash!"));
sl@0
   368
                ASSERT(0);
sl@0
   369
                User::Leave(KErrNotFound);
sl@0
   370
                }
sl@0
   371
sl@0
   372
            CMountCB* pMount = pFS->NewMountL();
sl@0
   373
            ASSERT(pMount);
sl@0
   374
sl@0
   375
            *apFileSystem = pFS; 
sl@0
   376
            return pMount;
sl@0
   377
            }
sl@0
   378
        }//if(aForceMount)
sl@0
   379
sl@0
   380
sl@0
   381
sl@0
   382
    //-- try instantiate a new CMountCB depending on the file system on the media
sl@0
   383
sl@0
   384
    CMountCB* pMatchedMount;
sl@0
   385
    TInt nRes = TryMountFilesystem(apDrive, &pMatchedMount, apFileSystem);
sl@0
   386
    
sl@0
   387
    if(nRes == KErrNone)
sl@0
   388
        {
sl@0
   389
        ASSERT(pMatchedMount);
sl@0
   390
        return pMatchedMount;
sl@0
   391
        }
sl@0
   392
sl@0
   393
sl@0
   394
sl@0
   395
    User::Leave(nRes);
sl@0
   396
    return NULL;
sl@0
   397
    }
sl@0
   398
sl@0
   399
//-----------------------------------------------------------------------------
sl@0
   400
/**
sl@0
   401
    Initialise this file system. Reads and processes configuration, fills in file system names container, etc. 
sl@0
   402
*/
sl@0
   403
void CAutoMounterFileSystem::InitialiseFileSystem()
sl@0
   404
    {
sl@0
   405
    __PRINT1(_L("#<<- CAutoMounterFileSystem::InitialiseFileSystem() [0x%x]"), this);
sl@0
   406
sl@0
   407
    ASSERT(State() == ENotInitialised);
sl@0
   408
sl@0
   409
    TInt nRes;
sl@0
   410
    
sl@0
   411
sl@0
   412
    //-- 1. initialise the array of file system names. These names shall be listed in a config string.
sl@0
   413
    //-- the config string is taken from estart.txt usually and its format is like this: 
sl@0
   414
    //-- section: [AutoMounter] and property "FSNames fat,exfat"
sl@0
   415
    //-- in debug version a special text property can override the config string. This allows controlling automounter from
sl@0
   416
    //-- the test environment.
sl@0
   417
sl@0
   418
    TBuf8<0x100> buf(0);   
sl@0
   419
    TBuf<0x100>  fsName;   
sl@0
   420
sl@0
   421
sl@0
   422
#ifdef _DEBUG
sl@0
   423
    const TUid KSID_Test1={0x10210EB3}; //-- SID of the test that will define and set test property to control volume mounting
sl@0
   424
    const TUint KPropKey = 0; //-- property key
sl@0
   425
sl@0
   426
    //-- in debug mode the property will override the estart.txt config
sl@0
   427
    if(RProperty::Get(KSID_Test1, KPropKey, buf) == KErrNone)
sl@0
   428
        {
sl@0
   429
        __PRINT(_L("#<<- reading config from the debug propery..."));
sl@0
   430
        }
sl@0
   431
    else
sl@0
   432
#endif
sl@0
   433
        {
sl@0
   434
        __PRINT(_L("#<<- reading config from estart.txt..."));
sl@0
   435
        _LIT8(KSection,  "AutoMounter");
sl@0
   436
        _LIT8(KProperty, "FSNames");
sl@0
   437
sl@0
   438
        nRes = F32Properties::GetString(KSection, KProperty, buf);
sl@0
   439
        if(!nRes)
sl@0
   440
            Fault(EPluginInitialise);
sl@0
   441
        }
sl@0
   442
sl@0
   443
sl@0
   444
    fsName.Copy(buf);
sl@0
   445
    __PRINT1(_L("#<<- config:'%S'"), &fsName);
sl@0
   446
sl@0
   447
    //-- parse CSV config line and fill in the file system names array
sl@0
   448
    const TChar chDelim = ','; //-- token delimiter, comma
sl@0
   449
    buf.Trim();
sl@0
   450
    TPtrC8 ptrCurrLine(buf);
sl@0
   451
    for(TInt i=0; ;++i)
sl@0
   452
        {
sl@0
   453
        const TInt delimPos = ptrCurrLine.Locate(chDelim);
sl@0
   454
        if(delimPos <= 0)
sl@0
   455
            {
sl@0
   456
            fsName.Copy(ptrCurrLine);
sl@0
   457
            }
sl@0
   458
        else
sl@0
   459
            {
sl@0
   460
            TPtrC8 temp(ptrCurrLine.Ptr(), delimPos);
sl@0
   461
            fsName.Copy(temp);
sl@0
   462
            }
sl@0
   463
sl@0
   464
        fsName.Trim();
sl@0
   465
        __PRINT2(_L("#<<- child FS[%d]: '%S'"), i, &fsName);
sl@0
   466
sl@0
   467
        
sl@0
   468
        if(fsName.Length() <= 0) 
sl@0
   469
            Fault(EPluginInitialise);
sl@0
   470
sl@0
   471
        //-- check if the FS name being appended is unique
sl@0
   472
        for(TUint j=0; j<iFSNames.Count(); ++j)
sl@0
   473
            {
sl@0
   474
            if(iFSNames[j] == fsName)
sl@0
   475
                {
sl@0
   476
                Fault(EPluginInitialise);
sl@0
   477
                }
sl@0
   478
            }
sl@0
   479
        
sl@0
   480
        
sl@0
   481
        nRes = iFSNames.Append(fsName);
sl@0
   482
        ASSERT(nRes ==KErrNone);
sl@0
   483
        
sl@0
   484
        if(delimPos <=0 )
sl@0
   485
            break;
sl@0
   486
sl@0
   487
        ptrCurrLine.Set(ptrCurrLine.Ptr()+delimPos+1, ptrCurrLine.Length()-delimPos-1);
sl@0
   488
        }
sl@0
   489
sl@0
   490
sl@0
   491
    SetState(EInitialised);
sl@0
   492
sl@0
   493
    //-- 2. check that the file server has all filesystems we need instantiated and stored in a global container
sl@0
   494
    TUint cnt = iFSNames.Count();
sl@0
   495
    if(cnt < 2)
sl@0
   496
        {
sl@0
   497
        __PRINT(_L("#<<- ::InitialiseFileSystem(): too few File Systems bound!"));
sl@0
   498
        Fault(EPluginInitialise);
sl@0
   499
        }
sl@0
   500
sl@0
   501
    while(cnt--)
sl@0
   502
        {
sl@0
   503
        GetChildFileSystem(cnt);
sl@0
   504
        }
sl@0
   505
sl@0
   506
sl@0
   507
    }
sl@0
   508
sl@0
   509
sl@0
   510
sl@0
   511
//-----------------------------------------------------------------------------
sl@0
   512
/**
sl@0
   513
    Tries to find out if some of the child file systems can be mounted on the given volume.
sl@0
   514
sl@0
   515
    @param  apDrive         pointer to the TDrive, child FS will need this to access media.
sl@0
   516
    @param                  on return will contain the pointer to the CMountCB object if some of the childs has decided that it can be mounted.
sl@0
   517
    @param  apFS            on return will contain the pointer to the CFileSystem that has produced the proped CMountCB if 
sl@0
   518
sl@0
   519
    @return KErrNone on success, otherwise standard error code.
sl@0
   520
sl@0
   521
*/
sl@0
   522
TInt CAutoMounterFileSystem::TryMountFilesystem(TDrive* apDrive, CMountCB** apMount, CFileSystem** apFS)
sl@0
   523
    {
sl@0
   524
    __PRINT1(_L("#<<- CAutoMounterFileSystem::TryMountFilesystem()[0x%x]"), this);
sl@0
   525
sl@0
   526
    const TInt KNumFS = iFSNames.Count();
sl@0
   527
  
sl@0
   528
    ASSERT(State() == EInitialised && (KNumFS >1));
sl@0
   529
sl@0
   530
sl@0
   531
    *apMount = NULL;
sl@0
   532
    *apFS    = NULL;
sl@0
   533
    
sl@0
   534
    
sl@0
   535
    TInt nRes;
sl@0
   536
    TInt cntFS;
sl@0
   537
    CMountCB*       pMountCB = NULL;
sl@0
   538
    CFileSystem*    pMatchedFS = NULL;
sl@0
   539
sl@0
   540
    for(cntFS=0; cntFS < KNumFS; ++cntFS)
sl@0
   541
        {
sl@0
   542
sl@0
   543
        __PRINT2(_L("#<<-@@ trying FS[%d]:%S"), cntFS, &iFSNames[cntFS]);
sl@0
   544
sl@0
   545
        CFileSystem* pFS = GetChildFileSystem(cntFS); //-- Find current filesystem object in the FileServer's global container
sl@0
   546
sl@0
   547
        //-- 2. create CMountCB instance and set it up
sl@0
   548
        pMountCB = NULL;
sl@0
   549
        
sl@0
   550
        TRAP(nRes, pMountCB = pFS->NewMountL());
sl@0
   551
        if(nRes != KErrNone)
sl@0
   552
            {
sl@0
   553
            return KErrNoMemory;
sl@0
   554
            }
sl@0
   555
sl@0
   556
        ASSERT(pMountCB);
sl@0
   557
        pMountCB->SetDrive(apDrive);
sl@0
   558
sl@0
   559
        
sl@0
   560
        //-- 2.1 Firstly try using special CMountCB interface to find out if current FS can be mounted on this media
sl@0
   561
        nRes = pMountCB->CheckFileSystemMountable();
sl@0
   562
        if(nRes == KErrNotSupported)
sl@0
   563
            {
sl@0
   564
            //-- file system doesn't support this feature,
sl@0
   565
            //-- 2.2 try to check the file system by mounting and dismounting later. It can result in some long activity, like FAT scanning etc.
sl@0
   566
            TRAP(nRes, pMountCB->MountL(EFalse));
sl@0
   567
            pMountCB->Dismounted(); //-- dismount the mountCB, it will be required in dismounted state anyway 
sl@0
   568
            }
sl@0
   569
        
sl@0
   570
        //-- 2.3 analyse the result of mounting 
sl@0
   571
        if(nRes != KErrNone)
sl@0
   572
            {
sl@0
   573
            if(nRes == KErrLocked)
sl@0
   574
                {//-- this is a special case; The media (SD card for example) is locked. 
sl@0
   575
                //-- Pretend that everything is OK and return CMountCB instance that is produced by the _default_ file system.
sl@0
   576
                //-- locked media case will be handled by the file server later.
sl@0
   577
                ASSERT(cntFS == KDefaultFSNo); //-- the default FS is tried first and must detect the locked media
sl@0
   578
                pMatchedFS = pFS;
sl@0
   579
                __PRINT(_L("#<<-@@ The media is LOCKED !"));
sl@0
   580
                break;
sl@0
   581
                }
sl@0
   582
sl@0
   583
            //-- failed to mount the file system, most likey it is not recognised
sl@0
   584
            pMountCB->Close(); //-- this is a self-destructing object!
sl@0
   585
            pMountCB = NULL;
sl@0
   586
            __PRINT(_L("#<<-@@ Mount FAILED !"));
sl@0
   587
            }
sl@0
   588
        else
sl@0
   589
            {
sl@0
   590
            //-- mounted OK, the file system is recognised
sl@0
   591
            __PRINT(_L("#<<-@@ Mount OK!"));
sl@0
   592
            
sl@0
   593
            pMatchedFS = pFS;
sl@0
   594
            break;
sl@0
   595
            }
sl@0
   596
    
sl@0
   597
        }//for(cntFS=0; cntFS<KNumFS; ++cntFS)
sl@0
   598
sl@0
   599
    if(cntFS >= KNumFS)
sl@0
   600
        {//-- no one from the FS factories recognised the file system
sl@0
   601
        __PRINT1(_L("#<<- ::TryMountFilesystem()[0x%x] No file system recognised!"), this);
sl@0
   602
        
sl@0
   603
        SetName(&KFileSystemName_AutoMounter); 
sl@0
   604
        return KErrCorrupt;
sl@0
   605
        }
sl@0
   606
sl@0
   607
    ASSERT(pMountCB && pMatchedFS); 
sl@0
   608
    *apMount = pMountCB;
sl@0
   609
    *apFS    = pMatchedFS;
sl@0
   610
    
sl@0
   611
    //-- set this FS name to the name of recognised FS. In this case the automounter "pretends" to be one of the child file systems on 
sl@0
   612
    //-- successful mounting. This behaviour was considered to be incorrect.
sl@0
   613
    //TPtrC fsName = pMatchedFS->Name();
sl@0
   614
    //SetName(&fsName); 
sl@0
   615
sl@0
   616
    return KErrNone;
sl@0
   617
sl@0
   618
    }
sl@0
   619
sl@0
   620
//-----------------------------------------------------------------------------
sl@0
   621
/**
sl@0
   622
    get the child file system object by the index in file child system names container
sl@0
   623
    
sl@0
   624
    @param  aIndex  index in the iFSNames
sl@0
   625
    @return pointer to the FS object if it is found, NULL otherwise
sl@0
   626
*/
sl@0
   627
CFileSystem* CAutoMounterFileSystem::GetChildFileSystem(TUint aIndex) const
sl@0
   628
    {
sl@0
   629
    ASSERT(State() == EInitialised && (iFSNames.Count() >1) && aIndex < iFSNames.Count());
sl@0
   630
sl@0
   631
    const TDesC& fsName = iFSNames[aIndex]; //-- registered child file system name
sl@0
   632
    CFileSystem* pFS = GetFileSystem(fsName); //-- Find filesystem object in the FileServer's global container
sl@0
   633
sl@0
   634
    if(!pFS)
sl@0
   635
        {
sl@0
   636
        __PRINT1(_L("#<<- CAutoMounterFileSystem::GetChildFileSystem() FileServer doesn't have FS:%S Added!"), &fsName);
sl@0
   637
        Fault(EFileSysNotAdded);
sl@0
   638
        }
sl@0
   639
sl@0
   640
    return pFS;
sl@0
   641
    }
sl@0
   642
sl@0
   643
//-----------------------------------------------------------------------------
sl@0
   644
/**
sl@0
   645
    Find the child file system object by the file system name name hash. 
sl@0
   646
    @param  aFsNameHash FS name hash
sl@0
   647
    @return pointer to the FS object if it is found, NULL otherwise
sl@0
   648
*/
sl@0
   649
CFileSystem* CAutoMounterFileSystem::GetChildFileSysteByNameHash(TUint32 aFsNameHash) const
sl@0
   650
    {
sl@0
   651
    ASSERT(State() == EInitialised && (iFSNames.Count() >1) && aFsNameHash);
sl@0
   652
    
sl@0
   653
    for(TUint i=0; i<iFSNames.Count(); ++i)
sl@0
   654
        {
sl@0
   655
        if(aFsNameHash == iFSNames.GetStringHash(i))
sl@0
   656
            {
sl@0
   657
            const TDesC& fsName = iFSNames[i];        //-- registered child file system name
sl@0
   658
            __PRINT2(_L("#<<- ::GetChildFileSysteByNameHash() found FsName:%S by hash:0x%x"), &fsName, aFsNameHash);
sl@0
   659
            CFileSystem* pFS = GetFileSystem(fsName); //-- Find filesystem object in the FileServer's global container
sl@0
   660
            ASSERT(pFS);
sl@0
   661
            return pFS;
sl@0
   662
            }
sl@0
   663
   
sl@0
   664
        }
sl@0
   665
   
sl@0
   666
    __PRINT1(_L("#<<- ::GetChildFileSysteByNameHash() No FS name found by hash:0x%x"), aFsNameHash);
sl@0
   667
   
sl@0
   668
    return NULL;
sl@0
   669
    }
sl@0
   670
sl@0
   671
sl@0
   672
sl@0
   673
sl@0
   674
//#######################################################################################################################################
sl@0
   675
//#     XStringArray implementation
sl@0
   676
//#######################################################################################################################################
sl@0
   677
sl@0
   678
XStringArray::XStringArray()
sl@0
   679
    {
sl@0
   680
    }
sl@0
   681
sl@0
   682
XStringArray::~XStringArray()
sl@0
   683
    {
sl@0
   684
    Reset();
sl@0
   685
    iStrings.Close();
sl@0
   686
    }
sl@0
   687
sl@0
   688
//-----------------------------------------------------------------------------
sl@0
   689
void XStringArray::Reset()
sl@0
   690
    {
sl@0
   691
    iStrings.ResetAndDestroy();
sl@0
   692
    }
sl@0
   693
sl@0
   694
//-----------------------------------------------------------------------------
sl@0
   695
const TDesC& XStringArray::operator[](TUint aIndex) const
sl@0
   696
    {
sl@0
   697
    if(aIndex >= (TUint)iStrings.Count())
sl@0
   698
        Panic(EIndexOutOfRange);
sl@0
   699
sl@0
   700
    HBufC* des=iStrings[aIndex];
sl@0
   701
    return *des;
sl@0
   702
    }
sl@0
   703
sl@0
   704
//-----------------------------------------------------------------------------
sl@0
   705
/**
sl@0
   706
    Append file system name to the container. The name is converted to upper case.
sl@0
   707
    @param aString name descriptor.
sl@0
   708
    @return standard error code
sl@0
   709
*/
sl@0
   710
TInt XStringArray::Append(const TDesC& aString)
sl@0
   711
    {
sl@0
   712
    HBufC* pBuf = aString.Alloc();
sl@0
   713
    if(!pBuf) 
sl@0
   714
        return KErrNoMemory;
sl@0
   715
    
sl@0
   716
    //-- string being appended shall be unique
sl@0
   717
    for(TUint i=0; i<Count(); ++i)
sl@0
   718
        {
sl@0
   719
        if(operator[](i).CompareF(aString) == 0)
sl@0
   720
            {
sl@0
   721
            ASSERT(0);
sl@0
   722
            return KErrNone;
sl@0
   723
            }
sl@0
   724
        }
sl@0
   725
sl@0
   726
    pBuf->Des().UpperCase(); //-- convert the FS name to upper-case in order to correctly calculate hash later
sl@0
   727
    return iStrings.Append(pBuf);
sl@0
   728
    }
sl@0
   729
sl@0
   730
sl@0
   731
//-----------------------------------------------------------------------------
sl@0
   732
/**
sl@0
   733
    Get child FS name hash by index in the names container.
sl@0
   734
    @param  aIndex name index in the container
sl@0
   735
    @return file system name hash (crc32)
sl@0
   736
*/
sl@0
   737
TUint32 XStringArray::GetStringHash(TUint aIndex) const
sl@0
   738
    {
sl@0
   739
    const TDesC& des = operator[](aIndex);
sl@0
   740
    return TVolFormatParam::CalcFSNameHash(des);
sl@0
   741
    }
sl@0
   742
sl@0
   743
sl@0
   744
sl@0
   745
void XStringArray::Panic(TPanicCode aPanicCode) const
sl@0
   746
    {
sl@0
   747
    _LIT(KPanicCat,"XStringArray");
sl@0
   748
    User::Panic(KPanicCat, aPanicCode);
sl@0
   749
    }
sl@0
   750
sl@0
   751
sl@0
   752
sl@0
   753
sl@0
   754
sl@0
   755
sl@0
   756
sl@0
   757
sl@0
   758
sl@0
   759
sl@0
   760
sl@0
   761
sl@0
   762
sl@0
   763
sl@0
   764
sl@0
   765
sl@0
   766
sl@0
   767
sl@0
   768
sl@0
   769
sl@0
   770
sl@0
   771
sl@0
   772
sl@0
   773
sl@0
   774
sl@0
   775
sl@0
   776
sl@0
   777
sl@0
   778
sl@0
   779
sl@0
   780
sl@0
   781