--- /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;
+ }