remotestoragefw/mountstore/src/rsfwmountstore.cpp
branchRCL_3
changeset 16 1aa8c82cb4cb
parent 0 3ad9d5175a89
equal deleted inserted replaced
15:88ee4cf65e19 16:1aa8c82cb4cb
       
     1 /*
       
     2 * Copyright (c) 2002-2004 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:  Access mount configuration storage
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 // In order to use the central repository,
       
    20 // The repository initialization file must be put in
       
    21 // [epoc32/release/winscw/udeb/]z/private/10202be9/101F9775.txt
       
    22 
       
    23 // The mount configurations form a table where
       
    24 // individual configuration entries form the rows and
       
    25 // the entry items form the columns.
       
    26 // - rows are indexed with the upper 24 bits of the Id, starting from 1.
       
    27 // - columns are indexed by the lower 8 bits of the Id, starting from 1.
       
    28 //
       
    29 // Row number 0 is reserved for system config name/value pairs (see RsfwConfig)
       
    30 
       
    31 // INCLUDES
       
    32 #include <centralrepository.h>
       
    33 #include <badesca.h>
       
    34 #include <aknnotewrappers.h> 
       
    35 #include <rsfwmountman.h>
       
    36 #include <rsfwmountentry.h>
       
    37 #include <rsfwmountentryitem.h>
       
    38 
       
    39 #include "rsfwmountstore.h"
       
    40 
       
    41 
       
    42 // CONSTANTS
       
    43 const TUid  KCRUidRsfwCtrl    = { 0x101F9775 };
       
    44 
       
    45 // Current mount configuration repository version
       
    46 const TInt  KCurrentVersion   = 1000;
       
    47 const TUint KCurrentVersionId = 0xff;
       
    48 
       
    49 const TInt  KColumnMaskSize   = 8;
       
    50 const TUint KRowMask          = 0xffffff00;
       
    51 const TUint KColumnMask       = 0x000000ff;
       
    52 
       
    53 const TUint KColumnName       = EMountEntryItemName;
       
    54 
       
    55 // ============================ MEMBER FUNCTIONS ==============================
       
    56 
       
    57 // ----------------------------------------------------------------------------
       
    58 // CRsfwMountStore::NewL
       
    59 // Two-phased constructor.
       
    60 // ----------------------------------------------------------------------------
       
    61 //
       
    62 EXPORT_C CRsfwMountStore* CRsfwMountStore::NewL(
       
    63     MRsfwMountStoreObserver* aMountStoreObserver)
       
    64     {
       
    65     CRsfwMountStore* self = new (ELeave) CRsfwMountStore();
       
    66     CleanupStack::PushL(self);
       
    67     self->ConstructL(aMountStoreObserver);
       
    68     CleanupStack::Pop(self);
       
    69     return self;
       
    70     }
       
    71 
       
    72 // ----------------------------------------------------------------------------
       
    73 // CRsfwMountStore::CRsfwMountStore
       
    74 // ----------------------------------------------------------------------------
       
    75 //
       
    76 CRsfwMountStore::CRsfwMountStore()
       
    77     {
       
    78     }
       
    79 
       
    80 // ----------------------------------------------------------------------------
       
    81 // CRsfwMountStore::ConstructL
       
    82 // ----------------------------------------------------------------------------
       
    83 //
       
    84 void CRsfwMountStore::ConstructL(MRsfwMountStoreObserver* aMountStoreObserver)
       
    85     {
       
    86     iMountStoreObserver = aMountStoreObserver;
       
    87     // if CenRep not found, just leave
       
    88     iRepository = CRepository::NewL(KCRUidRsfwCtrl);
       
    89 
       
    90     // Check version
       
    91     TInt version;
       
    92     // allow versionless repositories until the version id is
       
    93     // included in the backup/restore scheme.
       
    94     if (iRepository->Get(KCurrentVersionId, version) == KErrNone)
       
    95         {
       
    96         if (version != KCurrentVersion)
       
    97             {
       
    98             // This causes the repository to be cleared and
       
    99             // stamped with the current version
       
   100             CommitL();
       
   101             }
       
   102         }
       
   103     LoadEntriesL();
       
   104 
       
   105     // Start listening to changes in the repository
       
   106     iCenRepNotifyHandler = CCenRepNotifyHandler::NewL(*this, *iRepository);
       
   107     iCenRepNotifyHandler->StartListeningL();
       
   108     iReceivingCenRepNotifications = ETrue;
       
   109     }
       
   110 
       
   111 // ----------------------------------------------------------------------------
       
   112 // CRsfwMountStore::~CRsfwMountStore
       
   113 // ----------------------------------------------------------------------------
       
   114 //
       
   115 EXPORT_C CRsfwMountStore::~CRsfwMountStore()
       
   116     {
       
   117     iMountEntries.ResetAndDestroy();
       
   118     if (iCenRepNotifyHandler) 
       
   119       {
       
   120       iCenRepNotifyHandler->StopListening();
       
   121       delete iCenRepNotifyHandler;
       
   122       }
       
   123     delete iRepository;
       
   124     }
       
   125 
       
   126 // ----------------------------------------------------------------------------
       
   127 // CRsfwMountStore::LoadEntriesL
       
   128 // CenRep keeps data in alphabetical order, and we want also iMountEntries to
       
   129 // to be filled in the same order
       
   130 // ----------------------------------------------------------------------------
       
   131 //
       
   132 EXPORT_C void CRsfwMountStore::LoadEntriesL()
       
   133     {
       
   134     iMountEntries.ResetAndDestroy();
       
   135 
       
   136     // go through the records in CenRep and populate the array
       
   137     RArray<TUint32> nameIds;
       
   138     CleanupClosePushL(nameIds);
       
   139     User::LeaveIfError(iRepository->FindL(KColumnName, KColumnMask, nameIds));		
       
   140    	HBufC* item = HBufC::NewLC(KMaxMountConfItemLength);
       
   141    	TPtr itemPtr = item->Des();
       
   142    	TInt row;
       
   143 	for (row = 0; row < nameIds.Count(); row++)
       
   144     	{
       
   145     	TUint rowId = (nameIds[row] & KRowMask);
       
   146     	// don't touch record number 0, as it stores RSFW general data
       
   147     	if (rowId > 0)
       
   148         	{
       
   149         	CRsfwMountEntry* entry = CRsfwMountEntry::NewLC();
       
   150         	TUint i;
       
   151         	for (i = EMountEntryItemIndex; i < EMountEntryItemCount; i++)
       
   152             	{
       
   153             	TInt err = iRepository->Get(rowId | i, itemPtr);
       
   154                 if ( err != KErrNone && err != KErrNotFound )
       
   155                     {
       
   156                     User::Leave(err);
       
   157                     }
       
   158            	    entry->SetItemL(i, itemPtr);	
       
   159             	}
       
   160             User::LeaveIfError(iMountEntries.Append(entry));
       
   161             // ownership's been taken by the array
       
   162             CleanupStack::Pop(entry);
       
   163         	}
       
   164     	}
       
   165     CleanupStack::PopAndDestroy(item);
       
   166     CleanupStack::PopAndDestroy(&nameIds);
       
   167     
       
   168     // now mount entries array is up-to-date
       
   169     iCenRepChanged = EFalse;
       
   170     }
       
   171 
       
   172 // ----------------------------------------------------------------------------
       
   173 // CRsfwMountStore::GetNamesL
       
   174 // ----------------------------------------------------------------------------
       
   175 //
       
   176 EXPORT_C void CRsfwMountStore::GetNamesL(CDesC16Array* aNames)
       
   177     {
       
   178     ReloadEntriesL();
       
   179     aNames->Reset();
       
   180     HBufC* name = HBufC::NewLC(KMaxMountConfItemLength);
       
   181     TPtr namePtr = name->Des();
       
   182     TInt i;
       
   183     for (i = 0; i < iMountEntries.Count(); i++)
       
   184         {
       
   185         namePtr.Copy(*iMountEntries[i]->Item(EMountEntryItemName));
       
   186         aNames->AppendL(namePtr);
       
   187         }
       
   188     CleanupStack::PopAndDestroy(name);
       
   189     }
       
   190 
       
   191 // ----------------------------------------------------------------------------
       
   192 // CRsfwMountStore::GetDriveLettersL
       
   193 // ----------------------------------------------------------------------------
       
   194 //
       
   195 EXPORT_C void CRsfwMountStore::GetDriveLettersL(TDriveList& aDriveList)
       
   196     {
       
   197     ReloadEntriesL();
       
   198     aDriveList.Zero();
       
   199     HBufC* name = HBufC::NewLC(KMaxMountConfItemLength);
       
   200     TPtr namePtr = name->Des();
       
   201     TInt i;
       
   202     for (i = 0; i < iMountEntries.Count(); i++)
       
   203         {
       
   204         namePtr.Copy(*iMountEntries[i]->Item(EMountEntryItemDrive));
       
   205         aDriveList.Append(namePtr);
       
   206         }
       
   207     CleanupStack::PopAndDestroy(name);
       
   208     }
       
   209 
       
   210 // ----------------------------------------------------------------------------
       
   211 // CRsfwMountStore::LookupEntryByName
       
   212 // ----------------------------------------------------------------------------
       
   213 //
       
   214 EXPORT_C const CRsfwMountEntry* CRsfwMountStore::LookupEntryByNameL(const TDesC& aName)
       
   215     {
       
   216     ReloadEntriesL();
       
   217     TInt i;
       
   218     for (i = 0; i < iMountEntries.Count(); i++)
       
   219         {
       
   220         CRsfwMountEntry* entry = iMountEntries[i];
       
   221         const HBufC* name = entry->Item(EMountEntryItemName);
       
   222         if (name && name->CompareF(aName) == 0)
       
   223             {
       
   224             return entry;
       
   225             }
       
   226         }
       
   227     return NULL;
       
   228     }
       
   229  
       
   230 // ----------------------------------------------------------------------------
       
   231 // CRsfwMountStore::LookupEntryByDrive
       
   232 // ----------------------------------------------------------------------------
       
   233 //
       
   234 EXPORT_C const CRsfwMountEntry* CRsfwMountStore::LookupEntryByDriveL(TChar aDriveLetter)
       
   235     {
       
   236     ReloadEntriesL();
       
   237     TBuf<1> driveBuf;
       
   238     driveBuf.Append(aDriveLetter);
       
   239     TInt i;
       
   240     for (i = 0; i < iMountEntries.Count(); i++)
       
   241         {
       
   242         CRsfwMountEntry* entry = iMountEntries[i];
       
   243         const HBufC* drive = entry->Item(EMountEntryItemDrive);
       
   244         if (drive && drive->CompareF(driveBuf) == 0)
       
   245             {
       
   246             return entry;
       
   247             }
       
   248         }
       
   249     return NULL;
       
   250     }
       
   251  
       
   252 // ----------------------------------------------------------------------------
       
   253 // CRsfwMountStore::AddEntryL
       
   254 // Adds entry to CenRep, replaces existing item, so it can be used 
       
   255 // for edit operation as well
       
   256 // ----------------------------------------------------------------------------
       
   257 //
       
   258 EXPORT_C void CRsfwMountStore::AddEntryL(CRsfwMountEntry* aMountEntry)
       
   259     {
       
   260     // Take ownership
       
   261     CleanupStack::PushL(aMountEntry);
       
   262 
       
   263     if ((!aMountEntry) || 
       
   264         (!aMountEntry->Item(EMountEntryItemDrive)))
       
   265         {
       
   266         User::Leave(KErrArgument);
       
   267         }
       
   268 
       
   269     ReloadEntriesL();
       
   270 
       
   271     TPtrC drive(*aMountEntry->Item(EMountEntryItemDrive));
       
   272 
       
   273     // Check whether an entry with given drive letter exists.
       
   274     // If so, delete it and remember index of deleted item.
       
   275     // Otherwise find the index at which a new item should be added.
       
   276     // Keep in mind the order is aphabetical.
       
   277     TInt i;
       
   278     TInt index = -1;
       
   279     for (i = 0; i < iMountEntries.Count(); i++)
       
   280         {
       
   281         CRsfwMountEntry* entry = iMountEntries[i];
       
   282         TInt cmp = entry->Item(EMountEntryItemDrive)->CompareF(drive);
       
   283         if (cmp == 0)
       
   284             {
       
   285             // Replace an existing entry
       
   286             RemoveFromRepositoryL(entry);
       
   287             delete entry;
       
   288             entry = NULL;
       
   289             iMountEntries.Remove(i);
       
   290             // save the position, new item will be added here
       
   291             index = i;
       
   292             break;
       
   293             }
       
   294         else if (cmp > 0)
       
   295             {
       
   296             // we've found the entry whose drive letter is larger, which
       
   297             // means we've found the place where a new entry should be added
       
   298             index = i;
       
   299             break;
       
   300             }
       
   301         }
       
   302     
       
   303     // before we add a new entry, make sure that we don't exceed max drives allowed
       
   304     if (iMountEntries.Count() >= KMaxRemoteDrives)    
       
   305         {
       
   306         User::Leave(KErrInUse);
       
   307         }
       
   308 
       
   309     // add entry to the array
       
   310     if (index < 0)
       
   311         {
       
   312         // this means the drive letter of newly added entry is the latest 
       
   313         // in the alphabet. hence just append the entry
       
   314         User::LeaveIfError(iMountEntries.Append(aMountEntry));        
       
   315         }
       
   316     else
       
   317         {
       
   318         User::LeaveIfError(iMountEntries.Insert(aMountEntry, index));
       
   319         }
       
   320 
       
   321 
       
   322     // add to repository  
       
   323     AddToRepositoryL(aMountEntry);
       
   324 
       
   325     // cleanup
       
   326     CleanupStack::Pop(aMountEntry);
       
   327     }
       
   328 
       
   329 // ----------------------------------------------------------------------------
       
   330 // CRsfwMountStore::RemoveEntryL
       
   331 // ----------------------------------------------------------------------------
       
   332 //
       
   333 EXPORT_C void CRsfwMountStore::RemoveEntryL(const TDesC& aName)
       
   334     {
       
   335     ReloadEntriesL();
       
   336     TInt i;
       
   337     for (i = 0; i < iMountEntries.Count(); i++)
       
   338         {
       
   339         CRsfwMountEntry* entry = iMountEntries[i];
       
   340         const HBufC* name = entry->Item(EMountEntryItemName);
       
   341         if (name && name->CompareF(aName) == 0)
       
   342             {
       
   343             RemoveFromRepositoryL(entry);
       
   344             iMountEntries.Remove(i);
       
   345             delete entry;
       
   346             break;
       
   347             }
       
   348         }
       
   349     }
       
   350 
       
   351 // ----------------------------------------------------------------------------
       
   352 // CRsfwMountStore::RemoveEntryL
       
   353 // ----------------------------------------------------------------------------
       
   354 //
       
   355 EXPORT_C void CRsfwMountStore::RemoveEntryL(TChar aDrive)
       
   356     {
       
   357     ReloadEntriesL();
       
   358     TBuf<1> driveBuf;
       
   359     driveBuf.Append(aDrive);
       
   360     TInt i;
       
   361     for (i = 0; i < iMountEntries.Count(); i++)
       
   362         {
       
   363         CRsfwMountEntry* entry = iMountEntries[i];
       
   364         const HBufC* drive = entry->Item(EMountEntryItemDrive);
       
   365         if (drive && drive->CompareF(driveBuf) == 0)
       
   366             {
       
   367             RemoveFromRepositoryL(entry);
       
   368             iMountEntries.Remove(i);
       
   369             delete entry;
       
   370             break;
       
   371             }
       
   372         }
       
   373     }
       
   374 
       
   375 // ----------------------------------------------------------------------------
       
   376 // CRsfwMountStore::CommitL
       
   377 // ----------------------------------------------------------------------------
       
   378 //
       
   379 EXPORT_C void CRsfwMountStore::CommitL()
       
   380     {
       
   381     if (iRepository) 
       
   382         {
       
   383         // We don't want to get reports of our own changes
       
   384         iCenRepNotifyHandler->StopListening();
       
   385         ClearRepositoryL();
       
   386         TInt i;
       
   387         for (i = 0; i < iMountEntries.Count(); i++)
       
   388             {
       
   389             CRsfwMountEntry* entry = iMountEntries[i];
       
   390             AddToRepositoryL(entry);
       
   391             }
       
   392         // Set correct version id
       
   393         User::LeaveIfError(iRepository->Set(KCurrentVersionId, KCurrentVersion));
       
   394         // Restart listening
       
   395         iCenRepNotifyHandler->StartListeningL();
       
   396         }
       
   397     else 
       
   398         {
       
   399         _LIT(KWarningText, "Cannot store entries permanently!");
       
   400         TRAP_IGNORE(CAknWarningNote* note = new (ELeave) CAknWarningNote;
       
   401                     note->ExecuteLD(KWarningText);
       
   402             );
       
   403         }
       
   404     }
       
   405 
       
   406 // ----------------------------------------------------------------------------
       
   407 // CRsfwMountStore::AddToRepositoryL
       
   408 // ----------------------------------------------------------------------------
       
   409 //
       
   410 void CRsfwMountStore::AddToRepositoryL(const CRsfwMountEntry* aMountEntry)
       
   411     {
       
   412     // retrieve drive letter
       
   413     const HBufC* drive = aMountEntry->Item(EMountEntryItemDrive);
       
   414 
       
   415     // calculate record ID for the drive letter
       
   416     TInt recordId = MapDriveLetterToRecordIdL(drive);
       
   417 
       
   418     // write down the entry settings to given record ID
       
   419     TInt i = 0;
       
   420     for (i = EMountEntryItemIndex; i < EMountEntryItemCount; i++)
       
   421         {
       
   422         TInt fieldId = (recordId << KColumnMaskSize) | i;
       
   423         const HBufC* item = aMountEntry->Item(i);
       
   424         if (item)
       
   425             {
       
   426             User::LeaveIfError(iRepository->Create(fieldId, *item));
       
   427             }
       
   428         else
       
   429             {
       
   430             TPtrC null;
       
   431             User::LeaveIfError(iRepository->Create(fieldId, null));
       
   432             }
       
   433         }
       
   434     }    
       
   435 
       
   436 // ----------------------------------------------------------------------------
       
   437 // CRsfwMountStore::RemoveFromRepositoryL
       
   438 // ----------------------------------------------------------------------------
       
   439 //
       
   440 void CRsfwMountStore::RemoveFromRepositoryL(const CRsfwMountEntry* aMountEntry)
       
   441     {
       
   442     // retrieve drive letter
       
   443     const HBufC* drive = aMountEntry->Item(EMountEntryItemDrive);
       
   444 
       
   445     // calculate record ID for the drive letter
       
   446     TInt recordId = MapDriveLetterToRecordIdL(drive);
       
   447 
       
   448     // delete settings from given record ID
       
   449     TInt i = 0;
       
   450     for (i = EMountEntryItemIndex; i < EMountEntryItemCount; i++)
       
   451         {
       
   452         TInt fieldId = (recordId << KColumnMaskSize) | i;
       
   453         User::LeaveIfError(iRepository->Delete(fieldId));
       
   454         }
       
   455     }
       
   456 
       
   457 // ----------------------------------------------------------------------------
       
   458 // CRsfwMountStore::ClearRepositoryL
       
   459 // ----------------------------------------------------------------------------
       
   460 //
       
   461 void CRsfwMountStore::ClearRepositoryL()
       
   462     {
       
   463     // find all non-empty records
       
   464     RArray<TUint32> nameIds;
       
   465     CleanupClosePushL(nameIds);
       
   466     User::LeaveIfError(iRepository->FindL(KColumnName, KColumnMask, nameIds));
       
   467     
       
   468     TInt record;
       
   469     for (record = 0; record < nameIds.Count(); record++)
       
   470         {
       
   471         TUint recordId = (nameIds[record] & KRowMask);
       
   472         // don't touch record number 0, as it stores RSFW general data
       
   473         if (recordId > 0)
       
   474             {
       
   475             TInt i;
       
   476             for (i = EMountEntryItemIndex; i < EMountEntryItemCount; i++)
       
   477                 {
       
   478                 TUint fieldId = (recordId | i);
       
   479                 User::LeaveIfError(iRepository->Delete(fieldId));
       
   480                 }            
       
   481             }
       
   482         }
       
   483     CleanupStack::PopAndDestroy(&nameIds);
       
   484     }
       
   485 
       
   486 // ----------------------------------------------------------------------------
       
   487 // CRsfwMountStore::ReloadEntriesL
       
   488 // ----------------------------------------------------------------------------
       
   489 //
       
   490 void CRsfwMountStore::ReloadEntriesL()
       
   491     {
       
   492     if (!iReceivingCenRepNotifications || iCenRepChanged)
       
   493         {
       
   494         // We only need reload if it is not done automatically
       
   495         // through notifications
       
   496         LoadEntriesL();
       
   497         }
       
   498     }
       
   499 
       
   500 // ----------------------------------------------------------------------------
       
   501 // CRsfwMountStore::HandleNotifyGeneric
       
   502 // ----------------------------------------------------------------------------
       
   503 //
       
   504 void CRsfwMountStore::HandleNotifyGeneric(TUint32 /* aId */)
       
   505     {
       
   506     iCenRepChanged = ETrue;
       
   507     if (iMountStoreObserver)
       
   508         {
       
   509         iMountStoreObserver->HandleMountStoreEvent(
       
   510             EMountStoreEventMountConfigurationChanged,
       
   511             0,
       
   512             NULL);
       
   513         }
       
   514     }
       
   515 
       
   516 // ----------------------------------------------------------------------------
       
   517 // CRsfwMountStore::HandleNotifyError
       
   518 // ----------------------------------------------------------------------------
       
   519 //
       
   520 void CRsfwMountStore::HandleNotifyError(TUint32 /* aId */,
       
   521                                     TInt /* aError */, 
       
   522                                     CCenRepNotifyHandler* /* aHandler */)
       
   523     {
       
   524     iReceivingCenRepNotifications = EFalse;
       
   525     }
       
   526 
       
   527 // ----------------------------------------------------------------------------
       
   528 // CRsfwMountStore::MapDriveLetterToRecordIdL
       
   529 // drive with letter 'J' will take record number 1
       
   530 // drive with letter 'K' will take record number 2
       
   531 // etc.
       
   532 // (remember that record number 0 stores RSFW general data, so don't touch it)
       
   533 // ----------------------------------------------------------------------------
       
   534 //
       
   535 TInt CRsfwMountStore::MapDriveLetterToRecordIdL(const HBufC* drive)
       
   536     {
       
   537     if (!drive || !drive->Length())
       
   538         {
       
   539         User::Leave(KErrArgument);
       
   540         }
       
   541         
       
   542     // we have to convert HBufC to TChar and then TChar to TInt
       
   543     TChar driveChar = (*drive)[0];        
       
   544     TInt driveNumber;
       
   545     RFs fs;
       
   546 	User::LeaveIfError(fs.Connect());
       
   547 	TInt err = fs.CharToDrive(driveChar, driveNumber);
       
   548 	fs.Close();
       
   549     User::LeaveIfError(err);
       
   550 
       
   551     // count record ID based on drive number
       
   552     // +1 is to omit record number 0!
       
   553     return driveNumber - EDriveJ + 1;
       
   554     }
       
   555 
       
   556 //  End of File