coreapplicationuis/rfsplugins/FormatterRFSPlugin/src/formatterrfsplugin.cpp
changeset 0 2e3d3ce01487
child 4 0fdb7f6b0309
child 21 c4cbaa4fb734
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/coreapplicationuis/rfsplugins/FormatterRFSPlugin/src/formatterrfsplugin.cpp	Tue Feb 02 10:12:00 2010 +0200
@@ -0,0 +1,633 @@
+/*
+* Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Implementation of CFormatterRFSPlugin class
+*
+*/
+
+
+// SYSTEM INCLUDE
+#include <centralrepository.h>
+#include <driveinfo.h>
+#include <swi\sisregistrysession.h>
+#include <swi\sisregistryentry.h>
+#include <swi\sisregistrypackage.h>
+#include <mmf\common\mmfcontrollerpluginresolver.h>
+// USER INCLUDE
+#include "formatterrfsplugin.h"
+#include "formatterrfspluginprivatecrkeys.h"
+#include "formatterrfsplugincommon.h"
+#include "trace.h"
+
+// LOCAL CONSTANTS
+const TUid KCRUidCommsDb = { 0xcccccc00 };
+
+_LIT(KDelimeter, ":");
+_LIT(KPathDelimeter, "\\");
+
+
+// ================= LOCAL FUNCTIONS =======================
+
+// ---------------------------------------------------------------------------
+// ExcludeListNameL
+// ---------------------------------------------------------------------------
+//
+static void FileWriteL(RPointerArray<HBufC> &files)
+    {
+    RFs iFs;
+    RFile iFile;
+    User::LeaveIfError(iFs.Connect());
+    TInt err = iFile.Open(iFs,_L("c:\\private\\100059C9\\excludelistcache.txt"),EFileWrite);
+
+    if ( err != KErrNone )
+        {
+        RDebug::Print(_L("CFormatterRFSPlugin::ExcludeListNameL , FileWrite : Failed to open the file"));
+        return;
+        }
+    TBuf8 <1> newLine;
+    newLine.Append('\n');
+    TInt pos = 0;
+    iFile.Seek(ESeekEnd,pos);
+    TInt size = files.Count();
+    for ( TInt i=0; i < size; i++)
+        {
+        HBufC8* fileName = HBufC8::NewLC(files[i]->Size());
+        TPtr8 fileNamePtr(fileName->Des());
+        fileNamePtr.Copy(*files[i]);
+        iFile.Write(*fileName);
+        iFile.Write(newLine);
+        CleanupStack::PopAndDestroy();//Filename
+        iFile.Flush();
+        }
+    iFile.Close();
+    iFs.Close();
+    
+    }
+
+static void MergeFilesL()
+    {
+    
+    RFs iSession;
+    RFile iExclude;
+    
+    RFs iFs;
+    RFile iFile;
+    TInt pos = 0;
+    TInt size_of_script( 0 );
+    TInt buffer_size( sizeof(TText) );
+    TInt number_of_chars;
+    
+    User::LeaveIfError(iSession.Connect());
+    TInt ret = iExclude.Open(iSession,_L("c:\\private\\100059C9\\excludelist.txt"),EFileRead);
+
+    User::LeaveIfError(iFs.Connect());
+    TInt err1 = iFile.Open(iFs,_L("c:\\private\\100059C9\\excludelistcache.txt"),EFileWrite);
+    
+    iFile.Seek(ESeekEnd,pos);
+    if ( ret != KErrNone || err1 != KErrNone)
+            {
+            RDebug::Print(_L("CFormatterRFSPlugin::ExcludeListNameL , MergeFiles : Failed to open the file"));
+            return;
+            }
+    HBufC* buffer = HBufC::NewMaxLC( buffer_size );        
+    TPtr8 bufferPtr( (TUint8*)buffer->Ptr(), buffer_size);
+    
+    TInt err(0);
+    err = iExclude.Size( size_of_script );
+    number_of_chars = size_of_script / sizeof(TText);
+
+    TInt i(0);
+    for (i = 0; i < number_of_chars; i++)
+       {
+       if ( err == KErrNone )
+            {
+            err = iExclude.Read( bufferPtr);                
+            }
+        iFile.Write(bufferPtr);
+        }
+    iFile.Flush();
+    iFile.Close();
+    iFs.Close();
+    
+    iExclude.Close();
+    iSession.Close();
+
+    CleanupStack::PopAndDestroy();//buffer
+    
+    }
+
+static HBufC* ExcludeListNameL( TChar aSystemDrive )
+    {
+    FUNC_LOG;
+
+    RDebug::Print(_L("CFormatterRFSPlugin::ExcludeListNameL"));
+    
+    RFs iFs;
+    RFile iFile;
+    
+    _LIT8(KFileName, "c:\\private\\100059C9\\excludelistcache.txt\n");
+    TBuf8 <50> fileName;
+    fileName.Copy(KFileName);
+
+    User::LeaveIfError(iFs.Connect());
+    
+    RDir dir;
+    if(dir.Open(iFs,_L("c:\\private\\100059C9\\"),KEntryAttNormal) != KErrNone)
+        {
+        iFs.MkDir(_L("c:\\private\\100059C9\\"));
+        }
+    
+    TInt rev = iFile.Replace(iFs,_L("c:\\private\\100059C9\\excludelistcache.txt"),EFileWrite);
+    
+    RDebug::Print(_L("CFormatterRFSPlugin::ExcludeListNameL, Replace returned %d"),rev);
+    
+    iFile.Write(fileName);
+    iFile.Flush();
+    iFile.Close();
+    iFs.Close();
+    
+    Swi::RSisRegistrySession session;
+    CleanupClosePushL(session);
+    User::LeaveIfError(session.Connect());
+    
+    // Get the installed application UIDs
+    RArray<TUid> uids;
+    CleanupClosePushL(uids);
+    session.InstalledUidsL(uids);
+    TInt uidcount = uids.Count(); 
+    
+    Swi::RSisRegistryEntry entry;
+    Swi::RSisRegistryEntry entry2;
+    CleanupClosePushL(entry);
+    CleanupClosePushL(entry2);
+    
+    
+    //No issues until here
+    RPointerArray<HBufC> allfiles;
+    RPointerArray<HBufC> nonRemovableFiles;
+    RPointerArray<HBufC> nonRemovableAugmentedFiles;
+    CleanupResetAndDestroyPushL(allfiles);
+    CleanupResetAndDestroyPushL(nonRemovableFiles);
+    CleanupResetAndDestroyPushL(nonRemovableAugmentedFiles);
+    
+    //Logic starts
+    TInt count;
+    RPointerArray<Swi::CSisRegistryPackage> augmentationPackages;
+    CleanupResetAndDestroyPushL(augmentationPackages);
+    for ( TInt iter=0; iter<uidcount; iter++)
+        {
+        User::LeaveIfError(entry.Open(session,uids[iter]));
+        if(EFalse == entry.RemovableL())
+            {
+            entry.FilesL(nonRemovableFiles);
+            TInt fileCount = nonRemovableFiles.Count(); 
+            for (TInt z=fileCount-1; z>=0;z--)
+                {
+                TPtr firstChar(nonRemovableFiles[z]->Des());
+                if(firstChar.Mid(0,1) == _L("z"))
+                    {
+                    delete nonRemovableFiles[z];
+                    nonRemovableFiles.Remove(z);
+                    }
+                }
+            // Look for augmentations.
+            if(entry.IsAugmentationL())
+                {
+                entry.AugmentationsL(augmentationPackages);
+                count = entry.AugmentationsNumberL();
+                for (TInt i=0; i < count; ++i)
+                    {
+                    User::LeaveIfError(entry2.OpenL(session,*augmentationPackages[i]));
+                    if(EFalse == entry2.RemovableL())
+                        {
+                        entry2.FilesL(nonRemovableAugmentedFiles);
+                        for (TInt c=0; c<nonRemovableAugmentedFiles.Count();c++)
+                              {
+                              TPtr firstChar(nonRemovableAugmentedFiles[c]->Des());
+                              if(firstChar.Mid(0,1) == _L("z"))
+                                  {
+                                  delete nonRemovableAugmentedFiles[c];
+                                  nonRemovableAugmentedFiles.Remove(c);
+                                  }
+                              }
+                        }
+                    entry2.Close();
+                    }
+                }
+            }
+        entry.Close();
+        }
+    RDebug::Print(_L("CFormatterRFSPlugin::ExcludeListNameL Writing the file names to the excludelist.txt"));
+
+		FileWriteL(nonRemovableFiles);
+    FileWriteL(nonRemovableAugmentedFiles);
+    MergeFilesL();
+    
+    CleanupStack::PopAndDestroy(8,&session);
+
+    HBufC* buf = HBufC::NewLC( KExcludeListcache().Length() + KExcludeListPathNameLenExt );
+    TPtr bufPtr = buf->Des();
+    bufPtr.Append( aSystemDrive );
+    bufPtr.Append( KDriveDelimiter );
+    bufPtr.Append( KExcludeListcache );
+    CleanupStack::Pop( buf );
+    return buf;
+    }
+
+// ---------------------------------------------------------------------------
+// CheckFileExist
+// ---------------------------------------------------------------------------
+//
+static TBool CheckFileExist( RFs& aFs, const TDesC& aFullPath )
+    {
+    FUNC_LOG;
+
+    TBool ret( EFalse );
+    RDir dir;
+    TEntry entry;
+    
+    if ( dir.Open( aFs, aFullPath, KEntryAttNormal ) != KErrNone )
+        {
+        INFO_1( "Application exclude list '%S' does not exist", &aFullPath );
+        return EFalse;
+        }
+    if ( dir.Read( entry ) == KErrNone )
+        {
+        ret =  ETrue;
+        }
+    dir.Close();            
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// CheckAppExcludeLists
+// ---------------------------------------------------------------------------
+//
+static TBool CheckAppExcludeListsL( RFs& aFs, TChar aSystemDrive, TChar aRomDrive )
+    {
+    FUNC_LOG;
+    TBool ret( EFalse );
+    HBufC* buf = HBufC::NewLC( KMaxPath );
+    TPtr bufPtr = buf->Des();
+    
+    // Create search pattern and dir scanner    
+    bufPtr.Append( KApplicationExcludeListPath );
+    bufPtr.Append( KApplicationExcludeListFileSearchPattern );
+    
+    // Check system drive first
+    bufPtr[0] = aSystemDrive;
+    
+    ret = CheckFileExist( aFs, bufPtr );
+    
+    if( !ret )
+        {
+        bufPtr[0] = aRomDrive;
+        ret = CheckFileExist( aFs, bufPtr );
+        }
+
+    CleanupStack::PopAndDestroy( buf );
+    
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// ResetRepository
+// ---------------------------------------------------------------------------
+//
+static void ResetRepository( const TUid& aRepositoryUid )
+    {
+    FUNC_LOG;
+
+    //enforce central repository to re-read setting from .cre file…
+    //in next phase try to modify CentRep setting. Because .cre file is locked by CRepositorySession
+    //CentRep cannot make update and causes that repository goes to inconsistent state. Inconsistent
+    //state ensures that new security settings are readed from drive before any other operation
+    CRepository* repository( NULL );
+    TRAPD( err, repository = CRepository::NewL( aRepositoryUid ) );
+    ERROR_1( err, "Failed to open repository 0x%08x (continue)", aRepositoryUid.iUid );
+    if ( err == KErrNone )
+        {
+        err = repository->Reset();
+        ERROR_1( err, "Failed to reset repository 0x%08x (continue)", aRepositoryUid.iUid );
+        err = repository->Create( 0, 0 );
+        ERROR_1( err, "Failed to create repository 0x%08x (continue)", aRepositoryUid.iUid );
+        if ( err == KErrAlreadyExists )
+            {
+            err = repository->Set( 0, 0 );
+            ERROR_1( err, "Failed to set value in repository 0x%08x (continue)", aRepositoryUid.iUid );
+            }
+        }
+    delete repository;
+    }
+
+// ---------------------------------------------------------------------------
+// CFormatterRFSPlugin::NewL
+// ---------------------------------------------------------------------------
+//
+CFormatterRFSPlugin* CFormatterRFSPlugin::NewL( TAny* /*aInitParams*/ )
+    {
+    FUNC_LOG;
+
+    CFormatterRFSPlugin* self = new ( ELeave ) CFormatterRFSPlugin;
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CFormatterRFSPlugin::~CFormatterRFSPlugin()
+    {
+    FUNC_LOG;
+
+    delete iExcludeListName;
+    iFs.Close();
+    }
+
+// ---------------------------------------------------------------------------
+// CFormatterRFSPlugin::RestoreFactorySettingsL
+// ---------------------------------------------------------------------------
+//
+void CFormatterRFSPlugin::RestoreFactorySettingsL( const TRfsReason /*aType*/ )
+    {
+    FUNC_LOG;
+    
+    if(iDriveCountInt > 0)
+        {
+        for( TInt i = EDriveA; i <= EDriveZ; ++i )
+            {
+            if(iDriveListInt[i])
+                {
+                RDebug::Print(_L("CFormatterRFSPlugin::RestoreFactorySettingsL Performing format on drive = %d"), i);
+                TChar driveChar;
+                User::LeaveIfError( iFs.DriveToChar( i, driveChar ) );
+                TBuf<3> driveLetter;
+                driveLetter.Append( driveChar);
+                driveLetter.Append( KDelimeter);
+                driveLetter.Append( KPathDelimeter);
+                // perform format on the drive
+                PerformFormat(driveLetter);
+                }
+            }
+        }
+    
+    if ( iExcludeListName || iAppExcludeList )
+        {
+        RDebug::Print(_L("CFormatterRFSPlugin::RestoreFactorySettingsL Performing selective RFS on System Drive"));
+    
+        TIMESTAMP( "RFS begin" );
+
+        TRAPD( err, DoSecureFormatL() );
+               
+        if( err == KErrInvalidExcList )
+            {
+            if( iExcludeListName )
+                {
+                delete iExcludeListName;
+                iExcludeListName = NULL;
+                }
+            iAppExcludeList = EFalse;
+            return;
+            }
+        else
+            {
+            User::LeaveIfError( err );
+            }
+        
+        // Create directory structure for Central Repository
+        CreateDirectory( KCenRepPrivatePath );
+        CreateDirectory( KCenRepPersistsPath );
+        CreateDirectory( KCenRepBurPath );
+
+        ResetRepository( KCRUidCommsDb );
+
+        TIMESTAMP( "RFS end" );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CFormatterRFSPlugin::GetScriptL
+// ---------------------------------------------------------------------------
+//
+void CFormatterRFSPlugin::GetScriptL( const TRfsReason /*aType*/, TDes& aPath )
+    {
+    FUNC_LOG;
+
+    if ( !iExcludeListName && !iAppExcludeList )
+        {
+        // Add CenRep UID and key
+        aPath.Zero();
+        aPath.AppendNumFixedWidthUC( KCRUidFormatterRFSPlugin.iUid, EHex, KHexLength );
+        aPath.Append( KScriptKeySeparator );
+        aPath.AppendNumFixedWidthUC( KDeepFormatterRFSPlugin, EHex, KHexLength );
+        aPath.Append( KScriptUidSeparator );
+        INFO_1( "Script = '%S'", &aPath );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CFormatterRFSPlugin::ExecuteCustomCommandL
+// ---------------------------------------------------------------------------
+//
+void CFormatterRFSPlugin::ExecuteCustomCommandL(const TRfsReason /*aType*/, TDesC& /*aCommand*/ )
+    {
+    FUNC_LOG;
+    }
+
+// ---------------------------------------------------------------------------
+// CFormatterRFSPlugin::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CFormatterRFSPlugin::ConstructL()
+    {
+    FUNC_LOG;
+
+    User::LeaveIfError( iFs.Connect() );
+
+    User::LeaveIfError(DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, iSystemDrive ) );
+
+    
+    // Get the list of drives which have attribute of either internal or removable 
+    User::LeaveIfError( DriveInfo::GetUserVisibleDrives(iFs, iDriveListInt, iDriveCountInt, KDriveAttInternal | KDriveAttRemovable ));
+    RDebug::Print(_L("CFormatterRFSPlugin::ConstructL The number of internal/removable drives found = %d"), iDriveCountInt);
+    for( TInt i = EDriveA; i <= EDriveZ; ++i )
+        {
+        // Filter in the list of drives that are internal mass memory and are externally mountable i.e. are user accessible
+        if (iDriveListInt[i])
+            {
+            TUint drvStatus( 0 );
+            User::LeaveIfError( DriveInfo::GetDriveStatus( iFs, i, drvStatus ) );
+            if ( !((drvStatus & DriveInfo::EDriveInternal)&& (drvStatus & DriveInfo::EDriveExternallyMountable )))
+                {
+                iDriveCountInt--;
+                iDriveListInt[ i ] = NULL;
+                RDebug::Print(_L("CFormatterRFSPlugin::ConstructL() drive excluded = %d"), i);
+                }
+            }
+        }
+    RDebug::Print(_L("CFormatterRFSPlugin::ConstructL The number of internal/removable drives left after filtering = %d"), iDriveCountInt);
+    
+    iExcludeListName = ExcludeListNameL( iSystemDrive );
+
+    RFile file;
+    TInt err = file.Open( iFs, *iExcludeListName, EFileRead );
+    if ( err == KErrNone )
+        {
+        TInt fileSize( 0 );
+        err = file.Size( fileSize );
+        if ( err != KErrNone || fileSize == 0 )
+            {
+            // Empty file
+            INFO_1( "Exclude list '%S' is empty", iExcludeListName );
+            delete iExcludeListName;
+            iExcludeListName = NULL;
+            }
+        }
+    else
+        {
+        // File not found
+        INFO_1( "Exclude list '%S' does not exist", iExcludeListName );
+        delete iExcludeListName;
+        iExcludeListName = NULL;
+        }
+    file.Close();
+    
+    User::LeaveIfError( DriveInfo::GetDefaultDrive(DriveInfo::EDefaultRom, iDefaultRomDrive ) );
+    
+    iAppExcludeList = CheckAppExcludeListsL( iFs, iSystemDrive, iDefaultRomDrive );
+    
+    if( iAppExcludeList && !iExcludeListName )
+        {
+        iExcludeListName = KEmptyParameter().AllocL();
+        }  
+    }
+
+// ---------------------------------------------------------------------------
+// CFormatterRFSPlugin::DoSecureFormatL
+// ---------------------------------------------------------------------------
+//
+void CFormatterRFSPlugin::DoSecureFormatL() const
+    {
+    FUNC_LOG;
+
+    TIMESTAMP( "Secure format begin" );
+	
+	// check the exclude list file is present
+	if( NULL == iExcludeListName )
+	{
+	TInt error = KErrNotFound;
+	ERROR( error, "Exclude list file is not found. Secure formatter failed" );
+	User::LeaveIfError( error );
+	}
+
+    HBufC* arg = HBufC::NewLC(iExcludeListName->Length() + KSecureFormatterArgLenExt );
+    TPtr argPtr = arg->Des();
+    argPtr.Format(KSecureFormatterArgFmt, iExcludeListName,static_cast<TUint>( iSystemDrive ), KDriveDelimiter, KPathDelimiter );
+
+    RProcess process;
+    CleanupClosePushL( process );
+    TInt err = process.Create( KSecureFormatter, *arg );
+    ERROR( err, "Failed to create process" );
+    User::LeaveIfError( err );
+
+    TRequestStatus status;
+    process.Logon( status );
+    process.Resume();
+    User::WaitForRequest( status );
+    ERROR( status.Int(), "secure formatter failed" );
+    // Continue
+
+    CleanupStack::PopAndDestroy( &process );
+    CleanupStack::PopAndDestroy( arg );
+
+    TIMESTAMP( "Secure format end" );
+    }
+
+// ---------------------------------------------------------------------------
+// CFormatterRFSPlugin::CreateDirectory
+// ---------------------------------------------------------------------------
+//
+void CFormatterRFSPlugin::CreateDirectory( const TDesC& aDirName )
+    {
+    FUNC_LOG;
+
+    TBuf<KMaxPath> path;
+    path.Append( iSystemDrive );
+    path.Append( KDriveDelimiter );
+    path.Append( aDirName );
+    iFs.MkDirAll( path ); // Ignore errors
+    }
+
+// ---------------------------------------------------------------------------
+// CFormatterRFSPlugin::ExecuteFormatCommand
+// ---------------------------------------------------------------------------
+//
+TInt CFormatterRFSPlugin::PerformFormat(const TDesC& aDriveLetter)
+    {
+    RDebug::Print(_L("CRfsCommand::ExecuteFormatCommand()"));
+    RFormat formatter;
+    TInt ret( KErrNone );
+    
+    TInt count(0);
+    // Open formatter
+    ret = formatter.Open(iFs, aDriveLetter, EHighDensity | EFullFormat, count );
+    RDebug::Print(_L("CFormatterRFSPlugin::ExecuteFormatCommand(): Formatter open returned : %d"), ret);    
+    if ( ret == KErrInUse ) // Locked files in drive
+        {
+        TInt driveNumber = iMassStorageDrive; 
+
+        // Shouldn't assume it's the internal mass storage drive is E:, check the parameter 
+        ret = iFs.CharToDrive( aDriveLetter[ 0 ], driveNumber ); 
+        RDebug::Print(_L("CFormatterRFSPlugin::ExecuteFormatCommand(): drive numer %d"), driveNumber);   
+
+        // Get the file system name from the drive before dismounting it 
+        TFullName name; 
+        ret = iFs.FileSystemName(name, driveNumber); 
+        RDebug::Print(_L("CFormatterRFSPlugin::ExecuteFormatCommand(): FileSystemName returned : %d, name %S"), ret, &name); 
+
+        // Force a dismount
+        TRequestStatus dummyStat;
+        RDebug::Print(_L("CFormatterRFSPlugin::ExecuteFormatCommand(): Setting notifier"));
+        iFs.NotifyDismount( driveNumber, dummyStat, EFsDismountForceDismount );
+        iFs.DismountFileSystem( name, driveNumber );
+        
+        RDebug::Print(_L("CFormatterRFSPlugin::ExecuteFormatCommand(): Waiting for request complete"));
+        User::WaitForRequest(dummyStat);
+        RDebug::Print(_L("CFormatterRFSPlugin::ExecuteFormatCommand(): Request completed"));
+
+        // Now mount the file system again
+        ret = iFs.MountFileSystem(name, driveNumber);
+        RDebug::Print(_L("CFormatterRFSPlugin::ExecuteFormatCommand(): MountFileSystem returned : %d"), ret);
+
+        // Try to open formatter second time
+        ret = formatter.Open(iFs, aDriveLetter, EHighDensity | EFullFormat, count );
+        RDebug::Print(_L("CFormatterRFSPlugin::ExecuteFormatCommand(): Second try: Formatter open returned : %d"), ret);
+        }
+
+    if ( ret == KErrNone )
+        {
+        while ( count > 0 )
+            {
+            ret = formatter.Next( count );
+            RDebug::Print(_L("CFormatterRFSPlugin::ExecuteFormatCommand(): Format status: %d, tracks remaining %d"), ret, count);
+            }
+        }
+            
+    formatter.Close();
+ 
+    RDebug::Print(_L("CFormatterRFSPlugin::ExecuteFormatCommand(): End: returns %d"), ret);
+    return ret;
+    }