contextframework/cfw/src/cfscriptengine/CFScriptHandler.cpp
changeset 0 2e3d3ce01487
--- /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