terminalsecurity/SCP/SCPTimestampPlugin/src/SCPTimestampPlugin.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 12 Mar 2010 15:46:48 +0200
branchRCL_3
changeset 13 06f47423ecee
parent 2 5594fba90824
child 19 86979fe66c4c
permissions -rw-r--r--
Revision: 201007 Kit: 201008

/*
* 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 <e32base.h>
#include <e32std.h>
#include <ecom/implementationproxy.h>
#include <SCPParamObject.h>
#include <SCPTimestampPluginLang.rsg>
#include "SCP_IDs.h"
#include <bautils.h>
#include <hal.h>
#include <AknGlobalNote.h>
#include <AknGlobalConfirmationQuery.h>
// For wipe
//#include <StarterClient.h>
//#include <sysutil.h>
//#include <SysLangUtil.h>
//#include <rfsClient.h>
//#include "DMUtilClient.h"

#include "SCPTimestampPlugin.h"
#include <featmgr.h>
//#ifdef RD_MULTIPLE_DRIVE
//#include <DriveInfo.h>
//#include <PathInfo.h>
//#include <f32file.h>
//#endif //RD_MULTIPLE_DRIVEs
// CONSTANTS

// ============================= LOCAL FUNCTIONS  =============================



// ============================= MEMBER FUNCTIONS =============================

// ----------------------------------------------------------------------------
// CSCPTimestampPlugin::NewL
// Two-phased contructor
// 
// Status : Approved
// ----------------------------------------------------------------------------
//
CSCPTimestampPlugin* CSCPTimestampPlugin::NewL()
    {
	CSCPTimestampPlugin* self = new ( ELeave ) CSCPTimestampPlugin();
	CleanupStack::PushL( self );
	self->ConstructL();
	CleanupStack::Pop( self );
	
    Dprint ( ( _L( "( 0x%x ) CSCPPatternPlugin::NewL()" ), self ) );

    return self;
    }

// ----------------------------------------------------------------------------
// CSCPTimestampPlugin::CSCPTimestampPlugin
// Constructor
//
// Status : Approved
// ----------------------------------------------------------------------------
//
CSCPTimestampPlugin::CSCPTimestampPlugin()
    : iEventHandler( NULL ),
      iConfiguration( NULL ),
      iResOpen( EFalse )
    {
    Dprint ( ( _L( "CSCPTimestampPlugin::CSCPTimestampPlugin()" ) ) );
    return;
    }

// ----------------------------------------------------------------------------
// CSCPTimestampPlugin::ConstructL
// 2nd phase constructor
// 
// Status : Approved
// ----------------------------------------------------------------------------
//
void CSCPTimestampPlugin::ConstructL()
    {   
    FeatureManager::InitializeLibL();
		if(!FeatureManager::FeatureSupported(KFeatureIdSapDeviceLockEnhancements))
		{
    	FeatureManager::UnInitializeLib();
   		User::Leave( KErrNotSupported );
  	}
   	FeatureManager::UnInitializeLib();  
	iUserInfo = CSCPUserInf::NewL();
    Dprint ( ( _L( "CSCPTimestampPlugin::ConstructL()" ) ) );    
    
    return;
    }


// ----------------------------------------------------------------------------
// CSCPTimestampPlugin::~CSCPTimestampPlugin
// Destructor
//
// Status : Approved
// ----------------------------------------------------------------------------
//
CSCPTimestampPlugin::~CSCPTimestampPlugin()
    {
    Dprint( ( _L( "--> CSCPTimestampPlugin::~CSCPTimestampPlugin()" ) ) );
        
    iResFile.Close();
    
    if ( iConfiguration != NULL )
        {
        delete iConfiguration;
        iConfiguration = NULL;
        }

    if(iUserInfo)
        delete iUserInfo;
    Dprint( ( _L( "<-- CSCPTimestampPlugin::~CSCPTimestampPlugin()" ) ) );
    return;
    }
    
    
    
// ----------------------------------------------------------------------------
// CSCPTimestampPlugin::HandleEvent
// 
// 
// Status : Approved
// ----------------------------------------------------------------------------
//    
CSCPParamObject* CSCPTimestampPlugin::HandleEvent( TInt aID, CSCPParamObject& aParam )
	{		
	Dprint ( ( _L( "CSCPTimestampPlugin::HandleEvent()" ) ) );		
    	
	CSCPParamObject* retParams = NULL;
	
	// Get our current functional configuration
	if ( iEventHandler->GetParameters().Get( 
	        RTerminalControl3rdPartySession::EPasscodeExpiration, iExpiration ) != KErrNone )
	    {
	    iExpiration = 0;
	    }	    
	if ( iEventHandler->GetParameters().Get( 
	        RTerminalControl3rdPartySession::EPasscodeMinChangeInterval, iMinInterval) != KErrNone )
	    {
	    iMinInterval = 0;
	    }
	if ( iEventHandler->GetParameters().Get( 
	        RTerminalControl3rdPartySession::EPasscodeMinChangeTolerance, iMinTolerance) != KErrNone )
	    {
	    iMinTolerance = 0;
	    }
	if ( iEventHandler->GetParameters().Get( 
	        RTerminalControl3rdPartySession::EPasscodeMaxAttempts, iMaxAttempts ) != KErrNone )
	    {
	    iMaxAttempts = 0;
	    }	    	    
	    
	if ( !iResOpen )
	    {
	    // Load the resource file containing the localized texts
        TInt ret = GetResource();
        if ( ret == KErrNone )
            {
            iResOpen = ETrue;
            }
        // We'll continue without the resource if required
	    }		    
	
	switch ( aID )
	    {	    	    
	    case ( KSCPEventPasswordChangeQuery ):
	        {
	        if ( iMinInterval > 0 )
                {   
	            // Ignore errors, the plugin will stay silent on error
	            TRAP_IGNORE( IsChangeAllowedL( aParam, retParams ) );
                }
	        break;
	        }
	    
	    case ( KSCPEventConfigurationQuery ):
	        {
	        
	        TInt paramID;	            	            
	            	            
	        if ( aParam.Get( KSCPParamID, paramID ) == KErrNone ) 
	            {	                
	            ConfigurationQuery( paramID, aParam, retParams );
	            }
	                	                	            
	        break;
	        }

	    case ( KSCPEventPasswordChanged ):
	        {	            
	        PasswordChanged( aParam, retParams );
	        break;
	        }

        case ( KSCPEventAuthenticationAttempted ):
            {
            TInt authStatus;
            if ( aParam.Get( KSCPParamStatus, authStatus ) == KErrNone ) // Ignore errors
                {
                TBool isSuccess = ( authStatus == KErrNone );
                // No return value required in any case
                AuthenticationAttempt( isSuccess, aParam, retParams );
                }	            
           	                
            break;
            }
            
        case ( KSCPEventReset ):
              {
              // Reset the configuration for this plugin.
              if ( ReadConfiguration() == KErrNone )
                {
                iConfiguration->Reset();
                WriteConfiguration();
                }
              
              break;
              }            
            
        default:
            // No implementation required, we're not interested in other events
        break;	            	            
	    }	    	    
	
    // The caller will own this pointer from now on   
    return retParams; 
	}

// ----------------------------------------------------------------------------
// CSCPTimestampPlugin::HandleEvent
// 
// 
// Status : Approved
// ----------------------------------------------------------------------------
//    
void CSCPTimestampPlugin::SetEventHandler( MSCPPluginEventHandler* aHandler )
	{
	Dprint( ( _L( "CSCPPatternPlugin::SetEventHandler()" ) ) ) ;
	iEventHandler = aHandler;
	
	iFsSession = &(iEventHandler->GetFsSession());	
	}	


// ----------------------------------------------------------------------------
// CSCPTimestampPlugin::IsChangeAllowed()
// 
// 
// Status : Approved
// ----------------------------------------------------------------------------
// 
void CSCPTimestampPlugin::IsChangeAllowedL( CSCPParamObject& aParam, CSCPParamObject*& aRetParams )
    {  
    (void)aParam;
                          
    Dprint( (_L("CSCPTimestampPlugin::IsChangeAllowedL()") ));                      
    TInt ret = KErrNone;
    
    if ( ReadConfiguration() != KErrNone )
        {
        Dprint( (_L("CSCPTimestampPlugin::IsChangeAllowedL() ReadConfiguration() != KErrNone RETURNING") ));
        return; // Someting wrong
        }    
    
    // Check if the change is within the interval
    TInt ret2 = IsAfter( KSCPIntervalStartTime, iMinInterval, KSCPTypeHours );
            
    if ( ret2 == KSCPIsAfter )
        {
        // Interval exceeded, change OK
        Dprint( (_L("CSCPTimestampPlugin::IsChangeAllowedL() KSCPIsAfter") ));
        ret = KErrNone;                    
        }
    else if ( ret2 == KSCPIsNotAfter )
        {
        // Change within the interval, check the tolerance
        Dprint( (_L("CSCPTimestampPlugin::IsChangeAllowedL() KSCPIsNotAfter") )); 
        TInt tolerance = 0;
        iConfiguration->Get( KSCPUsedTolerance, tolerance ); // ignore errors
        Dprint( ( _L( "CSCPPatternPlugin::IsChangeAllowedL(): tolerance get: %d"), tolerance ) );                
        Dprint( ( _L( "CSCPPatternPlugin::IsChangeAllowedL(): iMinTolerance : %d"), iMinTolerance ) );                
        if ( tolerance >= iMinTolerance )
            {
            ret = KErrSCPCodeChangeNotAllowed;
            Dprint( (_L("CSCPTimestampPlugin::IsChangeAllowedL() KErrSCPCodeChangeNotAllowed") )); 
            }
        
        // Used tolerance will increment in passwordChanged                
        }
    else 
        {
        // Error, new interval will start in passwordChanged.
        Dprint( (_L("CSCPTimestampPlugin::IsChangeAllowedL() Error, new interval will start in passwordChanged") )); 
        }                                                                     
    
    if ( ret == KErrSCPCodeChangeNotAllowed )
        {
        // Code change is not allowed, send the info back to the user
        aRetParams  = CSCPParamObject::NewL();        
                        
        aRetParams->Set( KSCPParamStatus, KErrSCPCodeChangeNotAllowed );			        			        
        aRetParams->Set( KSCPParamAction, KSCPActionShowUI );
        aRetParams->Set( KSCPParamUIMode, KSCPUINote );
        aRetParams->Set( KSCPParamNoteIcon, KSCPUINoteError );
        
        HBufC16* resText = NULL;
        HBufC16* formatBuf = NULL;
                
        Dprint( ( _L( "CSCPPatternPlugin::IsChangeAllowedL(): iMinInterval : %d"), iMinInterval ) );                
        Dprint( ( _L( "CSCPPatternPlugin::IsChangeAllowedL(): iMinTolerance : %d"), iMinTolerance ) );                 
        if ( iMinInterval > 1 )
            {
            if ( iMinTolerance >1 )
                {
                Dprint( (_L("CSCPTimestampPlugin::IsChangeAllowedL(): iMinInterval > 1,iMinTolerance >= 1") ));                      
                resText = LoadResourceL( R_SET_SEC_CODE_CHANGE_DAY );
                }
            else
                {
                Dprint( (_L("CSCPTimestampPlugin::IsChangeAllowedL(): iMinInterval > 1,iMinTolerance !>= 1") ));                      
                resText = LoadResourceL( R_SET_SEC_CODE_CHANGE_HOURS );
                }
            }
        else
            if ( iMinTolerance > 1 )
                {
                Dprint( (_L("CSCPTimestampPlugin::IsChangeAllowedL(): iMinInterval !> 1,iMinTolerance >= 1") ));                      
                resText = LoadResourceL( R_SET_SEC_CODE_CHANGE_TIMES );
                }
            else
                {
                Dprint( (_L("CSCPTimestampPlugin::IsChangeAllowedL(): iMinInterval !> 1,iMinTolerance !>= 1") ));                      
                resText = LoadResourceL( R_SET_SEC_CODE_CHANGE_ONES );
                }         
                
        CleanupStack::PushL( resText );
        
        formatBuf = HBufC::NewL( resText->Length() + KSCPMaxMinChangeValueLen );
		    
		TPtr16 bufDes = formatBuf->Des();
		
        if ( iMinInterval > 1 )
            {
            if ( iMinTolerance > 1 )
                {
                bufDes.Format( resText->Des(), iMinTolerance , iMinInterval );
                }
            else
                {
                bufDes.Format( resText->Des(), iMinInterval );
                }
            }
        else
            if ( iMinTolerance > 1 )
                {
                bufDes.Format( resText->Des(), iMinTolerance  );
                }
            else
                {
                bufDes.Format( resText->Des() );
                }  		    	
		            
        aRetParams->Set( KSCPParamPromptText, bufDes );
            
        delete formatBuf;
		    
        CleanupStack::PopAndDestroy( resText );
        }
        
    // No need to write configuration changes            
    }


// ----------------------------------------------------------------------------
// CSCPTimestampPlugin::PasswordChanged()
// 
// 
// Status : Approved
// ----------------------------------------------------------------------------
//    
void CSCPTimestampPlugin::PasswordChanged( CSCPParamObject& aParam, CSCPParamObject*& aRetParams )
    {
    (void)aParam;
    (void)aRetParams;    
    Dprint( (_L("CSCPTimestampPlugin::PasswordChanged()") ));                      
    TInt err = ReadConfiguration();
    if ( err == KErrNone )
        {
        // Check if immediate expiration is set
        Dprint( (_L("CSCPTimestampPlugin::PasswordChanged() : ReadConfiguration = KErrNone") ));                      
        TInt expireNow = 0;
        if ( iConfiguration->Get( KSCPExpireOnNextCall, expireNow ) == KErrNone )
            {
            iConfiguration->Unset( KSCPExpireOnNextCall );
            }                                
        
        TBuf<KSCPMaxInt64Length> timeBuf; 
        timeBuf.Zero();       
        
        // Fetch the current time and fill the buffer
        TTime curTime;
        curTime.UniversalTime();
        
        timeBuf.AppendNum( curTime.Int64() );
        
        if ( iExpiration > 0 )
            {
            // Set the last time the password was changed, for expiration
            iConfiguration->Set( KSCPLastChangeTime, timeBuf );
            }        
        Dprint( ( _L( "CSCPPatternPlugin::PasswordChanged(): iMinInterval: %d"), iMinInterval ) );
        if ( iMinInterval > 0 )
            {
            TInt ret = IsAfter( KSCPIntervalStartTime, iMinInterval, KSCPTypeHours );
            if ( ret == KSCPIsAfter )
                {                                                        
                // Interval exceeded, start a new interval from here
                Dprint( (_L("CSCPTimestampPlugin::PasswordChanged() KSCPIsAfter") ));    
                iConfiguration->Set( KSCPIntervalStartTime, timeBuf );
                iConfiguration->Set( KSCPUsedTolerance, 1 );
                }
            else if ( ret == KSCPIsNotAfter )
                {
                // Change within the interval, increment the used tolerance
                Dprint( (_L("CSCPTimestampPlugin::PasswordChanged() KSCPIsNotAfter") ));
                TInt tolerance = 0;
                iConfiguration->Get( KSCPUsedTolerance, tolerance ); //ignore errors, default to 0
                Dprint( ( _L( "CSCPPatternPlugin::PasswordChanged(): tolerance get: %d"), tolerance ) );
                tolerance++;        
                iConfiguration->Set( KSCPUsedTolerance, tolerance );                
                Dprint( ( _L( "CSCPPatternPlugin::PasswordChanged(): tolerance set: %d"), tolerance ) );                
                }                                                                
            else // error
                {
                // No time set, start a new interval from here
                Dprint( (_L("CSCPTimestampPlugin::PasswordChanged() error") ));
                iConfiguration->Set( KSCPIntervalStartTime, timeBuf );
                TInt tolerance = 0;
                iConfiguration->Get( KSCPUsedTolerance, tolerance ); //ignore errors, default to 0
                Dprint( ( _L( "CSCPPatternPlugin::PasswordChanged(): tolerance get: %d"), tolerance ) );
                tolerance++;        
                iConfiguration->Set( KSCPUsedTolerance, tolerance );
                Dprint( ( _L( "CSCPPatternPlugin::PasswordChanged(): tolerance set: %d"), tolerance ) );  
                }                       
            }        
        
        WriteConfiguration();
        }
        else
        {
            Dprint( (_L("CSCPTimestampPlugin::PasswordChanged() ReadConfiguration() != KErrNone") ));                      
            Dprint( ( _L( "CSCPPatternPlugin::PasswordChanged(): ReadConfiguration() = %d"), err ) );
        }
    }


// ----------------------------------------------------------------------------
// CSCPTimestampPlugin::AuthenticationAttempt()
// 
// 
// Status : Approved
// ----------------------------------------------------------------------------
//    
void CSCPTimestampPlugin::AuthenticationAttempt( TBool aIsSuccessful, 
                                                 CSCPParamObject& aParam,
                                                 CSCPParamObject*& aRetParams )
    {
    if ( ReadConfiguration() != KErrNone )
        {
        return;
        }
    Dprint( (_L("CSCPTimestampPlugin::AuthenticationAttempt()") )); 
        
    // Check if immediate expiration is set
    TInt expireNow = 0;
    iConfiguration->Get( KSCPExpireOnNextCall, expireNow ); // ignore errors  
    
    if ( ( iExpiration == 0 ) && ( iMaxAttempts == 0) && ( expireNow == 0 ) )
        {
        return; // We have no interest in this call
        }                
    
    if ( aIsSuccessful )
        {
        TRAP_IGNORE( SuccessfulAuthenticationL( aParam, aRetParams ) );
        }
    else
        {
        // Failed authentication attempt
        if ( iMaxAttempts > 0 )
            {
		    Dprint( (_L("CSCPTimestampPlugin::iMaxAttempts > 0") )); 
            TInt failedCount = 0;
            iConfiguration->Get( KSCPFailedAttempts, failedCount ); // ignore errors
            failedCount++;                        
        
            if ( failedCount == iMaxAttempts - 1 )
                {
                // Warn the user. Only one attempt left. There's no use handling the error
                // so we'll just stay silent at this point on failure.
		        Dprint( (_L("CSCPTimestampPlugin::One Attempt Left") ));
				HBufC16* resText = NULL;
                resText = LoadResourceL( R_SET_SEC_CODE_WARNING_ATTEMPTS_LEFT );
                FormatResourceString(*resText);               
				// Call the dialog from an ActiveObj framework so that we could give control back to secui
		        Dprint( (_L("CSCPTimestampPlugin::start actv obj for dialog") ));
                iUserInfo->StartL(*resText);
                }
            else if ( failedCount >= iMaxAttempts )
                {
                // Try to wipe the device
                TRAPD( err, WipeDeviceL( aRetParams ) );
                if ( err != KErrNone )
                    {
                    Dprint( ( _L( "CSCPPatternPlugin::\
                        AuthenticationAttempt(): Wipe FAILED :%d"), err ) );
                    }
                }
            
            iConfiguration->Set( KSCPFailedAttempts, failedCount );
            }
        }
        
    WriteConfiguration();        
    }


// ----------------------------------------------------------------------------
// CSCPTimestampPlugin::SuccessfulAuthentication()
// 
// 
// Status : Approved
// ----------------------------------------------------------------------------
//
void CSCPTimestampPlugin::SuccessfulAuthenticationL( CSCPParamObject& aParam,
                                                    CSCPParamObject*& aRetParams )
    {
    // Reset the failed attempts -counter
    if ( iMaxAttempts > 0 )
        {
        iConfiguration->Set( KSCPFailedAttempts, 0 );
        }
                    
    // Check context, if the user is already changing the password, don't force it again.
    TInt context = 0;
    aParam.Get( KSCPParamContext, context ); // ignore errors

    // Check if immediate expiration is set
    TInt expireNow = 0;
    iConfiguration->Get( KSCPExpireOnNextCall, expireNow ); // ignore errors    
    
    // Check if the code should be changed now    
    if ( ( context != KSCPContextChangePsw ) && 
         ( ( iExpiration > 0 ) ||  ( expireNow ) ) )
        {                    
        if ( ( IsAfter( KSCPLastChangeTime, iExpiration, KSCPTypeDays ) == KSCPIsAfter ) ||
             ( expireNow ) )
            {
            // Force password change                        
            
            HBufC16* resText = NULL;
            TRAPD( err, resText = LoadResourceL( R_SET_SEC_CODE_AGING ) );         
            FormatResourceString(*resText);        
            if (err == KErrNone) // If this fails, go on anyway to signal the psw change
                {
                TPtr16 bufDes = resText->Des();
                TRequestStatus userResponse;

                CAknGlobalNote* note = CAknGlobalNote::NewLC();
                TRAP_IGNORE(
                        note->SetSoftkeys(R_AVKON_SOFTKEYS_OK_EMPTY);
                        note->ShowNoteL(userResponse, EAknGlobalWarningNote,
                                bufDes);
                );

                // Wait for the User Response
                User::WaitForRequest(userResponse);
                CleanupStack::PopAndDestroy(note);

                delete resText;
                }
            
            // Refill the parameters to inform the client that the password
            // should be changed.
            aRetParams = CSCPParamObject::NewL(); 
            aRetParams->Set( KSCPParamAction, KSCPActionForceChange );  
            }
        }
    }
    
    
// ----------------------------------------------------------------------------
// CSCPTimestampPlugin::IsAfter()
// 
// 
// Status : Approved
// ----------------------------------------------------------------------------
//
TInt CSCPTimestampPlugin::IsAfter( TInt aConfID, TInt aInterval, TInt aIntType )
    {
    TInt ret;
    Dprint( (_L("CSCPTimestampPlugin::IsAfter()") ));
    TTime curTime;
    curTime.UniversalTime();        
    
    TBuf<KSCPMaxInt64Length> savedTimeBuf;
    TInt64 savedTime;
    ret = iConfiguration->Get( aConfID, savedTimeBuf );
    if ( ret == KErrNone )
        {    
        Dprint( (_L("CSCPTimestampPlugin::IsAfter() iConfiguration->Get == KErrNone") ));    
        TLex lex( savedTimeBuf );
        ret = lex.Val( savedTime );
        if ( ret == KErrNone )
            {
            Dprint( (_L("CSCPTimestampPlugin::IsAfter() lex.Val( savedTime ) == KErrNone") ));
            TTime configTime( savedTime );
            switch ( aIntType )
                {
                case ( KSCPTypeMinutes ):
                    {
                    Dprint( (_L("CSCPTimestampPlugin::IsAfter() KSCPTypeMinutes") ));
                    TTimeIntervalMinutes interval = aInterval;
                    configTime += interval;
                    break;
                    }
                    
                case ( KSCPTypeHours ):
                    {
                    Dprint( (_L("CSCPTimestampPlugin::IsAfter() KSCPTypeHours") ));
                    TTimeIntervalHours interval = aInterval;
                    configTime += interval;                    
                    break;
                    }  
                    
                case ( KSCPTypeDays ):
                    {
                    Dprint( (_L("CSCPTimestampPlugin::IsAfter() KSCPTypeDays") ));
                    TTimeIntervalDays interval = aInterval;
                    configTime += interval;                    
                    break;
                    }                                         
                }

            if ( curTime > configTime )
                {
                ret = KSCPIsAfter;
                Dprint( (_L("CSCPTimestampPlugin::IsAfter() ret = KSCPIsAfter") ));
                }
            else
                {
                ret = KSCPIsNotAfter;
                Dprint( (_L("CSCPTimestampPlugin::IsAfter() ret = KSCPIsNotAfter") ));
                }
            }
        }
    
    return ret;
    }
    
// ----------------------------------------------------------------------------
// CSCPTimestampPlugin::ConfigurationQuery()
// 
// 
// Status : Approved
// ----------------------------------------------------------------------------
//    
void CSCPTimestampPlugin::ConfigurationQuery(  TInt aParamID, 
                                               CSCPParamObject& aParam, 
                                               CSCPParamObject*& aRetParams )
    {
    // First check if this is our ID    
    if ( ( aParamID == RTerminalControl3rdPartySession::EPasscodeExpiration ) ||
         ( aParamID == RTerminalControl3rdPartySession::EPasscodeMinChangeTolerance ) ||
         ( aParamID == RTerminalControl3rdPartySession::EPasscodeMinChangeInterval ) ||
         ( aParamID == RTerminalControl3rdPartySession::EPasscodeMaxAttempts ) )
        {
        // OK, get the value, the parameters above should be TInt:s
        TInt ret = KErrNone;
        
        if ( ReadConfiguration() != KErrNone )
            {
            return;
            }        
        
        TInt paramValue;
        TBool setPrivateStorage = EFalse;        
        if ( aParam.Get( KSCPParamValue, paramValue ) == KErrNone )
            {
            switch ( aParamID )
                {
                case ( RTerminalControl3rdPartySession::EPasscodeExpiration ):
                    {
                    if ( ( paramValue < KSCPExpireImmediately ) || 
                         ( paramValue > KSCPMaxExpiration) )
                        {
                        ret = KErrArgument;
                        }
                    else if ( paramValue == 0 )
                        {
                        // Feature disabled, remove the stored data
                        iConfiguration->Unset( KSCPLastChangeTime );
                        }                        
                    else if ( paramValue == KSCPExpireImmediately )
                        {
                        // Special case, expire immediately, but retain the previous timestamp
                        iConfiguration->Set( KSCPExpireOnNextCall,  ETrue );
                        // Tell the server that this param is stored in our private storage
                        // (note that in KSCPExpireImmediately-case only..)
                        setPrivateStorage = ETrue;
                        }
                    else if ( iExpiration == 0 )
                        {
                        // Check activated, start the expiration from this time
                        Dprint ( ( _L( "CSCPTimestampPlugin::ConfigurationQuery(): Check activated" ) ) );
                        TTime curTime;
                        curTime.UniversalTime();
                        
                        TBuf<KSCPMaxInt64Length> timeBuf;
                        timeBuf.Zero();
                        timeBuf.AppendNum( curTime.Int64() );
        
                        // Set this time as the starting point for expiration
                        iConfiguration->Set( KSCPLastChangeTime, timeBuf );
                        }
                        
                    break;
                    }
                        
                case ( RTerminalControl3rdPartySession::EPasscodeMinChangeTolerance ):
                    {
                    if ( ( paramValue < 0 ) || ( paramValue > KSCPMaxTolerance ) )
                        {
                        ret = KErrArgument;
                        }                         

                    break;
                    }
                        
                case ( RTerminalControl3rdPartySession::EPasscodeMinChangeInterval ):
                    {
                    if ( ( paramValue < 0 ) || ( paramValue > KSCPMaxInterval ) )
                        {
                        ret = KErrArgument;
                        }
                   else if ( paramValue == 0 )
                        {
                        // Feature disabled, remove the stored data
                        iConfiguration->Unset( KSCPIntervalStartTime );
                        iConfiguration->Unset( KSCPUsedTolerance );
                        }                        
                        
                    break;
                    }
                        
                case ( RTerminalControl3rdPartySession::EPasscodeMaxAttempts ):
                    {
                    if ( ( ( paramValue < KSCPMinAttempts ) || 
                           ( paramValue > KSCPMaxAttempts ) ) &&
                         ( paramValue != 0 ) )
                        {
                        ret = KErrArgument;
                        }
                    else if ( iMaxAttempts != paramValue )
                        {
                        // Remove the stored data, max attempts always restarts
                        iConfiguration->Unset( KSCPFailedAttempts );                        
                        }
                        
                    break;
                    }
                    
                default:
                    ret = KErrGeneral; // Something is seriously wrong if this is executed
                    break;                        
                } 
                
            WriteConfiguration();                       
            }
        else
            {
            // Something wrong, and this is our parameter. Signal an error
            ret = KErrArgument;
            }       
        
        TRAPD( err, aRetParams = CSCPParamObject::NewL() );        
        if ( err == KErrNone ) // If we can't create a paramObject, there's nothing we can do
            {
            aRetParams->Set( KSCPParamStatus, ret );
            if ( setPrivateStorage )
                {
                aRetParams->Set( KSCPParamStorage, KSCPStoragePrivate );
                }            
            }  
        }          
    }
    
    
    
// ----------------------------------------------------------------------------
// CSCPTimestampPlugin::WipeDeviceL()
// 
// 
// Status : Approved
// ----------------------------------------------------------------------------
//     
void CSCPTimestampPlugin::WipeDeviceL( CSCPParamObject*& aRetParams )
    {
    (void)aRetParams;
    
	Dprint( (_L("CSCPTimestampPlugin::WipeDeviceL") ));
	iUserInfo->DoRfsL();
    /*
    // First try to format other local drives than C:
    RRfsClient rfsClient;
    
    TInt ret = rfsClient.Connect();
    
    if ( ret == KErrNone )
        {        
        CleanupClosePushL( rfsClient );    
 #ifndef RD_MULTIPLE_DRIVE
        
        TDriveList list;
        iFsSession->DriveList( list );

        TInt   i;
        TUint8 c = 'A';

        // Loop through the drives
        for( i = 0; i < KMaxDrives &&  c < 'I'; i++, c++ )
            {
            if( (list[i] != 0) && (c != 'C') )
                {
                TBuf<KSCPFormatScriptMaxLen> formatScript;
                formatScript.Format(KSCPFormatScript, (TUint)c );
                Dprint( ( _L( "CSCPPatternPlugin::WipeDeviceL(): Formatting %c:"), c ) );
                    
                ret = rfsClient.RunScriptInDescriptor(formatScript);
                
                if ( ret != KErrNone )
                    {
                    Dprint( ( _L( "CSCPPatternPlugin::WipeDeviceL():\
                     FAILED to format %c: %d"), c, ret ) );
                    }
                }
            }
#else 
		RFs fs;
    	User::LeaveIfError(fs.Connect());
   		CleanupClosePushL(fs);
		TDriveList driveList;
 		TInt driveCount;
 		
 		//Get list of drives;
  		User::LeaveIfError( DriveInfo::GetUserVisibleDrives( fs, driveList, driveCount ) );
  		
  		TInt driveListLen( driveList.Length() ); 
  		TInt phoneMemoryDrive( EDriveC );
   		RFs::CharToDrive( PathInfo::PhoneMemoryRootPath()[0], phoneMemoryDrive );
  		TDriveNumber driveNumber;
  		
  		//Loop through all drives except phonem memory drive
  		for (TInt i(0); i<driveListLen; ++i)
  		{
  			if (driveList[i])
  			{
		  			driveNumber = TDriveNumber(i);
		  			if (phoneMemoryDrive != driveNumber)
		  			{
		  				TBuf<KSCPFormatScriptMaxLen> formatScript;
		  				TChar driveLetter;
		  				RFs::DriveToChar(i,driveLetter);
		                formatScript.Format(KSCPFormatScript, (TUint)driveLetter );
		                Dprint( ( _L( "CSCPPatternPlugin::WipeDeviceL(): Formatting %c:"), driveLetter ) );
		                    
		                ret = rfsClient.RunScriptInDescriptor(formatScript);
		                
		                if ( ret != KErrNone )
		                    {
		                    Dprint( ( _L( "CSCPPatternPlugin::WipeDeviceL():\
		                     FAILED to format %c: %d"), driveLetter, ret ) );
		                    }
		  			}
  			}
  		}
  		
  		CleanupStack::PopAndDestroy();
#endif  //RD_MULTIPLE_DRIVE   
        // In case of deep level RFS, set the default language code
        // here, before RFS reboot.
        TInt language( 0 );

        // If default language is not found, we reset anyway
        if ( SysLangUtil::GetDefaultLanguage( language ) == KErrNone )
            {
            HAL::Set( HALData::ELanguageIndex, language );
            }
        
        // Send NVD_SET_DEFAULT_REQ here, before reboot. Ignore errors.        

        CleanupStack::PopAndDestroy( &rfsClient );
        }       

    // Mark MMC card to be formatted also in bootup
	RDMUtil util;
	if ( util.Connect() == KErrNone )
	    {        
        TInt err = util.MarkMMCWipe();
        if( err != KErrNone )
        	{
        	// even if not successfull we try to reset as much as possible -> continue
        	Dprint( ( _L( "CSCPPatternPlugin::WipeDeviceL(): FAILED to mark MMC wipe: %d"), err ) );        	
        	}    
        util.Close();
	    }	

    // Reboot with RFS reason  

        RStarterSession startersession;
        if( startersession.Connect() == KErrNone )
            {
            startersession.Reset( RStarterSession::EDeepRFSReset );
            startersession.Close();
            }
                                           
    if ( ret != KErrNone )
        {
        Dprint( ( _L( "CSCPPatternPlugin::WipeDeviceL(): Rfs FAILED: %d"), ret ) );
        }     */                                                    
	Dprint( (_L("CSCPTimestampPlugin::~WipeDeviceL") ));
    }
    
// ----------------------------------------------------------------------------
// CSCPTimestampPlugin::ReadConfiguration()
// 
// 
// Status : Approved
// ----------------------------------------------------------------------------
// 
TInt CSCPTimestampPlugin::ReadConfiguration()
    {
    TInt ret = KErrNone;
    Dprint( (_L("CSCPTimestampPlugin::ReadConfiguration()") ));
    if ( iConfiguration == NULL )
        {
        TRAPD( err, iConfiguration = CSCPParamObject::NewL() );
        if ( err != KErrNone )
            {
            Dprint( (_L("CSCPTimestampPlugin::ReadConfiguration() err != KErrNone") ));
            return err;
            }

        TFileName configFile;
        TRAP( err, ret = iEventHandler->GetStoragePathL( configFile ) ); 
        
        if ( ( err != KErrNone ) && ( ret == KErrNone ) )
            {
            Dprint( (_L("CSCPTimestampPlugin::ReadConfiguration() err != KErrNone  &&  ret == KErrNone") ));
            ret = err;
            }               
        
        if ( ( err == KErrNone ) && ( ret == KErrNone ) )
            {
            configFile.Append( KSCPTSConfigFile );
            TRAP( ret, iConfiguration->ReadFromFileL( configFile, iFsSession ) );
            Dprint( (_L("CSCPTimestampPlugin::ReadConfiguration() err == KErrNone  &&  ret == KErrNone") ));
            if ( ret == KErrNotFound )
                {
                ret = KErrNone; // Not an error, we'll create this file
                }
            }        
        }
    
    return ret;
    }

        
// ----------------------------------------------------------------------------
// CSCPTimestampPlugin::WriteConfiguration()
// 
// 
// Status : Approved
// ----------------------------------------------------------------------------
// 
TInt CSCPTimestampPlugin::WriteConfiguration()
    {
    TInt ret = KErrGeneral;

    if ( iConfiguration != NULL )
        {                
        TFileName configFile;
        TRAPD( err, ret = iEventHandler->GetStoragePathL( configFile ) );
        
        if ( ( err != KErrNone ) && ( ret == KErrNone ) )
            {
            ret = err;
            }
        
        if ( ( err == KErrNone ) && ( ret == KErrNone ) )
            {
            configFile.Append( KSCPTSConfigFile );
            TRAP( ret, iConfiguration->WriteToFileL( configFile, iFsSession ) );           
            }        
        }    
    
    return ret;    
    }
    


// ----------------------------------------------------------------------------
// CSCPTimestampPlugin::GetResource
// GetResource
//
// Status : Approved
// ----------------------------------------------------------------------------
//

TInt CSCPTimestampPlugin::GetResource()
    {
 	Dprint( (_L("CSCPTimestampPlugin::GetResource()") ));
	// The resource has to be loaded manually since this is not an application.
        		    
    // Build the resource file name and localize it
    TFileName resourceFile;
    resourceFile.Append( KDriveZ );
    resourceFile.Append( KSCPTimestampPluginResFilename );
    BaflUtils::NearestLanguageFile( *iFsSession, resourceFile ); 
    
    TRAPD( err, iResFile.OpenL( *iFsSession, resourceFile ) );

    if ( err == KErrNone )
        {
        TRAP( err, iResFile.ConfirmSignatureL() );
        }               
    
    return err;
    }


// ----------------------------------------------------------------------------
// CSCPTimestampPlugin::LoadResourceLC
// 
//
// Status : Approved
// ----------------------------------------------------------------------------
//
HBufC16* CSCPTimestampPlugin::LoadResourceL( TInt aResId )
    {
	if ( !iResOpen )
	    {
	    User::Leave( KErrNotReady );
	    }
	    
	Dprint( (_L("CSCPTimestampPlugin::LoadResourceL()") ));
	
	// Load the actual resource
    HBufC8* readBuffer = iResFile.AllocReadLC( aResId );
    
    // As we are expecting HBufC16    
    const TPtrC16 ptrReadBuffer( (TText16*) readBuffer->Ptr(),
                                 ( readBuffer->Length() + 1 ) >> 1 );
                                 
    HBufC16* textBuffer = HBufC16::NewL( ptrReadBuffer.Length() );
    
    *textBuffer = ptrReadBuffer;
    
    FormatResourceString(*textBuffer);
    CleanupStack::PopAndDestroy( readBuffer );
  	
  	return textBuffer;
    }

// ----------------------------------------------------------------------------
// CSCPTimestampPlugin::FormatResourceString
// The buffer that is passed is formatted to have only %i as a format specifier instead of %N or %0N etc.
// 
// Status : Approved
// ----------------------------------------------------------------------------
//
void CSCPTimestampPlugin::FormatResourceString(HBufC16 &aResStr)
{
		TInt pos = 0;
		TInt flag = 0;
        TPtr16 bufPtr = aResStr.Des();
        _LIT (mess1, "%N");
        _LIT (mess2, "%i");
        _LIT (mess3, "%0N");
        _LIT (mess4, "%1N");
                              
        while ((pos = bufPtr.Find(mess1)) !=KErrNotFound)
        {
              bufPtr.Replace(pos,2,mess2); 
              flag = 1;
              break;                    
        }
               
        if(flag == 0)
        {
              while ((pos = bufPtr.Find(mess3)) != KErrNotFound)
              {
              		bufPtr.Replace(pos,3,mess2);
              }
               		
              while ((pos = bufPtr.Find(mess4)) != KErrNotFound)
              {
                	bufPtr.Replace(pos,3,mess2);
              }
        }	
}

// End of File