remotelock/RemoteLockEngine/Src/RemoteLock.cpp
changeset 0 164170e6151a
child 9 6e226572c5f0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/remotelock/RemoteLockEngine/Src/RemoteLock.cpp	Tue Jan 26 15:20:08 2010 +0200
@@ -0,0 +1,1519 @@
+/*
+* Copyright (c) 2006 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 RemoteLock Engine
+*
+*/
+
+
+// INCLUDE FILES 
+#include <smscmds.h>
+#include <smutset.h>
+#include <smuthdr.h>
+#include <e32property.h>
+#include <PSVariables.h>
+#include <mtclreg.h> //CClientMtmRegistry
+#include <smsclnt.h> //CSmsClientMtm
+#include <txtrich.h>
+#include <bautils.h> //file system utilities
+#include <remotelock.rsg>
+#ifdef RD_MULTIPLE_DRIVE 
+#include <driveinfo.h>
+#else
+#include <pathinfo.h> 
+#endif //RD_MULTIPLE_DRIVE 
+#include <coreapplicationuisdomainpskeys.h>
+#include <charconv.h>
+#include <ProfileEngineSDKCRKeys.h>
+#include <Profile.hrh>
+#include <stringresourcereader.h> //CStringResourceReader
+#include "RemoteLockTrace.h"
+#include "RemoteLock.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES  
+
+// CONSTANTS
+
+_LIT( KRLockResourceFileName ,"z:\\Resource\\apps\\Remotelock.RSC" );
+
+//Interval of reconnecting to the message server 
+const TInt KRLockTimerInterval( 10000000 ); 
+const TInt KRLockMaxMemoryCardPasswdLength( 8 );
+const TInt KBufLengthInUnicodeCheck = 200;
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ---------------------------------------------------------------------------
+// E32Main()
+// ---------------------------------------------------------------------------
+//
+GLDEF_C TInt E32Main() 
+    {    
+    __UHEAP_MARK;
+    if ( User::TrapHandler() != NULL )
+        {
+        User::SetTrapHandler( NULL );
+        }
+        
+    CTrapCleanup* cleanup = CTrapCleanup::New();
+    if ( !cleanup )
+        {
+        return KErrNone;
+        }
+
+    TRAPD( err, ThreadStartL() );
+    ( void ) err;
+    
+    delete cleanup;
+    __UHEAP_MARKEND;
+
+    return err;    
+    }
+
+
+// ---------------------------------------------------------------------------
+// ThreadStartL()
+// ---------------------------------------------------------------------------
+//
+LOCAL_C TInt ThreadStartL()
+    {
+    RL_TRACE_PRINT(" [ rl.exe ] Inside ThreadStartL() "); 
+    CActiveScheduler *threadScheduler = new CActiveScheduler;
+    
+    CleanupStack::PushL( threadScheduler );
+    
+    CActiveScheduler::Install( threadScheduler );
+    
+    RL_TRACE_PRINT(" [ rl.exe ] Create remotelock object "); 
+
+    CRemoteLock* remoteLock = CRemoteLock::NewL();
+    
+    RL_TRACE_PRINT(" [ rl.exe ] Creation of Remotelock is done" );
+    
+    CleanupStack::PushL( remoteLock );
+        
+    RL_TRACE_PRINT(" Doing Rendezvous..."); 
+    // Initialisation complete, now signal the client
+    RProcess::Rendezvous(KErrNone);            
+
+    CActiveScheduler::Start();
+    
+    CleanupStack::PopAndDestroy( 2 );
+    
+    return KErrNone;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CRemoteLock::NewL
+// Two-Phased constructor.
+// ---------------------------------------------------------------------------
+//
+CRemoteLock* CRemoteLock::NewL()
+    {
+    RL_TRACE_PRINT(" [ rl.exe ] NewL()");
+    
+    CRemoteLock* self = new ( ELeave ) CRemoteLock;
+    
+    CleanupStack::PushL( self );
+    
+    self->ConstructL();  
+    
+    CleanupStack::Pop();
+    
+    RL_TRACE_PRINT(" [ rl.exe ] exit NewL() ");
+    
+    return self;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+CRemoteLock::~CRemoteLock()
+    {
+    Cancel();
+    delete iRemoteLockSetting;
+    delete iRemoteLockCode;
+    delete iMemoryCardPasswd;
+    delete iStoredCode;
+    delete iStoredTrimmedCode;
+    delete iClientMtmForSending;
+    delete iMtmReg;
+    delete iMsvSession;
+    delete iObserver;
+    
+    if ( iProfileNotifyHandler ) 
+        {
+      iProfileNotifyHandler->StopListening();
+      delete iProfileNotifyHandler;
+        }
+    delete iProfileSession; 
+    }
+
+
+// ---------------------------------------------------------------------------
+// CRemoteLock::HandleSessionEventL
+//
+// Called by message server when new event occures.
+// ---------------------------------------------------------------------------
+//
+void CRemoteLock::HandleSessionEventL( 
+    TMsvSessionEvent aEvent, 
+    TAny* aArg1, 
+    TAny* aArg2, 
+    TAny* /*aArg3*/  )
+    {
+    RL_TRACE_PRINT(" [ rl.exe ] HandleSessionEventL() ");  
+    switch ( aEvent )
+        {            
+        // A new entry has been created in the message server
+        case EMsvEntriesCreated: 
+            {
+            RL_TRACE_PRINT(" [ rl.exe ] HandleSessionEventL() 1");  
+            if ( !iIsEnabled )
+                {
+                // Do nothing if remote lock is disabled
+                return;
+                }
+            
+            if ( *( static_cast<TMsvId*>( aArg2 ) ) != 
+                KMsvGlobalInBoxIndexEntryId )
+                {
+                // Doing nothing if not to inbox
+                return;
+                }
+
+            CMsvEntrySelection* entries =
+                static_cast<CMsvEntrySelection*>( aArg1 );
+
+            for ( TInt i = 0; i < entries->Count(); i++ )
+                {
+                TMsvEntry entryInfo;
+                TMsvId serviceId;
+                iMsvSession->GetEntry( entries->At( i ), serviceId, entryInfo );
+
+                if ( entryInfo.iMtm != KUidMsgTypeSMS || 
+                    entryInfo.iDescription.Length() > KRLockMaxLockCodeLength || 
+                    entryInfo.iDescription.Length() == 0)
+                    {
+                    // Doing nothing if not a SMS, or length not appropriate.
+                    return;
+                    }
+
+                // For performance reasons, lets first compare the content of 
+                // the SMS (taken from the TMsvEntry, containing no extra 
+                // spaces) against the saved digest of a trimmed remote lock 
+                // code. This way unnecessary access to CMsvEntry is avoided 
+                // if these two do not match.
+                
+                
+                if ( iRemoteLockSetting->CompareLockCodesL( 
+                    entryInfo.iDescription, *iStoredTrimmedCode ) )
+                    {
+                    CMsvEntry* entry = 
+                        iMsvSession->GetEntryL( entries->At( i ) );
+                
+                    // The CMsvEntry object must be deleted by the client
+                    // when it is no longer required. 
+                    CleanupStack::PushL( entry );
+
+                    TRAPD( error, HandleMessageL( entry ) );
+
+                    CleanupStack::PopAndDestroy( 1 ); // entry
+                    
+                    delete iRemoteLockCode;
+                    iRemoteLockCode = NULL;
+                    
+                    User::LeaveIfError( error );
+                    } // if
+                } // for
+            break;
+            } // case
+      
+        // When message server is closed and server terminated
+        case EMsvCloseSession:
+        case EMsvServerFailedToStart:
+        case EMsvServerTerminated:
+            {
+            RL_TRACE_PRINT(" [ rl.exe ] HandleSessionEventL() 2");  
+            // When server is terminated remote lock will
+            // try to reconnect it in every 10 seconds.
+            After( KRLockTimerInterval );
+            break;
+            }
+
+        default:
+            break;
+        }
+    RL_TRACE_PRINT(" [ rl.exe ] exit HandleSessionEventL() ");
+    }
+
+
+// ---------------------------------------------------------------------------
+// CRemoteLock::HandleRemoteLockNotifyL
+// Function is called when remote lock setting is changed by client
+// ---------------------------------------------------------------------------
+//
+void CRemoteLock::HandleRemoteLockNotifyL()
+    {
+    RL_TRACE_PRINT(" [ rl.exe ] HandleNotify() ");
+    CheckSettingsL();
+    RL_TRACE_PRINT(" [ rl.exe ] exit HandleNotify() ")
+    }
+    
+    
+// ---------------------------------------------------------------------------
+// CRemoteLock::CRemoteLock
+// default constructor
+// ---------------------------------------------------------------------------
+CRemoteLock::CRemoteLock() : CTimer( CActive::EPriorityStandard )
+    {
+    iRemoteLockCode = NULL;
+    iMemoryCardPasswd = NULL;
+    iStoredCode = NULL;
+    iStoredTrimmedCode = NULL;
+    iClientMtmForSending = NULL;
+    iMtmReg = NULL;
+    iRemoteLockSetting = NULL;
+    iMsvSession = NULL;
+    iIsEnabled = EFalse;
+    iLockedByRL = EFalse; 
+    iMemoryCardLockedByRL = EFalse;
+    iSubscribeProfile = EFalse;
+    iProfileSession = NULL;
+    iObserver = NULL;
+    iProfileNotifyHandler = NULL;   
+    }
+
+
+// ---------------------------------------------------------------------------
+// CRemoteLock::ConstructL
+// Symbian 2nd phase constructor can leave.
+// ---------------------------------------------------------------------------
+//
+void CRemoteLock::ConstructL()
+    {    
+    RL_TRACE_PRINT(" [ Rl.exe ] ConstructL()"); 
+    
+    CTimer::ConstructL();
+    
+    iRemoteLockSetting = CRemoteLockSettings::NewL( this ); 
+     
+    iRemoteLockSetting->RemoteLockNotifyL( ETrue );
+    
+    CheckSettingsL(); 
+    // Add active object into active scheduler
+    CActiveScheduler::Add( this );
+        
+    
+    
+    RL_TRACE_PRINT(" [ rl.exe ] exit ConstructL() ");
+    }
+    
+    
+// ---------------------------------------------------------------------------
+// CRemoteLock::HandleMessageL()
+//
+// Handles the message: checks if it really is remote lock message, and acts
+// accordingly.
+// ---------------------------------------------------------------------------
+//
+void CRemoteLock::HandleMessageL( CMsvEntry* aEntry )
+    {
+    RL_TRACE_PRINT(" [ rl.exe ] HandleMessageL() ");
+    delete iRemoteLockCode;
+    iRemoteLockCode = NULL;
+    TMsvEntry entryInfo = aEntry->Entry();
+    if ( !iMtmReg )
+        {
+        iMtmReg = CClientMtmRegistry::NewL( *iMsvSession );
+        }
+
+    // Loops 100 times to ensure the clientMtm is correctly created
+    CBaseMtm* clientMtm = NULL;
+    TInt error = 0;
+    TInt i;
+    for ( i = 0; i < 100; i++ )
+        {
+        TRAP( error, clientMtm = iMtmReg->NewMtmL( entryInfo.iMtm ));
+        if ( error == KErrNone )
+            {
+            break;
+            }
+        } 
+   
+    RL_TRACE_PRINT_NUM("[rl.exe] HandleMessageL() error after NewMTmL = %d", error );
+
+    User::LeaveIfError( error );
+    CleanupStack::PushL( clientMtm );        
+
+    clientMtm->SwitchCurrentEntryL( entryInfo.Id() );
+
+    RL_TRACE_PRINT(" [ rl.exe ] HandleMessageL() after switch Current EntryL");
+   
+    CSmsClientMtm* smsClientMTM = STATIC_CAST( CSmsClientMtm*, clientMtm );
+    
+    // Change from 100 to 20. When the message storage is memory card. 
+    // LoadMessageL() function return -21 when loading the message.
+    // It might be caused by slow operation, so we add 0.05 seconds pending 
+    // in each loop.
+    // @ check why loading operation is slow!
+    for ( i = 0; i < 20; i++ )
+        {   
+        RL_TRACE_PRINT_NUM("[rl.exe] HandleMessageL() error load message1 = %d", error );
+        
+        // Loops 100 times to ensure the LoadMessageL() succeedes
+        TRAP( error, smsClientMTM->LoadMessageL() );
+        
+        RL_TRACE_PRINT_NUM("[rl.exe] HandleMessageL() error load message2 = %d", error );
+        
+        if ( error == KErrNone )
+            {
+            break;
+            }
+        
+        const TInt KDelay = 50000; // 0.05s
+        User::After( KDelay );
+        }
+    
+    RL_TRACE_PRINT_NUM("[rl.exe] HandleMessageL() error after LoadMessageL = %d", error );
+    
+    User::LeaveIfError( error );        
+
+    CRichText& mtmBody = smsClientMTM->Body();                            
+    
+    // Let's then use the real content of the SMS (taken from 
+    // the message body) and compare that against the 
+    // saved digest of a complete (not trimmed) remote lock 
+    // code. This ensures that remote locking happens only
+    // if the SMS is exactly the same as what the user has 
+    // specified.
+    iRemoteLockCode = HBufC::NewL( mtmBody.DocumentLength() );
+
+    TPtr smsTextPtr = iRemoteLockCode->Des();
+    smsTextPtr.Copy( mtmBody.Read( 0, mtmBody.DocumentLength() ) );
+    
+    
+    // The following code is to get the current state
+    // of manuallock. If manuallock state is off, that means
+    // the owner has unlocked the phone or the phone has
+    // never been locked by both remote lock and auto lock.
+    RL_TRACE_PRINT(" [ rl.exe ] HandleMessageL() Pub&Sub Get autoLState");    
+    TInt autoLState;
+    RProperty property;
+    
+    #ifndef RD_STARTUP_CHANGE    
+    User::LeaveIfError( property.Attach( KUidSystemCategory, KPSUidAutolockStatusValue ));
+    #else
+    User::LeaveIfError( property.Attach( KPSUidCoreApplicationUIs, KCoreAppUIsAutolockStatus ));
+    #endif //RD_STARTUP_CHANGE
+    property.Get( autoLState );
+    
+    #ifndef RD_STARTUP_CHANGE
+    if ( autoLState == EPSAutolockOff ) 
+    #else
+    if ( autoLState == EAutolockOff ) 
+    #endif //RD_STARTUP_CHANGE      
+      {  
+      //Assign iLockedByRL to EFalse to indicate that
+      //the phone is not locked by Remote lock, the 
+      //reply SMS should be sent if correct remote lock
+      //code is received.
+      iLockedByRL = EFalse;
+      }
+    
+    property.Close();
+    
+    // If the phone receives correct lock code, the phone
+    // will be locked eventhough it may have been locked by
+    // auto lock.
+  
+    if ( VerifyAndLockL() ) 
+        {
+        RL_TRACE_PRINT(" [ rl.exe ] HandleMessageL() After VerifyAndLockL() ");
+        // Sets remote lock sms as read
+        entryInfo.SetVisible( ETrue );
+        entryInfo.SetUnread( EFalse );
+        entryInfo.SetNew( EFalse );
+        entryInfo.SetInPreparation( EFalse );
+        entryInfo.SetReadOnly( ETrue );
+        aEntry->ChangeL( entryInfo );
+        
+        
+        // Locks MemoryCard drive.
+        iStateMemoryCard = SetMemoryCardPasswdL( EFalse );
+
+        if ( iClientMtmForSending )
+            {
+            // Previous reply sending is still in progress, let's not start 
+            // sending new one.
+            User::Leave( KErrNone );
+            } 
+        
+        // The value of iLockedByRL is checked before sending SMS
+        // to make sure if the phone has been locked by remote 
+        // lock. By doing this, it is able to avoid the threat where 
+        // malware tries to use remote lock to keep on sending SMS.
+        
+        
+        if ( !iLockedByRL )
+            { 
+            RL_TRACE_PRINT(" [ rl.exe ] HandleMessageL() Send re-SMS ");
+            // Replies sms
+            iLockedByRL = ETrue;
+            CSmsHeader& header = smsClientMTM->SmsHeader();
+            HBufC* recipientAddress = header.FromAddress().AllocLC();
+
+            TBool initialSendMessage = EFalse;
+            TRAP( error, initialSendMessage = InitialSendMessageL() );
+            if ( error != KErrNone )
+                {
+                delete iClientMtmForSending;
+                iClientMtmForSending = NULL;
+                User::Leave( error );
+                }
+                
+            RL_TRACE_PRINT(" [ rl.exe ] HandleMessageL() Check recipientaddresslenght ");
+            if ( recipientAddress->Length() > 0 && initialSendMessage )
+                {
+                RL_TRACE_PRINT(" [ rl.exe ] HandleMessageL() before call sendMEssage ");
+                TRAP( error, SendMessageL( *recipientAddress ) );
+                if ( error != KErrNone )
+                    {
+                    RL_TRACE_PRINT(" [ rl.exe ] HandleMessageL() error occurs ");
+                    delete iClientMtmForSending;
+                    iClientMtmForSending = NULL;
+                    User::Leave( error );
+                    }
+                }
+            delete iClientMtmForSending;
+            iClientMtmForSending = NULL;
+
+            CleanupStack::PopAndDestroy( 1 ); // recipientAddress
+            }
+        CleanupStack::PopAndDestroy( 1 ); // clientMtm    
+        }
+    else
+        {
+        CleanupStack::PopAndDestroy( 1 ); // clientMtm
+        }
+    RL_TRACE_PRINT(" [ rl.exe ] exit HandleMessageL() ");
+    }
+
+
+// ---------------------------------------------------------------------------
+// CRemoteLock::VerifyAndLockL()
+//
+// Compares if the remote lock received in SMS is correct.
+// If correct, locks the terminal.
+// ---------------------------------------------------------------------------
+//
+TBool CRemoteLock::VerifyAndLockL()
+    {
+    RL_TRACE_PRINT(" [ rl.exe ] VerifyAndLockL() ");
+    
+    User::LeaveIfNull( iRemoteLockCode );
+    User::LeaveIfNull( iStoredCode );
+
+    if ( iRemoteLockSetting->CompareLockCodesL( 
+        *iRemoteLockCode, *iStoredCode ) )
+        {        
+        return ActivateDeviceLock();
+        }
+    RL_TRACE_PRINT(" [ rl.exe ] exit VerifyAndLockL() ");
+    return EFalse;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CRemoteLock::ActivateDeviceLock()
+// Activate the device lock to lock the phone
+// ---------------------------------------------------------------------------
+// 
+TBool CRemoteLock::ActivateDeviceLock()
+    {
+    RL_TRACE_PRINT(" [ rl.exe ] ActivateDeviceLock() ");
+       
+    RProperty property;
+        
+    TInt err = 0;
+       
+    #ifndef RD_STARTUP_CHANGE
+    err = property.Attach( KUidSystemCategory, 
+                               KPSUidAutolockStatusValue );
+    #else
+    err = property.Attach( KPSUidCoreApplicationUIs, 
+                               KCoreAppUIsAutolockStatus );
+    #endif 
+    if ( err != KErrNone )
+        {
+        return EFalse;
+        }
+
+    #ifndef RD_STARTUP_CHANGE
+    property.Set( EPSRemoteLocked );
+    #else
+    property.Set( ERemoteLocked );
+    #endif //RD_STARTUP_CHANGE 
+ 
+    property.Close();
+    RL_TRACE_PRINT(" [ rl.exe ] exit ActivateDeviceLock() ");
+    return ETrue;
+    }
+
+
+
+// ---------------------------------------------------------------------------
+// CRemoteLock::CheckSettingsL
+// Checks remote lock setting.
+// ---------------------------------------------------------------------------
+//
+void CRemoteLock::CheckSettingsL()
+    {
+    RL_TRACE_PRINT(" [ rl.exe ] CheckSettingsL () "); 
+    iRemoteLockSetting->GetEnabled( iIsEnabled );
+    
+    delete iStoredCode;
+    iStoredCode = NULL;
+    iStoredCode = HBufC::NewL( KRLockStoredLockCodeLength );
+    TPtr storedCodePtr = iStoredCode->Des();
+    
+    delete iStoredTrimmedCode;
+    iStoredTrimmedCode = NULL;
+    iStoredTrimmedCode = HBufC::NewL( KRLockStoredLockCodeLength );
+    TPtr storedTrimmedCodePtr = iStoredTrimmedCode->Des();
+    
+    iRemoteLockSetting->GetLockCode( storedCodePtr, storedTrimmedCodePtr );
+        
+    if ( iIsEnabled )
+        {
+        RL_TRACE_PRINT(" [ rl.exe ] CheckSettingsL() enable "); 
+       
+        if ( !iMsvSession )
+            {
+            TRAPD( error, iMsvSession = CMsvSession::OpenAsyncL( *this ) );
+        
+            RL_TRACE_PRINT_NUM(" [ rl.exe ] CheckSettingsL() openasyncL %d ", error );
+        
+            if ( error != KErrNone )
+                {
+                After( KRLockTimerInterval );
+                }  
+            }
+
+       if ( !iProfileSession )
+           {
+           RL_TRACE_PRINT(" [ rl.exe ] CheckSettingsL() create session "); 
+           iProfileSession = CRepository::NewL( KCRUidProfileEngine ); 
+           }
+       if ( !iObserver )
+           {
+           iObserver =  CRLLockObserver::NewL( this );      
+           } 
+       if( !iSubscribeProfile )
+           {
+           ProfileNotifyL( ETrue );
+           iSubscribeProfile = ETrue; 
+           }   
+        }
+    else
+        {
+        RL_TRACE_PRINT(" [ rl.exe ] CheckSettingsL() disable "); 
+        
+        delete iClientMtmForSending;
+        iClientMtmForSending = NULL;
+        delete iMtmReg;
+        iMtmReg = NULL;
+        delete iMsvSession;
+        iMsvSession = NULL;
+        
+        RL_TRACE_PRINT(" [ rl.exe ] CheckSettingsL() delete iMsvSession ");
+        
+        if ( iSubscribeProfile )
+            {
+            if ( !iProfileSession )
+                {
+                RL_TRACE_PRINT(" [ rl.exe ] CheckSettingsL() create session "); 
+                iProfileSession = CRepository::NewL( KCRUidProfileEngine ); 
+                }
+            ProfileNotifyL( EFalse );
+            delete iProfileSession;
+            iProfileSession = NULL;
+            delete iObserver;
+            iObserver = NULL; 
+            iSubscribeProfile = EFalse;
+            }  
+        }   
+    
+    RL_TRACE_PRINT(" [ rl.exe ] exit CheckSettingsL() ");
+    }
+    
+
+// ---------------------------------------------------------------------------
+// CRemoteLock::IsMemoryCardLocked
+// Check MemoryCard whether it is locked or not.
+// ---------------------------------------------------------------------------
+//
+TBool CRemoteLock::IsMemoryCardLocked( const TDriveInfo& aDriveInfo ) const
+    {
+    return aDriveInfo.iMediaAtt&( KMediaAttLocked );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CRemoteLock::HasMemoryCardPassword
+// Check MemoryCard whether it has password.
+// ---------------------------------------------------------------------------
+//
+TBool CRemoteLock::HasMemoryCardPassword( const TDriveInfo& aDriveInfo ) const
+    {
+    return aDriveInfo.iMediaAtt&( KMediaAttHasPassword );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CRemoteLock::IsMemoryCardPresent
+// Check MemoryCard whether it is mounted into the phone and it supports locking.
+// ---------------------------------------------------------------------------
+//
+TBool CRemoteLock::IsMemoryCardPresent( const TDriveInfo& aDriveInfo ) const
+    {
+    return aDriveInfo.iDriveAtt&( KDriveAttRemovable ) && 
+        aDriveInfo.iMediaAtt&( KMediaAttLockable );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CRemoteLock::SetMemoryCardPasswdL
+// Sets/remove the password to MemoryCard.
+// ---------------------------------------------------------------------------
+//
+TBool CRemoteLock::SetMemoryCardPasswdL( const TBool aClear )
+    {
+    RL_TRACE_PRINT(" [ rl.exe ] SetMemoryCardPasswdL() ");
+    if ( aClear )
+        {
+        if ( iMemoryCardLockedByRL && iLockedByRL )
+            {
+            //remove the password
+            if ( DoSetMemoryCardPasswdL( ETrue ) )
+                {
+                iMemoryCardLockedByRL = EFalse;
+                RL_TRACE_PRINT(" [ rl.exe ] exit SetMemoryCardPasswdL() ");    
+                return ETrue;   
+                }
+            else
+                {
+                //Only try to remove password once no matter success or not 
+                iMemoryCardLockedByRL = EFalse; 
+              }    
+             
+            }       
+        }
+    else
+        {
+        if ( iMemoryCardLockedByRL )
+            {
+            //the memory card is locked already by rlock, 
+            //just return ETrue;
+            return ETrue;
+            }
+        
+        if ( !iRemoteLockCode || iRemoteLockCode->Length() == 0 )
+            {
+            return EFalse;
+            }
+        //Change the password
+        if ( DoSetMemoryCardPasswdL( EFalse ) )
+            {
+            iMemoryCardLockedByRL = ETrue;
+            RL_TRACE_PRINT(" [ rl.exe ] exit SetMemoryCardPasswdL() ");    
+            return ETrue; 
+            }
+           
+        }
+    RL_TRACE_PRINT(" [ rl.exe ] exit SetMemoryCardPasswdL() ");    
+    return EFalse;
+    }   
+
+// ---------------------------------------------------------------------------
+// CRemoteLock::DoSetMemoryCardPasswdL
+// Do Sets/remove the password to MemoryCard.
+// ---------------------------------------------------------------------------
+//
+TBool CRemoteLock::DoSetMemoryCardPasswdL( TBool aClear )
+    {
+    RL_TRACE_PRINT(" [ rl.exe ] DoSetMemoryCardPasswdL() ");
+    RFs fsMemoryCard;
+    TInt err = fsMemoryCard.Connect();
+    if ( err != KErrNone )
+        {
+        RL_TRACE_PRINT(" [ rl.exe ] DoSetMemoryCardPasswdL() error");
+        return EFalse;
+        }
+         
+#ifdef RD_MULTIPLE_DRIVE 
+
+   // Get the removeable user visible drives
+   TDriveList driveList;
+   TInt driveCount;
+   
+   //Get all removeable drive, both physically and logically
+   User::LeaveIfError( DriveInfo::GetUserVisibleDrives(
+       fsMemoryCard, driveList, driveCount, KDriveAttRemovable ) );   
+   RL_TRACE_PRINT_NUM(" [ rl.exe ] DoSetMemoryCardPasswdL() driveCount = %d ", driveCount );
+ 
+   //boolen to indicate at least one operation(clear/add password) 
+   // in the loop is ok.
+   TBool OperationSucceed = EFalse;
+  
+   RArray<TInt> arrayMemoryCardIndex;
+  
+   TInt max( driveList.Length() );
+   
+   for ( TInt i = 0; i < max; i++ )
+       {
+       if ( driveList[ i ] )
+          {
+          TUint status;	
+          DriveInfo::GetDriveStatus( fsMemoryCard, i, status );	
+          //To make sure the drive is physically removeable not logically removeable	
+          if( status & DriveInfo::EDriveRemovable )	
+              {
+              //append all physical removable memory card index into this array	
+              arrayMemoryCardIndex.Append(i); 
+              RL_TRACE_PRINT_NUM(" [ rl.exe ] DoSetMemoryCardPasswdL() physically removable drive %d", i );
+		          }
+		      else
+		          {
+		          RL_TRACE_PRINT_NUM(" [ rl.exe ] DoSetMemoryCardPasswdL() logically removable drive %d", i );
+		          }    
+		      }    
+       }
+      
+   //Lock/Unblock all physical removeable memory card
+   for ( TInt i = 0; i < arrayMemoryCardIndex.Count(); i++ )
+       {
+       TDriveInfo driveInfoT;
+       TInt driveIndex = arrayMemoryCardIndex[i];
+       RL_TRACE_PRINT_NUM(" [ rl.exe ] DoSetMemoryCardPasswdL() driveIndex %d", driveIndex );	
+       fsMemoryCard.Drive( driveInfoT, driveIndex );
+    
+       if ( IsMemoryCardPresent( driveInfoT ) ) 
+          {
+          	RL_TRACE_PRINT(" [ rl.exe ] Memory card is present");
+          if ( aClear )
+              {
+              RL_TRACE_PRINT(" [ rl.exe ] DoSetMemoryCardPasswdL() Remove password");	
+              if ( HasMemoryCardPassword( driveInfoT ) || IsMemoryCardLocked( driveInfoT ) ) 
+                  { 
+                  TMediaPassword memoryCardPassword; 
+              
+                  // Converts MemoryCardpassword
+                  ConvertMemoryCardPassword( memoryCardPassword, ETrue  );
+              
+                  err = fsMemoryCard.ClearPassword( driveIndex, memoryCardPassword );
+              
+                  if ( err == KErrNone )
+                      {
+                  	  OperationSucceed = ETrue;
+                      }
+              
+                  RL_TRACE_PRINT_NUM(" [ rl.exe ] exit DoSetMemoryCardPasswdL() password for index %d is cleaned", driveIndex);
+                  //Go for next
+                  }
+              else
+                  {
+                  //Go for next
+                  }      
+               }
+            else
+               {
+               RL_TRACE_PRINT(" [ rl.exe ] DoSetMemoryCardPasswdL() Set password");
+               if ( !HasMemoryCardPassword( driveInfoT ) && !IsMemoryCardLocked( driveInfoT ) )
+                   { 
+                   TMediaPassword memoryCardPassword;
+                
+                   TMediaPassword nullMemoryCardPassword;
+                
+                   // Converts MemoryCardpassword
+                   ConvertMemoryCardPassword( memoryCardPassword, EFalse );
+                
+                   // Locks MemoryCard drive
+                   err = fsMemoryCard.LockDrive( driveIndex, nullMemoryCardPassword, memoryCardPassword, ETrue );        
+                
+                   if ( err == KErrNone )
+                      {
+                  	  OperationSucceed = ETrue;
+                      }
+                
+                   RL_TRACE_PRINT_NUM(" [ rl.exe ] DoSetMemoryCardPasswdL() password for index %d is set", driveIndex);
+                   
+                   //Go for next
+                   }
+                else
+                   {
+                   //go for next
+                   }   
+               }
+            } //if ( IsMemoryCardPresent( driveInfoT ) ) 
+         } //for
+    
+     
+     if ( aClear )
+         {
+     	   delete iMemoryCardPasswd; 
+         iMemoryCardPasswd = NULL; 
+         fsMemoryCard.Close(); 
+         
+         return OperationSucceed ? ETrue : EFalse;
+         }
+     else 
+        {
+
+        delete iMemoryCardPasswd;
+        iMemoryCardPasswd = NULL; 
+        iMemoryCardPasswd = iRemoteLockCode->AllocL();
+        fsMemoryCard.Close();	
+        
+        return OperationSucceed ? ETrue : EFalse;
+        }       
+#else
+    
+    TInt i = 0;
+    TParsePtrC folder( PathInfo::MemoryCardRootPath() );
+    fsMemoryCard.CharToDrive( folder.Drive()[ 0 ], i );
+      
+    TDriveInfo driveInfoT;
+    fsMemoryCard.Drive( driveInfoT, i );
+    
+    if ( IsMemoryCardPresent( driveInfoT ) ) 
+      {
+      if ( aClear )
+          {
+          if ( HasMemoryCardPassword( driveInfoT ) || IsMemoryCardLocked( driveInfoT ) ) 
+              { 
+              TMediaPassword memoryCardPassword; 
+              // Converts MemoryCardpassword
+              ConvertMemoryCardPassword( memoryCardPassword, ETrue  );
+              err = fsMemoryCard.ClearPassword( i, memoryCardPassword );
+              
+              if( err == KErrNone )
+                  {
+                  delete iMemoryCardPasswd; 
+                  iMemoryCardPasswd = NULL; 
+                  }
+              fsMemoryCard.Close(); 
+              RL_TRACE_PRINT(" [ rl.exe ] exit DoSetMemoryCardPasswdL() clear");
+              return ( err == KErrNone );
+              }
+          else
+              {
+              fsMemoryCard.Close();  
+              return ETrue;
+              }      
+           }
+        else
+           {
+           if ( !HasMemoryCardPassword( driveInfoT ) && !IsMemoryCardLocked( driveInfoT ) )
+                { 
+                TMediaPassword memoryCardPassword;
+                TMediaPassword nullMemoryCardPassword;
+                // Converts MemoryCardpassword
+                ConvertMemoryCardPassword( memoryCardPassword, EFalse );
+                // Locks MemoryCard drive
+                err = fsMemoryCard.LockDrive( i, nullMemoryCardPassword, memoryCardPassword, ETrue );        
+                if ( err == KErrNone )
+                    {
+                    if ( iMemoryCardPasswd )
+                          {
+                          delete iMemoryCardPasswd;
+                          iMemoryCardPasswd = NULL; 
+                          }
+                     iMemoryCardPasswd = iRemoteLockCode->AllocL();
+                     }
+          
+                fsMemoryCard.Close();
+                RL_TRACE_PRINT(" [ rl.exe ] exit DoSetMemoryCardPasswdL() change");
+                return ( err == KErrNone );  
+                }
+            else
+                {
+                fsMemoryCard.Close();  
+                return EFalse;
+                }   
+            }
+        }    
+    fsMemoryCard.Close();
+    return EFalse;  
+    
+#endif //RD_MULTIPLE_DRIVE       
+    }
+
+// ---------------------------------------------------------------------------
+// CRemoteLock::ConvertMemoryCardPasswordL
+// Converts MemoryCardPassword to acceptable format.
+// ---------------------------------------------------------------------------
+//
+void CRemoteLock::ConvertMemoryCardPassword( TMediaPassword& aPassword, const TBool aClear ) 
+    {
+    RL_TRACE_PRINT(" [ rl.exe ] ConvertMemoryCardPassword() ");
+    
+    TBuf16 < KMaxMediaPassword / 2 > memoryCardPassword; 
+    // Takes left most 8 digits of lockcode as
+    // the password of MemoryCard.
+    RL_TRACE_PRINT(" [ rl.exe ] ConvertMemoryCardPassword() 1");
+    
+    if ( aClear )
+        {
+        if ( iMemoryCardPasswd )
+           {
+           memoryCardPassword.Copy( iMemoryCardPasswd->Left( KRLockMaxMemoryCardPasswdLength ) );
+           }
+        }
+     else
+        {
+        if ( iRemoteLockCode )
+            {
+            memoryCardPassword.Copy( iRemoteLockCode->Left( KRLockMaxMemoryCardPasswdLength ) );
+            }
+        } 
+  
+    // Fills the descriptor's data area with binary zeroes, i.e. 0x00, 
+    // replacing any existing data.
+    RL_TRACE_PRINT(" [ rl.exe ] ConvertMemoryCardPassword() 2");
+    aPassword.FillZ( KMaxMediaPassword ); 
+
+    aPassword.Zero();
+    // Sets the length of the data to zero.
+    // Copies data into this descriptor replacing any existing data. 
+    // The length of this descriptor is set to reflect the new data
+    RL_TRACE_PRINT(" [ rl.exe ] ConvertMemoryCardPassword() 3");
+    aPassword.Copy( reinterpret_cast<TUint8 *>
+        ( &memoryCardPassword[ 0 ] ), memoryCardPassword.Length() * 2 );
+        
+    RL_TRACE_PRINT(" [ rl.exe ] ConvertMemoryCardPassword() over ");    
+    }
+  
+  
+// ---------------------------------------------------------------------------
+// CRemoteLock::InitialSendMessageL
+// Reply SMS when the terminal is successfully locked.
+// ---------------------------------------------------------------------------
+//
+TBool CRemoteLock::InitialSendMessageL()
+    {
+    RL_TRACE_PRINT(" [ rl.exe ] InitialSendMessageL() ");
+    
+    RProperty property;
+    
+    TInt err = 0;
+     
+    #ifndef RD_STARTUP_CHANGE        
+    err = property.Attach( KUidSystemCategory, KPSUidAutolockStatusValue );              
+    #else
+    err = property.Attach( KPSUidCoreApplicationUIs, KCoreAppUIsAutolockStatus );
+    #endif
+    
+    if ( err != KErrNone )
+        {
+      return EFalse;
+        }
+    
+    TInt state = 0;
+    
+    CleanupClosePushL( property );
+    
+    err = property.Get( state );
+    if ( err != KErrNone )
+        {
+      CleanupStack::PopAndDestroy( 1 );
+        return EFalse;
+        }
+         
+    #ifndef RD_STARTUP_CHANGE
+    if ( state  == EPSRemoteLocked )
+    #else
+    if ( state == ERemoteLocked )
+    #endif // RD_STARTUP_CHANGE 
+      {
+      // message server entry id
+      TMsvId msvId = NULL;
+      // Set up a new message
+      msvId = CreateNewMessageL();
+      //Set the new message to be the current entry
+      SetEntryL( msvId );
+      CleanupStack::PopAndDestroy( 1 ); // property
+      RL_TRACE_PRINT(" [ rl.exe ] exit InitialSendMessageL() ETrue "); 
+      return ETrue; 
+      }
+    CleanupStack::PopAndDestroy( 1 ); // property   
+    RL_TRACE_PRINT(" [ rl.exe ] exit InitialSendMessageL() "); 
+    return EFalse;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CRemoteLock::CreateNewMessageL()
+// Creates a new message server entry and set up default values.
+// Return values:      TMsvId (the id of created entry)
+// ---------------------------------------------------------------------------
+//
+TMsvId CRemoteLock::CreateNewMessageL()
+    {
+    RL_TRACE_PRINT(" [ rl.exe ] CreateNewMessageL() ");
+    TMsvEntry newEntry;
+    // The type of message is SMS
+    newEntry.iMtm = KUidMsgTypeSMS;
+    // The type of the entry: message
+    newEntry.iType = KUidMsvMessageEntry;                    
+    newEntry.iServiceId = KMsvLocalServiceIndexEntryId;
+    // Set the date of the entry to home time
+    newEntry.iDate.UniversalTime();                           
+    newEntry.SetInPreparation( ETrue );                      
+
+    CMsvEntry* entry = CMsvEntry::NewL( *iMsvSession, 
+        KMsvDraftEntryIdValue, TMsvSelectionOrdering() );
+    CleanupStack::PushL( entry );
+    CMsvOperationWait* wait = CMsvOperationWait::NewLC();
+    wait->Start();    
+
+    // Asynchronously create a new entry.    
+    CMsvOperation* oper = entry->CreateL( newEntry, wait->iStatus );
+    CleanupStack::PushL( oper );
+
+    CActiveScheduler::Start();
+
+    // Keep track of the progress of the create operation.
+    TMsvLocalOperationProgress progress = 
+        McliUtils::GetLocalProgressL( *oper );
+    User::LeaveIfError( progress.iError );
+
+    // Set entry context to the created one
+    // operation progress contains the ID of the created entry
+    entry->SetEntryL( progress.iId ); 
+
+    CleanupStack::PopAndDestroy( 3 );
+    RL_TRACE_PRINT(" [ rl.exe ] CreateNewMessageL() end ");
+    return progress.iId;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CRemoteLock::SetEntryL(TMsvId aEntryId)
+// Set up current message entry.
+// Note: It can be useful to remember the original entry id for 
+//       error handling.
+// ---------------------------------------------------------------------------
+//
+void CRemoteLock::SetEntryL( TMsvId aEntryId )
+    {
+    RL_TRACE_PRINT(" [ rl.exe ] SetEntryL() ");
+    // Get the server entry from our session
+    CMsvEntry* entry = iMsvSession->GetEntryL( aEntryId );
+    CleanupStack::PushL( entry );
+    delete iClientMtmForSending;
+    iClientMtmForSending = NULL;
+    
+    TInt error;
+    TInt i;
+    for ( i = 0; i < 100; i++ )
+        {
+        TRAP( error, 
+            iClientMtmForSending = iMtmReg->NewMtmL( entry->Entry().iMtm ) );
+        if ( error == KErrNone )
+            {
+             RL_TRACE_PRINT(" [ rl.exe ] SetEntryL() iClientMtmForSending ");
+            break;
+            }
+        } 
+
+    User::LeaveIfError( error );
+    iClientMtmForSending->SetCurrentEntryL( entry );
+
+    CleanupStack::Pop( 1 ); // entry
+    RL_TRACE_PRINT(" [ rl.exe ] exit SetEntryL() ");
+    entry = NULL;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CRemoteLock::MoveMessageEntryL(TMsvId aTarget) const
+// Moves an entry to another parent.
+// Return values:      TMsvId of the moved message
+// ---------------------------------------------------------------------------
+//
+TMsvId CRemoteLock::MoveMessageEntryL( TMsvId aTarget )
+    {
+    User::LeaveIfNull( iClientMtmForSending );
+    TMsvEntry msvEntry( ( iClientMtmForSending->Entry() ).Entry() );
+    TMsvId id = msvEntry.Id();
+
+    if ( msvEntry.Parent() != aTarget )
+        {
+        TMsvSelectionOrdering sort;
+        sort.SetShowInvisibleEntries( ETrue );    
+        // Take a handle to the parent entry
+        CMsvEntry* parentEntry = 
+            CMsvEntry::NewL( 
+            iClientMtmForSending->Session(), msvEntry.Parent(), sort );
+
+        CleanupStack::PushL( parentEntry );
+    
+        // Move original from the parent to the new location
+        CMsvOperationWait* wait = CMsvOperationWait::NewLC();
+        wait->Start();
+    
+        CMsvOperation* op = 
+                parentEntry->MoveL( msvEntry.Id(), aTarget, wait->iStatus );
+
+        CleanupStack::PushL( op );
+        CActiveScheduler::Start();     
+        TMsvLocalOperationProgress prog=McliUtils::GetLocalProgressL( *op );
+        User::LeaveIfError(prog.iError);
+    
+        id = prog.iId; 
+        CleanupStack::PopAndDestroy( 3 ); // op, wait, parentEntry
+        }
+    return id;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CRemoteLock::SendMessageL
+// Reply SMS when the terminal is successfully locked.
+// Return values:      ETrue or EFalse
+// ---------------------------------------------------------------------------
+//
+TBool CRemoteLock::SendMessageL( const TDesC& aRecipientAddress )
+    {
+    RL_TRACE_PRINT(" [ rl.exe ] SendMessageL() ");
+    
+    User::LeaveIfNull( iClientMtmForSending );
+    
+    RL_TRACE_PRINT(" [ rl.exe ] SendMessageL() 1 ");
+    
+    TMsvEntry msvEntry = ( iClientMtmForSending->Entry() ).Entry();
+
+    // We get the message body from Mtm and insert a bodytext
+    CRichText& mtmBody = iClientMtmForSending->Body();
+    mtmBody.Reset();
+    
+    TFileName fileName; 
+    fileName = KRLockResourceFileName;
+
+    // Use CStringResourceReader instead of StringLoader
+    // StringLoader is meant for applications in app framework   
+    CStringResourceReader* resourceReader = CStringResourceReader::NewLC( fileName );
+
+    RL_TRACE_PRINT(" [ rl.exe ] SendMessageL() 3");
+    
+    HBufC* retBuf = NULL;
+
+    if ( iStateMemoryCard )
+        {
+        RL_TRACE_PRINT(" [ rl.exe ] SendMessageL() memory card locked");
+        // When memory card is locked.
+        TPtrC buf;
+        buf.Set( resourceReader->ReadResourceString(R_RLOC_TI_EVERYTHING_LOCKED) );
+        retBuf = buf.AllocLC();
+        }
+    else
+        {
+        RL_TRACE_PRINT(" [ rl.exe ] SendMessageL() only phone locked ");
+        TPtrC buf;
+        buf.Set( resourceReader->ReadResourceString(R_RLOC_TI_PHONE_LOCKED) );
+        retBuf = buf.AllocLC();
+        }
+    mtmBody.InsertL( 0, *retBuf );
+    msvEntry.iDescription.Set( *retBuf );
+     
+    // Set aRecipientAddress into the Details of the entry
+    msvEntry.iDetails.Set( aRecipientAddress );  
+    msvEntry.SetInPreparation( EFalse );         
+    
+    // Set the sending state (immediately)
+    msvEntry.SetSendingState( KMsvSendStateWaiting );                         
+    msvEntry.iDate.UniversalTime();   
+    // To handle the sms specifics we start using SmsMtm
+    CSmsClientMtm* smsMtm = STATIC_CAST( CSmsClientMtm*, 
+                                         iClientMtmForSending );
+    smsMtm->RestoreServiceAndSettingsL();
+
+    // SMS MTM encapsulation of an SMS message.
+    CSmsHeader& header = smsMtm->SmsHeader();
+    CSmsSettings* sendOptions = CSmsSettings::NewL();
+    CleanupStack::PushL( sendOptions );
+    // Reset existing settings
+    sendOptions->CopyL( smsMtm->ServiceSettings() ); 
+    // Set unicode if needed
+    if ( NeedsToBeSentAsUnicodeL( retBuf->Des() ))
+        {
+        sendOptions->SetCharacterSet( TSmsDataCodingScheme::ESmsAlphabetUCS2 );
+        }
+    // Set send options to be delivered immediately
+    sendOptions->SetDelivery( ESmsDeliveryImmediately );      
+    header.SetSmsSettingsL( *sendOptions );
+    
+    // let's check if there's sc address
+    if (header.Message().ServiceCenterAddress().Length() == 0)
+        {
+        // no, there isn't. Use the default SC number. 
+        CSmsSettings* serviceSettings = NULL;
+        serviceSettings = &( smsMtm->ServiceSettings() );
+        
+        RL_TRACE_PRINT(" [ rl.exe ] SendMessageL() Get SC number ");    
+        if ( serviceSettings->ServiceCenterCount() )
+            {
+            //Set sc address to default.
+            CSmsServiceCenter& sc = serviceSettings->GetServiceCenter(
+                serviceSettings->DefaultServiceCenter() );
+            header.Message().SetServiceCenterAddressL( sc.Address() );
+            }
+        }
+    
+    // Add recipient to the list.
+    smsMtm->AddAddresseeL( aRecipientAddress, msvEntry.iDetails );
+
+    CMsvEntry& entry = iClientMtmForSending->Entry();
+    entry.ChangeL( msvEntry );                
+    smsMtm->SaveMessageL();                 
+
+    // Move message to outbox
+    TMsvId movedId;
+    TInt err;
+    for ( TInt i = 0; i < 100; i++ )
+        {
+        TRAP( err, movedId = MoveMessageEntryL( 
+                                 KMsvGlobalOutBoxIndexEntryId ));  
+        if ( err == KErrNone )
+            break;
+        }
+    RL_TRACE_PRINT(" [ rl.exe ] SendMessageL() put created message in outbox ");
+    User::LeaveIfError( err );
+    // We must create an entry selection for message copies 
+    CMsvEntrySelection* selection = new ( ELeave ) CMsvEntrySelection;
+    CleanupStack::PushL( selection );
+    selection->AppendL( movedId );        
+    // schedule the sending with the active scheduler
+    SetScheduledSendingStateL( selection );   
+    CleanupStack::PopAndDestroy( 4 ); // resourceReader,retbuf,sendOptions,selection 
+    RL_TRACE_PRINT(" [ rl.exe ] Exit SendMessageL() ");
+    return ETrue; 
+    }
+
+
+// ---------------------------------------------------------------------------
+// CRemoteLock::SetScheduledSendingStateL
+// Schedules the message to be sent through the etel server.
+// Return values:      none
+// ---------------------------------------------------------------------------
+//
+void CRemoteLock::SetScheduledSendingStateL( CMsvEntrySelection* aSelection )
+    {
+    User::LeaveIfNull( iClientMtmForSending );
+    // Add entry to task scheduler
+    TBuf8<1> dummyParams;
+    CMsvOperationWait* waiter = CMsvOperationWait::NewLC();
+    waiter->Start();
+
+    // invoking async schedule copy command on our mtm
+    CMsvOperation* op= iClientMtmForSending->InvokeAsyncFunctionL(
+            ESmsMtmCommandScheduleCopy,
+            *aSelection,
+            dummyParams,
+            waiter->iStatus );
+
+    CleanupStack::PushL( op );
+    CActiveScheduler::Start();
+
+    CleanupStack::PopAndDestroy( 2 ); // op, wait 
+    }
+
+
+// ---------------------------------------------------------------------------
+// CRemoteLock::RunL
+// Reconnect msg server after it is shut down
+// Return values:      none
+// ---------------------------------------------------------------------------
+//
+void CRemoteLock::RunL()
+    {
+    RL_TRACE_PRINT(" [ rl.exe ] RunL() ");
+    delete iClientMtmForSending;
+    iClientMtmForSending = NULL;
+    delete iMtmReg;
+    iMtmReg = NULL;
+    delete iMsvSession;
+    iMsvSession = NULL;
+
+    TRAPD( error, iMsvSession = CMsvSession::OpenAsyncL( *this ) );
+
+    if ( error != KErrNone )
+        {
+        After( KRLockTimerInterval );
+        }
+    RL_TRACE_PRINT(" [ rl.exe ] Exit RunL() ");    
+    }
+
+
+// ---------------------------------------------------------------------------
+// CRemoteLock::NeedsToBeSentAsUnicodeL
+// Check if needs to be sent as unicode
+// Return value ETrue or EFalse
+// ---------------------------------------------------------------------------
+//
+TBool CRemoteLock::NeedsToBeSentAsUnicodeL( const TDesC& aInputString ) const
+    {
+    TBool needsToBeSentAsUnicode = EFalse;
+    CCnvCharacterSetConverter* const
+        characterSetConverter = CCnvCharacterSetConverter::NewLC();
+    
+    RFs fsSession;
+    TInt err = fsSession.Connect();
+    User::LeaveIfError( err );
+    CleanupClosePushL( fsSession ); 
+    const TUint KSmsEdSmsStrictPluginID = 0x101F85CD;
+    characterSetConverter->PrepareToConvertToOrFromL(
+        KSmsEdSmsStrictPluginID,
+        fsSession);
+
+    characterSetConverter->SetDowngradeForExoticLineTerminatingCharacters(
+        CCnvCharacterSetConverter::EDowngradeExoticLineTerminatingCharactersToJustLineFeed );
+   
+    for (TPtrC remainderOfInputString( aInputString ); remainderOfInputString.Length()>0 ; )
+        {
+        TBuf8<KBufLengthInUnicodeCheck> notUsed;
+        TInt numberOfUnconvertibleCharacters = 0;
+        const TInt returnValue = 
+            characterSetConverter->ConvertFromUnicode( 
+                notUsed,
+                remainderOfInputString, 
+                numberOfUnconvertibleCharacters );
+        if (( returnValue < 0 ) || ( numberOfUnconvertibleCharacters > 0 )) 
+            // if there was an error in trying to do the conversion, or if there was an
+            // unconvertible character (e.g. a Chinese character)
+            {
+            needsToBeSentAsUnicode = ETrue;
+            break;
+            }
+        
+        remainderOfInputString.Set( remainderOfInputString.Right( returnValue ));
+        }
+    CleanupStack::PopAndDestroy( 2 );
+    return needsToBeSentAsUnicode;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CRemoteLock::HandleUnlockEvent()
+// Callback function for unlocking event observer
+// ---------------------------------------------------------------------------
+void CRemoteLock::HandleUnlockEvent()
+    { 
+    TRAPD( err, SetMemoryCardPasswdL( ETrue ) );
+    err = err;
+    iLockedByRL = EFalse;
+    }   
+
+// -----------------------------------------------------------------------------
+// CRemoteLock::ProfileNotifyL
+// Setup Profile notifier
+// Returns:   ETrue if everything is OK
+//            EFalse otherwise
+// -----------------------------------------------------------------------------
+//
+TBool CRemoteLock::ProfileNotifyL( 
+    const TBool aNotifyEnable ) 
+    {
+    RL_TRACE_PRINT(" [ rl.exe ] ProfileNotifyL() ");
+    
+    if ( !iProfileNotifyHandler )
+        {
+        RL_TRACE_PRINT(" [ rl.exe ] ProfileNotifyL() create notify handler");
+        iProfileNotifyHandler = CCenRepNotifyHandler::NewL( *this, *iProfileSession ); 
+        }
+    
+    if ( aNotifyEnable )
+        {
+        
+        TInt err = iProfileSession->Get( KProEngActiveProfile, iCurrentProfile );
+        User::LeaveIfError( err );
+        RL_TRACE_PRINT(" [ rl.exe ] ProfileNotifyL() startlisten");
+        iProfileNotifyHandler->StartListeningL();  
+        }
+    else
+        {
+        RL_TRACE_PRINT(" [ rl.exe ] ProfileNotifyL() stop listen ");
+        iProfileNotifyHandler->StopListening();
+        
+        delete iProfileNotifyHandler;
+        iProfileNotifyHandler = NULL;
+        }
+    RL_TRACE_PRINT(" [ rl.exe ] exit ProfileNotifyL() ");
+    return ETrue;
+    }
+    
+// -----------------------------------------------------------------------------
+// CRemoteLock::GetProfile
+// Get the current Profile
+// Returns:   ETrue if everything is OK
+//            EFalse otherwise
+// -----------------------------------------------------------------------------
+//
+TBool CRemoteLock::GetProfile( TInt& aProfile )
+    {
+    RL_TRACE_PRINT(" [ rl.exe ] GetProfile() ");
+    TInt err;
+    err = iProfileSession->Get( KProEngActiveProfile, aProfile );
+    RL_TRACE_PRINT(" [ rl.exe ] exit GetProfile() ");
+    return ( err == KErrNone );
+    }    
+
+
+// -----------------------------------------------------------------------------
+// CRemoteLock::HandleNotifyGeneric
+// Remote lock Notify handler 
+//
+// -----------------------------------------------------------------------------
+//
+void CRemoteLock::HandleNotifyGeneric(
+    TUint32 /*aId*/ ) 
+    {
+    RL_TRACE_PRINT(" [ rl.exe ] HandleNotifyGeneric() "); 
+    
+    TInt profile = 0; 
+    GetProfile( profile ); 
+    
+    if ( ( profile == EProfileOffLineId ) && ( iIsEnabled  ) && ( iCurrentProfile != EProfileOffLineId )) 
+        {
+        ActivateDeviceLock();  
+        }
+        
+    iCurrentProfile = profile;
+    RL_TRACE_PRINT(" [ rl.exe ] exit HandleNotifyGeneric() ");
+    }
+    
+//EOF  
+