--- /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 <e32math.h>
+#include <e32svr.h>
+#include <s32mem.h>
+#include <bautils.h>
+#include <s32file.h>
+#include <centralrepository.h>
+#include <gmxmldocument.h>
+#include <gmxmlelement.h>
+
+#ifdef RD_MULTIPLE_DRIVE
+#include <driveinfo.h>
+#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<CCFScript> 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<CCFScript> 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<CCFScript> 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<CCFScript> 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<CCFScript> 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<CCFScript> 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<CCFScript> 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<CCFScript>& 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<TInt> 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