diff -r 000000000000 -r 2e3d3ce01487 contextframework/cfw/src/cfscriptengine/CFScriptHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contextframework/cfw/src/cfscriptengine/CFScriptHandler.cpp Tue Feb 02 10:12:00 2010 +0200 @@ -0,0 +1,2014 @@ +/* +* Copyright (c) 2002-2008 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: The main interface class providing services of ScriptEngine module +* +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef RD_MULTIPLE_DRIVE +#include +#endif + +#include "CFScriptHandler.h" +#include "CFScript.h" +#include "ContextFrameworkPrivateCRKeys.h" +#include "cftrace.h" +#include "cfextendedcontextinterface.h" +#include "cfoperationpluginmanager.h" +#include "cfpersistentdata.h" +#include "cfcommon.h" +#include "cfscriptowner.h" + +// CONSTANTS + +#ifdef USE_TEMP_RULE_FOLDER + _LIT( KDefaultRuleFilePath, "c:\\Silmaril\\Rules\\" ); +#else + _LIT( KDefaultRuleFilePath, "!:\\private\\10282BC4\\Rules\\" ); +#endif + +// Default script search pattern +_LIT( KDefaultRuleFileSearchPattern, "*.rul" ); +_LIT( KWildCardChar, "*" ); + +const TInt KInitialScriptId = 1; +const TInt KUidLength = 8; +const TInt KTempScriptId = 0; + +const TUint KLimit = 0xFFFFFFFF; + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::CCFScriptHandler +// C++ default constructor can NOT contain any code, that might leave. +// ----------------------------------------------------------------------------- +// +CCFScriptHandler::CCFScriptHandler( + MCFExtendedContextInterface& aCF, + RFs& aFs, + MCFActionHandler& aScriptEventListener, + MCFSecurityChecker& aSecurityChecker ) + : iParserDataProvidingState( KError ), + iNextId( KInitialScriptId ), + iCF( aCF ), + iFs( aFs ), + iScriptEventListener( aScriptEventListener ), + iSecurityChecker( aSecurityChecker ) + { + FUNC_LOG; + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CCFScriptHandler::ConstructL() + { + FUNC_LOG; + + iParser = CMDXMLParser::NewL( this ); + iWaitParsing = new( ELeave ) CActiveSchedulerWait; + iOperationPluginManager = CCFOperationPluginManager::NewL( *this ); + +#ifdef RD_MULTIPLE_DRIVE + User::LeaveIfError( DriveInfo::GetDefaultDrive( + DriveInfo::EDefaultRom, iDefaultRomDrive ) ); + User::LeaveIfError( DriveInfo::GetDefaultDrive( + DriveInfo::EDefaultSystem, iDefaultSystemDrive ) ); +#else + iDefaultRomDrive = 'Z'; + iDefaultSystemDrive = 'C'; +#endif + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +EXPORT_C CCFScriptHandler* CCFScriptHandler::NewL( + MCFExtendedContextInterface& aCF, + RFs& aFs, + MCFActionHandler& aScriptEventListener, + MCFSecurityChecker& aSecurityChecker ) + { + FUNC_LOG; + + CCFScriptHandler* self = NewLC( aCF, aFs, aScriptEventListener, + aSecurityChecker ); + CleanupStack::Pop( self ); + return self; + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::NewLC +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +EXPORT_C CCFScriptHandler* CCFScriptHandler::NewLC( + MCFExtendedContextInterface& aCF, + RFs& aFs, + MCFActionHandler& aScriptEventListener, + MCFSecurityChecker& aSecurityChecker ) + { + FUNC_LOG; + + CCFScriptHandler* self = + new( ELeave ) CCFScriptHandler( aCF, aFs, aScriptEventListener, + aSecurityChecker ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + +// Destructor +EXPORT_C CCFScriptHandler::~CCFScriptHandler() + { + FUNC_LOG; + + iRollbackList.ResetAndDestroy(); + iLoadedScripts.Close(); + iScripts.ResetAndDestroy(); + iScriptIds.Close(); + delete iParser; + delete iWaitParsing; + delete iOperationPluginManager; + } + + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::AddScript +// Adds a new script. Calls AddScriptL that does the actual work. +// ----------------------------------------------------------------------------- +// +TInt CCFScriptHandler::AddScript( const TDesC& aName, + const TDesC8& aScript, + const TUid& aOwner, + const RThread& aOwnerThread, + MCFActionHandler& aActionHandler, + MCFScriptOwner* aScriptOwner ) + { + FUNC_LOG; + + TInt err = KErrNone; + + // Check that script with the name does not exist - notice script object + // ownership is not transfered + RPointerArray< CCFScript > scripts; + GetScriptsByUid( aOwner, scripts ); + for( TInt i = 0; i < scripts.Count(); ++i ) + { + // Compare names only if we are not updating existing script. + if ( scripts[ i ]->ScriptId() != iNextId ) + { + TPtrC scriptName( scripts[ i ]->Name() ); + if( scriptName.CompareF( aName ) == KErrNone ) + { + err = KErrAlreadyExists; + ERROR_2( err, "Script name %S already in use in client 0x%x", + &aName, aOwner ); + break; + } + } + } + scripts.Close(); + + // Add script + TInt ret = err; + if( err == KErrNone ) + { + TRAP( err, ret = AddScriptL( aName, + aScript, + aOwner, + aOwnerThread, + aActionHandler, + ETrue, + aScriptOwner ) ); + if ( err != KErrNone ) + { + ERROR( ret, "Unable to add script" ); + ret = err; + } + } + + // return script Id ( >0 ) or error code if error ( <0 ) + return ret; + } + + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::NumberOfScriptsByOwner +// +// ----------------------------------------------------------------------------- +// +TInt CCFScriptHandler::NumberOfScriptsByOwner( const TUid& aOwner ) + { + FUNC_LOG; + + TInt result( KErrNone ); + + // iterate thru all the existing scripts + for ( TInt i = 0; i < iScripts.Count(); i++ ) + { + // check if the owner Uid matches + if ( iScripts[ i ]->OwnerUid() == aOwner ) + { + // increment script count + result++; + } + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::NumberOfScripts +// +// ----------------------------------------------------------------------------- +// +TInt CCFScriptHandler::NumberOfScripts() + { + FUNC_LOG; + + return iScripts.Count(); + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::ScriptLength +// +// ----------------------------------------------------------------------------- +// +TInt CCFScriptHandler::ScriptLength( TInt aScriptId ) + { + FUNC_LOG; + + TInt result ( KErrNotFound ); + + // iterate thru all the existing scripts + for ( TInt i = 0; i < iScripts.Count(); i++ ) + { + // check if the script id matches + if ( iScripts[ i ]->ScriptId() == aScriptId ) + { + // get the descriptor length of the script + result = iScripts[ i ]->Length(); + } + } + return result; + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::GetEveryScriptId +// +// ----------------------------------------------------------------------------- +// +const RArray< TInt >& CCFScriptHandler::GetEveryScriptId() + { + FUNC_LOG; + + // local variable declarations + TInt err( KErrNone ); + + // reset array + iScriptIds.Reset(); + + // go thru all the scripts + for ( TInt i = 0; i < iScripts.Count(); i++ ) + { + // add Id to result array + err = iScriptIds.Append( iScripts[ i ]->ScriptId() ); + // handle error + if ( err != KErrNone ) + { + // return what we have created so far + return iScriptIds; + } + } + return iScriptIds; + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::GetEveryScriptIdByOwner +// +// ----------------------------------------------------------------------------- +// +const RArray< TInt >& CCFScriptHandler::GetEveryScriptIdByOwner( + const TUid& aScriptOwner ) + { + FUNC_LOG; + + // local variable declarations + TInt err( KErrNone ); + + // reset array + iScriptIds.Reset(); + + // go thru all the scripts + for ( TInt i = 0; i < iScripts.Count(); i++ ) + { + // if the owner Uid matches + if ( iScripts[ i ]->OwnerUid() == aScriptOwner ) + { + // add Id to result array + err = iScriptIds.Append( iScripts[ i ]->ScriptId() ); + // handle error + if ( err != KErrNone ) + { + // return what we have created so far + return iScriptIds; + } + } + } + return iScriptIds; + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::UpdateScript +// +// ----------------------------------------------------------------------------- +// +TInt CCFScriptHandler::UpdateScript( TInt aScriptID, + const RThread& aOwnerThread, + const TDesC8& aUpdatedScript, + MCFScriptOwner* aScriptOwner ) + { + FUNC_LOG; + + // local variable declaration & initialization + TInt err( KErrNotFound ); + TInt index = iScripts.Count() - 1; + TBool found( EFalse ); + + // search for the script + while ( !found && // script not found yet + index >= 0 ) // still scripts left + { + if ( iScripts[ index ]->ScriptId() == aScriptID ) + { + found = ETrue; + err = KErrNone; + break; // skip to not found + } + index--; + } + // not found + if ( !found ) + { + // return immediately with error code + return err; + } + // script found + else + { + // store session and owner Uid temporarily + MCFActionHandler& scriptSession + = ( iScripts[ index ]->ActionHandler() ); + + // handle Script Ids correctly + TInt nextAvailableScriptId = iNextId; + iNextId = iScripts[ index ]->ScriptId(); + + TUid scriptOwner = iScripts[ index ]->OwnerUid(); + + // remove found script from array and delete it + CCFScript* outdatedScript = iScripts [ index ]; + + // add the new script; note that the existing script + // file in filestore is removed automatically + iUpdatedScript = outdatedScript; + err = AddScript( outdatedScript->Name(), + aUpdatedScript, + scriptOwner, + aOwnerThread, + scriptSession, + aScriptOwner ); + iUpdatedScript = NULL; + + // remove the outdated script only if the new one is succesully added. + if( err > 0 ) + { + iScripts.Remove( index ); + delete outdatedScript; + } + // restore Next available Script Id + iNextId = nextAvailableScriptId; + } + // script added successfully + if ( err > 0 ) + { + err = KErrNone; + } + + return err; + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::SaveScript +// ----------------------------------------------------------------------------- +// +TInt CCFScriptHandler::SaveScript( const TDesC8& aScript, + TInt aScriptId, + const TUid& aOwnerUid ) + { + FUNC_LOG; + + TInt err = KErrNotFound; + for( TInt i = 0; i < iScripts.Count(); i++ ) + { + CCFScript* script = iScripts[i]; + // Check script ID + if( script->ScriptId() == aScriptId ) + { + // Check script owner + if( script->OwnerUid() == aOwnerUid || + KCFServerSid == aOwnerUid ) + { + // found matching uid - construct file path + HBufC* name = ScriptFilePath( script->Info() ); + if( name ) + { + err = DoSave( *name, aScript ); + } + else + { + err = KErrNoMemory; + } + delete name; + name = NULL; + break; + } + else + { + err = KErrAccessDenied; + } + } + } + + return err; + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::DeleteScriptByName +// ----------------------------------------------------------------------------- +// +TInt CCFScriptHandler::DeleteScriptByName( const TDesC& aScriptName, + const TUid& aOwnerUid ) + { + FUNC_LOG; + + TInt err = KErrNotFound; + + // Get script name + TParsePtrC parse( aScriptName ); + TPtrC scriptName( parse.Name() ); + + // Get scripts added by the owner + RPointerArray scripts; + GetScriptsByUid( aOwnerUid, scripts ); + + // If the script being deleted has already been deregistered, try to resolve + // the script path from the script name and owner uid + if( scripts.Count() ) + { + for( TInt i = 0; i < scripts.Count(); i++ ) + { + CCFScript* script = scripts[i]; + if( script->Name().CompareF( scriptName ) == KErrNone ) + { + // correct owner uid - delete script + HBufC* name = ScriptFilePath( script->Info() ); + if( name ) + { + // Delete script file + TPtrC namePtrC( *name ); + err = DeleteScriptFile( namePtrC, aOwnerUid ); + } + else + { + err = KErrNoMemory; + } + + delete name; + name = NULL; + break; + } + } + } + + // Check manually from the system drive if the script was not found + if( err == KErrNotFound ) + { + // Resolve script name from owner uid and script name + HBufC* name = ScriptFilePath( scriptName, aOwnerUid ); + if( name ) + { + // Delete script file + TPtrC namePtrC( *name ); + err = DeleteScriptFile( namePtrC, aOwnerUid ); + if( err == KErrNone ) + { + // Transfer err as KErrDeregisterNotNeeded since the script + // has already been deregistered + err = KErrDeregisterNotNeeded; + } + + // Clean up + delete name; + name = NULL; + } + } + + // Clean up + scripts.Close(); + + return err; + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::DeleteScriptByUid +// ----------------------------------------------------------------------------- +// +TInt CCFScriptHandler::DeleteScriptByUid( const TUid& aUid ) + { + FUNC_LOG; + + // Delete all scripts registered and stored by the client + TInt err = KErrNotFound; + HBufC* name = HBufC::New( KMaxFileName ); + if( name ) + { + RPointerArray scripts; + GetScriptsByUid( aUid, scripts ); + if( scripts.Count() ) + { + for( TInt i = 0; i < scripts.Count(); i++ ) + { + CCFScript* script = scripts[i]; + TPtr namePtr( name->Des() ); + ScriptFilePath( script->Info(), namePtr ); + err = BaflUtils::DeleteFile( iFs, namePtr ); + INFO_3( "Deleted script file %S from client %x with code %d", + &namePtr, aUid.iUid, err ); + } + + // Remove folder + TParsePtrC parse( *name ); + TPtrC dir( parse.DriveAndPath() ); + + // Check if not in rules base folder - delete this folder + if( aUid != KCFServerSid ) + { + err = iFs.RmDir( dir ); + INFO_2( "Removed directory %S with code %d", &dir, err ); + } + } + else + { + // Scripts not found (already deregistered), search the scripts + // manually + TPtr namePtr( name->Des() ); + namePtr.Format( KDefaultSystemRuleFileFormat, aUid.iUid, &KWildCardChar ); + namePtr[0] = iDefaultSystemDrive; + + // search all rule files from the particular client + CDir* dir = NULL; + err = iFs.GetDir( namePtr, KEntryAttNormal, ESortNone, dir ); + if( err == KErrNone && dir ) + { + for( TInt i = 0; i < dir->Count(); i++ ) + { + TParsePtrC entryNameParse( (*dir)[i].iName ); + TPtrC entryName( entryNameParse.Name() ); + namePtr.Format( KDefaultSystemRuleFileFormat, + aUid.iUid, &entryName ); + namePtr[0] = iDefaultSystemDrive; + + // Possible error values can be ignored since deleting + // multiple files + DeleteScriptFile( namePtr, aUid ); + } + err = KErrDeregisterNotNeeded; + } + else + { + // Basically no scripts found, convert err to KErrNotFound + err = KErrNotFound; + } + delete dir; + dir = NULL; + } + + // cleanup + scripts.Close(); + delete name; + name = NULL; + } + else + { + err = KErrNoMemory; + } + + return err; + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::AlreadyExists +// ----------------------------------------------------------------------------- +// +TBool CCFScriptHandler::AlreadyExists( const TDesC& aScriptName, + const TUid& aOwnerUid, + TInt& aScriptId ) const + { + FUNC_LOG; + + TParsePtrC parsePtrC( aScriptName ); + TPtrC scriptName( parsePtrC.Name() ); + TBool exists = EFalse; + RPointerArray scripts; + GetScriptsByUid( aOwnerUid, scripts ); + for( TInt i = 0; i < scripts.Count(); i++ ) + { + CCFScript* script = scripts[i]; + if( script->Name().CompareF( scriptName ) == KErrNone ) + { + // Name already in use - store script id + aScriptId = script->ScriptId(); + exists = ETrue; + break; + } + } + scripts.Close(); + + return exists; + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::CleanupPersistentDataByName +// ----------------------------------------------------------------------------- +// +void CCFScriptHandler::CleanupPersistentDataByName( const TDesC& aScriptName, + const TUid& aOwnerUid ) + { + FUNC_LOG; + + TParsePtrC parsePtrC( aScriptName ); + TPtrC scriptName( parsePtrC.Name() ); + RPointerArray scripts; + GetScriptsByUid( aOwnerUid, scripts ); + for( TInt i = 0; i < scripts.Count(); i++ ) + { + CCFScript* script = scripts[i]; + if( script->Name().CompareF( scriptName ) == KErrNone ) + { + script->CleanupPersistentData(); + } + } + scripts.Close(); + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::CleanupPersistentDataByUid +// ----------------------------------------------------------------------------- +// +void CCFScriptHandler::CleanupPersistentDataByUid( const TUid& aOwnerUid ) + { + FUNC_LOG; + + RPointerArray scripts; + GetScriptsByUid( aOwnerUid, scripts ); + for( TInt i = 0; i < scripts.Count(); i++ ) + { + CCFScript* script = scripts[i]; + script->CleanupPersistentData(); + } + scripts.Close(); + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::RestoreRomScript +// ----------------------------------------------------------------------------- +// +TInt CCFScriptHandler::RestoreRomScript( TInt aScriptId, + const TUid& /*aOwnerUid*/, + const RThread& aClient ) + { + FUNC_LOG; + + TInt err = KErrNotFound; + + // Check that the restored file actually exists + RPointerArray scripts; + GetScriptsByUid( KCFServerSid, scripts ); + CCFScript* script = NULL; + for( TInt i = 0; i < scripts.Count(); i++ ) + { + script = scripts[i]; + if( script->ScriptId() == aScriptId ) + { + // Script found - break from loop + break; + } + script = NULL; + } + scripts.Close(); + + // If the script was found + if( script ) + { + HBufC* name = ScriptFilePath( script->Info() ); + if( name ) + { + // Resolve rom script name and replace system drive letter with rom + TPtr namePtr( name->Des() ); + namePtr[0] = iDefaultRomDrive; + + TBool exists = BaflUtils::FileExists( iFs, namePtr ); + if( exists ) + { + HBufC8* scriptBuf = LoadScriptFromFile( namePtr ); + if( scriptBuf ) + { + MCFActionHandler& scriptSession = + script->ActionHandler(); + + // Check thath upgrade is allowed + err = IsUpgradeAllowed( script->Name(), *scriptBuf, + script->OwnerUid(), aClient, scriptSession ); + if( err == KErrNone ) + { + // Script data succesfully loaded - update script + err = UpdateScript( aScriptId, aClient, *scriptBuf, NULL ); + } + } + else + { + err = KErrCorrupt; + } + delete scriptBuf; + scriptBuf = NULL; + } + } + + // Clean up + delete name; + name = NULL; + } + + return err; + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::IsUpgradeAllowed +// ----------------------------------------------------------------------------- +// +TInt CCFScriptHandler::IsUpgradeAllowed( const TDesC& aName, + const TDesC8& aScript, + const TUid& aOwner, + const RThread& aOwnerThread, + MCFActionHandler& aActionHandler ) + { + FUNC_LOG; + + TInt allowed( KErrNotSupported ); + + // Since we are not creating a permanent script script id and owner are + // temporary + CCFScript* scriptUpgrade = NULL; + TRAP( allowed, scriptUpgrade = CreateScriptL( aName, aScript, aOwner, + aOwnerThread, aActionHandler, ETrue, KTempScriptId, NULL ) ); + if( allowed == KErrNone ) + { + if( scriptUpgrade ) + { + allowed = KErrNotFound; + RPointerArray scripts; + + // Get all rom scripts - this means all scripts with owner uid + // of cfserver sid + GetScriptsByUid( KCFServerSid, scripts ); + for( TInt i = 0; i < scripts.Count(); i++ ) + { + CCFScript* script = scripts[i]; + if( script->Name().CompareF( + scriptUpgrade->Name() ) == KErrNone ) + { + // Matching script found - check that script upgrade has at + // least the same capability level than the rom script + if( scriptUpgrade->UpgradeSecurity().HasCapabilities( + script->UpgradeSecurity() ) ) + { + // Check that client has the needed upgrade capabilities + TSecurityInfo client( aOwnerThread ); + if( client.iCaps.HasCapabilities( + scriptUpgrade->UpgradeSecurity() ) ) + { + allowed = KErrNone; + } + else + { + allowed = KErrAccessDenied; + } + } + else + { + allowed = KErrAccessDenied; + } + } + } + scripts.Close(); + } + else + { + allowed = KErrNotSupported; + } + } + + // clean up + delete scriptUpgrade; + scriptUpgrade = NULL; + + return allowed; + } + +//------------------------------------------------------------------------------ +// CCFScriptHandler::RemoveScriptByProviderUid +//------------------------------------------------------------------------------ +// +TInt CCFScriptHandler::RemoveScriptByProviderUid( const TUid& aProviderUid, + TBool aRollback ) + { + FUNC_LOG; + + TInt err = KErrNotFound; + + // Check all scripts which have dependency to the provider in question + for( TInt i = iScripts.Count() - 1; i >= 0; i-- ) + { + CCFScript* script = iScripts[i]; + if( script->HasDependency( aProviderUid ) ) + { + // Script has dependency to the provider, remove script + err = KErrNone; + if( aRollback ) + { + // Rollback needed, create a copy from info + TRAPD( rollbackErr, AddRollbackInfoL( *script ) ); + if( rollbackErr != KErrNone ) + { + TPtrC name( script->Name() ); + ERROR_2( rollbackErr, "Failed to rollback script [%S] from client [%x]", + &name, script->OwnerUid().iUid ); + } + } + iScripts.Remove( i ); + delete script; + script = NULL; + } + } + + return err; + } + +//------------------------------------------------------------------------------ +// CCFScriptHandler::RollbackScripts +//------------------------------------------------------------------------------ +// +void CCFScriptHandler::RollbackScripts() + { + FUNC_LOG; + + HBufC* path = HBufC::New( KMaxFileName ); + if( path ) + { + TPtr pathPtr( path->Des() ); + TBool rollback = EFalse; + + // Go through roll back list and automatically search for scripts in rom + // or ram. If a script is not found, owner of the script will be notified + // that an automatic script dereigstration has occured. + for( TInt i = iRollbackList.Count() - 1; i >= 0; i-- ) + { + // Format file path from script info + CCFScriptInfo* info = iRollbackList[i]; + ScriptFilePath( *info, pathPtr ); + if( BaflUtils::FileExists( iFs, pathPtr ) ) + { + // Script found from default system drive + rollback = ETrue; + } + else + { + // Script not found from default system drive, check rom if the + // owner if cfserver + if( info->OwnerUid() == KCFServerSid ) + { + // Check from rom + pathPtr[0] = iDefaultRomDrive; + if( BaflUtils::FileExists( iFs, pathPtr ) ) + { + // Script found from default rom drive + rollback = ETrue; + } + } + } + + // Rollback if possible + if( rollback ) + { + // Rollback + TRAPD( err, RollbackScriptL( *info, pathPtr ) ); + TPtrC name( info->Name() ); + if( err == KErrNone ) + { + INFO_2( "Script [%S] from owner [%x] succesfull restored", + &name, info->OwnerUid().iUid ); + } + else + { + INFO_2( "Script [%S] from owner [%x] failed to restore", + &name, info->OwnerUid().iUid ); + } + + // Clean up rollback info + iRollbackList.Remove( i ); + delete info; + info = NULL; + } + } + + // Check scripts which could not be automatically activated + while( iRollbackList.Count() ) + { + // Get the first script info + CCFScriptInfo* info = iRollbackList[0]; + + // Check if the owner is set and check all the other scripts by the + // same owner + MCFScriptOwner* owner = info->OwnerSession(); + if( owner ) + { + // Owner found, notify owner + NotifyScriptIds( owner ); + } + else + { + // Owner not set, delete info and update rollback list + iRollbackList.Remove( 0 ); + delete info; + info = NULL; + } + } + + // Clean up + delete path; + path = NULL; + } + else + { + ERROR( KErrNoMemory, "Failed to rollback scripts due OOM" ); + } + iRollbackList.ResetAndDestroy(); + } + +//------------------------------------------------------------------------------ +// CCFScriptHandler::DeregisterScriptOwner +//------------------------------------------------------------------------------ +// +void CCFScriptHandler::DeregisterScriptOwner( MCFScriptOwner* aScriptOwner ) + { + FUNC_LOG; + + for( TInt i = 0; i < iScripts.Count(); i++ ) + { + CCFScriptInfo& info = iScripts[i]->Info(); + if( info.OwnerSession() == aScriptOwner ) + { + info.SetOwnerSession( NULL ); + } + } + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::InitializePhaseL +// ----------------------------------------------------------------------------- +// +void CCFScriptHandler::InitializePhaseL( CCFPhaseBase::TCFPhaseId aPhaseId ) + { + FUNC_LOG; + + MCFStarterObserver* observer + = (MCFStarterObserver*) iOperationPluginManager; + observer->InitializePhaseL( aPhaseId ); + + switch( aPhaseId ) + { + case CCFPhaseBase::ECFDeviceStarting: + { + InitDeviceStartingPhaseL(); + break; + } + case CCFPhaseBase::ECFLoadingRules: + { + InitDeviceStartedPhaseL(); + break; + } + default: + { + break; + } + } + } + +//---------------------------------------------------------------------------- +// CCFScriptHandler::SetEventHandler +//---------------------------------------------------------------------------- +// +void CCFScriptHandler::SetEventHandler( MCFStarterEventHandler& /*aEventHandler*/ ) + { + FUNC_LOG; + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::UpdatePlugInsL +// ----------------------------------------------------------------------------- +// +void CCFScriptHandler::UpdatePlugInsL() + { + FUNC_LOG; + + iOperationPluginManager->UpdatePlugInsL(); // Let the "wait starter" to proceed. + } + + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::ParseFileCompleteL +// ----------------------------------------------------------------------------- +// +void CCFScriptHandler::ParseFileCompleteL() + { + FUNC_LOG; + + iWaitParsing->AsyncStop(); // Let the "wait starter" to proceed. + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::GetData +// ----------------------------------------------------------------------------- +// +void CCFScriptHandler::GetData( TPtrC8& aPtr, TRequestStatus& aStatus ) + { + FUNC_LOG; + + TRequestStatus *requestStatus = &aStatus; + switch( iParserDataProvidingState ) + { + case KInit: + aPtr.Set( iParserData ); + iParserDataProvidingState = KDataSent; + User::RequestComplete( requestStatus, KMoreData ); + break; + case KDataSent: + iParserDataProvidingState = KDone; + User::RequestComplete( requestStatus, KDataStreamEnd ); + break; + case KDone: + User::RequestComplete( requestStatus, KDataStreamEnd ); + break; + default: + User::RequestComplete( requestStatus, KDataStreamError ); + break; + }; + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::Disconnect +// ----------------------------------------------------------------------------- +// +void CCFScriptHandler::Disconnect() + { + FUNC_LOG; + + iParserData.Set( 0, 0 ); // Parser data can be invalidated. + iParserDataProvidingState = KDone; + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::AddScriptL +// Method that implements the adding operation of a new script. +// ----------------------------------------------------------------------------- +// +TInt CCFScriptHandler::AddScriptL( const TDesC& aName, + const TDesC8& aScript, + const TUid& aOwner, + const RThread& aOwnerThread, + MCFActionHandler& aActionHandler, + TBool aDoSecurityCheck, + MCFScriptOwner* aScriptOwner, + TInt aScriptId ) + { + FUNC_LOG; + + CCFScript* script = CreateScriptL( aName, aScript, aOwner, aOwnerThread, + aActionHandler, aDoSecurityCheck, aScriptOwner, aScriptId ); + + // Leave if script is not created + User::LeaveIfNull( script ); + + CleanupStack::PushL( script ); + if( iUpdatedScript ) + { + iUpdatedScript->CleanupPersistentData(); + } + script->ActivateL(); + User::LeaveIfError( iScripts.Append( script ) ); + CleanupStack::Pop( script ); + + return aScriptId != KErrNotFound ? aScriptId : iNextId++; + } + + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::RemoveScriptsBySession +// Removes all scripts that are associated to the given aSession. +// ----------------------------------------------------------------------------- +// +TInt CCFScriptHandler::RemoveScriptsBySession( + const MCFActionHandler& aSession ) + { + FUNC_LOG; + + // local variable declarations and initialization + TInt count( KErrNone ); // init to zero + TInt index = iScripts.Count() - 1; // index of last script + + // iterate through the scripts array + // and remove scripts if necessary + while ( index >= 0 ) + { + // get the currently last script in the array + CCFScript* script = iScripts[ index ]; + + // remove the script if the session matches + if ( &( script->ActionHandler() ) == &aSession ) + { + // remove from internal array + iScripts.Remove( index ); + delete script; + script = NULL; + // increment removed scripts count + count++; + } + // decrement index + index--; + } + // compress the array + iScripts.GranularCompress(); + // return # of scripts removed + return count; + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::RemoveScriptById +// Removes a script according to its unique Id, if it exists. +// ----------------------------------------------------------------------------- +// +TInt CCFScriptHandler::RemoveScriptById( TInt aScriptId, const RThread& aOwner ) + { + FUNC_LOG; + + // make sure got valid Id + if ( aScriptId <= 0 ) + { + ERROR_GEN( "Got negative script Id parameter" ); + return KErrArgument; + } + + // Iterate through the entire scripts array + TInt err = KErrNotFound; + for ( TInt i = iScripts.Count() - 1; i >= 0; i-- ) + { + CCFScript* script = iScripts[ i ]; + if ( script->ScriptId() == aScriptId ) + { + // script found + if ( script->OwnerUid() == aOwner.SecureId() ) + { + // remove from internal array + iScripts.Remove( i ); + delete script; + script = NULL; + err = KErrNone; + } + else + { + err = KErrAccessDenied; + } + break; + } + } + // return whether or not we removed the script + return err; + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::RemoveScriptByName +// ----------------------------------------------------------------------------- +// +TInt CCFScriptHandler::RemoveScriptByName( const TDesC& aScriptName, + const TUid& aOwnerUid ) + { + FUNC_LOG; + + TParsePtrC parsePtrC( aScriptName ); + TPtrC scriptName( parsePtrC.Name() ); + + TInt err = KErrNotFound; + for( TInt i = 0; i < iScripts.Count(); ++i ) + { + CCFScript* script = iScripts[i]; + + // Check owner + if( script->OwnerUid() == aOwnerUid ) + { + // Check name + if( script->Name().CompareF( scriptName ) == KErrNone ) + { + // Owner uid and name matches - remove script + iScripts.Remove( i ); + delete script; + script = NULL; + err = KErrNone; + break; + } + } + } + iScripts.GranularCompress(); + + return err; + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::RemoveScriptByUid +// ----------------------------------------------------------------------------- +// +TInt CCFScriptHandler::RemoveScriptByUid( const TUid& aUid ) + { + FUNC_LOG; + + TInt err = KErrNotFound; + for( TInt i = iScripts.Count() - 1; i >= 0; i-- ) + { + CCFScript* script = iScripts[i]; + if( script->OwnerUid() == aUid ) + { + // remove from internal array + iScripts.Remove( i ); + delete script; + script = NULL; + err = KErrNone; + } + } + iScripts.GranularCompress(); + + return err; + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::InitDeviceStartingPhaseL +// ----------------------------------------------------------------------------- +// +void CCFScriptHandler::InitDeviceStartingPhaseL() + { + FUNC_LOG; + + // Load context source manager configuration cenrep + CRepository* cenRep = CRepository::NewLC( KCRUidCFRuleScriptConf ); + TInt count = 0; + TInt err = cenRep->Get( KCRuleScriptNumberOfMandatoryRules, count ); + if( err == KErrNone && count ) + { + INFO_1( "Found %d scripts from cenrep", count ); + + TUint32 key = KCRuleScriptNumberOfMandatoryRules + 1; + HBufC* fileName = HBufC::NewLC( KMaxFileName ); + TPtr fileNamePtr = fileName->Des(); + for( TInt i = 0; i < count; i++ ) + { + // Ignore first key (count) + err = cenRep->Get( key + i, fileNamePtr ); + if( err == KErrNone && fileNamePtr != KNullDesC ) + { + // Check if the script has an upgrade + CompleteFilePath( fileNamePtr ); + fileNamePtr[0] = iDefaultSystemDrive; + if( !BaflUtils::FileExists( iFs, fileNamePtr ) ) + { + // Use default rom drive + fileNamePtr[0] = iDefaultRomDrive; + } + err = DoLoad( fileNamePtr ); + if( err == KErrNone ) + { + CCFScript* script = iScripts[iScripts.Count() - 1]; + if( script ) + { + TInt err = iLoadedScripts.Append( script ); + ERROR_1( err, "Unable to append script %S in loaded scripts array", + &fileNamePtr ); + } + } + } + else + { + INFO_2( "Script in file '%S' skipped, error code %d", &fileNamePtr, err ); + } + + fileNamePtr.Zero(); + } + CleanupStack::PopAndDestroy( fileName ); // fileName + } + CleanupStack::PopAndDestroy( cenRep ); // cenRep + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::InitDeviceStartedPhaseL +// ----------------------------------------------------------------------------- +// +void CCFScriptHandler::InitDeviceStartedPhaseL() + { + FUNC_LOG; + + // Create search pattern and dir scanner + HBufC* filePath = HBufC::NewLC( KMaxFileName ); + TPtr filePathPtr = filePath->Des(); + filePathPtr.Append( KDefaultRuleFilePath ); + filePathPtr.Append( KDefaultRuleFileSearchPattern ); + filePathPtr[0] = iDefaultRomDrive; + + CDirScan* dirScan = CDirScan::NewLC( iFs ); + dirScan->SetScanDataL( filePathPtr, KEntryAttNormal, ESortNone ); + CDir* dir = NULL; + + // First scan rom + dirScan->NextL( dir ); + while( dir ) + { + for( TInt i = 0; i < dir->Count(); i++ ) + { + filePathPtr.Copy( dirScan->FullPath() ); + const TEntry& entry = ( *dir )[i]; + filePathPtr.Append( entry.iName ); + + // Check for upgrade + filePathPtr[0] = iDefaultSystemDrive; + if( !BaflUtils::FileExists( iFs, filePathPtr ) ) + { + // Upgrade not found - use rom file + filePathPtr[0] = iDefaultRomDrive; + } + DoLoad( filePathPtr ); + } + delete dir; + dir = NULL; + dirScan->NextL( dir ); + } + + // Ensure that cfserver default rule folder exists + filePathPtr.Copy( KDefaultRuleFilePath ); + filePathPtr[0] = iDefaultSystemDrive; + BaflUtils::EnsurePathExistsL( iFs, filePathPtr ); + + // Scan ram for *.rul files but exclude all upgrade files + filePathPtr.Append( KDefaultRuleFileSearchPattern ); + dirScan->SetScanDataL( filePathPtr, KEntryAttNormal, ESortNone ); + dirScan->NextL( dir ); + while( dir ) + { + // Exlude all rom upgrade files + TPtrC fullPath( dirScan->FullPath() ); + if( fullPath.Length() > KDefaultRuleFilePath().Length() ) + { + for( TInt i = 0; i < dir->Count(); i++ ) + { + filePathPtr.Copy( dirScan->FullPath() ); + const TEntry& entry = ( *dir )[i]; + filePathPtr.Append( entry.iName ); + DoLoad( filePathPtr ); + } + } + delete dir; + dir = NULL; + dirScan->NextL( dir ); + } + + // Cleanup + CleanupStack::PopAndDestroy( dirScan ); // dirScan + CleanupStack::PopAndDestroy( filePath ); // filePath + + // Close loaded scripts array since it is not needed anymore + iLoadedScripts.Close(); + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::CompleteFilePath +// ----------------------------------------------------------------------------- +// +void CCFScriptHandler::CompleteFilePath( TDes& aFileName ) + { + FUNC_LOG; + + if( aFileName.MaxLength() > + aFileName.Length() + KDefaultRuleFilePath().Length() ) + { + aFileName.Insert( 0, KDefaultRuleFilePath ); + } + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::LoadScriptFromFile +// ----------------------------------------------------------------------------- +// +HBufC8* CCFScriptHandler::LoadScriptFromFile( const TDesC& aFilePath ) + { + FUNC_LOG; + + INFO_1( "Loading script: %S", &aFilePath ); + + HBufC8* script = NULL; + RFile file; + TInt err = file.Open( iFs, aFilePath, EFileRead ); + if( err == KErrNone ) + { + TInt size = 0; + err = file.Size( size ); + if( err == KErrNone ) + { + script = HBufC8::New( size ); + if( script ) + { + TPtr8 scriptPtr = script->Des(); + err = file.Read( scriptPtr ); + if( err == KErrNone ) + { + // Strip all unnecassary data from script + TInt pos = scriptPtr.FindF( KScriptStartTag ); + if( pos != KErrNotFound ) + { + scriptPtr.Copy( scriptPtr.MidTPtr( pos ) ); + } + else + { + // Incorrect script + delete script; + script = NULL; + } + } + else + { + delete script; + script = NULL; + } + } + } + } + + // Cleanup + file.Close(); + + ERROR_1( err, "Failed loading script: %S", &aFilePath ); + + return script; + } + +// CCFScriptHandler::GetScriptsByUid +// ----------------------------------------------------------------------------- +// +void CCFScriptHandler::GetScriptsByUid( const TUid& aUid, + RPointerArray& aArray ) const + { + FUNC_LOG; + + TInt err = KErrNone; + TInt count = iScripts.Count(); + for( TInt i = 0; i < count; i++ ) + { + CCFScript* script = iScripts[i]; + if( script->OwnerUid() == aUid ) + { + err = aArray.Append( script ); + if( err != KErrNone ) + { + // Something went wrong + break; + } + } + } + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::ScriptFilePath +// ----------------------------------------------------------------------------- +// +HBufC* CCFScriptHandler::ScriptFilePath( CCFScriptInfo& aInfo ) const + { + FUNC_LOG; + + HBufC* filepath = HBufC::New( KMaxFileName ); + if( filepath ) + { + TPtr filepathPtr( filepath->Des() ); + ScriptFilePath( aInfo, filepathPtr ); + } + + return filepath; + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::ScriptFilePath +// ----------------------------------------------------------------------------- +// +HBufC* CCFScriptHandler::ScriptFilePath( const TDesC& aName, + const TUid& aOwnerUid ) const + { + FUNC_LOG; + + HBufC* filepath = HBufC::New( KMaxFileName ); + if( filepath ) + { + TPtr filepathPtr( filepath->Des() ); + if( aOwnerUid == KCFServerSid ) + { + filepathPtr.Format( KDefaultRomRuleFileUpgradeFormat, &aName ); + } + else + { + filepathPtr.Format( KDefaultSystemRuleFileFormat, + aOwnerUid.iUid, &aName ); + } + filepathPtr[0] = iDefaultSystemDrive; + } + + return filepath; + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::ScriptFilePath +// ----------------------------------------------------------------------------- +// +void CCFScriptHandler::ScriptFilePath( CCFScriptInfo& aInfo, TDes& aFile ) const + { + FUNC_LOG; + + aFile.Zero(); + TPtrC name( aInfo.Name() ); + if( aInfo.OwnerUid() == KCFServerSid ) + { + aFile.Format( KDefaultRomRuleFileUpgradeFormat, &name ); + } + else + { + aFile.Format( KDefaultSystemRuleFileFormat, + aInfo.OwnerUid().iUid, &name ); + } + aFile[0] = iDefaultSystemDrive; + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::DoSave +// ----------------------------------------------------------------------------- +// +TInt CCFScriptHandler::DoSave( const TDesC& aFileName, const TDesC8& aScript ) + { + FUNC_LOG; + + TInt err = KErrNone; + + // Create the target folder if one needed + TParsePtrC parse( aFileName ); + TPtrC path( parse.DriveAndPath() ); + if( !BaflUtils::FolderExists( iFs, path ) ) + { + // Create the target folder + TInt err = iFs.MkDirAll( path ); + INFO_2( "Created rule path %S with code %d", &path, err ); + } + + // Create a new file and write script - replace + // existing file if one exists + RFile file; + err = file.Replace( iFs, aFileName, EFileWrite ); + if ( err == KErrNone ) + { + err = file.Write ( aScript, aScript.Length( ) ); + } + INFO_2( "Saved script file %S with code %d", + &aFileName, err ); + file.Close(); + + return err; + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::DoLoad +// ----------------------------------------------------------------------------- +// +TInt CCFScriptHandler::DoLoad( const TDesC& aFilePath ) + { + FUNC_LOG; + + // Check if the script has already been loaded + TBool loaded = EFalse; + TUid uid; + TPtrC name( KNullDesC ); + ParseUidAndName( aFilePath, uid, name ); + TInt err = KErrNone; + if ( uid.iUid != 0 ) // If Uid == 0, subfolder is not valid + { + for( TInt i = 0; i < iLoadedScripts.Count(); i++ ) + { + CCFScript* script = iLoadedScripts[i]; + if( script->OwnerUid() == uid && + script->Name().CompareF( name ) == KErrNone ) + { + // Script already loaded + INFO_1( "Script %S already loaded", + &aFilePath ); + loaded = ETrue; + iLoadedScripts.Remove( i ); + break; + } + } + + // Load script if it has not already been loaded + if( !loaded ) + { + // Load script from file and configure script + HBufC8* script = LoadScriptFromFile( aFilePath ); + if( script ) + { + INFO_1( "Script %S loaded", &aFilePath ); + + // If script is faulty just ignore it + RThread thread; + TRAP( err, AddScriptL( name, + *script, + uid, + thread, + iScriptEventListener, + EFalse, + NULL ) ); + + // Clean up + thread.Close(); // just in case + delete script; + script = NULL; + + ERROR_1( err, "Script %S not created", &aFilePath ); + if( err >= KErrNone ) + { + INFO_1( "Script %S succesfully created and initialized", + &aFilePath ); + } + } + else + { + err = KErrNotFound; + } + } + } + + return err >= 0 ? KErrNone : err; + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::ParseUidAndName +// ----------------------------------------------------------------------------- +// +void CCFScriptHandler::ParseUidAndName( const TDesC& aFilePath, + TUid& aUid, TPtrC& aName ) const + { + FUNC_LOG; + + // Resolve script name + TParsePtrC parse( aFilePath ); + aName.Set( parse.Name() ); + + // Resolve uid + TPtrC path( parse.DriveAndPath() ); + if( KDefaultRuleFilePath().Length() == path.Length() ) + { + // Cfserver sid since no additional sid folder found + aUid.iUid = KCFServerSid.iUid; + } + else + { + if( path.Length() == ( KDefaultRuleFilePath().Length() + KUidLength + 1 ) ) + { + // Parse client sid from the folder + TInt start = KDefaultRuleFilePath().Length(); + TPtrC uidPtrC( path.Mid( start, KUidLength ) ); + TLex lex( uidPtrC ); + + // Convert descriptor to unsigned int + TUint32 value = 0; + TInt err = lex.BoundedVal( value, EHex, KLimit ); + if( err == KErrNone ) + { + aUid.iUid = value; + } + ERROR_1( err, "Unable to parse uid from path %S", &aFilePath ); + } + else + { + INFO_1( "The additional folder in path %S is not sid folder", &aFilePath ); + // Set Uid = 0 and none script will be loaded from unsuitable subfolder + aUid.iUid = 0; + } + } + } + +// ----------------------------------------------------------------------------- +// CCFScriptHandler::CreateScriptL +// ----------------------------------------------------------------------------- +// +CCFScript* CCFScriptHandler::CreateScriptL( const TDesC& aName, + const TDesC8& aScript, + const TUid& aOwner, + const RThread& aOwnerThread, + MCFActionHandler& aActionHandler, + TBool aDoSecurityCheck, + MCFScriptOwner* aScriptOwner, + TInt aScriptId ) + { + FUNC_LOG; + + // check that we have a descriptor with content + TInt len = aScript.Length(); + if ( len <= 0 ) + { + ERROR_GEN( "Script length invalid" ); + User::Leave( KErrBadDescriptor ); + } + + // Init parser usage. + iParserData.Set( aScript ); + iParserDataProvidingState = KInit; + + iParser->SetSourceCharacterWidth( CMDXMLParser::EAscii ); + iParser->ParseSource( this ); + iWaitParsing->Start(); + + // Check errors. + CCFScript* script = NULL; + TXMLErrorCodeSeverity severity = iParser->ErrorSeverity(); + if ( severity == EXMLWorkable || severity == EXMLNone ) + { + CMDXMLDocument* document = iParser->DetachXMLDoc(); + if ( document ) + { + CleanupStack::PushL( document ); // CLEANUP<< document + CMDXMLElement* documentElement = document->DocumentElement(); + if ( documentElement ) + { + // Get script root + CMDXMLNode* child = documentElement->FirstChild(); + while ( child ) + { + if ( child->NodeType() != CMDXMLNode::EElementNode ) + { + child = child->NextSibling(); + continue; + } + else if ( script ) + { + // One aScript is allowed to have one root (one tree). + User::Leave( KErrNotSupported ); + } + + // Resolve script id + TInt scriptId = 0; + if( aScriptId != KErrNotFound ) + { + scriptId = aScriptId; + } + else + { + scriptId = iNextId; + } + + // Create new script + TParsePtrC parse( aName ); + script = CCFScript::NewLC( *child, + parse.Name(), + scriptId, + aOwner, + aActionHandler, + len, + iCF, + iSecurityChecker, + *iOperationPluginManager, + iFs, + aScriptOwner ); // CLEANUP<< script + + // Do security check for the script. + if ( aDoSecurityCheck ) + { + User::LeaveIfError( + script->CheckSecurity( aOwnerThread ) ); + } + + child = child->NextSibling(); + } + if( script ) + { + CleanupStack::Pop( script ); // CLEANUP>> script + } + } + CleanupStack::PopAndDestroy( document ); // CLEANUP>> document + } + } + else + { + ERROR_GEN_1( "CCFScriptHandler::CreateScriptL - Parser error [%d]", + iParser->Error() ); + User::LeaveIfError( iParser->Error() ); + } + + // Reset parser usage. + iParserData.Set( 0, 0 ); // Parser data will not be valid anymore. + iParserDataProvidingState = KError; + + return script; + } + +//------------------------------------------------------------------------------ +// CCFScriptHandler::RollbackScriptL +//------------------------------------------------------------------------------ +// +void CCFScriptHandler::RollbackScriptL( const CCFScriptInfo& aInfo, + const TDesC& aFilePath ) + { + FUNC_LOG; + + HBufC8* script = LoadScriptFromFile( aFilePath ); + User::LeaveIfNull( script ); + + CleanupStack::PushL( script ); + RThread mainThread; + CleanupClosePushL( mainThread ); + + // Security check is not needed since the client has already + // succesfully registered script, using cfsrver main thread as a temp + // thread handle + AddScriptL( aInfo.Name(), *script, aInfo.OwnerUid(), mainThread, + iScriptEventListener, EFalse, aInfo.OwnerSession(), aInfo.Id() ); + + // Clean up + CleanupStack::PopAndDestroy( &mainThread ); + CleanupStack::PopAndDestroy( script ); + } + +//------------------------------------------------------------------------------ +// CCFScriptHandler::NotifyScriptIds +//------------------------------------------------------------------------------ +// +void CCFScriptHandler::NotifyScriptIds( MCFScriptOwner* aScriptOwner ) + { + FUNC_LOG; + + RArray scriptIds; + for( TInt i = iRollbackList.Count() - 1; i >= 0; i-- ) + { + CCFScriptInfo* info = iRollbackList[i]; + if( aScriptOwner == info->OwnerSession() ) + { + // Error is ignored. If there is no memory left then the client + // will miss the deregister notification of some scripts + scriptIds.Append( info->Id() ); + + // Remove the info from rollback list + iRollbackList.Remove( i ); + delete info; + info = NULL; + } + } + aScriptOwner->HandleScriptsRemoved( scriptIds ); + scriptIds.Close(); + } + +//------------------------------------------------------------------------------ +// CCFScriptHandler::AddRollbackInfoL +//------------------------------------------------------------------------------ +// +void CCFScriptHandler::AddRollbackInfoL( CCFScript& aScript ) + { + FUNC_LOG; + + CCFScriptInfo* info = aScript.CopyInfoLC(); + iRollbackList.AppendL( info ); + CleanupStack::Pop( info ); + } + +//------------------------------------------------------------------------------ +// CCFScriptHandler::DeleteScriptFile +//------------------------------------------------------------------------------ +// +TInt CCFScriptHandler::DeleteScriptFile( const TDesC& aFilePath, + const TUid& aOwnerUid ) + { + FUNC_LOG; + + TInt err = KErrNotFound; + if( BaflUtils::FileExists( iFs, aFilePath ) ) + { + err = BaflUtils::DeleteFile( iFs, aFilePath ); + INFO_3( "Deleted script file %S from client %x with code %d", + &aFilePath, aOwnerUid.iUid, err ); + if( err == KErrNone ) + { + // All persistent data clean ups are not treated as errors + CDir* dir = NULL; + TParsePtrC parse( aFilePath ); + TPtrC driveAndPath( parse.DriveAndPath() ); + TPtrC name( parse.Name() ); + + // Cleanup all persistent data files + HBufC* persistentData = HBufC::New( KMaxFileName ); + if( persistentData ) + { + TPtr persistentDataPtr( persistentData->Des() ); + persistentDataPtr.Format( KPersistenDataFormat, + aOwnerUid.iUid, &name, &KWildCardChar ); + TInt persistentErr = iFs.GetDir( persistentDataPtr, KEntryAttNormal, + ESortNone, dir ); + if( persistentErr == KErrNone && dir ) + { + for( TInt i = 0; i < dir->Count(); i++ ) + { + TParsePtrC entryNameParse( (*dir)[i].iName ); + TPtrC entryName( entryNameParse.Name() ); + persistentDataPtr.Format( KPersistenDataFormat2, + aOwnerUid.iUid, &entryName ); + persistentDataPtr[0] = iDefaultSystemDrive; + + persistentErr = BaflUtils::DeleteFile( + iFs, persistentDataPtr ); + INFO_2( "Deleted persistent data file %S with code %d", + &persistentDataPtr, persistentErr ); + } + } + + // Clean up + delete dir; + dir = NULL; + + delete persistentData; + persistentData = NULL; + } + + // Check if not in rules base folder - delete this folder + // if the folder is empty + if( aOwnerUid != KCFServerSid ) + { + TInt rmDirErr = iFs.GetDir( driveAndPath, KEntryAttNormal, + ESortNone, dir ); + if( rmDirErr == KErrNone && dir ) + { + if( dir->Count() == 0 ) + { + rmDirErr = iFs.RmDir( driveAndPath ); + INFO_2( "Removed directory %S with code %d", + &driveAndPath, rmDirErr ); + } + } + delete dir; + dir = NULL; + } + } + } + return err; + } + +// End of file