remotestoragefw/remotefileengine/src/rsfwvolumetable.cpp
changeset 0 3ad9d5175a89
equal deleted inserted replaced
-1:000000000000 0:3ad9d5175a89
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:   data struct for all volumes
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <sysutil.h>
       
    20 #include <bautils.h>
       
    21 #include <rsfwmountman.h>
       
    22 #include <rsfwmountentry.h>
       
    23 
       
    24 #include "rsfwvolumetable.h"
       
    25 #include "rsfwvolume.h"
       
    26 #include "rsfwinterface.h"
       
    27 #include "rsfwmountstatemachine.h"
       
    28 #include "rsfwfileentry.h"
       
    29 #include "rsfwfiletable.h"
       
    30 #include "rsfwconfig.h"
       
    31 #include "rsfwfileengine.h"
       
    32 #include "rsfwrfeserver.h"
       
    33 
       
    34 #include "rsfwmountstore.h"
       
    35 #include "rsfwwaitnotemanager.h"
       
    36 #include "rsfwdormantmountloader.h"
       
    37 #include "mdebug.h"
       
    38 
       
    39 //CONSTANTS
       
    40 _LIT(KRsfwLruFileName, "lru.dat");
       
    41 _LIT(KRsfwRestorePendingMark, "rsfwmetadatarestorepending.dat");
       
    42 
       
    43 // ----------------------------------------------------------------------------
       
    44 // CRsfwVolumeTable::NewL
       
    45 //
       
    46 // ----------------------------------------------------------------------------
       
    47 //
       
    48 CRsfwVolumeTable* CRsfwVolumeTable::NewL(CRsfwRfeServer* aRfeServer,
       
    49                                  CRsfwConfig* aRsfwConfig)
       
    50     {
       
    51     CRsfwVolumeTable* self = new (ELeave) CRsfwVolumeTable;
       
    52     DEBUGSTRING(("CRsfwVolumeTable: in NewL 0x%x", self));
       
    53     CleanupStack::PushL(self);
       
    54     self->ConstructL(aRfeServer, aRsfwConfig);
       
    55     CleanupStack::Pop(self);
       
    56     return self;
       
    57     }
       
    58 
       
    59 
       
    60 // ----------------------------------------------------------------------------
       
    61 // CRsfwVolumeTable::RestoreDormantMountsL
       
    62 //
       
    63 // ----------------------------------------------------------------------------
       
    64 //
       
    65 void CRsfwVolumeTable::RestoreDormantMountsL() 
       
    66     {
       
    67     DEBUGSTRING(("CRsfwVolumeTable::RestoreDormantMountsL enter"));
       
    68     // Currently, we always enable persistence (used to be configurrable)
       
    69     iPermanence = ETrue;
       
    70     if (iPermanence)
       
    71         {
       
    72         // if restoring permanent state causes RFE panic, we must delete 
       
    73         // the old permanent metadata and skip restoring it
       
    74         // otherwise RFE will just crash every time
       
    75         // Strategy is to add a file that tells that the process is ongoing.
       
    76         // If it is not able to finish successfully, we can conclude that there was a crash
       
    77         // marker is deleted from CRsfwDormantMountLoader, when we have succesfully also checked for dirty files
       
    78         TBool internalize = CheckAndAddProcessStartMarker();
       
    79         if (internalize) 
       
    80             {
       
    81             WillLRUPriorityListBeInternalized();
       
    82             RestoreVolumesL();
       
    83             InternalizeLRUPriorityListL();
       
    84             }
       
    85         else 
       
    86             {
       
    87             CleanupCorruptedCacheL();
       
    88             }
       
    89         }
       
    90     iDormantMountRestorePending = EFalse;   
       
    91     DEBUGSTRING(("CRsfwVolumeTable::RestoreDormantMountsL exit"));
       
    92     }
       
    93 
       
    94 // ----------------------------------------------------------------------------
       
    95 // CRsfwVolumeTable::ConstructL
       
    96 //
       
    97 // ----------------------------------------------------------------------------
       
    98 //
       
    99 void CRsfwVolumeTable::ConstructL(CRsfwRfeServer* aRfeServer, CRsfwConfig* aRsfwConfig)
       
   100     {
       
   101     iRfeServer = aRfeServer;
       
   102     iRsfwConfig = aRsfwConfig;
       
   103 
       
   104     iAllEnginesIdle = ETrue;
       
   105     
       
   106     // set some local pointers for commonly used variable from CRsfwRfeServer::Env()
       
   107     iFs = CRsfwRfeServer::Env()->iFs;
       
   108     iCacheRoot = &(CRsfwRfeServer::Env()->iCacheRoot);
       
   109     
       
   110     TInt err = iRsfwConfig->Get(RsfwConfigKeys::KMaxCacheSize,
       
   111                                 iMaxCacheSize);
       
   112     if (err != KErrNone)
       
   113         {
       
   114         iMaxCacheSize = KDefaultMaxCacheSize;
       
   115         }
       
   116 
       
   117     err = iRsfwConfig->Get(RsfwConfigKeys::KMaxEntryCount,
       
   118                            iMaxEntryCount);
       
   119     if (err != KErrNone)
       
   120         {
       
   121         iMaxEntryCount = KDefaultMaxEntryCount;
       
   122         }
       
   123 
       
   124     HBufC* confItem = HBufC::NewLC(KMaxRsfwConfItemLength);
       
   125     TPtr confItemPtr = confItem->Des();
       
   126 
       
   127     // global wait notes manager class
       
   128     // must be created before restoring  the volumes
       
   129     iWaitNoteManager = CRsfwWaitNoteManager::NewL();
       
   130     
       
   131     RestoreDormantMountsL();
       
   132     
       
   133     err = iRsfwConfig->Get(RsfwConfigKeys::KFileCacheValidity,
       
   134                            iFileCacheTimeout);
       
   135     if (err)
       
   136         {
       
   137         iFileCacheTimeout = KDefaultCacheValidity;
       
   138         }
       
   139     err = iRsfwConfig->Get(RsfwConfigKeys::KDirCacheValidity,
       
   140                            iDirCacheTimeout);
       
   141     if (err)
       
   142         {
       
   143         iDirCacheTimeout = KDefaultDirCacheValidity;
       
   144         }
       
   145 
       
   146     err = iRsfwConfig->Get(RsfwConfigKeys::KRecognizerLimit,
       
   147                            iRecognizerLimit);
       
   148     if (err)
       
   149         {
       
   150         iRecognizerLimit = KDefaultRecognizerLimit;
       
   151         }
       
   152 
       
   153     err = iRsfwConfig->Get(RsfwConfigKeys::KCachingMode, confItemPtr);
       
   154     if (err == KErrNone)
       
   155         {
       
   156         TLex lex(confItemPtr);
       
   157         TChar firstChar = lex.Get();
       
   158         firstChar.UpperCase();
       
   159         switch (firstChar)
       
   160             {
       
   161         case 'W':
       
   162             iCachingMode = EWholeFileCaching;
       
   163             break;
       
   164 
       
   165         case 'F':
       
   166             iCachingMode = EFullIfa;
       
   167             break;
       
   168 
       
   169         case 'M':
       
   170         default:
       
   171             iCachingMode = EMetadataIfa;
       
   172             break;
       
   173             }
       
   174         }
       
   175     else
       
   176         {
       
   177         // caching mode configuration entry not found
       
   178         iCachingMode = EMetadataIfa;
       
   179         }
       
   180     if (iCachingMode != EWholeFileCaching)
       
   181         {
       
   182         GetMimeTypeSpecificLimits();
       
   183         }
       
   184 
       
   185     err = iRsfwConfig->Get(RsfwConfigKeys::KInactivityTimeout,
       
   186                            iInactivityTimeout);
       
   187     if (err)
       
   188         {
       
   189         iInactivityTimeout = KDefaultInactivityTimeout;
       
   190         }
       
   191 
       
   192     CleanupStack::PopAndDestroy(confItem);
       
   193 
       
   194     iMountStore = CRsfwMountStore::NewL(NULL);
       
   195 
       
   196     RProperty::Define(KRfeServerSecureUid,
       
   197                       ERsfwPSKeyConnect,
       
   198                       RProperty::EByteArray,
       
   199                       KMaxDrives);
       
   200 
       
   201     iMountStateProperty.Attach(KRfeServerSecureUid,
       
   202                                ERsfwPSKeyConnect);
       
   203 
       
   204 
       
   205    // this restores the dormant mounts asynchrously shortly after the server has started
       
   206     iDormantMountLoader = CRsfwDormantMountLoader::NewL(this);
       
   207     iDormantMountRestorePending = ETrue;
       
   208     }
       
   209 
       
   210 // ----------------------------------------------------------------------------
       
   211 // CRsfwVolumeTable::~CRsfwVolumeTable
       
   212 //
       
   213 // ----------------------------------------------------------------------------
       
   214 //
       
   215 CRsfwVolumeTable::~CRsfwVolumeTable()
       
   216     {
       
   217     // save LRU list to the file
       
   218     ExternalizeLRUPriorityList();
       
   219     
       
   220     TInt i;
       
   221     DEBUGSTRING(("Deleting all volumes"));
       
   222     for (i = 0; i < KMaxVolumes; i++)
       
   223         {
       
   224         if (iVolumes[i])
       
   225             {
       
   226             delete iVolumes[i];
       
   227             }
       
   228         }
       
   229     delete iMountStore;
       
   230     iMountStateProperty.Close();
       
   231     if (iWaitNoteManager)
       
   232     	{
       
   233     	delete iWaitNoteManager;
       
   234     	}
       
   235     if (iDormantMountLoader)
       
   236     	{
       
   237     	delete iDormantMountLoader;
       
   238     	}    	
       
   239     }
       
   240 
       
   241 // ----------------------------------------------------------------------------
       
   242 // CRsfwVolumeTable::DispatchL
       
   243 //
       
   244 // ----------------------------------------------------------------------------
       
   245 //
       
   246 void CRsfwVolumeTable::DispatchL(TAny* aIp, TAny* aOp)
       
   247     {
       
   248     TRfeInArgs* ip = reinterpret_cast<TRfeInArgs*>(aIp);
       
   249     TRfeOutArgs* op = reinterpret_cast<TRfeOutArgs*>(aOp);
       
   250     CRsfwFileEngine* fileEngine = NULL;
       
   251     TInt volumeId;
       
   252 
       
   253     if(ip->iOpCode == EFsRoot)
       
   254         {
       
   255         volumeId = iLastVolumeId;
       
   256         // boot  - assume that ROOT
       
   257         // immediately follows after MountL()
       
   258         if (volumeId)
       
   259             {
       
   260             DEBUGSTRING(("Volume: acquired engine %d", volumeId));
       
   261             CRsfwVolume* volume = iVolumes[volumeId];
       
   262             if (volume)
       
   263                 {
       
   264                 fileEngine = volume->iFileEngine;
       
   265                 }
       
   266             }
       
   267         }
       
   268     else
       
   269         {
       
   270         // iFid is always in the same position in the messages
       
   271         volumeId = static_cast<TRfeLookupInArgs*>(ip)->iFid.iVolumeId;
       
   272         CRsfwVolume* volume = VolumeByVolumeId(volumeId);
       
   273         if (volume)
       
   274             {
       
   275             fileEngine = volume->iFileEngine;
       
   276             }
       
   277         }
       
   278     if (fileEngine)
       
   279         {
       
   280         fileEngine->DispatchL(*ip, *op);
       
   281         }
       
   282     else
       
   283         {
       
   284         DEBUGSTRING(("Volume: no engine for %d", volumeId));
       
   285         User::Leave(KErrNotReady);
       
   286         }
       
   287     }
       
   288 
       
   289 // ----------------------------------------------------------------------------
       
   290 // CRsfwVolumeTable::VolumeIdByDriveLetter
       
   291 //
       
   292 // ----------------------------------------------------------------------------
       
   293 //
       
   294 TInt CRsfwVolumeTable::VolumeIdByDriveLetter(TChar aDriveLetter)
       
   295     {
       
   296     TInt driveNumber;
       
   297     iFs.CharToDrive(aDriveLetter, driveNumber);
       
   298     if (driveNumber < 0) // note that 0 = EDriveA is allowed
       
   299         {
       
   300         driveNumber = KErrNotFound;
       
   301         }
       
   302     return driveNumber;
       
   303     }
       
   304 
       
   305 // ----------------------------------------------------------------------------
       
   306 // CRsfwVolumeTable::VolumeByVolumeId
       
   307 //
       
   308 // ----------------------------------------------------------------------------
       
   309 //
       
   310 CRsfwVolume* CRsfwVolumeTable::VolumeByVolumeId(TInt aVolumeId)
       
   311     {
       
   312     if ((aVolumeId >= 0) && (aVolumeId < KMaxVolumes))
       
   313         {
       
   314         return iVolumes[aVolumeId];
       
   315         }
       
   316     return NULL;
       
   317     }
       
   318 
       
   319 // ----------------------------------------------------------------------------
       
   320 // CRsfwVolumeTable::VolumeByDriveLetter
       
   321 //
       
   322 // ----------------------------------------------------------------------------
       
   323 //
       
   324 CRsfwVolume* CRsfwVolumeTable::VolumeByDriveLetter(TChar aDriveLetter)
       
   325     {
       
   326     return VolumeByVolumeId(VolumeIdByDriveLetter(aDriveLetter));
       
   327     }
       
   328 
       
   329 // ----------------------------------------------------------------------------
       
   330 // CRsfwVolumeTable::RecoverVolumeL
       
   331 //
       
   332 // ----------------------------------------------------------------------------
       
   333 //
       
   334 TUint CRsfwVolumeTable::RecoverVolumeL(const TRsfwMountConfig& aMountConfig,
       
   335                                    CRsfwMountStateMachine* aCaller)
       
   336     {
       
   337     DEBUGSTRING(("Recovering volume"));
       
   338     TUint transactionId = 0;
       
   339     CRsfwVolume* volume = VolumeByVolumeId(aCaller->iVolumeId);
       
   340     if (volume)
       
   341         {
       
   342         aCaller->iVolume = volume;
       
   343         // set also fileengine pointer in the state machine,
       
   344         // so that the operation can be cancelled
       
   345         aCaller->SetFileEngine(volume->iFileEngine);
       
   346         if (User::UpperCase(
       
   347                 aCaller->iVolume->iMountInfo.iMountConfig.iDriveLetter) ==
       
   348             User::UpperCase(aMountConfig.iDriveLetter))
       
   349             {
       
   350             if (aCaller->iVolume->iMountInfo.iMountConfig.iFlags &
       
   351                 KMountFlagOffLine)
       
   352                 {
       
   353                 // We are working offline
       
   354                 aCaller->iVolume->iMountInfo.iMountStatus.iConnectionState =
       
   355                     KMountNotConnected;
       
   356                 }
       
   357             else
       
   358                 {
       
   359                 aCaller->iVolume->iMountInfo.iMountStatus.iConnectionState =
       
   360                     KMountStronglyConnected;
       
   361                 }
       
   362 
       
   363             transactionId =
       
   364                 aCaller->iVolume->iFileEngine->RequestConnectionStateL(
       
   365                     aCaller->iVolume->iMountInfo.iMountStatus.iConnectionState,
       
   366                     aCaller);
       
   367             }
       
   368         else
       
   369             {
       
   370             User::Leave(KErrArgument);
       
   371             }
       
   372         }
       
   373     else
       
   374         {
       
   375         User::Leave(KErrNotFound);
       
   376         }
       
   377 
       
   378     return transactionId;
       
   379     }
       
   380 
       
   381 // ----------------------------------------------------------------------------
       
   382 // CRsfwVolumeTable::MountState
       
   383 //
       
   384 // ----------------------------------------------------------------------------
       
   385 //
       
   386 TInt CRsfwVolumeTable::MountState(TChar aDriveLetter)
       
   387     {
       
   388     DEBUGSTRING(("Getting mount state"));
       
   389     TInt state;
       
   390     // Find the volume
       
   391     CRsfwVolume* volume = VolumeByDriveLetter(aDriveLetter);
       
   392     if (volume)
       
   393         {
       
   394         TRsfwMountInfo& mountInfo = volume->iMountInfo;
       
   395         DEBUGSTRING16(("mount '%S'in state %d",
       
   396                        &mountInfo.iMountConfig.iName,
       
   397                        mountInfo.iMountStatus.iMountState));
       
   398         state = mountInfo.iMountStatus.iMountState;
       
   399         }
       
   400     else
       
   401         {
       
   402         DEBUGSTRING(("mount not found"));
       
   403         state = 0; // define KMountStateNone=0 in RsfwControl.h
       
   404         }
       
   405     return state;
       
   406     }
       
   407 
       
   408 // ----------------------------------------------------------------------------
       
   409 // CRsfwVolumeTable::GetMountConfigL
       
   410 //
       
   411 // ----------------------------------------------------------------------------
       
   412 //
       
   413 TInt CRsfwVolumeTable::GetMountConfigL(TRsfwMountConfig& aMountConfig)
       
   414     {
       
   415     DEBUGSTRING16(("Getting mount config for name '%S', drive %c",
       
   416                    &aMountConfig.iName,
       
   417                    TUint(aMountConfig.iDriveLetter)));
       
   418     TInt err = KErrNone;
       
   419     const CRsfwMountEntry* entry =
       
   420         iMountStore->LookupEntryByDriveL(aMountConfig.iDriveLetter);
       
   421     if (!entry)
       
   422         {
       
   423         // Could not find by drive letter - retry with name
       
   424         entry = iMountStore->LookupEntryByNameL(aMountConfig.iName);
       
   425         }
       
   426     if (entry &&
       
   427         entry->Item(EMountEntryItemDrive) &&
       
   428         entry->Item(EMountEntryItemUri))
       
   429         {
       
   430         if (entry->Item(EMountEntryItemDrive)->Length())
       
   431             {
       
   432             TLex parse(*entry->Item(EMountEntryItemDrive));
       
   433             aMountConfig.iDriveLetter = parse.Get();
       
   434             if (entry->Item(EMountEntryItemName))
       
   435                 {
       
   436                 aMountConfig.iName.Copy(*entry->Item(EMountEntryItemName));
       
   437                 }
       
   438             else
       
   439                 {
       
   440                 aMountConfig.iName.SetLength(0);
       
   441                 }
       
   442             aMountConfig.iUri.Copy(*entry->Item(EMountEntryItemUri));
       
   443             if (entry->Item(EMountEntryItemUserName))
       
   444                 {
       
   445                 aMountConfig.iUserName.Copy(
       
   446                     *entry->Item(EMountEntryItemUserName));
       
   447                 }
       
   448             else
       
   449                 {
       
   450                 aMountConfig.iUserName.SetLength(0);
       
   451                 }
       
   452 
       
   453             if (entry->Item(EMountEntryItemPassword))
       
   454                 {
       
   455                 aMountConfig.iPassword.Copy(
       
   456                     *entry->Item(EMountEntryItemPassword));
       
   457                 }
       
   458             else
       
   459                 {
       
   460                 aMountConfig.iPassword.SetLength(0);
       
   461                 }
       
   462 
       
   463             if (entry->Item(EMountEntryItemIap))
       
   464                 {
       
   465                 aMountConfig.iAuxData.Copy(
       
   466                     *entry->Item(EMountEntryItemIap));
       
   467                 }
       
   468             else
       
   469                 {
       
   470                 aMountConfig.iAuxData.SetLength(0);
       
   471                 }
       
   472 
       
   473             TInt inactivityTimeout = iInactivityTimeout;
       
   474             if (entry->Item(EMountEntryItemInactivityTimeout))
       
   475                 {
       
   476                 TLex timeout(*entry->Item(EMountEntryItemInactivityTimeout));
       
   477                 timeout.Val(inactivityTimeout);
       
   478                 DEBUGSTRING(("Set inactivity timeout = %d",
       
   479                              inactivityTimeout));
       
   480                 }
       
   481             aMountConfig.iInactivityTimeout = inactivityTimeout;
       
   482 
       
   483             aMountConfig.iFlags = 0;
       
   484             }
       
   485         else
       
   486             {
       
   487             err = KErrArgument;
       
   488             }
       
   489         }
       
   490     else
       
   491         {
       
   492         DEBUGSTRING(("mount configuration not found"));
       
   493         err = KErrNotFound;
       
   494         }
       
   495 
       
   496     return err;
       
   497     }
       
   498 
       
   499 
       
   500 // ----------------------------------------------------------------------------
       
   501 // CRsfwVolumeTable::RestoreVolumesL
       
   502 //
       
   503 // ----------------------------------------------------------------------------
       
   504 //
       
   505 void CRsfwVolumeTable::RestoreVolumesL()
       
   506     {
       
   507     DEBUGSTRING(("CRsfwVolumeTable::RestoreVolumesL"));
       
   508     // Load persistently stored volumes
       
   509     CDir* dirList;
       
   510     TInt err = iFs.GetDir(*iCacheRoot,
       
   511                          KEntryAttMaskSupported,
       
   512                          ESortByName,
       
   513                          dirList);
       
   514     CleanupStack::PushL(dirList);
       
   515     DEBUGSTRING(("GetDir for cacheRoot returned %d", err));
       
   516     if (err == KErrNone)
       
   517         {
       
   518         TInt i;
       
   519         for (i = 0; i < dirList->Count(); i++)
       
   520             {
       
   521             const TEntry& entry = (*dirList)[i];
       
   522             if (entry.iAtt & KEntryAttDir)
       
   523                 {
       
   524                 // The name of cache directories are C<volume_id>
       
   525                 _LIT(KCacheMatch, "C*");
       
   526                 if (entry.iName.Match(KCacheMatch) == 0)
       
   527                     {
       
   528                     TLex volumeAlpha(entry.iName.Mid(1));
       
   529                     TInt volumeId;
       
   530                     err = volumeAlpha.Val(volumeId);
       
   531                     if ((err == KErrNone) &&
       
   532                         (volumeId >= 0) &&
       
   533                         (volumeId < KMaxVolumes))
       
   534                         {
       
   535                         TRsfwMountConfig* mountConfig = new (ELeave) TRsfwMountConfig;
       
   536                         CleanupStack::PushL(mountConfig);
       
   537                         HBufC* metaDataPath = HBufC::NewLC(KMaxPath);
       
   538                         TPtr metaDataPathPtr = metaDataPath->Des();
       
   539                         metaDataPathPtr.Copy(*iCacheRoot);
       
   540                         metaDataPathPtr.Append(entry.iName);
       
   541                         metaDataPathPtr.Append('\\');
       
   542                         metaDataPathPtr.Append(KMetaDataFileName);
       
   543                         CRsfwMetaDataStore* metaDataStore =
       
   544                             CRsfwMetaDataStore::NewLC(metaDataPathPtr);
       
   545                         // Get the mount configuration info from the
       
   546                         // persistent store
       
   547                         TRAP(err,
       
   548                              metaDataStore->GetMountConfigL(*mountConfig));
       
   549                         // metaDataStore, metaDataPath
       
   550                         CleanupStack::PopAndDestroy(2);
       
   551                         if (err == KErrNone)
       
   552                             {
       
   553                             DEBUGSTRING16(("Restoring '%S' as volume %d'",
       
   554                                            &mountConfig->iUri,
       
   555                                            volumeId));
       
   556                             TRAP_IGNORE(MountDormantL(*mountConfig,
       
   557                                                       volumeId));
       
   558                             // In case of error, we should clear the cache
       
   559                             }
       
   560                         CleanupStack::PopAndDestroy(mountConfig);
       
   561                         }
       
   562                     }
       
   563                 }
       
   564             }
       
   565         }
       
   566     CleanupStack::PopAndDestroy(dirList); // dirList
       
   567     }
       
   568 
       
   569 // ----------------------------------------------------------------------------
       
   570 // CRsfwVolumeTable::DismountByVolumeId
       
   571 //
       
   572 // ----------------------------------------------------------------------------
       
   573 //
       
   574 void CRsfwVolumeTable::DismountByVolumeIdL(TInt aVolumeId,
       
   575                                        TBool aDiscardPermanentData)
       
   576     {
       
   577     DEBUGSTRING(("Dismounting volume %d", aVolumeId));
       
   578     CRsfwVolume* volume = VolumeByVolumeId(aVolumeId);
       
   579     if (volume)
       
   580         {
       
   581         if (aDiscardPermanentData)
       
   582             {
       
   583             // Delete also the meta data
       
   584             CRsfwFileEngine* fileEngine = volume->iFileEngine;
       
   585             if (fileEngine)
       
   586                 {
       
   587                 // Clear cache of files and meta data
       
   588                 fileEngine->SetPermanenceL(EFalse);
       
   589                 if (!volume->iMountInfo.iMountStatus.iPermanence)
       
   590                     {
       
   591                     // There was no change in the above -
       
   592                     // so, we have to clear the cache explicitly
       
   593                     fileEngine->iFileTable->SetupCacheL();
       
   594                     }
       
   595                 }
       
   596             }
       
   597         delete volume;
       
   598         iVolumes[aVolumeId] = NULL;
       
   599         }
       
   600     else
       
   601         {
       
   602         User::Leave(KErrNotFound);
       
   603         }
       
   604     }
       
   605 
       
   606 // ----------------------------------------------------------------------------
       
   607 // CRsfwVolumeTable::DismountByDriveLetter
       
   608 //
       
   609 // ----------------------------------------------------------------------------
       
   610 //
       
   611 void CRsfwVolumeTable::DismountByDriveLetterL(TChar aDriveLetter,
       
   612                                           TBool aDiscardPermanentData)
       
   613     {
       
   614     DEBUGSTRING(("Dismounting drive %c", TUint(aDriveLetter)));
       
   615     CRsfwVolume* volume = VolumeByDriveLetter(aDriveLetter);
       
   616     if (volume)
       
   617         {
       
   618         DismountByVolumeIdL(volume->iMountInfo.iMountStatus.iVolumeId,
       
   619                             aDiscardPermanentData);
       
   620         }
       
   621     else
       
   622         {
       
   623         User::Leave(KErrNotFound);
       
   624         }
       
   625     }
       
   626 
       
   627 // ----------------------------------------------------------------------------
       
   628 // CRsfwVolumeTable::GetMountList
       
   629 //
       
   630 // ----------------------------------------------------------------------------
       
   631 //
       
   632 void CRsfwVolumeTable::GetMountList(TDriveList& aMountList)
       
   633     {
       
   634     aMountList.Zero();
       
   635     TInt i;
       
   636     for (i = 0; i < KMaxVolumes; i++)
       
   637         {
       
   638         if (iVolumes[i])
       
   639             {
       
   640             aMountList.Append(iVolumes[i]->
       
   641                               iMountInfo.iMountConfig.iDriveLetter);
       
   642             }
       
   643         }
       
   644     }
       
   645 
       
   646 // ----------------------------------------------------------------------------
       
   647 // CRsfwVolumeTable::GetMountInfo
       
   648 //
       
   649 // ----------------------------------------------------------------------------
       
   650 //
       
   651 TInt CRsfwVolumeTable::GetMountInfo(TRsfwMountInfo& aMountInfo)
       
   652     {
       
   653     CRsfwVolume* volume =
       
   654         VolumeByDriveLetter(aMountInfo.iMountConfig.iDriveLetter);
       
   655     if (volume)
       
   656         {
       
   657         volume->GetMountInfo(aMountInfo);
       
   658         return KErrNone;
       
   659         }
       
   660     return KErrNotFound;
       
   661     }
       
   662 
       
   663 
       
   664 // ----------------------------------------------------------------------------
       
   665 // CRsfwVolumeTable::GetMimeTypeSpecificLimits
       
   666 //
       
   667 // ----------------------------------------------------------------------------
       
   668 //
       
   669 void CRsfwVolumeTable::GetMimeTypeSpecificLimits()
       
   670     {
       
   671     TInt err;
       
   672     err = iRsfwConfig->Get(RsfwConfigKeys::KImgJpegLimit, iImageJpegLimit);
       
   673     if (err != KErrNone)
       
   674         {
       
   675         iImageJpegLimit = KDefaultJpegLimit;
       
   676         }
       
   677 
       
   678     err = iRsfwConfig->Get(RsfwConfigKeys::KAudMpegLimit, iAudioMpegLimit);
       
   679     if (err)
       
   680         {
       
   681         iAudioMpegLimit = KDefaultMpegLimit;
       
   682         }
       
   683     }
       
   684 
       
   685 
       
   686 
       
   687 // ----------------------------------------------------------------------------
       
   688 // CRsfwVolumeTable::EnsureCacheCanBeAddedL
       
   689 //
       
   690 // ----------------------------------------------------------------------------
       
   691 //
       
   692 TBool CRsfwVolumeTable::EnsureCacheCanBeAddedL(TInt aBytes)
       
   693     {
       
   694     DEBUGSTRING(("CACHE MANAGER: ensure that %d bytes can be added to cache",
       
   695                  aBytes));
       
   696     DEBUGSTRING(("CACHE MANAGER: total cached size is currently %d",
       
   697                  TotalCachedSize()));
       
   698     DEBUGSTRING(("CACHE MANAGER: max cache size is %d", iMaxCacheSize));
       
   699  
       
   700 
       
   701     // FIRST: Is there enough space on the cache drive to store the new data
       
   702     TInt cacheDrive = CRsfwRfeServer::Env()->iCacheDrive;
       
   703     TBool isDiskFull = SysUtil::DiskSpaceBelowCriticalLevelL(&iFs,
       
   704                                                              aBytes,
       
   705                                                              cacheDrive);
       
   706     if ( isDiskFull )
       
   707         {
       
   708         // check whether clearing cache may help at all
       
   709         if ( aBytes > TotalCachedSize() )
       
   710             {
       
   711             isDiskFull = SysUtil::DiskSpaceBelowCriticalLevelL(&iFs,
       
   712                                                                aBytes - TotalCachedSize(),
       
   713                                                                cacheDrive);
       
   714             if ( isDiskFull )
       
   715                 {
       
   716                 DEBUGSTRING(("CACHE MANAGER: no space on disk"));
       
   717                 return EFalse;
       
   718                 }
       
   719             }
       
   720         // seems that clearing cache may help
       
   721         else
       
   722             {
       
   723             DEBUGSTRING(("CACHE MANAGER: running out of disk space, attempting to purge some bytes from cache"));
       
   724             do
       
   725                 {
       
   726                 CRsfwFileEntry* victim = iLRUPriorityList.GetAndRemoveFirstEntry();
       
   727 
       
   728                 if (!victim)
       
   729                     {
       
   730                     DEBUGSTRING(("CACHE MANAGER: nothing to delete!!!"));
       
   731                     return EFalse; // cannot clear enough cache space
       
   732                     }
       
   733 
       
   734                 DEBUGSTRING(("CACHE MANAGER: removing fid %d from the cache ",
       
   735                              victim->Fid().iNodeId));
       
   736 
       
   737                 TDesC* cacheNamep = victim->CacheFileName();
       
   738                 User::LeaveIfError(iFs.Delete(*cacheNamep));
       
   739 
       
   740                 victim->SetCached(EFalse);
       
   741                 victim->iCachedSize = 0;
       
   742                 victim->Parent()->SetLocallyDirty();
       
   743 
       
   744 
       
   745                 isDiskFull = SysUtil::DiskSpaceBelowCriticalLevelL(&iFs,
       
   746                                                                    aBytes,
       
   747                                                                    cacheDrive);
       
   748                 }
       
   749             while ( isDiskFull );
       
   750             }
       
   751         }
       
   752 
       
   753     // SECOND: is there enough space in the cache
       
   754     if (TotalCachedSize() + aBytes > iMaxCacheSize)
       
   755         {
       
   756         TInt bytesDeleted = 0;
       
   757         TInt bytesToBeDeleted = TotalCachedSize() + aBytes - iMaxCacheSize;
       
   758         DEBUGSTRING(("CACHE MANAGER: attempting to purge %d bytes from cache",
       
   759                      bytesToBeDeleted));
       
   760 
       
   761         while (bytesDeleted < bytesToBeDeleted)
       
   762             {
       
   763             CRsfwFileEntry* victim = iLRUPriorityList.GetAndRemoveFirstEntry();
       
   764 
       
   765             if (!victim)
       
   766                 {
       
   767                 DEBUGSTRING(("CACHE MANAGER: XXXX: nothing to delete!!!"));
       
   768                 return EFalse; // cannot clear enough cache space
       
   769                 }
       
   770 
       
   771             DEBUGSTRING(("CACHE MANAGER: removing fid %d from the cache ",
       
   772                          victim->Fid().iNodeId));
       
   773 
       
   774             TDesC* cacheNamep = victim->CacheFileName();
       
   775             TInt victimSize = victim->iCachedSize;
       
   776             User::LeaveIfError(iFs.Delete(*cacheNamep));
       
   777 
       
   778             victim->SetCached(EFalse);
       
   779             victim->iCachedSize = 0;
       
   780             victim->Parent()->SetLocallyDirty();
       
   781 
       
   782             bytesDeleted = bytesDeleted + victimSize;
       
   783             }
       
   784         }
       
   785 
       
   786     return ETrue;
       
   787     }
       
   788 
       
   789 // ----------------------------------------------------------------------------
       
   790 // CRsfwVolumeTable::EnsureMetadataCanBeAddedL
       
   791 // This function is called at any time a new CRsfwFileEntry object is about to 
       
   792 // be created in memory.
       
   793 // However we want to prevent the scenario in which parent entry is deleted 
       
   794 // just before its kid creation.
       
   795 // That's why function takes as a parameter a parent entry for the entry 
       
   796 // that is about to be created.
       
   797 // ----------------------------------------------------------------------------
       
   798 //
       
   799 TBool CRsfwVolumeTable::EnsureMetadataCanBeAddedL(CRsfwFileEntry* aParent)
       
   800     {
       
   801     DEBUGSTRING(("memory cap: number of entries %d, entry limit: %d",
       
   802                  TotalEntryCount(), iMaxEntryCount));
       
   803 
       
   804     TBool parentFound = EFalse;
       
   805 
       
   806     while ( TotalEntryCount() >= iMaxEntryCount )
       
   807     {
       
   808         CRsfwFileEntry* victim = iMetadataLRUPriorityList.GetAndRemoveFirstEntry();
       
   809 
       
   810         // if no entries to delete on metadata LRU list try to remove item from file cache LRU list
       
   811         if (!victim)
       
   812             {
       
   813             victim = iLRUPriorityList.GetAndRemoveFirstEntry();
       
   814 
       
   815             if (!victim)
       
   816                 {
       
   817                 DEBUGSTRING(("memory cap: nothing to delete!!!"));
       
   818                 return EFalse; // no posibility to add new entry
       
   819                 }
       
   820             }
       
   821 
       
   822         // don't touch the root items
       
   823         if ( IsRoot(victim) )
       
   824             {
       
   825             continue;
       
   826             }
       
   827         
       
   828         // if we've found the parent don't touch it, just find the other victim ...
       
   829         if (victim && aParent && victim == aParent)
       
   830             {
       
   831             DEBUGSTRING(("<<<<< SAVED THE PARENT!!!! >>>>"));
       
   832             parentFound = ETrue;
       
   833             continue;
       
   834             }
       
   835 
       
   836 
       
   837         // destroy the item
       
   838         DEBUGSTRING(("memory cap: removing fid %d from memory",
       
   839                          victim->Fid().iNodeId));
       
   840         // victim's parent metadata will become out-of-date if we remove victim from memory
       
   841         if ( victim->Parent() )
       
   842             {
       
   843             victim->Parent()->iUseCachedData = EFalse;    
       
   844             }
       
   845 
       
   846         victim->DropLD();
       
   847     }
       
   848     
       
   849     // put the parent back to the list if it was removed from the list.
       
   850     // the reason is that at this point we are not sure whether child will be in fact created.
       
   851     // for now we were only interested in preventing the parent from being deleted, nothing more
       
   852     // as soon as the child is created, the parent will be removed from the list anyway
       
   853     if (parentFound)
       
   854         {
       
   855         iMetadataLRUPriorityList.AddNodeL(aParent, ECachePriorityNormal);
       
   856         }
       
   857     
       
   858     return ETrue;
       
   859     }
       
   860 
       
   861 // ----------------------------------------------------------------------------
       
   862 // CRsfwVolumeTable::IsRoot
       
   863 // Checks whether given entry is a root of some file table
       
   864 // ----------------------------------------------------------------------------
       
   865 //
       
   866 TBool CRsfwVolumeTable::IsRoot(const CRsfwFileEntry* aEntry)
       
   867     {
       
   868     if (!aEntry)
       
   869         {
       
   870         return EFalse;
       
   871         }
       
   872         
       
   873     TInt i;
       
   874     for ( i = 0; i < KMaxVolumes; i++ )
       
   875         {
       
   876         CRsfwVolume* volume;
       
   877         volume = iVolumes[i];
       
   878         if ( volume && aEntry == volume->iFileEngine->iFileTable->Root())
       
   879             {
       
   880             return ETrue;
       
   881             }
       
   882         }
       
   883     return EFalse;
       
   884     }
       
   885 
       
   886 // ----------------------------------------------------------------------------
       
   887 // CRsfwVolumeTable::TotalCachedSize
       
   888 //
       
   889 // ----------------------------------------------------------------------------
       
   890 //
       
   891 TInt CRsfwVolumeTable::TotalCachedSize()
       
   892     {
       
   893     TInt totalSize = 0;
       
   894     CRsfwVolume* volume;
       
   895     TInt i = 0;
       
   896     while (i < KMaxVolumes)
       
   897         {
       
   898         volume = iVolumes[i];
       
   899         if (volume)
       
   900             {
       
   901             TInt newSize = volume->iFileEngine->iFileTable->TotalCachedSize();
       
   902             totalSize += newSize;
       
   903             }
       
   904         i++;
       
   905         }
       
   906     return totalSize;
       
   907     }
       
   908 
       
   909 // ----------------------------------------------------------------------------
       
   910 // CRsfwVolumeTable::TotalEntryCount
       
   911 //
       
   912 // ----------------------------------------------------------------------------
       
   913 //
       
   914 TInt CRsfwVolumeTable::TotalEntryCount()
       
   915     {
       
   916     TInt totalCount = 0;
       
   917     CRsfwVolume* volume;
       
   918     for ( TInt i = 0; i < KMaxVolumes; i++ )
       
   919         {
       
   920         volume = iVolumes[i];
       
   921         if (volume)
       
   922             {
       
   923             TInt volumeCount = volume->iFileEngine->iFileTable->TotalEntryCount();
       
   924             totalCount += volumeCount;
       
   925             }
       
   926         }
       
   927     return totalCount;
       
   928     }
       
   929 
       
   930 // ----------------------------------------------------------------------------
       
   931 // CRsfwVolumeTable::AddToLRUPriorityListL
       
   932 //
       
   933 // ----------------------------------------------------------------------------
       
   934 //
       
   935 void CRsfwVolumeTable::AddToLRUPriorityListL(CRsfwFileEntry *aFe, TInt aPriority)
       
   936     {
       
   937     DEBUGSTRING(("CACHE MANAGER: adding fid '%d' to the LRU cache",
       
   938                  aFe->Fid().iNodeId));
       
   939     iLRUPriorityList.AddNodeL(aFe, aPriority);
       
   940     }
       
   941 
       
   942 // ----------------------------------------------------------------------------
       
   943 // CRsfwVolumeTable::RemoveFromLRUPriorityList
       
   944 //
       
   945 // ----------------------------------------------------------------------------
       
   946 //
       
   947 void CRsfwVolumeTable::RemoveFromLRUPriorityList(CRsfwFileEntry *aFe)
       
   948     {
       
   949     DEBUGSTRING(("CACHE MANAGER: removing fid '%d' from the LRU cache",
       
   950                   aFe->Fid().iNodeId));
       
   951     iLRUPriorityList.RemoveNode(aFe);
       
   952     }
       
   953 
       
   954 // ----------------------------------------------------------------------------
       
   955 // CRsfwVolumeTable::AddToMetadataLRUPriorityListL
       
   956 //
       
   957 // ----------------------------------------------------------------------------
       
   958 //
       
   959 void CRsfwVolumeTable::AddToMetadataLRUPriorityListL(CRsfwFileEntry *aFe, TInt aPriority)
       
   960     {
       
   961     DEBUGSTRING(("memory cap: adding fid '%d' to the metadata LRU list",
       
   962                  aFe->Fid().iNodeId));
       
   963     iMetadataLRUPriorityList.AddNodeL(aFe, aPriority);
       
   964     }
       
   965 
       
   966 // ----------------------------------------------------------------------------
       
   967 // CRsfwVolumeTable::RemoveFromMetadataLRUPriorityList
       
   968 //
       
   969 // ----------------------------------------------------------------------------
       
   970 //
       
   971 void CRsfwVolumeTable::RemoveFromMetadataLRUPriorityList(CRsfwFileEntry *aFe)
       
   972     {
       
   973     DEBUGSTRING(("CRsfwVolumeTable::RemoveFromMetadataLRUPriorityList"));
       
   974     iMetadataLRUPriorityList.RemoveNode(aFe);
       
   975     }
       
   976 
       
   977 // ----------------------------------------------------------------------------
       
   978 // CRsfwVolumeTable::MoveToTheBackOfMetadataLRUPriorityList
       
   979 //
       
   980 // ----------------------------------------------------------------------------
       
   981 //
       
   982 void CRsfwVolumeTable::MoveToTheBackOfMetadataLRUPriorityListL(CRsfwFileEntry *aFe)
       
   983     {
       
   984     // just try to remove the entry from the list and if it was on the list then append it again
       
   985     if ( iMetadataLRUPriorityList.RemoveNode(aFe) == KErrNone )
       
   986         {
       
   987         DEBUGSTRING(("memory cap: moving fid '%d' to the back of metadata LRU list",
       
   988                      aFe->Fid().iNodeId));
       
   989         iMetadataLRUPriorityList.AddNodeL(aFe, ECachePriorityNormal);
       
   990         }
       
   991     }
       
   992 
       
   993 
       
   994 
       
   995 // ----------------------------------------------------------------------------
       
   996 // CRsfwVolumeTable::CheckAndAddProcessStartMarker
       
   997 //
       
   998 // ----------------------------------------------------------------------------
       
   999 //
       
  1000 TBool CRsfwVolumeTable::CheckAndAddProcessStartMarker()
       
  1001     {
       
  1002     DEBUGSTRING(("CRsfwVolumeTable::CheckAndAddProcessStartMarker"));
       
  1003     TFileName path;
       
  1004     path.Copy(*iCacheRoot);
       
  1005     path.Append(KRsfwRestorePendingMark);
       
  1006     
       
  1007     if (BaflUtils::FileExists(iFs, path))
       
  1008         {
       
  1009         // file already exists, the previous attempt to restore metadata must have failed
       
  1010         DEBUGSTRING(("returning EFalse; file already exists"));
       
  1011         return EFalse;
       
  1012         }
       
  1013     else 
       
  1014         {
       
  1015         // create an empty file
       
  1016         TInt err;
       
  1017         RFile markerFile;
       
  1018         err = markerFile.Create(iFs, path, EFileWrite);
       
  1019         if (err) 
       
  1020             {
       
  1021             return EFalse;
       
  1022             }
       
  1023         else 
       
  1024             {
       
  1025             DEBUGSTRING(("returning ETrue; file created"));
       
  1026             markerFile.Close();
       
  1027             return ETrue;
       
  1028             }
       
  1029  
       
  1030         }
       
  1031     }
       
  1032     
       
  1033 // ----------------------------------------------------------------------------
       
  1034 // CRsfwVolumeTable::DeleteTheMarker
       
  1035 //
       
  1036 // ----------------------------------------------------------------------------
       
  1037 //
       
  1038 void CRsfwVolumeTable::DeleteTheMarker()
       
  1039     {    
       
  1040     TFileName path;
       
  1041     path.Copy(*iCacheRoot);
       
  1042     path.Append(KRsfwRestorePendingMark);
       
  1043     
       
  1044     // ignore the error
       
  1045     // if this fails for some reason, lets allow the file to be there
       
  1046     // as "something" must be wrong
       
  1047     iFs.Delete(path);
       
  1048     }
       
  1049 
       
  1050 // ----------------------------------------------------------------------------
       
  1051 // CRsfwVolumeTable::CleanupCorrutedCacheL
       
  1052 //
       
  1053 // ----------------------------------------------------------------------------
       
  1054 //
       
  1055 void CRsfwVolumeTable::CleanupCorruptedCacheL()
       
  1056     {    
       
  1057     // delete everything from the cache
       
  1058     TFileName cachepath;
       
  1059     cachepath.Copy(*iCacheRoot);
       
  1060     CFileMan* fileMan = CFileMan::NewL(iFs);
       
  1061     fileMan->Delete(cachepath, CFileMan::ERecurse);
       
  1062     delete fileMan;
       
  1063     }
       
  1064 
       
  1065 
       
  1066 // ----------------------------------------------------------------------------
       
  1067 // CRsfwVolumeTable::WillExternalizedLRUPriorityListBeUsed
       
  1068 //
       
  1069 // ----------------------------------------------------------------------------
       
  1070 //
       
  1071 void CRsfwVolumeTable::WillLRUPriorityListBeInternalized()
       
  1072     {
       
  1073     DEBUGSTRING(("CRsfwVolumeTable::WillLRUPriorityListBeInternalized"));
       
  1074     iUseExternalizedLRUList = EFalse;
       
  1075     // check whether the file with externalized data exists
       
  1076     TFileName path;
       
  1077     path.Copy(*iCacheRoot);
       
  1078     path.Append(KRsfwLruFileName);
       
  1079 
       
  1080     if (BaflUtils::FileExists(iFs, path))
       
  1081         {
       
  1082         iUseExternalizedLRUList = ETrue;
       
  1083         }
       
  1084     DEBUGSTRING(("...set to %d", iUseExternalizedLRUList)); 
       
  1085     }
       
  1086 
       
  1087 
       
  1088 // ----------------------------------------------------------------------------
       
  1089 // CRsfwVolumeTable::ExternalizeLRUPriorityList
       
  1090 //
       
  1091 // ----------------------------------------------------------------------------
       
  1092 //
       
  1093 void CRsfwVolumeTable::ExternalizeLRUPriorityList()
       
  1094     {
       
  1095     TRAPD(err, ExternalizeLRUPriorityListL());
       
  1096     if (err)
       
  1097         {
       
  1098         DEBUGSTRING(("Externalizing LRU priority list failed!"));
       
  1099         }
       
  1100     }
       
  1101 
       
  1102 // ----------------------------------------------------------------------------
       
  1103 // CRsfwVolumeTable::ExternalizeLRUPriorityList
       
  1104 //
       
  1105 // ----------------------------------------------------------------------------
       
  1106 //
       
  1107 void CRsfwVolumeTable::ExternalizeLRUPriorityListL()
       
  1108     {        
       
  1109     // prepare temp path
       
  1110     _LIT(KRsfwLruTempFileName, "lru.temp");
       
  1111     TFileName tempPath;
       
  1112     tempPath.Copy(*iCacheRoot);
       
  1113     tempPath.Append(KRsfwLruTempFileName);
       
  1114     
       
  1115     // create temp file
       
  1116     RFile file;
       
  1117     CleanupClosePushL(file);
       
  1118     User::LeaveIfError(file.Replace(iFs, tempPath, EFileShareAny | EFileWrite));
       
  1119 
       
  1120     // associate stream
       
  1121     RFileWriteStream stream(file);
       
  1122     CleanupClosePushL(stream);
       
  1123 
       
  1124     // externalize
       
  1125     iLRUPriorityList.ExternalizeL(stream);
       
  1126     stream.CommitL();
       
  1127 
       
  1128     // cleanup
       
  1129     CleanupStack::PopAndDestroy(2); // stream, file        
       
  1130 
       
  1131     // everything went ok -> rename lru.temp into lru.dat
       
  1132     TFileName path;
       
  1133     path.Copy(*iCacheRoot);
       
  1134     path.Append(KRsfwLruFileName);
       
  1135     CFileMan* fm = CFileMan::NewL(iFs);
       
  1136     CleanupStack::PushL(fm);
       
  1137     TInt err = fm->Rename(tempPath, path, CFileMan::EOverWrite);
       
  1138     if (err)
       
  1139         {
       
  1140         fm->Delete(tempPath);
       
  1141         fm->Delete(path);
       
  1142         User::Leave(err);
       
  1143         }
       
  1144     CleanupStack::PopAndDestroy(fm);
       
  1145     }
       
  1146 
       
  1147 // ----------------------------------------------------------------------------
       
  1148 // CRsfwVolumeTable::InternalizeLRUPriorityList
       
  1149 //
       
  1150 // ----------------------------------------------------------------------------
       
  1151 //
       
  1152 void CRsfwVolumeTable::InternalizeLRUPriorityListL()
       
  1153     {
       
  1154     if (!iUseExternalizedLRUList)
       
  1155         {
       
  1156         // it means LRU has been already populated when loading metadata
       
  1157         // so nothing to do here
       
  1158         return;
       
  1159         }
       
  1160     // prepare path
       
  1161     TFileName path;
       
  1162     path.Copy(*iCacheRoot);
       
  1163     path.Append(KRsfwLruFileName);
       
  1164     
       
  1165     // open file
       
  1166     RFile file;
       
  1167     TInt err = file.Open(iFs, path, EFileShareAny | EFileRead);
       
  1168     if ( err == KErrNone )
       
  1169         {
       
  1170         CleanupClosePushL(file);
       
  1171 
       
  1172         // associate stream
       
  1173         RFileReadStream stream(file);
       
  1174         CleanupClosePushL(stream);
       
  1175 
       
  1176         // internalize
       
  1177         TRAP(err, iLRUPriorityList.InternalizeL(stream, this));
       
  1178 
       
  1179         // cleanup
       
  1180         CleanupStack::PopAndDestroy(2); // stream, file        
       
  1181         }
       
  1182 
       
  1183     DEBUGSTRING(("InternalizeLRUPriorityListL: status %d", err));
       
  1184         
       
  1185     // once internalizing is done, the file is not needed anymore 
       
  1186     // ignore the result
       
  1187     iFs.Delete(path);
       
  1188     }
       
  1189 
       
  1190 // ----------------------------------------------------------------------------
       
  1191 // CRsfwVolumeTable::OperationCompleted()
       
  1192 // This function may shut down RFE.
       
  1193 // ----------------------------------------------------------------------------
       
  1194 //
       
  1195 void CRsfwVolumeTable::OperationCompleted(CRsfwVolume* /* aVolume */)
       
  1196     {
       
  1197     DEBUGSTRING(("Volume operation completed"));
       
  1198     // Shut down the whole server if all remaining mounts are dormant
       
  1199     // and we are not still restoring dormant mounts
       
  1200     if ((iAllEnginesIdle) && (!iDormantMountRestorePending))
       
  1201         {
       
  1202         iRfeServer->AllEnginesIdling(KRsfwDormantShutdownTimeout);
       
  1203         }
       
  1204     }
       
  1205 
       
  1206 // ----------------------------------------------------------------------------
       
  1207 // CRsfwVolumeTable::VolumeStateChanged()
       
  1208 //
       
  1209 // ----------------------------------------------------------------------------
       
  1210 //
       
  1211 void CRsfwVolumeTable::VolumeStateChanged(CRsfwVolume* aVolume)
       
  1212     {
       
  1213     DEBUGSTRING(("Volume state changed"));
       
  1214 
       
  1215     TBool allEnginesIdle = ETrue;
       
  1216     TInt i = 0;
       
  1217     do
       
  1218         {
       
  1219         if (iVolumes[i])
       
  1220             {
       
  1221             if (!IsMountIdle(iVolumes[i]->iMountInfo.iMountStatus))
       
  1222                 {
       
  1223                 // Do not shut down if there are connected mounts
       
  1224                 allEnginesIdle = EFalse;
       
  1225                 }
       
  1226             }
       
  1227         } while ((++i < KMaxVolumes) && allEnginesIdle);
       
  1228 
       
  1229     // one more thing is to check the current volume since 
       
  1230     // if the drive was newly mounted, it will not be found from the volume table 
       
  1231     if (allEnginesIdle)
       
  1232         {
       
  1233         TInt driveNumber = VolumeIdByDriveLetter(aVolume->MountInfo()->iMountConfig.iDriveLetter);     
       
  1234         if ((driveNumber != KErrNotFound) && 
       
  1235             (!IsMountIdle(aVolume->MountInfo()->iMountStatus)))
       
  1236             {
       
  1237             allEnginesIdle = EFalse;
       
  1238             }         
       
  1239         }
       
  1240 
       
  1241     DEBUGSTRING(("All engines idle = %d", allEnginesIdle));
       
  1242     iAllEnginesIdle = allEnginesIdle;
       
  1243     }
       
  1244 
       
  1245 // ----------------------------------------------------------------------------
       
  1246 // CRsfwVolumeTable::PublishConnectionStatus()
       
  1247 //
       
  1248 // ----------------------------------------------------------------------------
       
  1249 //
       
  1250 void CRsfwVolumeTable::PublishConnectionStatus(CRsfwVolume* aVolume)
       
  1251     {
       
  1252     DEBUGSTRING(("Publishing connection status:"));
       
  1253     TDriveList driveList;
       
  1254     driveList.FillZ(driveList.MaxLength());
       
  1255     TInt i;
       
  1256     // (at least) record the state of the volume received as a parameter
       
  1257     // (if the drive was newly mounted, it will not be found from the volume table 
       
  1258     TInt driveNumber = VolumeIdByDriveLetter(aVolume->MountInfo()->iMountConfig.iDriveLetter);     
       
  1259     if ((driveNumber != KErrNotFound) && 
       
  1260        (aVolume->MountInfo()->iMountStatus.iMountState != KMountStateDormant))
       
  1261         {
       
  1262         DEBUGSTRING(("- connected: %c", TUint(aVolume->MountInfo()->iMountConfig.iDriveLetter)));
       
  1263         driveList[driveNumber] = 1;
       
  1264         }    
       
  1265     
       
  1266     // for convenience, record the states of other volumes too from the volume table
       
  1267     for (i = 0; i < KMaxVolumes; i++)
       
  1268         {
       
  1269         if (iVolumes[i])
       
  1270             {
       
  1271             TRsfwMountInfo& mountInfo = iVolumes[i]->iMountInfo;
       
  1272             if (mountInfo.iMountStatus.iMountState != KMountStateDormant)
       
  1273                 {
       
  1274                 driveNumber =
       
  1275                     VolumeIdByDriveLetter(mountInfo.iMountConfig.iDriveLetter);
       
  1276                 if (driveNumber != KErrNotFound)
       
  1277                     {
       
  1278                     DEBUGSTRING(("- connected: %c",
       
  1279                                  TUint(mountInfo.iMountConfig.iDriveLetter)));
       
  1280                     driveList[driveNumber] = 1;
       
  1281                     }
       
  1282                 }
       
  1283             }
       
  1284         }
       
  1285           
       
  1286     iMountStateProperty.Set(driveList);
       
  1287     }
       
  1288 
       
  1289 // ----------------------------------------------------------------------------
       
  1290 // CRsfwVolumeTable::WaitNoteManager()
       
  1291 //
       
  1292 // ----------------------------------------------------------------------------
       
  1293 //
       
  1294 CRsfwWaitNoteManager* CRsfwVolumeTable::WaitNoteManager()
       
  1295 	{
       
  1296 	return iWaitNoteManager;
       
  1297 	}
       
  1298 
       
  1299 // ----------------------------------------------------------------------------
       
  1300 // CRsfwVolumeTable::IsCachedDataStillValid()
       
  1301 //
       
  1302 // ----------------------------------------------------------------------------
       
  1303 //
       
  1304 TBool CRsfwVolumeTable::IsCachedDataStillValid(TTime aCachedTime)
       
  1305 	{
       
  1306 	return IsCacheStillValid(aCachedTime,
       
  1307 						TTimeIntervalSeconds(iFileCacheTimeout));
       
  1308 	}
       
  1309 
       
  1310 // ----------------------------------------------------------------------------
       
  1311 // CRsfwVolumeTable::IsCachedAttrStillValid()
       
  1312 //
       
  1313 // ----------------------------------------------------------------------------
       
  1314 //
       
  1315 TBool CRsfwVolumeTable::IsCachedAttrStillValid(TTime aCachedTime)
       
  1316 	{
       
  1317 	return IsCacheStillValid(aCachedTime,
       
  1318 						TTimeIntervalSeconds(iDirCacheTimeout));
       
  1319 	}
       
  1320 
       
  1321 
       
  1322 
       
  1323 // ----------------------------------------------------------------------------
       
  1324 // CRsfwVolumeTable::MountDormantL
       
  1325 //
       
  1326 // ----------------------------------------------------------------------------
       
  1327 //
       
  1328 void CRsfwVolumeTable::MountDormantL(const TRsfwMountConfig& aMountConfig,
       
  1329                                  TInt aVolumeId)
       
  1330     {
       
  1331     // Bind a volume id to a file engine
       
  1332     DEBUGSTRING16(("Restoring drive '%c' with uri '%S' and flags 0x%x",
       
  1333                    TUint(aMountConfig.iDriveLetter),
       
  1334                    &aMountConfig.iUri,
       
  1335                    aMountConfig.iFlags));
       
  1336 
       
  1337     // Create a file engine for the volume
       
  1338     CRsfwVolume* volume = new (ELeave) CRsfwVolume();
       
  1339     CleanupStack::PushL(volume);
       
  1340     volume->iMountInfo.iMountConfig = aMountConfig;
       
  1341     volume->iMountInfo.iMountStatus.iVolumeId = aVolumeId;
       
  1342     volume->iVolumeTable = this;
       
  1343     volume->iMountInfo.iMountStatus.iPermanence = iPermanence;
       
  1344     // We are working offline
       
  1345     volume->iMountInfo.iMountStatus.iMountState = KMountStateDormant;
       
  1346     volume->iMountInfo.iMountStatus.iConnectionState = KMountNotConnected;
       
  1347     CRsfwFileEngine* fileEngine = CRsfwFileEngine::NewL(volume);
       
  1348     volume->iFileEngine = fileEngine;
       
  1349     delete iVolumes[aVolumeId];
       
  1350     iVolumes[aVolumeId] = volume;
       
  1351     CleanupStack::Pop(volume);
       
  1352     }
       
  1353 
       
  1354 // ----------------------------------------------------------------------------
       
  1355 // CRsfwVolumeTable::IsCachedAttrStillValid()
       
  1356 //
       
  1357 // ----------------------------------------------------------------------------
       
  1358 //
       
  1359 TBool CRsfwVolumeTable::IsCacheStillValid(TTime aCachedTime,
       
  1360 									  TTimeIntervalSeconds aValidity)
       
  1361 	{
       
  1362 	TTime now;
       
  1363 	TTime comp;
       
  1364 
       
  1365 	now.UniversalTime();
       
  1366 	comp = now - aValidity;
       
  1367 
       
  1368     if (comp >= aCachedTime)
       
  1369         {
       
  1370         return EFalse;
       
  1371         }
       
  1372     else
       
  1373         {
       
  1374         return ETrue;
       
  1375         }
       
  1376 	}
       
  1377 	
       
  1378 // ----------------------------------------------------------------------------
       
  1379 // CRsfwVolumeTable::PurgeFromCache()
       
  1380 //
       
  1381 // ----------------------------------------------------------------------------
       
  1382 //	
       
  1383 TInt CRsfwVolumeTable::PurgeFromCache(TDesC& aCachePath) 
       
  1384     {
       
  1385     // get the volume id for this path
       
  1386     TParse parser;
       
  1387     parser.Set(aCachePath, NULL, NULL);
       
  1388     if (!(parser.DrivePresent())) 
       
  1389         {
       
  1390         return KErrArgument;
       
  1391         }
       
  1392     TPtrC drive = parser.Drive();
       
  1393     CRsfwVolume* volume = VolumeByDriveLetter(drive[0]);
       
  1394     if (!volume) 
       
  1395         {
       
  1396         return KErrNotFound;
       
  1397         }
       
  1398     
       
  1399     if (!(parser.PathPresent())) 
       
  1400         {
       
  1401         return KErrArgument;
       
  1402         }
       
  1403             
       
  1404     if (parser.NamePresent()) 
       
  1405         {
       
  1406         // this is a file
       
  1407         return KErrArgument;
       
  1408         }
       
  1409     return volume->iFileEngine->PurgeFromCache(parser.Path());
       
  1410     }
       
  1411 
       
  1412 // ----------------------------------------------------------------------------
       
  1413 // CRsfwVolumeTable::CancelTransfer()
       
  1414 //
       
  1415 // ----------------------------------------------------------------------------
       
  1416 //	
       
  1417 TInt CRsfwVolumeTable::CancelTransferL(TDesC& aFilePath) 
       
  1418     {
       
  1419     DEBUGSTRING16(("CRsfwVolumeTable::CancelTransferL for %S", &aFilePath));
       
  1420       // get the volume id for this path
       
  1421     TParse parser;
       
  1422     parser.Set(aFilePath, NULL, NULL);
       
  1423     if (!(parser.DrivePresent())) 
       
  1424         {
       
  1425         return KErrArgument;
       
  1426         }
       
  1427     TPtrC drive = parser.Drive();
       
  1428     CRsfwVolume* volume = VolumeByDriveLetter(drive[0]);
       
  1429     if (!volume) 
       
  1430         {
       
  1431         return KErrNotFound;
       
  1432         }
       
  1433               
       
  1434     if (!(parser.NamePresent())) 
       
  1435         {
       
  1436         // this is not a file
       
  1437         return KErrArgument;
       
  1438         }
       
  1439        
       
  1440     
       
  1441     // mark the file entry as "cancelled"
       
  1442     TPtrC pathPtr  = aFilePath.Right(aFilePath.Length() - 2); //drop the drive letter
       
  1443     CRsfwFileEntry* targetFid = volume->iFileEngine->FetchFep(pathPtr);
       
  1444     if (targetFid)
       
  1445         {
       
  1446         DEBUGSTRING(("setting KNodeWritingCancelled for fid %d", targetFid->Fid().iNodeId));
       
  1447         targetFid->SetFlags(KNodeWritingCancelled);
       
  1448         }
       
  1449         
       
  1450     volume->iFileEngine->CancelTransactionL(aFilePath);
       
  1451 
       
  1452     return KErrNone;
       
  1453     }
       
  1454 
       
  1455 // ----------------------------------------------------------------------------
       
  1456 // CRsfwVolumeTable::IsMountIdle()
       
  1457 //
       
  1458 // ----------------------------------------------------------------------------
       
  1459 //	
       
  1460 TBool CRsfwVolumeTable::IsMountIdle(TRsfwMountStatus& aMountStatus) 
       
  1461     {
       
  1462     if (aMountStatus.iMountState != KMountStateDormant
       
  1463         || aMountStatus.iConnectionState == KMountConnecting)
       
  1464         {
       
  1465         return EFalse;
       
  1466         }
       
  1467     else
       
  1468         {
       
  1469         return ETrue;
       
  1470         }
       
  1471     }