terminalsecurity/SCP/SCPTimestampPlugin/src/SCPTimestampPlugin.cpp
changeset 0 b497e44ab2fc
child 2 5594fba90824
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/terminalsecurity/SCP/SCPTimestampPlugin/src/SCPTimestampPlugin.cpp	Thu Dec 17 09:07:52 2009 +0200
@@ -0,0 +1,1134 @@
+/*
+* 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();  
+    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;
+        }
+
+    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;
+        }
+        
+    // 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 )
+            {
+            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.
+                TRAP_IGNORE(                                        
+                    HBufC16* resText = NULL;
+                    resText = LoadResourceL( R_SET_SEC_CODE_WARNING_ATTEMPTS_LEFT );
+                    FormatResourceString(*resText);
+    		        CleanupStack::PushL( resText );
+    		        
+    			    TPtr16 bufDes = resText->Des();
+    			    
+    			    CAknGlobalConfirmationQuery* note = CAknGlobalConfirmationQuery::NewLC();
+    			        			    
+    			    TRequestStatus status;
+    			    note->ShowConfirmationQueryL(status,
+    			    							 bufDes,
+    			    							 R_AVKON_SOFTKEYS_OK_EMPTY,
+    			    							 R_QGN_NOTE_WARNING_ANIM );
+    			    User::WaitForRequest( status );
+                                  			    
+    			    CleanupStack::PopAndDestroy( note );
+    			     
+                    CleanupStack::PopAndDestroy( 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();
+                
+                TRAP_IGNORE(
+                    CAknGlobalNote* note = CAknGlobalNote::NewLC();
+    		        note->ShowNoteL( EAknGlobalWarningNote, bufDes );
+    		        CleanupStack::PopAndDestroy( note );
+    		        );    	        
+    	        
+    	        // Wait here a while so the dialog won't appear on top of the note
+                User::After( KSCPNoteTimeout ); 
+                
+                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;
+    
+    // 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 ) );
+        }                                                         
+    }
+    
+// ----------------------------------------------------------------------------
+// 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