diff -r 000000000000 -r 164170e6151a remotelock/RemoteLockEngine/Src/RemoteLock.cpp --- /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 +#include +#include +#include +#include +#include //CClientMtmRegistry +#include //CSmsClientMtm +#include +#include //file system utilities +#include +#ifdef RD_MULTIPLE_DRIVE +#include +#else +#include +#endif //RD_MULTIPLE_DRIVE +#include +#include +#include +#include +#include //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( aArg2 ) ) != + KMsvGlobalInBoxIndexEntryId ) + { + // Doing nothing if not to inbox + return; + } + + CMsvEntrySelection* entries = + static_cast( 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 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 + ( &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 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 +