filebrowser/src/FBFileOps.cpp
branchRCL_3
changeset 46 fad26422216a
equal deleted inserted replaced
45:b3cee849fa46 46:fad26422216a
       
     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:  
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include "FBFileOps.h"
       
    21 #include "FBFileUtils.h"
       
    22 #include "FBModel.h"
       
    23 #include "FBTraces.h"
       
    24 
       
    25 #ifndef FILEBROWSER_LITE
       
    26   #include "FBFileOpClient.h"
       
    27 #endif  
       
    28 
       
    29 #include <f32file.h>
       
    30 #include <bautils.h>
       
    31 #include <eikenv.h>
       
    32 #include <babackup.h>
       
    33 
       
    34 const TInt KSecureBackupStartDelay = 750000;
       
    35 const TInt KSecureBackupLoopDelay = 100000;
       
    36 const TInt KSecureBackupEndDelay = 200000;
       
    37 const TInt KMaxFileLockAttempts = 3;
       
    38 
       
    39 
       
    40 // ================= MEMBER FUNCTIONS =======================
       
    41 
       
    42 CFileBrowserFileOps* CFileBrowserFileOps::NewL(CFileBrowserModel* aModel)
       
    43 	{
       
    44 	CFileBrowserFileOps* self = new(ELeave) CFileBrowserFileOps(aModel);
       
    45 	CleanupStack::PushL(self);
       
    46 	self->ConstructL();
       
    47 	CleanupStack::Pop();
       
    48 	return self;
       
    49 	}
       
    50 
       
    51 // --------------------------------------------------------------------------------------------
       
    52 
       
    53 CFileBrowserFileOps::CFileBrowserFileOps(CFileBrowserModel* aModel) : iModel(aModel)
       
    54 	{
       
    55 	}
       
    56 
       
    57 // --------------------------------------------------------------------------------------------
       
    58 
       
    59 void CFileBrowserFileOps::ConstructL()
       
    60 	{
       
    61 	iRecursiveState = EFileOpInvalid;
       
    62 	iSecureBackUpActive = EFalse;
       
    63 	iFileCommandActivatedSecureBackup = EFalse;
       
    64 	
       
    65     User::LeaveIfError(iFs.Connect());
       
    66     iFileMan = CFileMan::NewL( iFs, this );
       
    67 	}
       
    68 
       
    69 // --------------------------------------------------------------------------------------------
       
    70 
       
    71 CFileBrowserFileOps::~CFileBrowserFileOps()
       
    72 	{
       
    73 	if (iSBEClient)
       
    74 	    delete iSBEClient;
       
    75 	
       
    76     #ifndef FILEBROWSER_LITE	
       
    77         if (iFileOpClient)
       
    78             delete iFileOpClient;
       
    79     #endif	
       
    80 
       
    81     delete iFileMan;
       
    82     iFs.Close();    
       
    83     }
       
    84 
       
    85 // --------------------------------------------------------------------------------------------
       
    86 
       
    87 TInt CFileBrowserFileOps::ActivateSecureBackUpViaFileOp()
       
    88     {
       
    89     iFileManObserverResult = MFileManObserver::EContinue;
       
    90     // if already activate by a file command, return ok
       
    91     if (iFileCommandActivatedSecureBackup)
       
    92         return KErrNone;
       
    93     else
       
    94         {
       
    95         // if secure backup is already active, disable it first, because it may in wrong state
       
    96         if (iSecureBackUpActive)
       
    97             DeActivateSecureBackUp();
       
    98         }
       
    99     
       
   100     // try to activate full secure backup
       
   101     TInt err = ActivateSecureBackUp(conn::EBURBackupFull, conn::EBackupBase);
       
   102     
       
   103     if (err == KErrNone)
       
   104         iFileCommandActivatedSecureBackup = ETrue;
       
   105     
       
   106     return err;
       
   107     }
       
   108 
       
   109 // --------------------------------------------------------------------------------------------
       
   110 
       
   111 TInt CFileBrowserFileOps::DeActivateSecureBackUpViaFileOp()
       
   112     {
       
   113     TInt err(KErrGeneral);
       
   114     iFileManObserverResult = MFileManObserver::EContinue;
       
   115     
       
   116     // if activate by a file command, try to reactivate it
       
   117     if (iFileCommandActivatedSecureBackup)
       
   118         {
       
   119         err = DeActivateSecureBackUp();
       
   120         
       
   121         // even if it fails, forget the state
       
   122         iFileCommandActivatedSecureBackup = EFalse;
       
   123         }
       
   124 
       
   125     return err;
       
   126     }    
       
   127     
       
   128 // --------------------------------------------------------------------------------------------
       
   129 
       
   130 TInt CFileBrowserFileOps::ActivateSecureBackUp(conn::TBURPartType aPartType, conn::TBackupIncType aBackupIncType)
       
   131     {
       
   132     iFileManObserverResult = MFileManObserver::EContinue;
       
   133     // check for invalid parameters
       
   134     if (aPartType == conn::EBURNormal || aBackupIncType == conn::ENoBackup)
       
   135         User::Panic(_L("Inv.Usage.SE"), 532);
       
   136     
       
   137     TInt err(KErrNone);
       
   138     
       
   139     if (!iSBEClient)
       
   140         {
       
   141         TRAP(err, iSBEClient = conn::CSBEClient::NewL());
       
   142         if (err != KErrNone)
       
   143             return err;
       
   144         }
       
   145     
       
   146     TDriveList driveList;
       
   147     err = iFs.DriveList(driveList);
       
   148     
       
   149     if (err == KErrNone)
       
   150         {
       
   151         // make sure that the application has a system status to prevent getting shut down events
       
   152         iModel->EikonEnv()->SetSystem(ETrue);
       
   153     
       
   154         // activating secure back up removes locks from files which respect this fuctionality                
       
   155         TRAP(err, iSBEClient->SetBURModeL(driveList, aPartType, aBackupIncType));
       
   156         
       
   157         if (err == KErrNone)
       
   158             {
       
   159             iSecureBackUpActive = ETrue;
       
   160             User::After(KSecureBackupStartDelay); // a short delay to wait to activate
       
   161             }
       
   162         }
       
   163 
       
   164     return err;
       
   165     }
       
   166 
       
   167 // --------------------------------------------------------------------------------------------
       
   168 
       
   169 TInt CFileBrowserFileOps::DeActivateSecureBackUp()
       
   170     {
       
   171     TInt err(KErrNone);
       
   172     
       
   173     if (!iSBEClient)
       
   174         {
       
   175         TRAP(err, iSBEClient = conn::CSBEClient::NewL());
       
   176         if (err != KErrNone)
       
   177             return err;
       
   178         
       
   179         // make sure that the application has a system status
       
   180         iModel->EikonEnv()->SetSystem(ETrue);
       
   181         }
       
   182         
       
   183     TDriveList driveList;
       
   184     err = iFs.DriveList(driveList);
       
   185     
       
   186     if (err == KErrNone)
       
   187         {
       
   188         // deactivate secure backup
       
   189         TRAP(err, iSBEClient->SetBURModeL(driveList, conn::EBURNormal, conn::ENoBackup));
       
   190         
       
   191         User::After(KSecureBackupEndDelay); // a short delay to wait to deactivate
       
   192 
       
   193         // system status not needed anymore
       
   194         iModel->EikonEnv()->SetSystem(EFalse);
       
   195         }
       
   196     
       
   197     iSecureBackUpActive = EFalse;
       
   198 
       
   199     return err;
       
   200     }
       
   201         
       
   202 // --------------------------------------------------------------------------------------------
       
   203 
       
   204 TInt CFileBrowserFileOps::DoFindEntries(const TDesC& aFileName, const TDesC& aPath)
       
   205     {
       
   206     TFindFile fileFinder(iFs);
       
   207     CDir* dir;
       
   208     TInt err = fileFinder.FindWildByPath(aFileName, &aPath, dir);
       
   209 
       
   210     while (err == KErrNone && iFileManObserverResult != MFileManObserver::ECancel)
       
   211         {
       
   212         for (TInt i=0; i<dir->Count(); i++)
       
   213             {
       
   214             TEntry entry = (*dir)[i];
       
   215 
       
   216             if (entry.iName.Length() && aPath.Length())
       
   217                 {
       
   218                 // parse the entry
       
   219                 TParse parsedName;
       
   220                 parsedName.Set(entry.iName, &fileFinder.File(), NULL);
       
   221                 
       
   222                 if (parsedName.Drive().Length() && aPath.Length() && parsedName.Drive()[0] == aPath[0])
       
   223                     {
       
   224                     // get full source path
       
   225                     TFileName fullSourcePath = parsedName.FullName();
       
   226                     if (entry.IsDir())
       
   227                         fullSourcePath.Append(_L("\\"));
       
   228                     
       
   229                     // call the file operation command
       
   230                     switch(iRecursiveState)
       
   231                         {
       
   232                         case EFileOpAttribs:
       
   233                             {
       
   234                             // the same attribs command can be given for both directories and files
       
   235                             FileOpAttribs(fullSourcePath, iUint1, iUint2, iTime1, iUint3);
       
   236                             }
       
   237                             break;
       
   238 
       
   239                         case EFileOpCopy:
       
   240                             {
       
   241                             // calculate length of new entries added to the original source path
       
   242                             TUint newEntriesLength = fullSourcePath.Length() - iBuf1.Length();
       
   243                             
       
   244                             // get pointer description to the rightmost data
       
   245                             TPtr16 newEntriesPtr = fullSourcePath.RightTPtr(newEntriesLength);
       
   246                             
       
   247                             // generate target path
       
   248                             TFileName fullTargetPath = iBuf2;
       
   249                             fullTargetPath.Append(newEntriesPtr);
       
   250                             
       
   251                             if (entry.IsDir())
       
   252                                 {
       
   253                                 // if it is a directory entry, just create it based on the entry's attributes
       
   254                                 FileOpMkDirAll(fullTargetPath, entry.iAtt);
       
   255                                 }
       
   256                             else
       
   257                                 {
       
   258                                 // otherwise copy the file
       
   259                                 FileOpCopy(fullSourcePath, fullTargetPath, iUint1);
       
   260                                 }
       
   261                             }
       
   262                             break;
       
   263 
       
   264                         case EFileOpDelete:
       
   265                             {
       
   266                             if (entry.IsDir())
       
   267                                 {
       
   268                                 // for directories call rmdir    
       
   269                                 FileOpRmDir(fullSourcePath, iUint1);
       
   270                                 }
       
   271                             else
       
   272                                 {
       
   273                                 // for files call the normal file deletion operation    
       
   274                                 FileOpDeleteFile(fullSourcePath, iUint1);
       
   275                                 }
       
   276                             }
       
   277                             break;
       
   278                                                     
       
   279                         default:
       
   280                             User::Panic (_L("FileOpRecurs"), 775);
       
   281                             break;
       
   282                         }                        
       
   283                     }
       
   284                 }
       
   285                 if ( iFileManObserverResult == MFileManObserver::ECancel ) break;
       
   286             }
       
   287 
       
   288         delete dir;
       
   289         dir = NULL;
       
   290         if ( iFileManObserverResult != MFileManObserver::ECancel )
       
   291             {
       
   292             err = fileFinder.FindWild(dir);
       
   293             }
       
   294         }
       
   295 
       
   296     return err;
       
   297     }
       
   298 
       
   299 // --------------------------------------------------------------------------------------------
       
   300 
       
   301 TInt CFileBrowserFileOps::DoFindEntriesRecursiveL(const TDesC& aFileName, const TDesC& aPath)
       
   302 	{
       
   303     TInt err(KErrNone);
       
   304 
       
   305     // it is logical to scan upwards when deleting and changing attributes
       
   306     CDirScan::TScanDirection scanDirection = CDirScan::EScanUpTree;
       
   307     
       
   308     // when copying files, it is more logical to move downwards
       
   309     if (iRecursiveState == EFileOpCopy)
       
   310         scanDirection = CDirScan::EScanDownTree;
       
   311     
       
   312     
       
   313     CDirScan* scan = CDirScan::NewLC(iFs);
       
   314     scan->SetScanDataL(aPath, KEntryAttDir|KEntryAttMatchMask, ESortByName | EAscending | EDirsFirst, scanDirection);
       
   315     CDir* dir = NULL;
       
   316 
       
   317     for(;;)
       
   318         {
       
   319         TRAP(err, scan->NextL(dir));
       
   320         if (!dir  || (err != KErrNone))
       
   321             break;
       
   322 
       
   323         for (TInt i=0; i<dir->Count(); i++)
       
   324             {
       
   325             TEntry entry = (*dir)[i];
       
   326             
       
   327             if (entry.IsDir())
       
   328                 {
       
   329                 TFileName path(scan->FullPath());
       
   330                 
       
   331                 if (path.Length())
       
   332                     {
       
   333                     path.Append(entry.iName);
       
   334                     path.Append(_L("\\"));
       
   335                     // test path.Left(iBuf2.Length()).Compare(iBuf2) - to prevent never ending recursive copy (in case of copy folder under itself)
       
   336                     if( iRecursiveState == EFileOpCopy && path.Left(iBuf2.Length()).Compare(iBuf2) )
       
   337                         {
       
   338                         DoFindEntries(aFileName, path);
       
   339                         }
       
   340                     }
       
   341                 }
       
   342             if ( iFileManObserverResult == MFileManObserver::ECancel )
       
   343                 {
       
   344                 break;
       
   345                 }
       
   346             }
       
   347         delete(dir);
       
   348         if ( iFileManObserverResult == MFileManObserver::ECancel )
       
   349             {
       
   350             break;
       
   351             }
       
   352         }
       
   353 
       
   354     CleanupStack::PopAndDestroy(scan);
       
   355     return err;
       
   356     }
       
   357     
       
   358 // --------------------------------------------------------------------------------------------
       
   359 // --------------------------------------------------------------------------------------------
       
   360 
       
   361 TInt CFileBrowserFileOps::Copy(const TFileEntry& aSourceEntry, const TDesC& aTargetFullName, TUint aSwitch, TBool aDeleteSource) 
       
   362     {
       
   363     iOperationError = KErrNone;
       
   364     iFileManObserverResult = MFileManObserver::EContinue;
       
   365     
       
   366     TFileName sourcePath = aSourceEntry.iPath;
       
   367     sourcePath.Append(aSourceEntry.iEntry.iName);
       
   368     
       
   369     TInt err(KErrNone);
       
   370 
       
   371     if (aSourceEntry.iEntry.IsDir() && (aSwitch & CFileMan::ERecurse))
       
   372         {
       
   373         // find all files recursively and run the operation for them
       
   374         iRecursiveState = EFileOpCopy;
       
   375         sourcePath.Append(_L("\\"));
       
   376         
       
   377         TFileName targetPath = aTargetFullName;
       
   378         targetPath.Append(_L("\\"));
       
   379         
       
   380         // remove the recursion flag because we will implement our own recursion
       
   381         TUint newSwitch(aSwitch);
       
   382         newSwitch &= ~CFileMan::ERecurse;
       
   383     
       
   384         iBuf1.Copy(sourcePath);
       
   385         iBuf2.Copy(targetPath);
       
   386         iUint1 = newSwitch;
       
   387         
       
   388         // create initial directory - if it does not succeed, do not even try to continue
       
   389         err = FileOpMkDirAll(targetPath, aSourceEntry.iEntry.iAtt);
       
   390         
       
   391         if (iOperationError == KErrNone)
       
   392             {
       
   393             TRAP(err, DoFindEntries(_L("*"), sourcePath));              // entries under current directory entry
       
   394             if ( iFileManObserverResult != MFileManObserver::ECancel )
       
   395                 {
       
   396                 TRAP(err, DoFindEntriesRecursiveL(_L("*"), sourcePath));    // recursively under directories of current directory entry
       
   397                 }
       
   398             }
       
   399         }
       
   400 
       
   401     else if (aSourceEntry.iEntry.IsDir())
       
   402         {
       
   403         TFileName targetPath = aTargetFullName;
       
   404         targetPath.Append(_L("\\"));
       
   405         
       
   406         // just create a directory based on the file attributes of the source directory
       
   407         err = FileOpMkDirAll(targetPath, aSourceEntry.iEntry.iAtt);
       
   408         }
       
   409         
       
   410     else
       
   411         {
       
   412         // remove a recursion flag if present (this should never happen, but some extra error checking)
       
   413         if (aSwitch & CFileMan::ERecurse)
       
   414             aSwitch &= ~CFileMan::ERecurse;    
       
   415             
       
   416         // do the operation for a file entry
       
   417         err = FileOpCopy(sourcePath, aTargetFullName, aSwitch);
       
   418         }
       
   419     
       
   420         
       
   421     // delete source if needed and copy succeeded without any errors (== move operation)
       
   422     if ( aDeleteSource && iOperationError == KErrNone &&
       
   423          iFileManObserverResult != MFileManObserver::ECancel )
       
   424         {
       
   425         err = Delete(aSourceEntry, aSwitch);    
       
   426         }
       
   427     
       
   428     if ( !iOperationError && iFileManObserverResult == MFileManObserver::ECancel )
       
   429         {
       
   430         iOperationError = KErrCancel;
       
   431         }
       
   432         
       
   433     return iOperationError; 
       
   434     }
       
   435 
       
   436 // --------------------------------------------------------------------------------------------
       
   437 
       
   438 TInt CFileBrowserFileOps::FileOpCopy(const TDesC& aSourceFullName, const TDesC& aTargetFullName, TUint aSwitch) 
       
   439     {
       
   440     TInt err = DoFileOpCopy(aSourceFullName, aTargetFullName, aSwitch);
       
   441 
       
   442     // if locked, unlock the file and retry
       
   443     if (iModel->Settings().iRemoveFileLocks && err == KErrInUse)
       
   444         {
       
   445         // try to remove the file lock by activating secure backup mode
       
   446         if (ActivateSecureBackUpViaFileOp() == KErrNone)
       
   447             {
       
   448             // try the operation several times
       
   449             for (TInt i=0; i<KMaxFileLockAttempts; i++)
       
   450                 {
       
   451                 err = DoFileOpCopy(aSourceFullName, aTargetFullName, aSwitch);
       
   452                 
       
   453                 if (err != KErrInUse)
       
   454                     break;
       
   455                 else
       
   456                     User::After(KSecureBackupLoopDelay);
       
   457                 }
       
   458             }
       
   459         }
       
   460 
       
   461     // if access denied, then try to remove the target path and try again
       
   462     if (iModel->Settings().iIgnoreProtectionsAtts && err == KErrAccessDenied && BaflUtils::FileExists(iFs, aTargetFullName))
       
   463         {
       
   464         if (FileOpDeleteFile(aTargetFullName, 0) == KErrNone)
       
   465             {
       
   466             err = DoFileOpCopy(aSourceFullName, aTargetFullName, aSwitch);
       
   467             }
       
   468         }
       
   469 
       
   470     // if the file already exists, it is not an error    
       
   471     if (err == KErrAlreadyExists)
       
   472         err = KErrNone;
       
   473     
       
   474     
       
   475     // if copying from a ROM drive, remove the writing protection flag
       
   476     if (iModel->Settings().iRemoveROMWriteProrection && err == KErrNone && aSourceFullName.Length() > 3 && (aSourceFullName[0]=='z' || aSourceFullName[0]=='Z'))
       
   477         {
       
   478         FileOpAttribs(aTargetFullName, 0, KEntryAttReadOnly, 0, 0);
       
   479         }
       
   480     
       
   481     
       
   482     // remember the "lowest" error
       
   483     if (err < iOperationError)
       
   484         iOperationError = err;
       
   485 
       
   486     LOGSTRING4("FileBrowser: FileOpCopy %S -> %S, err=%d", &aSourceFullName, &aTargetFullName, err);
       
   487         
       
   488     return err; 
       
   489     }
       
   490             
       
   491 // --------------------------------------------------------------------------------------------
       
   492 
       
   493 TInt CFileBrowserFileOps::DoFileOpCopy(const TDesC& aSourceFullName, const TDesC& aTargetFullName, TUint aSwitch) 
       
   494     {
       
   495     #ifndef FILEBROWSER_LITE
       
   496     if (iModel->Settings().iBypassPlatformSecurity)
       
   497         {
       
   498         if (!iFileOpClient)
       
   499             iFileOpClient = CFBFileOpClient::NewL();   
       
   500             
       
   501         return iFileOpClient->Copy(aSourceFullName, aTargetFullName, aSwitch);
       
   502         }
       
   503     else
       
   504         {
       
   505     #endif
       
   506         CAsyncWaiter* waiter = CAsyncWaiter::NewLC();
       
   507         TInt result = iFileMan->Copy( aSourceFullName, aTargetFullName, aSwitch, waiter->iStatus );
       
   508         waiter->StartAndWait();
       
   509         if ( !result ) result = waiter->Result();
       
   510         CleanupStack::PopAndDestroy( waiter );
       
   511         return result;
       
   512     #ifndef FILEBROWSER_LITE
       
   513         }    
       
   514     #endif
       
   515     }
       
   516 
       
   517 // --------------------------------------------------------------------------------------------
       
   518 // --------------------------------------------------------------------------------------------
       
   519 
       
   520 TInt CFileBrowserFileOps::Rename(const TFileEntry& aSourceEntry, const TDesC& aNew, TUint aSwitch)
       
   521     {
       
   522     iOperationError = KErrNone;
       
   523     iFileManObserverResult = MFileManObserver::EContinue;
       
   524     
       
   525     TFileName sourcePath = aSourceEntry.iPath;
       
   526     sourcePath.Append(aSourceEntry.iEntry.iName);
       
   527     
       
   528     if (aSourceEntry.iEntry.IsDir())
       
   529         {
       
   530         // do the operation for a directory entry
       
   531         FileOpRename(sourcePath, aNew, aSwitch);
       
   532         }
       
   533     else
       
   534         {
       
   535         // do the operation for a file
       
   536         FileOpRename(sourcePath, aNew, aSwitch);
       
   537         }
       
   538 
       
   539     return iOperationError; 
       
   540     }
       
   541 
       
   542 // --------------------------------------------------------------------------------------------
       
   543 
       
   544 TInt CFileBrowserFileOps::FileOpRename(const TDesC& aName, const TDesC& aNew, TUint aSwitch)
       
   545     {
       
   546     TBool setBackROFlag(EFalse);
       
   547 
       
   548     TInt err = DoFileOpRename(aName, aNew, aSwitch);
       
   549 
       
   550     // if locked, unlock the file and retry
       
   551     if (iModel->Settings().iRemoveFileLocks && err == KErrInUse)
       
   552         {
       
   553         // try to remove the file lock by activating secure backup mode
       
   554         if (ActivateSecureBackUpViaFileOp() == KErrNone)
       
   555             {
       
   556             // try the operation several times
       
   557             for (TInt i=0; i<KMaxFileLockAttempts; i++)
       
   558                 {
       
   559                 err = DoFileOpRename(aName, aNew, aSwitch);
       
   560                 
       
   561                 if (err != KErrInUse)
       
   562                     break;
       
   563                 else
       
   564                     User::After(KSecureBackupLoopDelay);
       
   565                 }
       
   566             }
       
   567         }
       
   568 
       
   569     // if write protected, remove protection and retry
       
   570     else if (iModel->Settings().iIgnoreProtectionsAtts && err == KErrAccessDenied)
       
   571         {
       
   572         // remove write protection and try again
       
   573         if (FileOpAttribs(aName, 0, KEntryAttReadOnly, 0, 0) == KErrNone)
       
   574             {
       
   575             err = DoFileOpRename(aName, aNew, aSwitch);
       
   576             
       
   577             setBackROFlag = ETrue;
       
   578             }
       
   579         }
       
   580 
       
   581     // if still access denied, then try to remove the target path and try again
       
   582     if (iModel->Settings().iIgnoreProtectionsAtts && err == KErrAccessDenied && BaflUtils::FileExists(iFs, aNew))
       
   583         {
       
   584         if (FileOpDeleteFile(aNew, 0) == KErrNone)
       
   585             {
       
   586             err = DoFileOpRename(aName, aNew, aSwitch);
       
   587             }
       
   588         }
       
   589 
       
   590     // set back the read only flag
       
   591     if (setBackROFlag)
       
   592         FileOpAttribs(aName, KEntryAttReadOnly, 0, 0, 0);
       
   593             
       
   594 
       
   595     // remember the "lowest" error
       
   596     if (err < iOperationError)
       
   597         iOperationError = err;
       
   598 
       
   599     LOGSTRING3("FileBrowser: FileOpRename %S, err=%d", &aName, err);
       
   600         
       
   601     return err; 
       
   602     }
       
   603     
       
   604 // --------------------------------------------------------------------------------------------
       
   605 
       
   606 TInt CFileBrowserFileOps::DoFileOpRename(const TDesC& aName, const TDesC& aNew, TUint aSwitch)
       
   607     {
       
   608     #ifndef FILEBROWSER_LITE
       
   609     if (iModel->Settings().iBypassPlatformSecurity)
       
   610         {
       
   611         if (!iFileOpClient)
       
   612             iFileOpClient = CFBFileOpClient::NewL();   
       
   613 
       
   614         return iFileOpClient->Rename(aName, aNew, aSwitch);
       
   615         }
       
   616     else
       
   617         {
       
   618     #endif
       
   619         return iFileMan->Rename(aName, aNew, aSwitch);
       
   620     #ifndef FILEBROWSER_LITE
       
   621         }    
       
   622     #endif
       
   623     }
       
   624 
       
   625 // --------------------------------------------------------------------------------------------
       
   626 // --------------------------------------------------------------------------------------------
       
   627 
       
   628 TInt CFileBrowserFileOps::Attribs(const TFileEntry& aSourceEntry, TUint aSetMask, TUint aClearMask, const TTime& aTime, TUint aSwitch) 
       
   629     {
       
   630     iOperationError = KErrNone;
       
   631     iFileManObserverResult = MFileManObserver::EContinue;
       
   632     
       
   633     TFileName sourcePath = aSourceEntry.iPath;
       
   634     sourcePath.Append(aSourceEntry.iEntry.iName);
       
   635     
       
   636     TInt err(KErrNone);
       
   637 
       
   638     if (aSourceEntry.iEntry.IsDir() && (aSwitch & CFileMan::ERecurse))
       
   639         {
       
   640         // do the operation for a current directory entry
       
   641         err = FileOpAttribs(sourcePath, aSetMask, aClearMask, aTime, 0);
       
   642 
       
   643         // find all files recursively and run the operation for them
       
   644         iRecursiveState = EFileOpAttribs;
       
   645         sourcePath.Append(_L("\\"));
       
   646     
       
   647         iBuf1.Copy(sourcePath);
       
   648         iUint1 = aSetMask;
       
   649         iUint2 = aClearMask;
       
   650         iTime1 = aTime;
       
   651         iUint3 = 0;
       
   652         
       
   653         TRAP(err, DoFindEntriesRecursiveL(_L("*"), sourcePath));    // recursively under directories of current directory entry
       
   654         TRAP(err, DoFindEntries(_L("*"), sourcePath));              // entries under current directory entry
       
   655         }
       
   656 
       
   657     else if (aSourceEntry.iEntry.IsDir())
       
   658         {
       
   659         //sourcePath.Append(_L("\\"));   // <-- do not apply!
       
   660     
       
   661         // do the operation for a directory entry
       
   662         err = FileOpAttribs(sourcePath, aSetMask, aClearMask, aTime, 0);
       
   663         }
       
   664             
       
   665     else
       
   666         {
       
   667         // do the operation for a file entry
       
   668         err = FileOpAttribs(sourcePath, aSetMask, aClearMask, aTime, 0);
       
   669         }
       
   670 
       
   671     return iOperationError;     
       
   672     }
       
   673 
       
   674 // --------------------------------------------------------------------------------------------
       
   675     
       
   676 TInt CFileBrowserFileOps::FileOpAttribs(const TDesC& aName, TUint aSetMask, TUint aClearMask, const TTime& aTime, TUint aSwitch) 
       
   677     {
       
   678     TInt err = DoFileOpAttribs(aName, aSetMask, aClearMask, aTime, aSwitch);
       
   679 
       
   680     // if locked, unlock the file and retry
       
   681     if (iModel->Settings().iRemoveFileLocks && err == KErrInUse)
       
   682         {
       
   683         // try to remove the file lock by activating secure backup mode
       
   684         if (ActivateSecureBackUpViaFileOp() == KErrNone)
       
   685             {
       
   686             // try the operation several times
       
   687             for (TInt i=0; i<KMaxFileLockAttempts; i++)
       
   688                 {
       
   689                 err = DoFileOpAttribs(aName, aSetMask, aClearMask, aTime, aSwitch);
       
   690                 
       
   691                 if (err != KErrInUse)
       
   692                     break;
       
   693                 else
       
   694                     User::After(KSecureBackupLoopDelay);
       
   695                 }
       
   696             }
       
   697         }
       
   698 
       
   699     // remember the "lowest" error
       
   700     if (err < iOperationError)
       
   701         iOperationError = err;
       
   702 
       
   703     LOGSTRING3("FileBrowser: FileOpAttribs %S, err=%d", &aName, err);
       
   704         
       
   705     return err;    
       
   706     }
       
   707     
       
   708 // --------------------------------------------------------------------------------------------
       
   709     
       
   710 TInt CFileBrowserFileOps::DoFileOpAttribs(const TDesC& aName, TUint aSetMask, TUint aClearMask, const TTime& aTime, TUint aSwitch) 
       
   711     {
       
   712     #ifndef FILEBROWSER_LITE
       
   713     if (iModel->Settings().iBypassPlatformSecurity)
       
   714         {
       
   715         if (!iFileOpClient)
       
   716             iFileOpClient = CFBFileOpClient::NewL();   
       
   717 
       
   718         return iFileOpClient->Attribs(aName, aSetMask, aClearMask, aTime, aSwitch);
       
   719         }
       
   720     else
       
   721         {
       
   722     #endif
       
   723         return iFileMan->Attribs(aName, aSetMask, aClearMask, aTime, aSwitch);
       
   724     #ifndef FILEBROWSER_LITE
       
   725         }    
       
   726     #endif
       
   727     }
       
   728 
       
   729 // --------------------------------------------------------------------------------------------
       
   730 // --------------------------------------------------------------------------------------------
       
   731 
       
   732 TInt CFileBrowserFileOps::Delete(const TFileEntry& aSourceEntry, TUint aSwitch) 
       
   733     {
       
   734     iOperationError = KErrNone;
       
   735     iFileManObserverResult = MFileManObserver::EContinue;
       
   736     
       
   737     TFileName sourcePath = aSourceEntry.iPath;
       
   738     sourcePath.Append(aSourceEntry.iEntry.iName);
       
   739     
       
   740     TInt err(KErrNone);
       
   741 
       
   742     if (aSourceEntry.iEntry.IsDir() && (aSwitch & CFileMan::ERecurse))
       
   743         {
       
   744         // find all files recursively and run the operation for them
       
   745         iRecursiveState = EFileOpDelete;
       
   746         sourcePath.Append(_L("\\"));
       
   747     
       
   748         iBuf1.Copy(sourcePath);
       
   749         iUint1 = 0;
       
   750         
       
   751         TRAP(err, DoFindEntriesRecursiveL(_L("*"), sourcePath));    // recursively under directories of current directory entry
       
   752         if ( iFileManObserverResult != MFileManObserver::ECancel )
       
   753             {
       
   754             TRAP(err, DoFindEntries(_L("*"), sourcePath));              // entries under current directory entry
       
   755             }
       
   756         
       
   757         if ( iFileManObserverResult != MFileManObserver::ECancel )
       
   758             {
       
   759             // do the operation for a current directory entry as well
       
   760             err = FileOpRmDir(sourcePath, 0);
       
   761             }
       
   762         }
       
   763 
       
   764     else if (aSourceEntry.iEntry.IsDir())
       
   765         {
       
   766         sourcePath.Append(_L("\\"));
       
   767     
       
   768         // do the operation for a directory entry
       
   769         err = FileOpRmDir(sourcePath, 0);
       
   770         }
       
   771 
       
   772     else
       
   773         {
       
   774         // do the operation for a file entry
       
   775         err = FileOpDeleteFile(sourcePath, 0);
       
   776         }
       
   777     if ( !iOperationError && iFileManObserverResult == MFileManObserver::ECancel )
       
   778         {
       
   779         iOperationError = KErrCancel;
       
   780         }
       
   781     return iOperationError; 
       
   782     }
       
   783 
       
   784 // --------------------------------------------------------------------------------------------
       
   785 
       
   786 TInt CFileBrowserFileOps::FileOpDeleteFile(const TDesC& aName, TUint aSwitch) 
       
   787     {
       
   788     TInt err = DoFileOpDeleteFile(aName, aSwitch);
       
   789 
       
   790     // if locked, unlock the file and retry
       
   791     if (iModel->Settings().iRemoveFileLocks && err == KErrInUse)
       
   792         {
       
   793         // try to remove the file lock by activating secure backup mode
       
   794         if (ActivateSecureBackUpViaFileOp() == KErrNone)
       
   795             {
       
   796             // try the operation several times
       
   797             for (TInt i=0; i<KMaxFileLockAttempts; i++)
       
   798                 {
       
   799                 err = DoFileOpDeleteFile(aName, aSwitch);
       
   800                 
       
   801                 if (err != KErrInUse)
       
   802                     break;
       
   803                 else
       
   804                     User::After(KSecureBackupLoopDelay);
       
   805                 }
       
   806             }
       
   807         }
       
   808 
       
   809     // if write protected or system file, remove protections and retry
       
   810     else if (iModel->Settings().iIgnoreProtectionsAtts && (err == KErrAccessDenied || err == KErrNotFound))
       
   811         {
       
   812         // remove protections  and try again
       
   813         if (FileOpAttribs(aName, 0, KEntryAttReadOnly|KEntryAttSystem|KEntryAttHidden, 0, 0) == KErrNone)
       
   814             {
       
   815             err = DoFileOpDeleteFile(aName, aSwitch);
       
   816             }
       
   817         }
       
   818 
       
   819     // remember the "lowest" error
       
   820     if (err < iOperationError)
       
   821         iOperationError = err;
       
   822 
       
   823     LOGSTRING3("FileBrowser: FileOpDeleteFile %S, err=%d", &aName, err);
       
   824         
       
   825     return err; 
       
   826     }
       
   827         
       
   828 // --------------------------------------------------------------------------------------------
       
   829 
       
   830 TInt CFileBrowserFileOps::DoFileOpDeleteFile(const TDesC& aName, TUint aSwitch) 
       
   831     {
       
   832     #ifndef FILEBROWSER_LITE
       
   833     if (iModel->Settings().iBypassPlatformSecurity)
       
   834         {
       
   835         if (!iFileOpClient)
       
   836             iFileOpClient = CFBFileOpClient::NewL();   
       
   837 
       
   838         return iFileOpClient->Delete(aName, aSwitch);
       
   839         }
       
   840     else
       
   841         {
       
   842     #endif
       
   843         CAsyncWaiter* waiter = CAsyncWaiter::NewLC();
       
   844         TInt result = iFileMan->Delete( aName, aSwitch, waiter->iStatus );
       
   845         waiter->StartAndWait();
       
   846         if ( iFileManObserverResult == MFileManObserver::ECancel ) result = KErrCancel;
       
   847         if ( !result ) result = waiter->Result();
       
   848         CleanupStack::PopAndDestroy( waiter );
       
   849         return result;
       
   850     #ifndef FILEBROWSER_LITE
       
   851         }    
       
   852     #endif
       
   853     }
       
   854 
       
   855 // --------------------------------------------------------------------------------------------
       
   856 
       
   857 TInt CFileBrowserFileOps::FileOpRmDir(const TDesC& aName, TUint aSwitch) 
       
   858     {
       
   859     TInt err = DoFileOpRmDir(aName, aSwitch);
       
   860 
       
   861     // if write protected or system directory, remove protections and retry
       
   862     if (iModel->Settings().iIgnoreProtectionsAtts && (err == KErrAccessDenied || err == KErrInUse))
       
   863         {
       
   864         // remove protections and try again
       
   865         if (FileOpAttribs(aName.Left(aName.Length()-1), 0, KEntryAttReadOnly|KEntryAttSystem|KEntryAttHidden, 0, 0) == KErrNone)
       
   866             {
       
   867             err = DoFileOpRmDir(aName, aSwitch);
       
   868             }
       
   869         }
       
   870 
       
   871     // remember the "lowest" error
       
   872     if (err < iOperationError)
       
   873         iOperationError = err;
       
   874 
       
   875     LOGSTRING3("FileBrowser: FileOpRmDir %S, err=%d", &aName, err);
       
   876         
       
   877     return err; 
       
   878     }
       
   879         
       
   880 // --------------------------------------------------------------------------------------------
       
   881 
       
   882 TInt CFileBrowserFileOps::DoFileOpRmDir(const TDesC& aDirName, TUint aSwitch)
       
   883     {
       
   884     #ifndef FILEBROWSER_LITE
       
   885     if (iModel->Settings().iBypassPlatformSecurity)
       
   886         {
       
   887         if (!iFileOpClient)
       
   888             iFileOpClient = CFBFileOpClient::NewL();   
       
   889 
       
   890         return iFileOpClient->RmDir(aDirName, aSwitch);
       
   891         }
       
   892     else
       
   893         {
       
   894     #endif
       
   895         if ( aSwitch & CFileMan::ERecurse )
       
   896             {
       
   897             CAsyncWaiter* waiter = CAsyncWaiter::NewLC();
       
   898             TInt result = iFileMan->RmDir( aDirName, waiter->iStatus );
       
   899             waiter->StartAndWait();
       
   900             if ( iFileManObserverResult == MFileManObserver::ECancel ) result = KErrCancel;
       
   901             if ( !result ) result = waiter->Result();
       
   902             CleanupStack::PopAndDestroy( waiter);
       
   903             return result;
       
   904             }
       
   905         else
       
   906             return iFs.RmDir(aDirName);    
       
   907     #ifndef FILEBROWSER_LITE
       
   908         }    
       
   909     #endif
       
   910    }
       
   911 
       
   912 // --------------------------------------------------------------------------------------------
       
   913 // --------------------------------------------------------------------------------------------
       
   914 
       
   915 TInt CFileBrowserFileOps::MkDirAll(const TDesC& aPath, TInt aSetAtts, TBool aQuickOperation) 
       
   916     {
       
   917     iFileManObserverResult = MFileManObserver::EContinue;
       
   918     if (aQuickOperation)
       
   919         return DoFileOpMkDirAll(aPath);
       
   920     else
       
   921         return FileOpMkDirAll(aPath, aSetAtts);
       
   922     }
       
   923 
       
   924 // --------------------------------------------------------------------------------------------
       
   925 
       
   926 TInt CFileBrowserFileOps::FileOpMkDirAll(const TDesC& aPath, TInt aSetAtts) 
       
   927     {
       
   928     TInt err = DoFileOpMkDirAll(aPath);
       
   929 
       
   930     // if the directory already exists, it is not an error    
       
   931     if (err == KErrAlreadyExists)
       
   932         err = KErrNone;
       
   933     
       
   934     
       
   935     // set attributes for directory just created
       
   936     if (aSetAtts > 0 && err == KErrNone && aPath.Length() > 3)
       
   937         {
       
   938         // a path has a trailing backslash so it needs to be removed before the call
       
   939         err = FileOpAttribs(aPath.Left(aPath.Length()-1), aSetAtts, 0, 0, 0);
       
   940         }
       
   941     
       
   942 
       
   943     // remember the "lowest" error
       
   944     if (err < iOperationError)
       
   945         iOperationError = err;
       
   946     
       
   947     LOGSTRING3("FileBrowser: FileOpMkDirAll %S, err=%d", &aPath, err);
       
   948     
       
   949     return err;
       
   950     }
       
   951         
       
   952 // --------------------------------------------------------------------------------------------
       
   953 
       
   954 TInt CFileBrowserFileOps::DoFileOpMkDirAll(const TDesC& aPath) 
       
   955     {
       
   956     #ifndef FILEBROWSER_LITE
       
   957     if (iModel->Settings().iBypassPlatformSecurity)
       
   958         {
       
   959         if (!iFileOpClient)
       
   960             iFileOpClient = CFBFileOpClient::NewL();   
       
   961 
       
   962         return iFileOpClient->MkDirAll(aPath);
       
   963         }
       
   964     else
       
   965         {
       
   966     #endif
       
   967         return iFs.MkDirAll(aPath);
       
   968     #ifndef FILEBROWSER_LITE
       
   969         }    
       
   970     #endif
       
   971     }
       
   972 
       
   973 // --------------------------------------------------------------------------------------------
       
   974 // --------------------------------------------------------------------------------------------
       
   975 
       
   976 TInt CFileBrowserFileOps::CreateEmptyFile(const TDesC& aName) 
       
   977     {
       
   978     return DoFileOpCreateEmptyFile(aName);
       
   979     }
       
   980 
       
   981 // --------------------------------------------------------------------------------------------
       
   982 
       
   983 TInt CFileBrowserFileOps::FileOpCreateEmptyFile(const TDesC& aName) 
       
   984     {
       
   985     TInt err = DoFileOpCreateEmptyFile(aName);
       
   986 
       
   987     // remember the "lowest" error
       
   988     if (err < iOperationError)
       
   989         iOperationError = err;
       
   990     
       
   991     LOGSTRING3("FileBrowser: FileOpCreateEmptyFile %S, err=%d", &aName, err);
       
   992     
       
   993     return err;
       
   994     }
       
   995 
       
   996 // --------------------------------------------------------------------------------------------
       
   997     
       
   998 TInt CFileBrowserFileOps::DoFileOpCreateEmptyFile(const TDesC& aName) 
       
   999     {
       
  1000     #ifndef FILEBROWSER_LITE
       
  1001     if (iModel->Settings().iBypassPlatformSecurity)
       
  1002         {
       
  1003         if (!iFileOpClient)
       
  1004             iFileOpClient = CFBFileOpClient::NewL();   
       
  1005 
       
  1006         return iFileOpClient->CreateEmptyFile(aName);
       
  1007         }
       
  1008     else
       
  1009         {
       
  1010     #endif
       
  1011         TInt err(KErrNone);
       
  1012             
       
  1013         RFile newFile;
       
  1014         err = newFile.Create(iFs, aName, EFileShareExclusive);
       
  1015         if (err == KErrNone)
       
  1016             err = newFile.Flush(); 
       
  1017         newFile.Close();
       
  1018         
       
  1019         return err; 
       
  1020     #ifndef FILEBROWSER_LITE
       
  1021         }    
       
  1022     #endif
       
  1023     }
       
  1024 
       
  1025 // --------------------------------------------------------------------------------------------
       
  1026 
       
  1027 TInt CFileBrowserFileOps::DriveSnapShot(TChar aSourceDriveLetter, TChar aTargetDriveLetter)
       
  1028     {
       
  1029     TInt err(KErrNone);
       
  1030     iFileManObserverResult = MFileManObserver::EContinue;
       
  1031     
       
  1032     // remember old settings and force them to be true for this operation
       
  1033     TBool currentRemoveFileLocksValue = iModel->Settings().iRemoveFileLocks;
       
  1034     TBool currentIgnoreProtectionAttsValue = iModel->Settings().iIgnoreProtectionsAtts;
       
  1035     TBool currentRemoveROMWriteProrection = iModel->Settings().iRemoveROMWriteProrection;
       
  1036     iModel->Settings().iRemoveFileLocks = ETrue;
       
  1037     iModel->Settings().iIgnoreProtectionsAtts = ETrue;
       
  1038     iModel->Settings().iRemoveROMWriteProrection = ETrue;
       
  1039 
       
  1040     
       
  1041     TFileName sourceDir;
       
  1042     sourceDir.Append(aSourceDriveLetter);
       
  1043     sourceDir.Append(_L(":"));
       
  1044 
       
  1045     _LIT(KTargetDir, "%c:\\SnapShot_%c_drive");
       
  1046     TFileName targetDir;
       
  1047     targetDir.Format(KTargetDir, TUint(aTargetDriveLetter), TUint(aSourceDriveLetter));            
       
  1048 
       
  1049     // remove any existing content, first get TEntry
       
  1050     TEntry entry;
       
  1051     err = iFs.Entry(targetDir, entry);
       
  1052 
       
  1053     // entry directory exists, delete it
       
  1054     if (err == KErrNone && entry.IsDir())
       
  1055         {
       
  1056         TFileName targetRoot;
       
  1057         targetRoot.Append(aTargetDriveLetter);
       
  1058         targetRoot.Append(_L(":\\"));
       
  1059 
       
  1060         TFileEntry targetEntry;
       
  1061         targetEntry.iPath = targetRoot;
       
  1062         targetEntry.iEntry = entry;
       
  1063 
       
  1064         err = Delete(targetEntry, CFileMan::ERecurse);                
       
  1065         }
       
  1066         
       
  1067     // do not care if removing succeeded or not, just continue with copying    
       
  1068     TEntry fakeEntry;
       
  1069     fakeEntry.iAtt |= KEntryAttDir;
       
  1070 
       
  1071     TFileEntry sourceEntry;
       
  1072     sourceEntry.iPath = sourceDir;
       
  1073     sourceEntry.iEntry = fakeEntry;
       
  1074 
       
  1075     err = Copy(sourceEntry, targetDir, CFileMan::ERecurse|CFileMan::EOverWrite);                
       
  1076 
       
  1077 
       
  1078     // restore back settings
       
  1079     iModel->Settings().iRemoveFileLocks = currentRemoveFileLocksValue;
       
  1080     iModel->Settings().iIgnoreProtectionsAtts = currentIgnoreProtectionAttsValue;    
       
  1081     iModel->Settings().iRemoveROMWriteProrection = currentRemoveROMWriteProrection;    
       
  1082 
       
  1083 
       
  1084     return iOperationError;
       
  1085     }
       
  1086 
       
  1087 // --------------------------------------------------------------------------------------------
       
  1088 
       
  1089 TInt CFileBrowserFileOps::EraseMBR(TUint aDriveNumber) 
       
  1090     {
       
  1091     #ifndef FILEBROWSER_LITE
       
  1092 
       
  1093         if (!iFileOpClient)
       
  1094             iFileOpClient = CFBFileOpClient::NewL();
       
  1095         
       
  1096         return iFileOpClient->EraseMBR(aDriveNumber);
       
  1097 
       
  1098     #else
       
  1099         return KErrNotSupported;
       
  1100     #endif
       
  1101     }
       
  1102 
       
  1103 // --------------------------------------------------------------------------------------------
       
  1104 
       
  1105 TInt CFileBrowserFileOps::PartitionDrive(TUint aDriveNumber, TUint aNumberOfPartitions) 
       
  1106     {
       
  1107     #ifndef FILEBROWSER_LITE
       
  1108 
       
  1109         if (!iFileOpClient)
       
  1110             iFileOpClient = CFBFileOpClient::NewL();
       
  1111         
       
  1112         return iFileOpClient->PartitionDrive(aDriveNumber, aNumberOfPartitions);
       
  1113 
       
  1114     #else
       
  1115         return KErrNotSupported
       
  1116     #endif
       
  1117     }
       
  1118 
       
  1119 // --------------------------------------------------------------------------------------------
       
  1120 
       
  1121 MFileManObserver::TControl CFileBrowserFileOps::NotifyFileManStarted()
       
  1122     {
       
  1123     return iFileManObserverResult;
       
  1124     }
       
  1125 
       
  1126 // --------------------------------------------------------------------------------------------
       
  1127 
       
  1128 MFileManObserver::TControl CFileBrowserFileOps::NotifyFileManOperation()
       
  1129     {
       
  1130     return iFileManObserverResult;
       
  1131     }
       
  1132 // --------------------------------------------------------------------------------------------
       
  1133 
       
  1134 MFileManObserver::TControl CFileBrowserFileOps::NotifyFileManEnded()
       
  1135     {
       
  1136     return iFileManObserverResult;
       
  1137     }
       
  1138 
       
  1139 // --------------------------------------------------------------------------------------------
       
  1140 
       
  1141 void CFileBrowserFileOps::CancelOp()
       
  1142     {
       
  1143 #ifndef FILEBROWSER_LITE
       
  1144 
       
  1145     if ( iModel->Settings().iBypassPlatformSecurity )
       
  1146         {
       
  1147         if ( !iFileOpClient )
       
  1148             iFileOpClient = CFBFileOpClient::NewL();
       
  1149         
       
  1150         iFileOpClient->CancelOp();
       
  1151         }
       
  1152 
       
  1153     // we need this information even when using iFileOpClient
       
  1154     // to be able to not execute aggregate operations 
       
  1155     iFileManObserverResult = MFileManObserver::ECancel;
       
  1156     
       
  1157 #else
       
  1158     iFileManObserverResult = MFileManObserver::ECancel;
       
  1159 #endif
       
  1160     }
       
  1161 
       
  1162 // End of File