terminalsecurity/SCP/SCPServer/src/SCPServer.cpp
changeset 0 b497e44ab2fc
child 13 86979fe66c4c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/terminalsecurity/SCP/SCPServer/src/SCPServer.cpp	Thu Dec 17 09:07:52 2009 +0200
@@ -0,0 +1,2915 @@
+/*
+* Copyright (c) 2000 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Implementation of terminalsecurity components
+*
+*/
+
+
+// INCLUDE FILES
+#include <utf.h>
+#include <e32svr.h>
+#include <e32math.h>
+#include <gsmerror.h>
+
+#include "SCPServer.h"
+#include "SCPSession.h"
+
+#ifdef SCP_USE_POLICY_ENGINE
+#include <PolicyEngineClient.h>
+#include <PolicyEngineXACML.h>
+#include <RequestContext.h>
+#include "DMUtilObserver.h"
+#include "SCPParamDBController.h"
+#endif // SCP_USE_POLICY_ENGINE
+
+//#ifdef __SAP_DEVICE_LOCK_ENHANCEMENTS
+#include "SCPPluginManager.h"
+#include "SCPPluginEventHandler.h"
+#include <SCPParamObject.h>
+#include "SCP_IDs.h"
+// For Central Repository
+#include <centralrepository.h>
+#include "SCPCodePrivateCRKeys.h"
+#include "SCPLockCode.h"
+#include <TerminalControl3rdPartyAPI.h>
+//#endif // __SAP_DEVICE_LOCK_ENHANCEMENTS
+
+#include <mmtsy_names.h>
+
+#include "SCPDebug.h"
+#include <featmgr.h>
+// For Device encryption
+#include <DevEncEngineConstants.h>
+#include <DevEncSession.h>
+
+// ==================== LOCAL FUNCTIONS ====================
+
+// ---------------------------------------------------------
+// PanicServer Panics the server thread
+// 
+// Status : Approved
+// ---------------------------------------------------------
+//
+GLDEF_C void PanicServer(TSCPServPanic aPanic)
+	{
+	_LIT( KTxtServerPanic,"SCP Server panic" );
+	User::Panic( KTxtServerPanic, aPanic );
+	}
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------
+// CSession2* CSCPServer::CSCPServer()
+// C++ default constructor
+// 
+// Status : Approved
+// ---------------------------------------------------------
+//
+CSCPServer::CSCPServer(TInt aPriority)
+	: CPolicyServer( aPriority, CSCPServerPolicy ),
+	  iConfiguration( &iRfs ),
+	  iALPeriodRep( NULL ),
+	  iShutdownTimer( NULL ),
+	  iOverrideForCleanup(EFalse) {
+	Dprint( (_L("--> CSCPServer::CSCPServer()") ));
+	
+	Dprint( (_L("<-- CSCPServer::CSCPServer()") ));
+	}
+
+
+
+// ---------------------------------------------------------
+// CSession2* CSCPServer::ConstructL()
+// Symbian 2nd phase constructor
+// 
+// Status : Approved
+// ---------------------------------------------------------
+//
+void CSCPServer::ConstructL()
+    {
+    Dprint(_L("[CSCPServer]-> ConstructL() >>>"));
+
+    TRAPD( errf, FeatureManager::InitializeLibL() );
+	if( errf != KErrNone )
+	{
+		User::Leave(errf);
+	}
+	
+    StartL( KSCPServerName );
+    
+    User::LeaveIfError( iRfs.Connect() );
+       
+    iConfiguration.Initialize();
+    
+    // Assign default config flag
+    iConfiguration.iConfigFlag = KSCPConfigUnknown;
+    
+    // Assign the default codes
+    iConfiguration.iSecCode.Zero();
+    iConfiguration.iSecCode.Append( KSCPDefaultSecCode );
+
+//#ifdef __SAP_DEVICE_LOCK_ENHANCEMENTS 
+if(FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+{
+    // Reset code block parameters
+    iConfiguration.iFailedAttempts = 0;
+    iConfiguration.iBlockedAtTime = KSCPNotBlocked;
+    
+    iPluginEventHandler = CSCPPluginEventHandler::NewL( &iRfs );
+    
+    iPluginManager = CSCPPluginManager::NewL( this );           
+        
+    // Hash the default code
+    TBuf<KSCPMaxHashLength> hashBuf;
+    hashBuf.Zero();
+    
+    HBufC* codeHBuf = HBufC::NewLC( KSCPPasscodeMaxLength + 1 );
+    TPtr codeBuf = codeHBuf->Des();
+    codeBuf.Zero();
+    
+    codeBuf.Copy( KSCPDefaultEnchSecCode );
+    iPluginEventHandler->HashInput( codeBuf, hashBuf );
+    
+    iConfiguration.iEnhSecCode.Zero();
+    iConfiguration.iEnhSecCode.Append( hashBuf );
+    
+    CleanupStack::PopAndDestroy( codeHBuf );
+}
+//#endif
+   
+    // Assign the default max timeout
+    iConfiguration.iMaxTimeout = KSCPDefaultMaxTO;
+   	iConfiguration.iBlockedInOOS = 0;
+   
+    // Read the configuration, overwriting the default values
+    TInt ret = KErrNone;
+    TRAPD( err, ret = iConfiguration.ReadSetupL() );
+    if ( ( err != KErrNone ) || ( ret != KErrNone ) )
+        {
+        Dprint( (_L("CSCPServer::ConstructL(): ERROR reading the \
+            configuration file: %d"), err ));        
+        }         
+    else
+        {
+        Dprint( (_L("CSCPServer::ConstructL(): Configration read OK") ));
+        }
+        
+    Dprint( (_L("CSCPServer::ConstructL(): Connecting to CenRep") ));
+    iALPeriodRep = CRepository::NewL( KCRUidSecuritySettings );        
+    
+    // Check for factory settings
+    CheckIfRfsPerformedL();
+    Dprint(_L("[CSCPServer]-> ConstructL() <<< "));
+    }
+
+
+
+
+// ---------------------------------------------------------
+// CSession2* CSCPServer::NewL()
+// Static constructor.
+// 
+// Status : Approved
+// ---------------------------------------------------------
+//
+CSCPServer* CSCPServer::NewL()
+    {
+    Dprint( (_L("--> CSCPServer::NewL()") ));
+
+    CSCPServer *pS = new (ELeave) CSCPServer( EPriority );    
+
+    CleanupStack::PushL( pS );
+    pS->ConstructL();
+    CleanupStack::Pop( pS );
+	
+    Dprint( (_L("<-- CSCPServer::NewL()") ));
+    return pS;
+    }
+	
+   
+   
+// ---------------------------------------------------------
+// CSession2* CSCPServer::~CSCPServer ()
+// Destructor
+// 
+// Status : Approved
+// ---------------------------------------------------------
+//
+CSCPServer::~CSCPServer()
+	{
+	Dprint( (_L("--> CSCPServer::~CSCPServer()") ));
+
+    TRAPD( err, iConfiguration.WriteSetupL() );
+    if ( err != KErrNone )
+        {
+        Dprint( (_L("CSCPServer::~CSCPServer(): ERROR writing the \
+            configuration file: %d"), err ));
+        }
+                           
+    delete iALPeriodRep;
+    iALPeriodRep = NULL;
+    
+//#ifdef __SAP_DEVICE_LOCK_ENHANCEMENTS
+if(FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+{
+	
+    delete iPluginManager;
+    iPluginManager = NULL;
+    
+    delete iPluginEventHandler;
+    iPluginEventHandler = NULL;
+}
+FeatureManager::UnInitializeLib();
+//#endif // __SAP_DEVICE_LOCK_ENHANCEMENTS 
+
+	if ( iPhone.SubSessionHandle() )
+	    {    
+	    iPhone.Close();
+	    }
+	    	    
+    if ( iTelServ.Handle() )
+        {        
+        iTelServ.Close();                        
+        }
+        
+    if ( iRfs.Handle() )
+        {
+        iRfs.Close();
+        }    
+                          
+	Dprint( (_L("<-- CSCPServer::~CSCPServer()") ));
+	}
+
+
+
+// ---------------------------------------------------------
+// CSession2* CSCPServer::NewSessionL (const TVersion &aVersion, const RMessage2& aMsg )
+// Checks the version and creates a new session if it matches the server version.
+// 
+// Status : Approved
+// ---------------------------------------------------------
+//
+CSession2* CSCPServer::NewSessionL (const TVersion &aVersion, 
+                                    const RMessage2& aMsg ) const
+	{
+	Dprint( (_L("--> CSCPServer::NewSessionL()") ));
+	(void)aMsg;
+			
+	// Check we're the right version
+	TVersion v( KSCPServMajorVersionNumber, KSCPServMinorVersionNumber, 
+	            KSCPServBuildVersionNumber );
+
+	if ( !User::QueryVersionSupported(v, aVersion) ) 
+	    User::Leave( KErrNotSupported );	
+
+	Dprint( (_L("<-- CSCPServer::NewSessionL()") ));
+	
+	return CSCPSession::NewL( (CSCPServer&)( *this ) );
+	}
+
+
+
+// ---------------------------------------------------------
+// TInt CSCPServer::ThreadFunctionStage2()
+// Constructs the active scheduler and the server object, and
+// runs the server.
+// 
+// Status : Approved
+// ---------------------------------------------------------
+//
+TInt CSCPServer::ThreadFunctionStage2L()
+    {
+    Dprint( (_L("--> CSCPServer::ThreadFunctionStage2()") ));
+    
+    // Naming the server thread after the server helps to debug panics  
+    User::LeaveIfError( User::RenameThread( KSCPServerName ) );
+	
+    // Construct the active scheduler
+    CActiveScheduler* activeScheduler = new (ELeave) CActiveScheduler;
+    CleanupStack::PushL(activeScheduler);
+
+    // Install active scheduler
+    // We don't need to check whether an active scheduler is already installed
+    // as this is a new thread, so there won't be one
+    CActiveScheduler::Install( activeScheduler );
+
+    // Construct our server    
+    CSCPServer* server = CSCPServer::NewL();
+    CleanupStack::PushL( server );
+
+    RProcess::Rendezvous(KErrNone);
+	
+    // Start handling requests
+    Dprint( (_L("CSCPServer: Server started") ));
+    CActiveScheduler::Start();
+        
+    CleanupStack::PopAndDestroy( server );
+    CleanupStack::PopAndDestroy( activeScheduler );
+	
+    Dprint( (_L("<-- CSCPServer::ThreadFunctionStage2()") ));
+    return KErrNone;
+    }
+	
+	
+	
+// ---------------------------------------------------------
+// TInt CSCPServer::ThreadFunction( TAny* )
+// First-stage server entry point, creates the cleanup stack,
+// and calls the actual server worker function.
+// 
+// Status : Approved
+// ---------------------------------------------------------
+//	
+TInt CSCPServer::ThreadFunction(TAny* /*aNone*/)
+    {	
+    Dprint( (_L("--> CSCPServer::ThreadFunction()") ));
+	
+    __UHEAP_MARK;
+    
+    CTrapCleanup* cleanupStack = CTrapCleanup::New();
+    if ( !cleanupStack )
+	      {
+        PanicServer( ECreateTrapCleanup );
+        }	
+
+    TRAPD( err, ThreadFunctionStage2L() );
+    if ( err != KErrNone )
+        {
+        PanicServer( ESvrStartServer );
+        }
+
+    delete cleanupStack;
+    cleanupStack = NULL;
+    
+    __UHEAP_MARKEND;
+
+    Dprint( (_L("<-- CSCPServer::ThreadFunction()") ));
+    return KErrNone;
+    }
+
+
+// ---------------------------------------------------------
+// void CSCPServer::GetEtelHandlesL()
+// Opens the handles to the Etel API, if not open, and copies
+// their addresses to the given pointers, if available.
+// 
+// Status : Approved
+// ---------------------------------------------------------
+//
+void CSCPServer::GetEtelHandlesL( RTelServer** aTelServ, RMobilePhone** aPhone )
+    {
+    if ( !iTelServ.Handle() )
+        {
+        // Connect to Etel
+        User::LeaveIfError( iTelServ.Connect() );
+                
+        Dprint( (_L("CSCPServer::GetEtelHandlesL(): TelServ connected OK") ));
+        }
+	
+	if ( !iPhone.SubSessionHandle() )
+	    {
+        // Load the phone module
+        TInt err = iTelServ.LoadPhoneModule( KMmTsyModuleName );
+        if ( err != KErrAlreadyExists )
+            {
+            User::LeaveIfError( err );
+            }	        
+        Dprint( (_L("CSCPServer::GetEtelHandlesL(): LoadPhoneModule OK") ));
+           
+        // Open the multimode TSY
+        User::LeaveIfError( iPhone.Open( iTelServ, KMmTsyPhoneName ) );
+                 
+        Dprint( (_L("CSCPServer::GetEtelHandlesL(): MM-Phone connected OK") ));
+	    }	    
+
+	if ( aTelServ )
+	    {
+	    *aTelServ = &iTelServ;
+	    }
+	
+	if ( aPhone )
+	    {
+	    *aPhone = &iPhone;
+	    }            
+    }
+    
+
+// ---------------------------------------------------------
+// TInt CSCPServer::GetCode( TDes& aCode )
+// Writes the stored ISA code to aCode
+// 
+// Status : Approved
+// ---------------------------------------------------------
+//	
+TInt CSCPServer::GetCode( TDes& aCode )
+    {
+    Dprint( (_L("--> CSCPServer::GetCode()") ));
+   
+    aCode.Zero();
+    aCode.Copy( iConfiguration.iSecCode );
+   
+    Dprint( (_L("<-- CSCPServer::GetCode()") ));   
+    return KErrNone;
+    }
+   
+   
+   
+// ---------------------------------------------------------
+// TInt CSCPServer::StoreCode( TDes& aCode )
+// Sets the stored ISA code to aCode and saves it to flash
+// 
+// Status : Approved
+// ---------------------------------------------------------
+//	
+TInt CSCPServer::StoreCode( TDes& aCode )
+    {
+    Dprint( (_L("--> CSCPServer::StoreCode()") ));
+    
+    TInt ret = KErrNone;
+    
+    iConfiguration.iSecCode.Zero();
+    iConfiguration.iSecCode.Copy( aCode );
+
+    // Unset the invalid configuration flag
+    iConfiguration.iConfigFlag = KSCPConfigOK;
+    
+    // The code has changed, write the new value instantly to flash
+    TRAPD( err, iConfiguration.WriteSetupL() );
+    if ( err != KErrNone )
+        {
+        Dprint( (_L("CSCPServer::~CSCPServer(): ERROR writing the configuration\
+            file: %d"), err ));
+        ret = err;
+        }           
+
+    Dprint( (_L("<-- CSCPServer::StoreCode(): %d"), ret ));
+    
+    return ret;
+    }   
+   
+
+
+// ---------------------------------------------------------
+// CSCPServer::ChangeISACodeL()
+// Initializes the TSY and calls the function to change 
+// the ISA-side code. Automatically uses the old code stored
+// on the server.
+// 
+// Status : Approved
+// ---------------------------------------------------------
+//
+void CSCPServer::ChangeISACodeL( RMobilePhone::TMobilePassword& aNewPassword )
+    {
+    Dprint( (_L("--> CSCPServer::ChangeISACodeL()") ));    
+           
+    RMobilePhone::TMobilePassword oldPassword;
+    TInt ret;
+    
+    // Check the given code
+    if ( !IsValidISACode( aNewPassword ) )
+        {
+        Dprint( (_L("CSCPServer::ChangeISACodeL(): ERROR:\
+            Invalid code format") ));
+        User::Leave( KErrArgument );
+	    }           
+   
+    // No access to the ISA side in emulator      
+    GetEtelHandlesL();
+			
+    // Fetch the stored ISA password from the server    
+
+    ret = GetCode( oldPassword );
+    if ( ret != KErrNone )
+        {
+        Dprint( (_L("CSCPServer::ChangeISACodeL(): ERROR:\
+            Failed to get stored code") ));
+        User::Leave( ret );
+        }           
+    
+    TRequestStatus status = KErrNone;    
+    
+#ifndef __WINS__    
+    // No access to the ISA side in emulator, for WINS the call always succeeds
+    
+    RMobilePhone::TMobilePhonePasswordChangeV1 changeInfo;
+    changeInfo.iOldPassword = oldPassword;
+    changeInfo.iNewPassword = aNewPassword;
+   
+    RMobilePhone::TMobilePhoneSecurityCode securityCode = 
+        RMobilePhone::ESecurityCodePhonePassword;
+	
+	Dprint( (_L("CSCPServer::ChangeISACodeL(): Trying to change\
+	    the code, values %s, %s"), oldPassword.PtrZ(), aNewPassword.PtrZ() ));
+	    
+	iPhone.ChangeSecurityCode(status, securityCode, changeInfo );
+	
+	// This is a quick call, just wait here
+	User::WaitForRequest( status );
+	
+#endif // WINS
+    ret = status.Int();
+
+	if ( ret == KErrNone )
+		{
+		Dprint( (_L("CSCPServer::ChangeISACodeL(): Code change OK") ));
+		
+		// Update the stored code in the server
+		if ( StoreCode( aNewPassword ) != KErrNone )
+            {
+            Dprint( (_L("CSCPServer::ChangeISACodeL():\
+                Failed to store the new code!") ));
+            ret = KErrGeneral;
+            }
+		}
+	else
+		{
+        Dprint( (_L("CSCPServer::ChangeISACodeL(): FAILED:\
+            ChangeSecurityCode returned %d"), ret ));					
+		}	
+	
+	User::LeaveIfError( ret );
+	Dprint( (_L("<-- CSCPServer::ChangeISACodeL()") ));	
+	}	
+
+
+
+// ---------------------------------------------------------
+// TInt CSCPServer::CheckIfRfsPerformedL()
+// Checks if RFS has been run from the DMUtil server.
+// 
+// Status : Approved
+// ---------------------------------------------------------
+//	
+void CSCPServer::CheckIfRfsPerformedL()
+    {
+    Dprint( (_L("--> CSCPServer::CheckIfRfsPerformedL()") ));
+    
+    TBool resetServer = EFalse;
+    
+#ifdef SCP_USE_POLICY_ENGINE
+	Dprint( (_L("--> CSCPServer::CheckIfRfsPerformedL() : checking if Rfs performed") ));
+	TRAPD(err,TDMUtilPassiveObserver::IsRFSPerformedL());
+    if ( err == 1 )
+        {
+        resetServer = ETrue;
+        }
+    else if ( err == 0)
+    	{
+    	Dprint( (_L("--> CSCPServer::CheckIfRfsPerformedL() : Rfs is not performed") ));
+    	}
+    else
+   		{
+    	Dprint( (_L("--> CSCPServer::CheckIfRfsPerformedL() : Leave occured. Ignore it.") ));
+    	}
+#endif // SCP_USE_POLICY_ENGINE       
+    
+    if ( resetServer )
+        {
+        Dprint( (_L("CSCPServer::CheckIfRfsPerformedL(): Rfs performed, resetting parameters") ));
+                
+        // Reset max. period
+        iConfiguration.iMaxTimeout = 0;
+        
+//#ifdef __SAP_DEVICE_LOCK_ENHANCEMENTS    
+if(FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))   
+{
+        // Reset the common plugin parameter storage
+        TRAPD( err, iPluginEventHandler->ResetConfigurationL() );
+        if ( err != KErrNone )
+            {
+            Dprint( (_L("CSCPServer::CheckIfRfsPerformedL(): ERROR resetting the plugin\
+                configuration: %d"), err ));
+            }
+        
+        // Reset the plugin's private storage
+        CSCPParamObject* inParams = CSCPParamObject::NewL();
+        CleanupStack::PushL( inParams );
+        
+        inParams->Set( KSCPParamContext, KSCPContextRfs );        
+                
+        CSCPParamObject* reply = 
+            iPluginManager->PostEvent( KSCPEventReset, *inParams );
+        CleanupStack::PopAndDestroy( inParams ); 
+        
+        // Ignore the reply, no plugin should request any actions
+        if ( reply != NULL )
+            {
+            delete reply;
+            }
+}
+//#endif // __SAP_DEVICE_LOCK_ENHANCEMENTS               
+
+        } 
+    
+    Dprint( (_L("<-- CSCPServer::CheckIfRfsPerformedL()") ));        
+    }
+    
+    
+    
+   
+// ---------------------------------------------------------
+// void CSCPServer::ValidateConfigurationL()
+// Checks if the correct ISA code is stored on the server.
+// This method is used to counter the 3-button format function
+// available on some devices.
+// 
+// Status : Approved
+// ---------------------------------------------------------
+//	
+void CSCPServer::ValidateConfigurationL( TInt aMode )
+    {
+    Dprint( (_L("--> CSCPServer::ValidateConfigurationL()") ));
+    
+    if ( iConfiguration.iConfigFlag == KSCPConfigOK )
+        {
+        // The configuration has already been checked, exit
+        Dprint( (_L("CSCPServer::ValidateConfigurationL(): Configuration is non-default.") ));
+        User::Leave( KErrNone );
+        }
+    else if ( aMode == KSCPInitial )
+        {
+        // Return here, must be checked by complete mode
+        User::Leave( KErrAccessDenied );
+        }
+    
+    RMobilePhone::TMobilePassword storedCode;
+    storedCode.Zero();
+    
+    User::LeaveIfError( GetCode( storedCode ) );
+    TInt hashedISAcode;
+    TSCPSecCode hashedCode;
+//#ifdef __SAP_DEVICE_LOCK_ENHANCEMENTS    
+if(FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+{
+	/*TInt*/ hashedISAcode = HashISACode( iConfiguration.iEnhSecCode );
+   // TSCPSecCode hashedCode;
+    hashedCode.Zero();
+    hashedCode.AppendNum( hashedISAcode );
+}
+//#endif // __SAP_DEVICE_LOCK_ENHANCEMENTS    
+            
+    Dprint( (_L("CSCPServer::ValidateConfigurationL(): Checking code: %s"), storedCode.PtrZ() ));
+    
+    // Check that the ISA code is stored correctly
+    TRAPD( err, CheckISACodeL( storedCode ) );
+    if ( err == KErrNone ) 
+        {
+        iConfiguration.iConfigFlag = KSCPConfigOK;
+        }
+    else if ( err == KErrAccessDenied )
+        {        
+        iConfiguration.iConfigFlag = KSCPConfigInvalid;
+        }
+    else if ( err == KErrLocked )
+        {
+        Dprint( (_L("CSCPServer::ValidateConfigurationL(): ISA code locked.") ));
+        }
+    else
+        {
+        Dprint( (_L("CSCPServer::ValidateConfigurationL(): ERROR in validation.") ));
+        }
+
+//#ifdef __SAP_DEVICE_LOCK_ENHANCEMENTS         
+if(FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+{
+    if ( err == KErrNone )
+        {
+        // Check that the codes are in-sync with each other. Especially the default ISA code must
+        // be changed according to the default enhanced code.        
+        if ( storedCode.Compare( hashedCode ) != 0 )
+            {
+            Dprint( (_L("CSCPServer::ValidateConfigurationL(): Correct ISA code stored.\
+               Changing ISA code to match enhanced code => %d"), hashedISAcode ));
+               
+            storedCode.Copy( hashedCode );
+            // Change the ISA code to match the hashed code
+            ChangeISACodeL( storedCode );
+            }
+        }
+    else if ( ( err == KErrAccessDenied ) && ( storedCode.Compare( hashedCode ) != 0 ) )
+        {
+        // Try again with the hashed code
+        TRAP( err, CheckISACodeL( hashedCode ) );
+        
+        if ( err == KErrNone )
+            {            
+            Dprint( (_L("CSCPServer::ValidateConfigurationL(): Hashed code is correct.\
+               Storing hashed code(%d)"), hashedISAcode ));
+               
+            if ( StoreCode( hashedCode ) == KErrNone )
+                {
+                iConfiguration.iConfigFlag = KSCPConfigOK;
+                }
+            }        
+        }
+}
+//#endif // __SAP_DEVICE_LOCK_ENHANCEMENTS
+    
+    TRAPD( err2, iConfiguration.WriteSetupL() );
+    if ( err2 != KErrNone )
+        {
+        Dprint( (_L("CSCPServer::ValidateConfigurationL(): WARNING: failed to write configuration\
+            : %d"), err2 ));        
+        } 
+    
+    User::LeaveIfError( err );
+    
+    Dprint( (_L("<-- CSCPServer::ValidateConfigurationL()") ));
+    }
+
+        
+    
+    
+// ---------------------------------------------------------
+// void CSCPServer::CheckISACodeL( )
+// Verifies the given ISA code.
+// 
+// Status : Approved
+// ---------------------------------------------------------
+//	
+void CSCPServer::CheckISACodeL( RMobilePhone::TMobilePassword aCode )
+    {        
+    TInt ret = KErrNone;    
+
+#ifdef __WINS__    
+    
+    (void)aCode;    
+
+#endif // __WINS__
+   
+    RMobilePhone::TMobilePhoneSecurityCode secCodeType;
+    secCodeType = RMobilePhone::ESecurityCodePhonePassword;
+    
+    RMobilePhone::TMobilePassword required_fourth;
+                
+    TRequestStatus status = KRequestPending;
+            
+    GetEtelHandlesL();
+    
+#ifndef __WINS__   // We cannot check the code in WINS, always return KErrNone. 
+       
+    iPhone.VerifySecurityCode( status, secCodeType, aCode, required_fourth );
+    
+    // This should be quick, wait here
+    User::WaitForRequest( status );
+    
+    ret = status.Int();
+    
+#endif // !__WINS__
+        
+    if ( ret == KErrNone )
+        {
+        // Code OK
+        Dprint( (_L("CSCPServer::CheckISACodeL(): ISA code OK") ));
+        iConfiguration.iBlockedInOOS = 0;
+        }
+    else 
+        {
+        if ( ( ret == KErrAccessDenied ) || ( ret == KErrGsm0707IncorrectPassword ) )
+            {
+            Dprint( (_L("CSCPServer::CheckISACodeL(): ISA code NOT OK") ));
+            if (iConfiguration.iBlockedInOOS == 1)
+	         {
+	            	iConfiguration.iBlockedInOOS = 0;
+   	            	Dprint( (_L("CSCPServer::CheckISACodeL():iBlockedInOOS = 0, KErrAccessDenied") ));
+	         }            
+            ret = KErrAccessDenied;             
+            }
+        else if ( ( ret == KErrGsmSSPasswordAttemptsViolation ) || ( ret == KErrLocked ) )
+            {
+            Dprint( (_L("CSCPServer::CheckISACodeL(): ISA code BLOCKED") ));            
+            if (ret==KErrGsmSSPasswordAttemptsViolation)
+            {
+            	Dprint( (_L("CSCPServer::CheckISACodeL(): KErrGsmSSPasswordAttemptsViolation") ));            	
+            }
+            else
+            {
+            	Dprint( (_L("CSCPServer::CheckISACodeL(): KErrLocked") ));
+            }	            
+            ret = KErrLocked;
+            if (iConfiguration.iBlockedInOOS == 0)
+        	 {
+            	iConfiguration.iBlockedInOOS = 1;
+            	Dprint( (_L("CSCPServer::CheckISACodeL():iBlockedInOOS = 1, KSCPErrCodeBlockStarted") ));
+            	ret = KSCPErrCodeBlockStarted;	
+        	 }
+            }            
+        else
+            {
+            Dprint( (_L("CSCPServer::CheckISACodeL(): ERROR reply checking ISA code: %d"),
+                status.Int() ));
+            }            
+        }
+        TRAPD( err, iConfiguration.WriteSetupL() );
+        if ( err != KErrNone )
+            {
+            Dprint( (_L("CSCPServer::StoreEnhCode(): WARNING:\
+                failed to write configuration: %d"), err ));         
+        }                
+    
+    User::LeaveIfError( ret );
+    }    
+
+
+//#ifdef __SAP_DEVICE_LOCK_ENHANCEMENTS
+
+// ---------------------------------------------------------
+// CSCPServer::HashISACode()
+// Creates a 5-digit ISA code from the given MD5 digest.
+// 
+// Status : Approved
+// ---------------------------------------------------------
+//	
+TInt CSCPServer::HashISACode( TDes& aHashBuf )
+    {                
+    // aHashBuf must be a MD5 hash digest
+    if(!FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+	{
+			return KErrNotSupported;
+	}
+    if ( aHashBuf.Length() < KSCPMD5HashLen )
+        {
+        PanicServer( EBadHashDigest );
+        }
+        
+    // Compute the hash sum as four 32-bit integers.
+    TInt64 hashSum = *(reinterpret_cast<TInt32*>(&aHashBuf[0])) + 
+                     *(reinterpret_cast<TInt32*>(&aHashBuf[4])) + 
+                     *(reinterpret_cast<TInt32*>(&aHashBuf[8])) +
+                     *(reinterpret_cast<TInt32*>(&aHashBuf[12]));
+    
+    // Create a five-digit security code from this number
+    TInt ISAcode = ( hashSum % 90000 ) + 10000;
+    Dprint( (_L("CSCPServer::HashISACode(): Hashed ISA code is %d"), ISAcode ));
+    
+    return ISAcode;
+    }
+    
+   
+// ---------------------------------------------------------
+// TInt CSCPServer::StoreEnhCode( TDes& aCode )
+// Sets the stored enhanced code to aCode and saves it to flash
+// 
+// Status : Approved
+// ---------------------------------------------------------
+//	
+TInt CSCPServer::StoreEnhCode( TDes& aCode, TSCPSecCode* aNewDOSCode /*=NULL*/)
+    {
+    
+    if(!FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+	{
+			return KErrNotSupported;
+	}
+    Dprint( (_L("CSCPServer::StoreEnhCode()") ));
+    
+    // Hash the code and save it
+    TBuf<KSCPMaxHashLength> hashBuf;
+    hashBuf.Zero();
+    iPluginEventHandler->HashInput( aCode, hashBuf );        
+        
+    TInt ISAcode = HashISACode( hashBuf );
+    
+    RMobilePhone::TMobilePassword newCode;
+    newCode.Zero();
+    newCode.AppendNum( ISAcode );
+    
+    // Change the ISA code
+    TRAPD( err, ChangeISACodeL( newCode ) );
+    
+    if ( err == KErrNone )
+        {
+        iConfiguration.iEnhSecCode.Zero();
+        iConfiguration.iEnhSecCode.Copy( hashBuf );        
+
+        if ( aNewDOSCode != NULL )
+            {
+            // Copy the updated DOS code
+            (*aNewDOSCode).Copy( newCode );
+            }
+        
+        TRAPD( err, iConfiguration.WriteSetupL() );
+        if ( err != KErrNone )
+            {
+            Dprint( (_L("CSCPServer::StoreEnhCode(): WARNING:\
+                failed to write configuration: %d"), err ));         
+                                            
+            }    
+        else
+        	{
+        	/* Get the very first character of the new lock code and set the default input mode of the
+         	lock code query on the basis of the first character. */
+         	ch = aCode[0];
+		
+				CRepository* repository = NULL;
+			def_mode = ch.IsDigit() ? 0 : 1;
+    		TRAPD(err, repository = CRepository::NewL( KCRUidSCPParameters ));
+    		if (err == KErrNone)
+    		{    	
+    			err = repository->Set( KSCPLockCodeDefaultInputMode , def_mode );
+    	   	delete repository;
+    		}
+    		
+    		/* Set the value in the cenrep that the default lock code has been changed if it is not 
+    		 * already set
+    		 * */
+    		TRAP(err, repository = CRepository :: NewL(KCRUidSCPLockCode));
+    		
+    		if(err == KErrNone) {
+                err = repository->Set(KSCPLockCodeDefaultLockCode, 0);
+                delete repository;
+    		}
+        	}    
+        }
+    else
+        {
+        Dprint( (_L("CSCPServer::StoreEnhCode(): ERROR:\
+            failed to change ISA code, aborting storage operation: %d"), err ));
+        
+        }    
+    
+    return err;   
+    }
+
+//#endif // __SAP_DEVICE_LOCK_ENHANCEMENTS
+
+
+
+
+// ---------------------------------------------------------
+// TBool CSCPServer::IsOperationInProgress( TSCPAdminCommand aCommand )
+// Loops through the sessions on the server and and calls the
+// query command to check if the given operation is in progress.
+// 
+// Status : Approved
+// ---------------------------------------------------------
+//	
+TBool CSCPServer::IsOperationInProgress( TSCPAdminCommand aCommand )
+    {
+    Dprint( (_L("--> CSCPServer::IsOperationInProgress()") ));
+   
+    // Iterate through the sessions and find out if one has started the given operation
+    TBool ret = EFalse;
+   
+    iSessionIter.SetToFirst();
+    CSCPSession* curSession = NULL;
+    while ( ( curSession = static_cast<CSCPSession*>( iSessionIter++ ) ) != NULL )
+        {                
+        if ( curSession->IsOperationInProgress( aCommand ) )
+            {
+            ret = ETrue;
+            break;        
+            }   
+        }    
+    
+    Dprint( (_L("<-- CSCPServer::IsOperationInProgress(): %d"), ret ));    
+    return ret;
+    }   
+
+
+
+
+// ---------------------------------------------------------
+// TBool CSCPServer::AcknowledgementReceived( TSCPAdminCommand aCommand )
+// Loops through the sessions on the server, sends the acknowledgements,
+// and checks if one was waiting for it (ETrue).
+// 
+// Status : Approved
+// ---------------------------------------------------------
+//	
+TBool CSCPServer::AcknowledgementReceived( TSCPAdminCommand aCommand )
+    {
+    Dprint( (_L("--> CSCPServer::AcknowledgementReceived()") ));
+   
+    // Iterate through the sessions and propagate the acknowledgement.
+    // Set the return parameter, if one was waiting for the ack
+    TBool ret = EFalse;
+   
+    iSessionIter.SetToFirst();
+    CSCPSession* curSession = NULL;
+    while ( ( curSession = static_cast<CSCPSession*>( iSessionIter++ ) ) != NULL )
+        {
+        if ( curSession->AcknowledgeOperation( aCommand ) ) ret = ETrue;
+        }    
+    
+    Dprint( (_L("<-- CSCPServer::AcknowledgementReceived(): %d"), ret ));    
+    return ret;
+    }   
+   
+   
+   
+   
+// ---------------------------------------------------------
+// TInt CSCPServer::SetAutolockPeriod()
+// Sets the autolock period in either SharedData or CenRep.
+// 
+// Status : Approved
+// ---------------------------------------------------------
+// 
+TInt CSCPServer :: SetAutolockPeriodL(TInt aValue) {
+    Dprint( (_L("CSCPServer::SetAutolockPeriodL(): Setting the value") ));
+
+    TInt ret = KErrNone;
+    
+    
+    // Change the value in CenRep     
+    ret = iALPeriodRep->Set( KSettingsAutoLockTime, aValue );            
+     
+    Dprint( (_L("[CSCPServer]-> SetAutolockPeriodL() <<<") ));
+    return ret;
+    }   
+    
+// ---------------------------------------------------------
+// TInt CSCPServer::GetAutolockPeriodL( TInt& aValue )
+// Gets the autolock period from either SharedData or CenRep.
+// 
+// Status : Approved
+// ---------------------------------------------------------
+// 
+TInt CSCPServer::GetAutolockPeriodL( TInt& aValue )
+    {
+    TInt ret = KErrNone;    
+    
+    Dprint( (_L("CSCPServer::GetAutolockPeriodL(): Getting the value") )); 
+            
+    // Fetch the value from CenRep   
+    ret = iALPeriodRep->Get( KSettingsAutoLockTime, aValue );
+    
+    return ret;
+    } 
+    
+    
+    
+    
+// ---------------------------------------------------------
+// CSCPServer::ChangeCodePolicy()
+// Sets the new policy either internally or through the policy
+// engine.
+// 
+// Status : Approved
+// ---------------------------------------------------------
+//
+TInt CSCPServer::ChangeCodePolicy( const TDesC& aValue )
+    {    
+    TInt ret = KErrNone;
+    
+    TLex lex( aValue );
+    TInt value;
+                
+    ret = lex.Val( value );
+                
+    if ( ret == KErrNone )
+        {
+        if ( ( value < 0 ) || ( value > 1 ) ) 
+            {
+            ret = KErrArgument;
+            }
+        else
+            {
+            Dprint( (_L("CSCPServer::ChangeCodePolicy(): %d"), value ));
+            
+#ifdef SCP_USE_POLICY_ENGINE
+    
+            RPolicyEngine policyEngine;
+            ret = policyEngine.Connect();
+
+            RPolicyManagement policyManagement;
+            if ( ret == KErrNone )
+                {               
+                ret = policyManagement.Open( policyEngine );
+                }
+    
+            TParserResponse response;        
+    
+            if ( ret == KErrNone )
+                {
+                Dprint( (_L("CSCPServer::ChangeCodePolicy(): Executing operation") ));
+                if ( value == 1 )
+                    {
+                    // Allow change
+                    ret = policyManagement.ExecuteOperation( 
+                        KSCPCodePolicyAllowOperation,
+                        response
+                        );
+                    }
+                else
+                    {
+                    // Deny change                    
+                    ret = policyManagement.ExecuteOperation( 
+                        KSCPCodePolicyDisallowOperation, 
+                        response
+                        );                        
+                    }
+                
+                if ( ret == KErrNone )
+                    {
+                    const TDesC8& retMsg = response.GetReturnMessage();
+                    
+                    if ( retMsg.Compare( KSCPOKResponse ) != 0 )
+                        {
+                        #ifdef _DEBUG
+                        TBuf<256> dummyBuf;
+                        dummyBuf.Copy( retMsg );
+                        Dprint( (_L("CSCPServer::ChangeCodePolicy(): Response not OK:\
+                            %S"), &dummyBuf ));
+                        #endif
+                        
+                        // We must check this for an error as well
+                        ret = KErrGeneral;
+                        }
+                    }
+                }
+                
+            if ( policyManagement.SubSessionHandle() )
+                {
+                policyManagement.Close();
+                }
+
+            if ( policyEngine.Handle() )
+                {
+                policyEngine.Close();
+                }                        
+                                
+#else // !SCP_USE_POLICY_ENGINE
+               
+            iCodePolicy = value;                
+
+#endif // SCP_USE_POLICY_ENGINE                
+            }                
+        }
+
+    Dprint( (_L("<-- CSCPServer::ChangeCodePolicy(): %d"), ret ));
+    return ret;
+    }
+      
+      
+      
+        
+// ---------------------------------------------------------
+// CSCPServer:GetCodePolicy()
+// Gets the policy from internal storage of from the policy
+// engine.
+// 
+// Status : Approved
+// ---------------------------------------------------------
+//        
+TInt CSCPServer::GetCodePolicy( TDes& aValue )
+    {
+    Dprint( (_L("--> CSCPServer::GetCodePolicy()") ));
+    TInt ret = KErrNone;
+
+    aValue.Zero();
+    
+#ifdef SCP_USE_POLICY_ENGINE            
+    TResponse response;
+    RPolicyEngine policyEngine;
+    ret = policyEngine.Connect();
+
+    RPolicyRequest policyRequest;
+    if ( ret == KErrNone )
+        {        
+        ret = policyRequest.Open( policyEngine );
+        }
+
+    if(ret == KErrNone) {
+        TRequestContext context;
+    
+        using namespace PolicyEngineXACML;
+        TRAPD( err ,
+            context.AddResourceAttributeL(  KResourceId, 
+                                            KDeviceLockPasscodeVisibility,
+                                            KStringDataType)
+              );
+        if ( err == KErrNone )
+            {
+            ret = policyRequest.MakeRequest( context, response );
+            }
+        else
+            {
+            ret = err;
+            }        
+        }
+
+    if ( ret == KErrNone )
+        {
+        if ( response.GetResponseValue() == EResponsePermit )
+            {
+    	    // Allow security code change
+	        aValue.AppendNum( 1 );
+            }
+        else
+            {
+	        // Do not allow security code change
+	        aValue.AppendNum( 0 );
+            }                    
+        }
+    
+    if ( policyRequest.SubSessionHandle() )
+        {
+        policyRequest.Close();
+        }
+
+    if ( policyEngine.Handle() )
+        {
+        policyEngine.Close();
+        }    
+            
+#else // !SCP_USE_POLICY_ENGINE
+                            
+     aValue.AppendNum( iCodePolicy );
+            
+#endif // SCP_USE_POLICY_ENGINE    
+
+    Dprint((_L("[CSCPServer] <<< GetCodePolicy(): %d"), ret));
+    return ret;
+    }
+
+
+
+
+// ---------------------------------------------------------
+// TInt CSCPServer::SetParameterValueL( TSCPParameterID aID, TDesC& aValue )
+// Handles the setting of the parameter values. 
+// 
+// Status : Approved
+// ---------------------------------------------------------
+//    
+TInt CSCPServer::SetParameterValueL( TInt aID, const TDesC& aValue, TUint32 aCallerIdentity )
+    {    
+    Dprint( (_L("--> CSCPServer::SetParameterValueL( %d )"), aID ));
+    
+#ifdef __SCP_DEBUG
+    // Used to "emulate 3-button boot" in debug builds
+    if ( aID == 9999 )
+        {
+        iConfiguration.iConfigFlag = KSCPConfigUnknown;
+        iConfiguration.iSecCode = KSCPDefaultSecCode;
+        return KErrNone;
+        }    
+#endif // __SCP_DEBUG    
+    
+    TInt lRetStatus(KErrNone);
+    Dprint(_L("[CSCPServer]-> Initiating branching on parameter..."));
+    
+    switch ( aID )
+        {
+        case ( ESCPAutolockPeriod ):
+        // Flow through            
+        case ( ESCPMaxAutolockPeriod ):
+            {
+            // Convert the value, and set it
+            TInt value;
+            TLex lex(aValue);
+            lRetStatus = lex.Val(value);
+             
+
+            if((lRetStatus != KErrNone ) || ( value < 0) || ( value > KSCPAutolockPeriodMaximum )) {
+                lRetStatus = KErrArgument;
+                break;
+                }
+                  
+            //Check if the device memory is encrypted or not.
+            TBool encryptionEnabled = IsDeviceMemoryEncrypted();
+            
+            // Value OK
+            if(aID == ESCPMaxAutolockPeriod) 
+						{
+						   if (  encryptionEnabled )
+                  {
+                  Dprint(_L("Memory is encrypted"));
+                  if (( 0 == value) || value > KMaxAutolockPeriod)
+                      {
+                      Dprint((_L("Denying setting of max auto lock as value is %d"), value));
+                      User::Leave( KErrPermissionDenied );
+                      }
+                      
+                  }
+                else
+                    {
+                    Dprint(_L("Memory is decrypted, hence no restrictions to max autolock"));
+                    }
+                    
+                Dprint(_L("[CSCPServer]-> Branched to ESCPMaxAutolockPeriod..."));
+                CSCPParamDBController* lParamDB = CSCPParamDBController :: NewLC();
+                lRetStatus = SetBestPolicyL(RTerminalControl3rdPartySession :: EMaxTimeout, aValue, aCallerIdentity, lParamDB);
+
+                if(lRetStatus == KErrNone) 
+								{
+                    // Do we have to change the Autolock period as well?
+                    TInt currentALperiod;
+                    lRetStatus = GetAutolockPeriodL(currentALperiod);
+
+                    if(lRetStatus == KErrNone) 
+										{
+                        if((iConfiguration.iMaxTimeout > 0) && ((iConfiguration.iMaxTimeout < currentALperiod) || (currentALperiod == 0))) 
+												{
+                           Dprint((_L("[CSCPServer]-> Changing AL period to Max. AL period (Current ALP: %d, Max. ALP: %d)"), currentALperiod, value));
+                           lRetStatus = SetAutolockPeriodL(value);
+                        }
+                    }
+                    else 
+										{
+                        Dprint((_L("[CSCPServer]-> ERROR: Couldn't get the Autolock period: %d"), lRetStatus));
+                    }
+                }
+
+                CleanupStack :: PopAndDestroy(); //lParamDB
+            }
+            
+            else 
+            { // Autolock Period
+            	
+            			//Code is commented as it is already taken care by the below condition #1343 irrespective of the drive encryption state.
+            	     /*  if ( 0 == value )
+                    {
+                    if ( encryptionEnabled )
+                        {
+                        Dprint(_L("Permission denied!"));
+                        User::Leave( KErrPermissionDenied );
+                        }
+                    }*/
+                    
+                Dprint(_L("[CSCPServer]-> Branched to ESCPAutolockPeriod..."));
+                //  Check if this value is not allowed by the Max. Autolock period
+                if ((iConfiguration.iMaxTimeout > 0) && ((iConfiguration.iMaxTimeout < value) || (value == 0))) {
+                    Dprint((_L("[CSCPServer]-> ERROR: The value %d for AL period not allowed (Max. AL period: %d)"), value, iConfiguration.iMaxTimeout));
+
+                    lRetStatus = KErrArgument;
+                }
+                else {
+                    lRetStatus = SetAutolockPeriodL(value);
+
+                    if(lRetStatus != KErrNone) {
+                        Dprint((_L("[CSCPServer]-> ERROR: Couldn't set the Autolock period: %d"), lRetStatus));
+                    }
+                }
+            }
+        }
+        break;
+        case ESCPCodeChangePolicy:
+            Dprint(_L("[CSCPServer]-> Branched to ESCPCodeChangePolicy..."));
+            lRetStatus = ChangeCodePolicy( aValue );
+        break;
+        default: {
+//#ifdef __SAP_DEVICE_LOCK_ENHANCEMENTS
+            Dprint(_L("[CSCPServer]-> Branched to default condition, aID=%d"), aID);
+            
+            if(FeatureManager :: FeatureSupported(KFeatureIdSapDeviceLockEnhancements)) {
+                RPointerArray<HBufC> lSpecStrArray;
+                CleanupClosePushL(lSpecStrArray);
+
+                Dprint(_L("[CSCPServer]-> Creating an instance of the private DB..."));
+                CSCPParamDBController* lParamDB = CSCPParamDBController :: NewLC();
+                Dprint(_L("[CSCPServer]-> Private DB instance created successfully..."));
+                
+                Dprint(_L("[CSCPServer]-> Creating ParamObject..."));
+                CSCPParamObject* lInParams = CSCPParamObject :: NewLC();
+                Dprint(_L("[CSCPServer]-> ParamObject created successfully..."));
+                
+                //lInParams->Set(KSCPParamIdentity, aCallerIdentity);
+                
+                /*
+                 * Map KSCPParamIdentity with the SID of TCServer (not aCallerIdentity)
+                 */
+                lInParams->Set(KSCPParamIdentity, this->Message().SecureId());
+
+                switch(aID) {
+                    case RTerminalControl3rdPartySession :: EPasscodeAllowSpecific:
+                    case RTerminalControl3rdPartySession :: EPasscodeClearSpecificStrings: {
+                        RPointerArray<HBufC> lSharedStrArray;
+                        CleanupClosePushL(lSharedStrArray);
+
+                        /* If the choice is EPasscodeAllowSpecific then parse the specific strings mentioned and
+                         * list the specific strings in an Array (multiple specific strings can be seperated with a single space)
+                         * The Memory alloted for each of the tokens representing each individual specific string will be
+                         * deallocated when the array lSpecStrArray is cleared by a call to ResetAndDestroy().
+                         */
+                        if(aID == RTerminalControl3rdPartySession :: EPasscodeAllowSpecific) {
+                            TLex16 lex (aValue);
+                            lex.Mark();
+
+                            while(!lex.Eos()) {
+                                while(lex.Peek() != ' ' && !lex.Eos()) {
+                                    lex.Inc();
+                                }
+
+                                const TDesC& lToken = lex.MarkedToken();
+                                HBufC* lBuff(NULL);
+                                TRAP(lRetStatus, lBuff = HBufC :: NewL(lToken.Length()));
+
+                                if(lRetStatus != KErrNone) {
+                                    lSpecStrArray.ResetAndDestroy();
+                                    User :: Leave(lRetStatus);
+                                }
+
+                                lBuff->Des().Append(lToken);
+                                lSpecStrArray.Append(lBuff);
+                                lex.Inc();
+                                lex.Mark();
+                            }
+                        }
+                        else {
+                            lRetStatus = lParamDB->GetValuesL(RTerminalControl3rdPartySession :: EPasscodeDisallowSpecific,
+                                    lSpecStrArray, aCallerIdentity);
+                        }
+
+                        TInt lCnt = lSpecStrArray.Count();
+                        lInParams->Set(KSCPParamID, RTerminalControl3rdPartySession :: EPasscodeAllowSpecific);
+
+                        for(TInt i=0; i < lCnt; i++) {
+                            HBufC* lPtr = lSpecStrArray[i];
+                            TBool lIsShared(EFalse);
+
+                            TRAPD(lErr, lIsShared = lParamDB->IsParamValueSharedL(lSpecStrArray[i], aCallerIdentity));
+
+                            if(lErr != KErrNone) {
+                                lSpecStrArray.ResetAndDestroy();
+                                lSharedStrArray.ResetAndDestroy();
+                                User :: Leave(lErr);
+                            }
+
+                            if(EFalse == lIsShared) {
+                                TUint16* ptr = const_cast<TUint16*>(lPtr->Des().Ptr());
+                                TPtr valBuf(ptr, lPtr->Des().Length(), lPtr->Des().Length());
+                                lInParams->Set(KSCPParamValue, valBuf);
+
+                                CSCPParamObject* reply = iPluginManager->PostEvent(KSCPEventConfigurationQuery, *lInParams);
+
+                                if((reply != NULL) && (reply->Get(KSCPParamStatus, lRetStatus) == KErrNone)) {
+                                    if(lRetStatus != KErrNone) {
+                                        lSpecStrArray.ResetAndDestroy();
+                                        lSharedStrArray.ResetAndDestroy();
+                                        User :: Leave(lRetStatus);
+                                    }
+
+                                    delete reply;
+                                }
+                            }
+                            else {
+                                lSpecStrArray.Remove(i);
+                                lSharedStrArray.Append(lPtr);
+                                i--;
+                                lCnt--;
+                            }
+                        }
+
+                        /*
+                         * Drop all the 'disallow strings' that are not shared between any other applications from the database.
+                         */
+                        TRAPD(lErr, lRetStatus = lParamDB->DropValuesL(RTerminalControl3rdPartySession :: EPasscodeDisallowSpecific, lSpecStrArray));
+
+                        if(lErr != KErrNone) {
+                            lSpecStrArray.ResetAndDestroy();
+                            lSharedStrArray.ResetAndDestroy();
+                            User :: Leave(lErr);
+                        }
+
+                        if(lRetStatus == KErrNone) {
+                            /*
+                             * Drop the entries of 'disallow strings' of only the called application
+                             * (Any application that shares these 'disallow strings' will not be affected)
+                             */
+                            TRAP(lErr, lRetStatus = lParamDB->DropValuesL(RTerminalControl3rdPartySession :: EPasscodeDisallowSpecific,
+                                    lSharedStrArray, aCallerIdentity));
+    
+                            if(lErr != KErrNone) {
+                                lSpecStrArray.ResetAndDestroy();
+                                lSharedStrArray.ResetAndDestroy();
+                                User :: Leave(lErr);
+                            }
+    
+                            if(lRetStatus != KErrNone) {
+                                Dprint(_L("[CSCPServer]-> Unable to drop 'disallow strings' from the private database..."));
+                            }
+                        }
+                        else {
+                            Dprint(_L("[CSCPServer]-> Unable to drop unshared 'disallow strings' from the private database..."));
+                        }
+
+                        lSharedStrArray.ResetAndDestroy();
+                        CleanupStack :: PopAndDestroy(); // lSharedStrArray
+                    }
+                    break;
+                    default: {
+                        lInParams->Set(KSCPParamID, aID);
+                        TUint16* ptr = const_cast<TUint16*>(aValue.Ptr());
+                        TPtr valBuf(ptr, aValue.Length(), aValue.Length());
+                        lInParams->Set(KSCPParamValue, valBuf);
+
+                        Dprint(_L("[CSCPServer]-> INFO: Posting the event to the plugins..."));                        
+                        CSCPParamObject* reply = iPluginManager->PostEvent(KSCPEventConfigurationQuery, *lInParams);
+
+                        if((reply != NULL) && (reply->Get(KSCPParamStatus, lRetStatus) == KErrNone)) {
+                            if(lRetStatus == KErrNone) {
+                                Dprint(_L("[CSCPServer]-> INFO: The event was consumed by one of the plugins, initiating storage activities (if any)..."));
+                                // Check if the plugin wishes to save the parameters itself
+                                TInt storage = KSCPStorageCommon;
+                                reply->Get(KSCPParamStorage, storage);
+
+                                if(storage == KSCPStoragePrivate) {
+                                    switch(aID) {
+                                        /* The plugin will take care of storing the values for EPasscodeDisallowSpecific, this is to make sure the
+                                         * value is updated accordingly even in the private database (which is used as a reference to set the best policy-done
+                                         * as per MfE-Part 3 requirement
+                                        */
+                                        case RTerminalControl3rdPartySession :: EPasscodeDisallowSpecific: {
+                                            TLex16 lex (aValue);
+                                            lex.Mark();
+
+                                            while(!lex.Eos()) {
+                                                while(lex.Peek() != ' ' && !lex.Eos()) {
+                                                    lex.Inc();
+                                                }
+
+                                                const TDesC& lToken = lex.MarkedToken();
+                                                HBufC* lBuff(NULL);
+                                                TInt lErr(KErrNone);
+                                                TRAP(lErr, lBuff = HBufC :: NewL(lToken.Length()));
+
+                                                if(lErr != KErrNone) {
+                                                    lSpecStrArray.ResetAndDestroy();
+                                                    delete reply;
+                                                    User :: Leave(lErr);
+                                                }
+
+                                                lBuff->Des().Append(lToken);
+                                                lSpecStrArray.Append(lBuff);
+                                                lex.Inc();
+                                                lex.Mark();
+                                            }
+
+                                            TInt lRet(KErrNone);
+
+                                            TRAP(lRet, lRetStatus = lParamDB->SetValuesL(RTerminalControl3rdPartySession :: EPasscodeDisallowSpecific,
+                                                    lSpecStrArray, aCallerIdentity));
+
+                                            if(lRet != KErrNone) {
+                                                lRetStatus = lRet;
+                                            }
+                                        }
+                                        break;
+                                        default:
+                                            // Don't store the parameter, the plugin will handle this
+                                            Dprint((_L("[CSCPServer]-> Param %d stored in private storage..."), aID));
+                                        break;
+                                    }
+                                }
+                                else {
+                                    Dprint((_L("[CSCPServer]-> Param %d stored in common storage..."), aID));
+                                    lRetStatus = SetBestPolicyL(aID, aValue, aCallerIdentity, lParamDB);
+                                }
+                            }
+                        }
+                        else {                        
+                            Dprint(_L("[CSCPServer]-> INFO: Event posting failed, reply=%d"), reply);
+                        }
+                        
+                        delete reply;
+                        break;
+                    }
+                }
+
+                lSpecStrArray.ResetAndDestroy();
+                CleanupStack :: PopAndDestroy(3); // lSpecStrArray, lParamDB, lInParams
+            }
+//#endif // __SAP_DEVICE_LOCK_ENHANCEMENTS
+            break;
+        }
+    }
+
+    Dprint((_L("[CSCPServer]-> <<< SetParameterValueL(): %d"), lRetStatus));
+    return lRetStatus;
+}
+// ---------------------------------------------------------
+// TInt CSCPServer::GetParameterValueL( TSCPParameterID aID, TDes& aValue )
+// Handles the fetching of parameter values.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//
+TInt CSCPServer::GetParameterValueL( TInt aID, TDes& aValue, TUint32 aCallerIdentity )
+    {
+    Dprint( (_L("CSCPServer::GetParameterValueL( %d )"), aID ));
+    TInt ret = KErrNone;
+
+    switch ( aID )
+        {
+        case ( ESCPAutolockPeriod ):
+            {
+            // Get the actual autolock period
+            TInt value;
+            if ( GetAutolockPeriodL( value ) != KErrNone )
+                {
+                Dprint( (_L("CSCPServer::SetParameterValueL(): ERROR: Couldn't \
+                    get the Autolock period") ));
+                }
+            else
+                {
+                aValue.Zero();
+                aValue.AppendNum(value);
+                }
+            }                
+        break;
+            
+        case ( ESCPMaxAutolockPeriod ):
+            {
+            // Just fetch the value into the buffer
+            aValue.Zero();
+            aValue.AppendNum( iConfiguration.iMaxTimeout );
+            }                
+        break;  
+        
+        case ( ESCPCodeChangePolicy ):
+            {
+            ret = GetCodePolicy( aValue );                        
+            }
+        break;                  
+            
+        default:
+            ret = KErrNotSupported;
+            
+//#ifdef __SAP_DEVICE_LOCK_ENHANCEMENTS                                               
+if(FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+	{
+                        
+            // "Ask" the plugins, if this caller is allowed to access this value or
+            // if the value is in private storage, retrieve the value.
+            CSCPParamObject* inParams = CSCPParamObject::NewL();
+            CleanupStack::PushL( inParams );
+            inParams->Set( KSCPParamID, aID );
+            inParams->Set( KSCPParamIdentity, aCallerIdentity );
+                
+            CSCPParamObject* repParams = 
+                iPluginManager->PostEvent( KSCPEventRetrieveConfiguration, *inParams );
+        
+            CleanupStack::PopAndDestroy( inParams );
+            
+            TBool getFromCommonStorage = ETrue;
+            TInt status;
+            if ( ( repParams != NULL ) && 
+                 ( repParams->Get( KSCPParamStatus, status ) == KErrNone ) )
+                {                
+                ret = status;
+                if ( ret != KErrNone )
+                    {
+                    getFromCommonStorage = EFalse;
+                    Dprint( (_L("CSCPServer::GetParameterValueL():\
+                            Retrieve configuration for param %d not OK: %d"), aID, ret ));
+                    }
+                else
+                    {
+                    // Has the plugin sent the value?
+                    TInt valueLen = repParams->GetParamLength( KSCPParamValue );
+                    if ( valueLen > 0 )
+                        {
+                        getFromCommonStorage = EFalse;
+                        // Try to retrieve the value (Get will check for overflow)
+                        ret = repParams->Get( KSCPParamValue, aValue );
+                        }
+                    }
+                } 
+            
+            if ( getFromCommonStorage )
+                {
+                // OK, no objection, so try to get the value from common storage
+                ret = iPluginEventHandler->GetParameters().Get( aID, aValue );
+                }            
+            
+            if ( repParams != NULL )
+                {
+                delete repParams;
+                }
+	}
+//#endif // __SAP_DEVICE_LOCK_ENHANCEMENTS                
+                
+        break;
+        }
+        
+    Dprint( (_L("<-- CSCPServer::GetParameterValueL(): %d"), ret )); 
+    return ret;        
+    }    
+      
+      
+        
+        
+// ---------------------------------------------------------
+// static TBool CSCPServer::IsValidISACode( TDes& aCode )
+// Checks that the given string is a valid ISA security code.
+// That is, exacly 5 chars, and contains only digits.
+// 
+// Status : Approved
+// ---------------------------------------------------------
+//    
+
+TBool CSCPServer::IsValidISACode( TDes& aCode )
+    {
+    TBool ret = ETrue;
+    
+    if ( aCode.Length() != KSCPCodeMaxLen ) 
+        {
+        ret = EFalse;
+        }
+    else
+        {
+        for ( TInt i = 0; i < aCode.Length(); i++ )
+            {        
+            if ( !( ((TChar)aCode[i]).IsDigit() ) )
+                {
+                ret = EFalse;
+                }
+            }        
+        }
+    
+    return ret;
+    }
+    
+
+
+
+// ---------------------------------------------------------
+// void CSCPServer::SessionClosed()
+// Checks if this was the final session. If so, exit the 
+// server thread.
+// 
+// Status : Approved
+// ---------------------------------------------------------
+//    
+
+void CSCPServer::SessionClosed()
+    {
+    iSessionIter.SetToFirst();
+    iSessionIter++; // Skip the closing session
+    
+    if ( iSessionIter++ == NULL )
+        {
+        // No more sessions
+        Dprint( (_L("CSCPServer::SessionClosed(): No more sessions, starting timeout") ));
+        
+//#ifdef __SAP_DEVICE_LOCK_ENHANCEMENTS
+if(FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+	{
+        // Save the plugin configuration
+        TRAP_IGNORE( iPluginEventHandler->WritePluginConfigurationL() );
+	}
+//#endif // __SAP_DEVICE_LOCK_ENHANCEMENTS        
+        
+        // Start shutdown timer
+        TRAPD( err, iShutdownTimer = CSCPTimer::NewL( KSCPServerShutdownTimeout,
+                                          NULL,
+                                          this ) );
+        if ( err != KErrNone )
+            {
+            // Cannot create the timer!
+            // No more sessions
+            Dprint( (_L("CSCPServer::SessionClosed(): ERROR: Timer creation failed! Exiting..")));
+            iShutdownTimer = NULL;
+            Timeout( NULL );
+            }    
+        }
+    }
+    
+    
+ 
+// ---------------------------------------------------------
+// void CSCPServer::SessionOpened()
+// Stops the shutdown timer, if started.
+// 
+// Status : Approved
+// ---------------------------------------------------------
+//  
+void CSCPServer::SessionOpened()
+    {
+    // Stop the shutdown timer
+	if ( iShutdownTimer != NULL )
+	    {
+	    delete iShutdownTimer;
+	    iShutdownTimer = NULL;    	
+	    }      
+    }
+    
+    
+    
+    
+// ---------------------------------------------------------
+// void CSCPServer::Timeout()
+// Shuts down the server stopping the active scheduler since 
+// the shutdown timer has elapsed.
+// 
+// Status : Approved
+// ---------------------------------------------------------
+//      
+void CSCPServer::Timeout( TAny* aParam )
+    {
+    (void)aParam;
+    
+    delete iShutdownTimer;
+    iShutdownTimer = NULL;
+    
+    Dprint( (_L("CSCPServer::Timeout(): Shutting down SCP server") ));
+    
+    CActiveScheduler::Stop();
+    }    
+    
+    
+        
+// ********************** NEW FEATURES ********************>>>>
+
+//#ifdef __SAP_DEVICE_LOCK_ENHANCEMENTS
+
+// ---------------------------------------------------------
+// CSCPServer::IsValidEnhCode()
+// Checks that the given buffer is an alphanumeric string 
+// and its length is between the minimum and maximum.
+// 
+// Status : Approved
+// ---------------------------------------------------------
+// 
+TBool CSCPServer::IsValidEnhCode( TDes& aCode )
+    {
+    
+    if(!FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+    {
+    	return KErrNotSupported;
+    }
+    TBool ret = ETrue;
+    
+    // Check length
+    if (    ( aCode.Length() < KSCPPasscodeMinLength ) || 
+            ( aCode.Length() > KSCPPasscodeMaxLength ) )
+        {
+        ret = EFalse;
+        }
+        
+    // Check the characters
+    if ( ret )
+        {
+        for ( TInt i = 0; i < aCode.Length(); i++ )
+            {
+            TChar curChar = aCode[i];
+            TChar::TCategory chCat = curChar.GetCategory();
+            if ( curChar < 1 || curChar > 126 || curChar.IsSpace() )
+            /* if ( ( !curChar.IsAlphaDigit() ) && ( chCat != TChar::ENdCategory ) ) */
+                {
+                ret = EFalse;
+                }
+            }
+        }
+    
+    return ret;
+    }
+
+
+// ---------------------------------------------------------
+// CSCPServer::IsCodeBlocked()
+// Checks if the code is blocked, and zeroes the attempt counter
+// when necessary.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//  
+TBool CSCPServer::IsCodeBlocked()
+    {
+    
+    if(!FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+    {
+    	return KErrNotSupported;
+    }
+    TBool ret = EFalse;
+    
+    if ( iConfiguration.iBlockedAtTime.Compare( KSCPNotBlocked ) == 0 )
+        {
+        ret = EFalse;
+        }
+    else
+        {
+        TTime curTime;
+        curTime.UniversalTime();        
+
+        TTimeIntervalMinutes interval = KSCPCodeBlockedTimeMin;
+        
+        TInt64 savedTime;
+        TLex lex( iConfiguration.iBlockedAtTime );
+        ret = lex.Val( savedTime );        
+        
+        if ( ret == KErrNone )
+            {
+            TTime configTime( savedTime );
+            if ( ( configTime + interval ) > curTime )
+                {
+                Dprint( (_L("CSCPServer::IsCodeBlocked(): Code BLOCKED") ));
+                // Restart the timer                
+                iConfiguration.iBlockedAtTime.Zero();
+                iConfiguration.iBlockedAtTime.AppendNum( curTime.Int64() );
+                
+                ret = ETrue;
+                }            
+            else
+                {
+                // Not blocked anymore
+                
+                Dprint( (_L("CSCPServer::IsCodeBlocked(): Resetting code block") ));
+                iConfiguration.iFailedAttempts = 0;
+                iConfiguration.iBlockedAtTime.Zero();
+                iConfiguration.iBlockedAtTime.Copy( KSCPNotBlocked );                    
+                    
+                ret = EFalse;
+                }
+                                                
+            TRAPD( err, iConfiguration.WriteSetupL() );
+            if ( err != KErrNone )
+                {
+                Dprint( (_L("CSCPServer::IsCodeBlocked(): WARNING:\
+                    failed to write configuration: %d"), err ));
+                                            
+                }                 
+            }       
+        }
+    
+    return ret;
+    }
+    
+    
+    
+
+// ---------------------------------------------------------
+// CSCPServer::SendInvalidDOSCode()
+// Resets the DOS password attempts if required and verifies the
+// code.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//  
+void CSCPServer::SendInvalidDOSCode( RMobilePhone::TMobilePassword& aCodeToSend )
+    {
+    
+    if(!FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+    {
+    	return ;
+    }
+    // Reset the DOS-side PSW-attempts by changing the code to the same one
+    RMobilePhone::TMobilePassword correctPsw;
+    TRAPD( err, 
+           GetCode( correctPsw );
+           ChangeISACodeL( correctPsw );
+         );
+    if ( err != KErrNone )
+        {
+        Dprint( (_L("CSCPServer::SendInvalidDOSCode(): WARNING:\
+            DOS code change failed, where it shouldn't have: %d"), err ));
+        }
+    
+    // Send the incorrect code to DOS side
+    TRAPD( ret, CheckISACodeL( aCodeToSend ) );
+    #ifndef __WINS__
+    if ( ( ret != KErrAccessDenied ) && ( ret != KErrGsm0707IncorrectPassword ) )
+        {
+        Dprint( (_L("CSCPServer::SendInvalidDOSCode(): WARNING:\
+            invalid DOS code validation error: %d"), ret ));
+        }
+    #endif // __WINS__
+    }
+
+
+
+
+// ---------------------------------------------------------
+// CSCPServer::IsCorrectEnhCode()
+// Checks if the given code is the correct enhanced code.
+// If the configuration is not up-to-date, the code will be hashed
+// and verified from the ISA-side.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//  
+TInt CSCPServer::IsCorrectEnhCode( TDes& aCode, TInt aFlags )
+    {
+    
+    if(!FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+    {
+    	return KErrNotSupported;
+    }
+    TInt ret = KErrAccessDenied;
+    
+    // Hash the code
+    TBuf<KSCPMaxHashLength> hashBuf;
+    hashBuf.Zero();
+    iPluginEventHandler->HashInput( aCode, hashBuf );
+        
+    TInt ISACode = HashISACode( hashBuf );
+        
+    RMobilePhone::TMobilePassword pswCandidate;
+    pswCandidate.Zero();
+    pswCandidate.AppendNum( ISACode );
+        
+    TBool enhancedCodeMatches = EFalse;
+    if ( hashBuf.Compare( iConfiguration.iEnhSecCode ) == 0 )
+        {
+        enhancedCodeMatches = ETrue;
+        }
+        
+    // Check if the code is blocked (don't check if we're out-of-sync)
+    if ( ( iConfiguration.iConfigFlag == KSCPConfigOK ) && ( IsCodeBlocked() ) )
+        {
+        if ( aFlags & KSCPEtelRequest )
+            {
+            // Check if the code is correct
+            if ( enhancedCodeMatches )
+                {
+                // Mess-up the code                 
+                RMobilePhone::TMobilePassword codeToSend;
+                codeToSend.Zero();
+                codeToSend.AppendNum( ISACode + 1 );
+                
+                SendInvalidDOSCode( codeToSend );
+                }
+            else 
+                {
+                // OK, the code is already invalid
+                SendInvalidDOSCode( pswCandidate );
+                }
+            }
+        return KErrLocked;
+        }       
+    
+    TBool writeSetup = EFalse;
+    
+    if ( iConfiguration.iConfigFlag == KSCPConfigOK )
+        {
+        // Normal situation: we have the correct code stored.
+        // Compare the hashes (hashing error will result in EFalse )
+        if ( enhancedCodeMatches )
+            {
+            ret = KErrNone;
+            
+            if ( aFlags & KSCPEtelRequest )
+                {
+                // Send the correct code to DOS side
+                TRAP( ret, CheckISACodeL( pswCandidate ) );
+                }  
+                
+            if ( ret == KErrNone )
+                {
+                if ( iConfiguration.iFailedAttempts > 0 )
+                    {
+                    iConfiguration.iFailedAttempts = 0;  
+                    Dprint( (_L("CSCPServer::IsCorrectEnhCode():KErrAccessDenied: iFailedAttempts (%d)."), iConfiguration.iFailedAttempts ));
+                    writeSetup = ETrue;
+                    }                
+                }
+            else
+                {
+                Dprint( (_L("CSCPServer::IsCorrectEnhCode(): WARNING:\
+                    ISA code validation failed, where it shouldn't have: %d"), ret ));
+                }
+            }
+        else
+            {
+            ret = KErrAccessDenied;
+            
+            iConfiguration.iFailedAttempts++;
+            Dprint( (_L("CSCPServer::IsCorrectEnhCode():KErrAccessDenied: iFailedAttempts (%d)."), iConfiguration.iFailedAttempts ));
+            writeSetup = ETrue;
+            
+            if ( iConfiguration.iFailedAttempts == KSCPCodeBlockLimit )
+                {
+                // Block the code
+                TTime curTime;
+                curTime.UniversalTime();
+                
+                iConfiguration.iBlockedAtTime.Zero();
+                iConfiguration.iBlockedAtTime.AppendNum( curTime.Int64() );
+                                                                
+                // The code will be blocked for now on
+                ret = KSCPErrCodeBlockStarted;
+                }
+            
+            if ( aFlags & KSCPEtelRequest )
+                {
+                SendInvalidDOSCode( pswCandidate );
+                }
+            }
+        }
+    else 
+        {
+        // iConfiguration.iConfigFlag == KSCPConfigInvalid or KSCPConfigUnknown
+        
+        // We might be out-of-sync, no idea about the real code.
+        // Check if the DOS code hashed from the given code is correct.
+        Dprint( (_L("CSCPServer::IsCorrectEnhCode(): Attempting to correct OoS situation.") ));
+                
+        TRAP( ret, CheckISACodeL( pswCandidate ) );
+
+        if ( ret == KErrNone )
+            {
+            // OK, we must assume that this is the correct code, since
+            // the hashed DOS code is correct. Save the codes, and return OK.
+
+            Dprint( (_L("CSCPServer::IsCorrectEnhCode(): Given code has the correct hash (%d)\
+                , saving codes."), ISACode ));
+                
+            iConfiguration.iEnhSecCode.Zero();
+            iConfiguration.iEnhSecCode.Copy( hashBuf );
+
+            iConfiguration.iSecCode.Zero();
+            iConfiguration.iSecCode.AppendNum( ISACode );
+            
+            // Unset the invalid configuration flag
+            iConfiguration.iConfigFlag = KSCPConfigOK;
+            writeSetup = ETrue;
+            }
+        else
+            {
+				
+            Dprint( (_L("CSCPServer::IsCorrectEnhCode(): Given code does not have the \
+                correct hash: ret; %d user enter password: %d"), ret ));
+			TRAP( ret, CheckISACodeL( aCode ) );
+			if (ret == KErrNone)
+			{
+				//store this code in our interal storage as it is used as oldpassword while changing at ISA side in next command
+				//ChangeISACodeL. 
+				iConfiguration.iSecCode.Zero();
+				iConfiguration.iSecCode.Append( aCode );
+				TRAP(ret,ChangeISACodeL(pswCandidate));
+			}
+			if (ret == KErrNone)
+			{
+			iConfiguration.iEnhSecCode.Zero();
+            iConfiguration.iEnhSecCode.Copy( hashBuf );
+
+            iConfiguration.iSecCode.Zero();
+            iConfiguration.iSecCode.AppendNum( ISACode );
+            
+            // Unset the invalid configuration flag
+            iConfiguration.iConfigFlag = KSCPConfigOK;
+            writeSetup = ETrue;
+			}
+            }
+        }
+    
+    // Write setup if needed
+    if ( writeSetup )
+        {
+        TRAPD( err, iConfiguration.WriteSetupL() );
+        if ( err != KErrNone )
+            {
+            Dprint( (_L("CSCPServer::IsCorrectEnhCode(): WARNING:\
+                failed to write configuration: %d"), err ));                                        
+            }                 
+        }
+        
+    return ret;
+    }
+    
+
+
+// ---------------------------------------------------------
+// CSCPServer::CheckCodeAndGiveISA()
+// Check the given code, and notify the plugins of the result.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//    
+TInt CSCPServer::CheckCodeAndGiveISAL( TDes& aCodeToCheck,
+                                      TDes& aISACodeToReturn,
+                                      CSCPParamObject*& aRetParams,
+                                      TInt aFlags )
+    {
+    
+    if(!FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+    {
+    	return KErrNotSupported;
+    }
+    TInt ret = KErrNone;
+    TInt status = KErrNone;
+    
+    // Check the code, note that IsCorrectEnhCode might change the stored code,
+    // so we'll get the code after the call.    
+    
+    TBool isSuccessful = EFalse;
+                            
+    status = IsCorrectEnhCode( aCodeToCheck, aFlags );
+    
+    if ( status == KErrLocked )
+        {
+        // If the code is locked, no attempts count as failed or successful
+        return status;
+        }
+    else if ( status == KErrNone )
+        {
+        // OK, successful authentication
+        TSCPSecCode realCode;
+		ret = GetCode( realCode );
+
+        User::LeaveIfError( ret );
+        
+        aISACodeToReturn.Copy( realCode );
+        isSuccessful = ETrue;
+        }
+    else // KSCPErrCodeBlockStarted or KErrAccessDenied
+        {
+        // Authentication attempt failed
+        TSCPSecCode realCode;
+        ret = GetCode( realCode );
+        
+        User::LeaveIfError( ret );
+        
+        TSCPSecCode fakeCode;
+        do
+            {
+            // Create a fake code, which is between 10000-99999
+            fakeCode.Zero();
+            TUint32 code = Math::Random();
+            code = code % 90000 + 10000;
+            fakeCode.AppendNum( code );
+            } while ( fakeCode.Compare( realCode ) == 0 );
+        
+        aISACodeToReturn.Copy( fakeCode );
+        
+        if ( status == KSCPErrCodeBlockStarted )
+            {
+        	status = KErrLocked; // Set this as the external error code
+            }
+        }
+            
+    // Send information about the authentication attempt to the plugins
+    CSCPParamObject* inParams = CSCPParamObject::NewL();
+    CleanupStack::PushL( inParams );
+    inParams->Set( KSCPParamContext, KSCPContextQueryPsw );
+    
+    if ( isSuccessful )
+        {
+        // Authentication successful
+        inParams->Set( KSCPParamStatus, KErrNone );
+        }
+    else
+        {
+        // Authentication failed
+        inParams->Set( KSCPParamStatus, KErrAccessDenied );
+        }
+            
+    CSCPParamObject* repParams = 
+    iPluginManager->PostEvent( KSCPEventAuthenticationAttempted, *inParams );
+    
+    CleanupStack::PopAndDestroy( inParams );
+      
+    if ( repParams != NULL )            
+        {
+        // No status information here, just propagate the paramobject
+        aRetParams = repParams; // pointer ownership changed
+        }              
+    
+    return status;
+    }
+    
+    
+    
+    
+// ---------------------------------------------------------
+// CSCPServer::CheckAndChangeEnhCodeL()
+// Check the given code, and if correct, send it to the plugins
+// for validation.
+//
+// Status : Approved
+// ---------------------------------------------------------
+//     
+TInt CSCPServer::CheckAndChangeEnhCodeL( TDes& aOldPass, 
+                                        TDes& aNewPass,
+                                        CSCPParamObject*& aRetParams,
+                                        TSCPSecCode& aNewDOSCode )
+    {        
+    
+    if(!FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+    {
+    	return KErrNotSupported;
+    }
+    TInt ret = KErrNone;
+    
+    ret = IsCorrectEnhCode( aOldPass, 0 ); 
+    if ( ret == KErrNone )
+        {
+        // Authentication successful
+        CSCPParamObject* inParams = CSCPParamObject::NewL();
+        CleanupStack::PushL( inParams );
+       
+        inParams->Set( KSCPParamStatus, KErrNone ); 
+        inParams->Set( KSCPParamContext, KSCPContextChangePsw );
+        CSCPParamObject* repParams = 
+            iPluginManager->PostEvent( KSCPEventAuthenticationAttempted, *inParams );
+        
+        if ( repParams != NULL )            
+                {
+                // Ignore the return params at this point
+                delete repParams;
+                }  
+                
+        inParams->Reset();
+        
+        // Validate the code                
+        inParams->Set( KSCPParamPassword, aNewPass );
+        
+        repParams = iPluginManager->PostEvent( KSCPEventValidate, *inParams );
+        
+        CleanupStack::PopAndDestroy( inParams );
+        
+        if ( repParams != NULL )
+            {
+            // Check if the validation failed
+            TInt status;
+            if ( repParams->Get( KSCPParamStatus, status ) == KErrNone )
+                {
+                if ( status != KErrNone )
+                    {
+                    ret = status;
+                    }
+                }
+                
+            aRetParams = repParams; // pointer ownership changed                           
+            }
+        
+        // Set the new code, if it was OK
+        if ( ret == KErrNone )
+            {
+            if ( IsValidEnhCode( aNewPass ) )
+                {
+                ret = StoreEnhCode( aNewPass, &aNewDOSCode );
+                }                        
+            else
+                {
+                // Invalid code format! Should not happen at this point, but make sure.
+                ret = KErrArgument; 
+                }
+            
+            if ( ret == KErrNone )
+                {
+                CSCPParamObject* inParams = CSCPParamObject::NewL();
+                CleanupStack::PushL( inParams );
+                inParams->Set( KSCPParamPassword, aNewPass );
+        
+                CSCPParamObject* repParams = 
+                    iPluginManager->PostEvent( KSCPEventPasswordChanged, *inParams );
+        
+                CleanupStack::PopAndDestroy( inParams );
+            
+                if ( repParams != NULL )            
+                    {
+                    // Ignore the return params at this point
+                    delete repParams;
+                    }
+                }       
+            }
+        }    
+    else
+        {
+        if ( ( ret == KErrAccessDenied ) || ( ret == KSCPErrCodeBlockStarted ) )
+            {
+            // Authentication failed
+            CSCPParamObject* inParams = CSCPParamObject::NewL();
+            CleanupStack::PushL( inParams );
+           
+            inParams->Set( KSCPParamStatus, KErrAccessDenied );
+            inParams->Set( KSCPParamContext, KSCPContextChangePsw );                   
+            CSCPParamObject* repParams = 
+                iPluginManager->PostEvent( KSCPEventAuthenticationAttempted, *inParams );
+            
+            CleanupStack::PopAndDestroy( inParams );
+            
+            if ( repParams != NULL )            
+                {
+                // No status information here, just propagate the paramobject                
+                aRetParams = repParams; // pointer ownership changed
+                } 
+                
+            if ( ret == KSCPErrCodeBlockStarted )
+                {
+        	    ret = KErrLocked; // Set this as the external error code
+                }                            
+            }
+        }
+                
+    return ret;    
+    }
+
+
+
+
+// ---------------------------------------------------------
+// CSCPServer::GetEventHandlerL()
+// Return a pointer to the event handler object. 
+//
+// Status : Approved
+// ---------------------------------------------------------
+//      
+MSCPPluginEventHandler* CSCPServer::GetEventHandlerL()
+    {
+    if(!FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+    {
+    	return NULL;
+    }
+    return iPluginEventHandler;
+    }
+    
+
+
+// ---------------------------------------------------------
+// CSCPServer::IsPasswordChangeAllowedL()
+// Check from the plugins if the password is allowed to be changed.
+//
+// Status : Approved
+// ---------------------------------------------------------
+          
+TInt CSCPServer::IsPasswordChangeAllowedL( CSCPParamObject*& aRetParams )
+    {
+    
+    if(!FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
+    {
+    	return KErrNotSupported;
+    }
+    TInt ret = KErrNone;
+    
+    // Post the event to the plugins to find out if the password can
+    // be changed
+    
+    CSCPParamObject* inParams = CSCPParamObject::NewL();
+    CleanupStack::PushL( inParams );
+   
+    // No additional parameters
+                      
+    CSCPParamObject* repParams = 
+        iPluginManager->PostEvent( KSCPEventPasswordChangeQuery, *inParams );
+    
+    CleanupStack::PopAndDestroy( inParams );
+    
+    if ( repParams != NULL )            
+        {
+        // Check status
+        TInt status;
+        if ( repParams->Get( KSCPParamStatus, status ) == KErrNone )
+            {
+            if ( status != KErrNone )
+                {
+                ret = status;
+                }
+            }
+                       
+        aRetParams = repParams; // pointer ownership changed
+        }
+    
+    return ret;
+    }
+    
+    
+    // ---------------------------------------------------------
+// CSCPServer::IsDeviceMemoryEncrypted
+// Checks if phone memory is encrypted or not. 
+// ---------------------------------------------------------
+TBool CSCPServer::IsDeviceMemoryEncrypted()
+    {
+    Dprint(_L("CSCPServer::IsDeviceMemoryEncrypted >>"));
+    
+    TBool ret(EFalse);
+    
+    //First check if the feature is supported on device
+    TRAPD(ferr, FeatureManager::InitializeLibL());
+    if (ferr != KErrNone)
+        {
+        Dprint(_L("feature mgr initialization error, %d"), ferr);
+        return EFalse;
+        }
+    ret = FeatureManager::FeatureSupported( KFeatureIdFfDeviceEncryptionFeature);
+    FeatureManager::UnInitializeLib();
+ 
+    //If feature is supported, check if any drive is encrypted.
+    if (ret)
+        {
+        CDevEncSession* devEncSession = new CDevEncSession( EDriveC );
+        
+        if (!devEncSession)
+            {
+            Dprint(_L("Can't instantiate device encryption session.."));
+            return EFalse;
+            }
+
+        TInt err = devEncSession->Connect();
+        if (err == KErrNone)
+            {
+            //Session with device encryption is established. Check if any drive is encrypted
+            TInt encStatus (KErrNone);
+            TInt err = devEncSession->DiskStatus( encStatus );
+            Dprint(_L("err = %d, encstatus = %d"), err, encStatus);
+            if (  err == KErrNone && encStatus != EDecrypted )
+                {
+                Dprint(_L("Memory is encrypted"));
+                ret = ETrue;
+                }
+            else
+                {
+                Dprint(_L("Memory is not encrypted"));
+                ret = EFalse;
+                }
+            }
+        else
+            {
+            Dprint(_L("Error %d while establishing connection with device encryption engine"), err);
+            ret = EFalse;
+            }
+        
+        delete devEncSession; devEncSession = NULL;
+        }
+    
+    Dprint(_L("CSCPServer::IsDeviceMemoryEncrypted, ret = %d <<"), ret);
+    return ret;
+    }
+    
+
+/**
+* Sets the best policy for the parameters that are under conflict. This is part of changes done for MFE-requirement part3.
+* @params   aID: The ID of the parameter that needs to be set
+*           aValue: Value of the parameter identified in aID
+*           aCalledIdentity: The UID of the called application/process
+*
+* @return TInt: KErrNone is successful, otherwise a system error code
+*/
+TInt CSCPServer :: SetBestPolicyL( TInt aID, const TDesC& aValue, TUint32 aCallerIdentity, CSCPParamDBController* aParamDB ) {
+    Dprint( (_L("[CSCPServer]-> SetBestPolicyL() >>>")));
+    Dprint( (_L("[CSCPServer]-> ParamID=%d "), aID, aValue));
+    Dprint( (_L("[CSCPServer]-> ParamValue=%d "), aValue));
+
+    TBool lFirstTime(EFalse);
+    TInt32 lNumValue (-1);
+    TInt32 lNumValDB (-1);
+    TInt32 lRetStatus = KErrNone;
+
+    switch(aID) {
+        case RTerminalControl3rdPartySession :: EMaxTimeout:
+        case RTerminalControl3rdPartySession :: EPasscodeMinLength:
+        case RTerminalControl3rdPartySession :: EPasscodeMaxLength:
+        case RTerminalControl3rdPartySession :: EPasscodeRequireUpperAndLower:
+        case RTerminalControl3rdPartySession :: EPasscodeRequireCharsAndNumbers:
+        case RTerminalControl3rdPartySession :: EPasscodeExpiration:
+        case RTerminalControl3rdPartySession :: EPasscodeMaxRepeatedCharacters:
+        case RTerminalControl3rdPartySession :: EPasscodeMinChangeTolerance:
+        case RTerminalControl3rdPartySession :: EPasscodeMinChangeInterval:
+        case RTerminalControl3rdPartySession :: EPasscodeCheckSpecificStrings:
+        case RTerminalControl3rdPartySession :: EPasscodeMaxAttempts:
+        case RTerminalControl3rdPartySession :: EPasscodeConsecutiveNumbers:
+        case RTerminalControl3rdPartySession :: EPasscodeHistoryBuffer:
+        case RTerminalControl3rdPartySession :: EPasscodeMinSpecialCharacters:
+        case RTerminalControl3rdPartySession :: EPasscodeDisallowSimple:
+            break;
+        case RTerminalControl3rdPartySession :: EPasscodeClearSpecificStrings:
+        case RTerminalControl3rdPartySession :: EPasscodeDisallowSpecific:
+        case RTerminalControl3rdPartySession :: EPasscodeAllowSpecific:
+           return KErrNotSupported;
+        default:
+            // No best policy check required for parameters other than the above 19 (Only 19 of the current parameters conflict!)
+            TUint16* ptr = const_cast<TUint16*>( aValue.Ptr());
+            TPtr valBuf( ptr, aValue.Length(), aValue.Length());
+            lRetStatus = iPluginEventHandler->GetParameters().Set( aID, valBuf);
+            return lRetStatus;
+    }
+    
+    TLex lex( aValue );
+    // Convert the parameter value to its numeric equivalent
+    if (lex.Val( lNumValue ) != KErrNone) {
+        return KErrArgument;
+    }
+
+    if(iOverrideForCleanup) {
+        Dprint( _L("[CSCPServer]-> SetBestPolicy() Overriding decision logic..."));
+        lRetStatus = aParamDB->DropValuesL(aID);
+    }
+    else {
+        // Fetch the previous value of the parameter from the private database
+        switch(aID) {
+            case RTerminalControl3rdPartySession :: EMaxTimeout:
+            case RTerminalControl3rdPartySession :: EPasscodeMinLength:
+            case RTerminalControl3rdPartySession :: EPasscodeMaxLength:
+            case RTerminalControl3rdPartySession :: EPasscodeRequireUpperAndLower:
+            case RTerminalControl3rdPartySession :: EPasscodeRequireCharsAndNumbers:
+            case RTerminalControl3rdPartySession :: EPasscodeExpiration:
+            case RTerminalControl3rdPartySession :: EPasscodeMaxRepeatedCharacters:
+            case RTerminalControl3rdPartySession :: EPasscodeMinChangeTolerance:
+            case RTerminalControl3rdPartySession :: EPasscodeMinChangeInterval:
+            case RTerminalControl3rdPartySession :: EPasscodeCheckSpecificStrings:
+            case RTerminalControl3rdPartySession :: EPasscodeMaxAttempts:
+            case RTerminalControl3rdPartySession :: EPasscodeConsecutiveNumbers:
+            case RTerminalControl3rdPartySession :: EPasscodeHistoryBuffer:
+            case RTerminalControl3rdPartySession :: EPasscodeMinSpecialCharacters:
+            case RTerminalControl3rdPartySession :: EPasscodeDisallowSimple: {
+                Dprint( (_L("[CSCPServer]-> Fetching the value of parameter '%d' from private database..."), aID));
+
+                TInt32 lAppID;
+
+                lRetStatus = aParamDB->GetValueL(aID, lNumValDB, lAppID);
+
+                switch(lRetStatus) {
+                case KErrNotFound: {
+                    TInt lLSValue(0);
+                    lFirstTime = ETrue;
+
+                    switch(aID) {
+                    case RTerminalControl3rdPartySession :: EMaxTimeout:
+                    case RTerminalControl3rdPartySession :: EPasscodeMaxRepeatedCharacters:
+                    case RTerminalControl3rdPartySession :: EPasscodeExpiration:
+                    case RTerminalControl3rdPartySession :: EPasscodeMinChangeTolerance:
+                    case RTerminalControl3rdPartySession :: EPasscodeMinChangeInterval:
+                    case RTerminalControl3rdPartySession :: EPasscodeMaxAttempts:
+                    case RTerminalControl3rdPartySession :: EPasscodeMaxLength:
+                    case RTerminalControl3rdPartySession :: EPasscodeDisallowSimple:
+                        /* For these parameters, if it is the first time that the values are being
+                           set then no decision is imposed regarding the best policy...
+                         */
+                        break;
+                    default:
+                        // Get the default values for the parameter...
+                        lRetStatus = iPluginEventHandler->GetParameters().Get(aID, lLSValue);
+                        break;
+                    }
+
+                    lNumValDB = lLSValue;
+                    Dprint((_L("[CSCPServer]-> Unable to fetch the value of parameter '%d' from private database, value from internal tree=%d"), aID, lLSValue));
+                }
+                break;
+                case KErrNone:
+                    break;
+                default:
+                    Dprint((_L("[CSCPServer]-> Failed to fetch parameter '%d' from the private database. ErrCode=%d"), aID, lRetStatus));
+                    return lRetStatus;
+                }
+                break;
+            }
+        }
+
+        if(lNumValue == lNumValDB) {
+            Dprint(_L("[CSCPServer]-> INFO: New parameter value and value from the database are the same. Overriding SetBestPolicy()..."));
+            return KErrNone;
+        }
+
+        lRetStatus = KErrNone;
+
+        // Decision code that verifies if policy is strongest
+        switch(aID) {
+        case RTerminalControl3rdPartySession :: EMaxTimeout:
+        case RTerminalControl3rdPartySession :: EPasscodeMaxRepeatedCharacters:
+        case RTerminalControl3rdPartySession :: EPasscodeExpiration:
+        case RTerminalControl3rdPartySession :: EPasscodeMinChangeTolerance:
+        case RTerminalControl3rdPartySession :: EPasscodeMinChangeInterval:
+        case RTerminalControl3rdPartySession :: EPasscodeMaxAttempts:
+            if(!lFirstTime && ((lNumValue > lNumValDB) || (lNumValue == 0))) {
+                lRetStatus = KErrArgument;
+            }
+            break;
+        case RTerminalControl3rdPartySession :: EPasscodeMaxLength:
+            if(!lFirstTime && (lNumValue < lNumValDB)) {
+                lRetStatus = KErrArgument;
+            }
+            break;
+        case RTerminalControl3rdPartySession :: EPasscodeMinLength:
+        case RTerminalControl3rdPartySession :: EPasscodeHistoryBuffer:
+        case RTerminalControl3rdPartySession :: EPasscodeMinSpecialCharacters:
+            if(lNumValue < lNumValDB) {
+                lRetStatus = KErrArgument;
+            }
+            break;
+        case RTerminalControl3rdPartySession :: EPasscodeRequireUpperAndLower:
+        case RTerminalControl3rdPartySession :: EPasscodeRequireCharsAndNumbers:
+        case RTerminalControl3rdPartySession :: EPasscodeCheckSpecificStrings:
+        case RTerminalControl3rdPartySession :: EPasscodeConsecutiveNumbers:
+        case RTerminalControl3rdPartySession :: EPasscodeDisallowSimple:
+            if(lNumValue == false && lNumValDB == true) {
+                lRetStatus = KErrArgument;
+            }
+            break;
+        }
+
+        if(lRetStatus != KErrNone) {
+            return KErrArgument;
+        }
+
+        // Update the best policy to the DB as well as the local storage tree
+        Dprint((_L("[CSCPServer]-> Updating the value of parameter '%d' to private database...UID=%d"), aID, aCallerIdentity));
+
+        lRetStatus = aParamDB->SetValueL(aID, lNumValue, aCallerIdentity);
+    }
+
+    Dprint(_L("[CSCPServer]-> lRetStatus after DB operation = %d "), lRetStatus);
+    /* Update is NOT ATOMIC!!!
+     * If the earlier aParamDB->SetValueL() was successful, there is a chance that
+     * the config.ini and the DB are out of sync if the operation iConfiguration.WriteSetupL()
+     * is not successful (disk space not enough etc) or when the WriteToFileL() in ParamObject  
+     * from iPluginEventHandler->GetParameters() fails.
+     * (WriteToFileL() is called in some destructor when the SCPServer terminates) 
+    */
+    if (lRetStatus == KErrNone) {
+        switch (aID) {
+        case RTerminalControl3rdPartySession :: EMaxTimeout:
+            iConfiguration.iMaxTimeout = lNumValue;
+            lRetStatus = iConfiguration.WriteSetupL();
+            Dprint(_L("[CSCPServer]-> After setting EMaxTimeout lRetStatus = %d "), lRetStatus);
+            break;
+        default:
+            TUint16* ptr = const_cast<TUint16*>(aValue.Ptr());
+            TPtr valBuf(ptr, aValue.Length(), aValue.Length());
+            lRetStatus = iPluginEventHandler->GetParameters().Set(aID, valBuf);
+            Dprint(_L("[CSCPServer]-> After setting (%d ) lRetStatus = %d "), aID, lRetStatus);
+            break;
+        }
+    }
+
+    Dprint(_L("[CSCPServer]-> SetBestPolicyL() lRetStatus = %d <<<"), lRetStatus);
+    return lRetStatus;
+}
+
+TInt CSCPServer :: PerformCleanupL(HBufC8* aAppIDBuffer, RArray<const TParamChange>& aChangeArray, RPointerArray<HBufC8>& aParamValArray) {
+    Dprint( (_L("[CSCPServer]-> PerformCleanupL() >>>")));
+
+    if(!aAppIDBuffer) {
+        return KErrArgument;
+    }
+    
+    TInt32 lAppCount = aAppIDBuffer->Length();
+    
+    if(lAppCount < 1) {
+        return KErrArgument;
+    }
+    
+    lAppCount /= sizeof(TInt32);
+    
+    TPtr8 bufPtr = aAppIDBuffer->Des();
+    
+    TInt lStatus(KErrNone);
+    CSCPParamDBController* lParamDB = CSCPParamDBController :: NewLC();
+    
+    RDesReadStream lBufReadStream(bufPtr);
+    CleanupClosePushL(lBufReadStream);
+    
+    Dprint(_L("[CSCPServer]-> INFO: Total items received for cleanup is %d"), lAppCount);
+    
+    RArray <TInt> lParamIds;
+    CleanupClosePushL(lParamIds);
+    
+    TBool lSubOpsFailed = EFalse;
+    HBufC* lDefValueBuf = HBufC :: NewLC(20);
+    
+    // Loop through each of the byte packed application ID's specified in aAppIDBuffer and clean them up iteratively
+    for(TInt i=0; i < lAppCount; i++) {
+        TInt32 lAppID = lBufReadStream.ReadInt32L();        
+        Dprint((_L("[CSCPServer]-> Initiating cleanup on %d  "), lAppID));
+
+
+        lParamIds.Reset();
+        lStatus = lParamDB->ListParamsUsedByAppL(lParamIds, lAppID);
+        
+        Dprint(_L("[CSCPServer]-> Status of ListParamsUsedByAppL() = %d"), lStatus);
+        
+       	TInt lCount = lParamIds.Count();
+       	
+        Dprint(_L("[CSCPServer]-> lCount=%d"), lCount);
+       	
+       	// Make sure that LockCodeMinChangeTolerance is always cleanedup before LockCodeHistoryBuffer
+       	if(lCount > 1) {
+            Dprint(_L("[CSCPServer]-> Updating the cleanup order for EPasscodeMinChangeTolerance and EPasscodeHistoryBuffer if needed..."));
+            TInt lHistBuffIndex = -1;
+            TInt lMinTolIndex = -1;
+            
+            for(TInt i=0; i < lCount; i++) {
+                if(lHistBuffIndex >= 0 && lMinTolIndex >= 0) {
+                    // If both the indexes have been found, stop the search
+                    break;
+                }
+                
+                switch(lParamIds[i]) {
+                case RTerminalControl3rdPartySession :: EPasscodeMinChangeTolerance:
+                    lMinTolIndex = i;
+                    break;
+                case RTerminalControl3rdPartySession :: EPasscodeHistoryBuffer:
+                    lHistBuffIndex = i;
+                    break;
+                }
+            }
+            
+            // This step is required only if both the parameters are marked for cleanup
+            if(lHistBuffIndex >= 0 && lMinTolIndex >= 0) {
+                /* Switch the cleanup order of the two parameters
+                 * This step is needed because ListParamsUsedByAppL() always returns the parameters
+                 * in Ascending order and because LockCodeMinChangeTolerance is always required to be 
+                 * cleanedup before LockCodeHistoryBuffer
+                */
+                lParamIds[lHistBuffIndex] = RTerminalControl3rdPartySession :: EPasscodeMinChangeTolerance;
+                lParamIds[lMinTolIndex] = RTerminalControl3rdPartySession :: EPasscodeHistoryBuffer;
+                Dprint(_L("[CSCPServer]-> Switching the cleanup order of EPasscodeHistoryBuffer and EPasscodeMinChangeTolerance"));
+                Dprint(_L("[CSCPServer]-> Old Index of EPasscodeHistoryBuffer=%d"), lHistBuffIndex);
+                Dprint(_L("[CSCPServer]-> Old Index of EPasscodeMinChangeTolerance=%d"), lMinTolIndex);
+            }
+       	}
+
+        for(TInt j=0; j < lCount; j++) {
+            TInt lCurrParamID = lParamIds[j];            
+            lDefValueBuf->Des().Zero();
+            lDefValueBuf->Des().Format(_L("%d "), 0);
+            // Initialize the default values here...
+            switch(lCurrParamID) {
+                case RTerminalControl3rdPartySession :: EMaxTimeout:
+                    // lDefValueBuf already has the default value, 0 initialized...
+                    lCurrParamID = ESCPMaxAutolockPeriod;
+                    break;
+                case RTerminalControl3rdPartySession :: EPasscodeMinLength:
+                    lDefValueBuf->Des().Format(_L("%d"), 4);
+                    break;
+                case RTerminalControl3rdPartySession :: EPasscodeMaxLength:
+                    lDefValueBuf->Des().Format(_L("%d"), 255);
+                    break;                    
+                default:
+                    // lDefValueBuf already has the default value, 0 initialized...
+                    break;
+            }
+    
+            switch(lCurrParamID) {
+                case RTerminalControl3rdPartySession :: EPasscodeDisallowSpecific: {
+                    RPointerArray<HBufC> lDesArr;
+                    CleanupClosePushL(lDesArr);
+                    
+                    lStatus = lParamDB->GetValuesL(lCurrParamID, lDesArr, lAppID);
+                    
+                    if(KErrNone == lStatus) {
+                        iOverrideForCleanup = ETrue;
+                    TInt lDesCount = lDesArr.Count();
+                        
+                        for(TInt k=0; k < lDesCount; k++) {
+                            TRAP(lStatus, lStatus = SetParameterValueL(lCurrParamID, lDesArr[k]->Des(), lAppID));
+                            if(KErrNone != lStatus) {
+                                Dprint(_L("[CSCPServer]-> ERROR: Unable to cleanup parameter %d error %d"), lParamIds[j], lStatus);
+                                lSubOpsFailed = ETrue;
+                            }
+                        }
+                    
+                    iOverrideForCleanup = EFalse;
+                    }
+                    
+                    lDesArr.ResetAndDestroy();
+                    CleanupStack :: PopAndDestroy(1); // lDesArray
+                }
+                break;
+                default: {
+                    iOverrideForCleanup = ETrue;
+                    TRAP(lStatus, lStatus = SetParameterValueL(lCurrParamID, lDefValueBuf->Des(), lAppID));
+                    iOverrideForCleanup = EFalse;
+    
+                    if(KErrNone == lStatus) {
+                        HBufC8* lTmpBuffer = HBufC8 :: NewL(lDefValueBuf->Length());
+                        lTmpBuffer->Des().Copy(lDefValueBuf->Des());
+                        
+                        const TParamChange lChange(lParamIds[j], lTmpBuffer->Des());
+                        aChangeArray.AppendL(lChange);
+                        
+                        // No need to destroy lTmpBuffer, it will be cleaned up by the caller (on cleanup of aParamValArray)
+                        aParamValArray.AppendL(lTmpBuffer);
+                    }
+                }
+            }
+            
+            if(KErrNone != lStatus) {
+                Dprint(_L("[CSCPServer]-> ERROR: Unable to cleanup parameter %d error %d"), lParamIds[j], lStatus);
+                lSubOpsFailed = ETrue;
+            }
+        }
+    }
+
+    Dprint( (_L("[CSCPServer]-> PerformCleanupL() <<<")));
+    CleanupStack :: PopAndDestroy(4); // lParamIds lParamDB lBufReadStream lDefValueBuf
+    return (lSubOpsFailed) ? KErrGeneral : KErrNone;
+}
+
+//#endif //  __SAP_DEVICE_LOCK_ENHANCEMENTS
+// <<<< ********************** NEW FEATURES ********************
+
+// ================= OTHER EXPORTED FUNCTIONS ==============
+
+ // __ARMI__ /
+
+// ---------------------------------------------------------
+// E32Main EXE entry point
+// Returns: TInt: Process exit value
+//          
+// Status : Approved
+// ---------------------------------------------------------
+//
+GLDEF_C TInt E32Main()
+    {
+    return CSCPServer::ThreadFunction(NULL);
+    }
+
+
+
+//  End of File  
+