--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usbclasses/usbmscpersonality/src/CUsbActiveMscHandlerMdrv.cpp Thu Dec 17 09:14:30 2009 +0200
@@ -0,0 +1,1016 @@
+/*
+* Copyright (c) 2006-2008 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: Main class for UsbMscPersonality
+*
+*/
+
+#include <centralrepository.h>
+#include <AknSkinsInternalCRKeys.h>
+#include <usbman.h>
+#include <e32property.h>
+#include <tusbpersonalityparams.h>
+#include <startupdomainpskeys.h>
+#include <SettingsInternalCRKeys.h>
+#include "CUsbActiveMscHandlerMdrv.h"
+#include "CUsbMscPersonalityTimer.h"
+#include "debug.h"
+
+#include <featmgr.h> // for checking DE feature
+#include <DevEncSessionBase.h>
+#include <DevEncEngineConstants.h>
+
+// LITERALS
+_LIT( KMsFs,"MSFS.FSY" );
+_LIT( KMsFsyName, "MassStorageFileSystem" );
+_LIT( KFatFsyName, "Fat" );
+
+const TUint32 KDismountFatTimeoutValue = 5000000; // 5 seconds
+const TInt KMscDismountRetryCount = 3;
+const TUint32 KWaitMscToComplete = 50000; // 50 ms
+
+// ============================ MEMBER FUNCTIONS ==============================
+
+// ----------------------------------------------------------------------------
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// ----------------------------------------------------------------------------
+//
+CUsbActiveMscHandler::CUsbActiveMscHandler(TUsbPersonalityParams& aPersonalityParams)
+ : CUsbPersonalityPlugin(aPersonalityParams), iMountChanged(EFalse)
+ {
+ CActiveScheduler::Add( this );
+ }
+
+// ----------------------------------------------------------------------------
+// Symbian 2nd phase constructor can leave.
+// ----------------------------------------------------------------------------
+//
+void CUsbActiveMscHandler::ConstructL()
+ {
+ FLOG( _L( "[USBWATCHER]\tCUsbActiveMscHandler: ConstructL" ) );
+
+ iDismountFatTimer = new (ELeave) CUsbMscPersonalityTimer(
+ TCallBack(DismountFatCallBack, this), KDismountFatTimeoutValue);
+
+ iMscState = EUsbMscStateIdle;
+ User::LeaveIfError(iFs.Connect());
+ iRepository = CRepository::NewL(KCRUidSecuritySettings);
+ LoadDevEncSessionL();
+ }
+
+// ----------------------------------------------------------------------------
+// Two-phased constructor.
+// ----------------------------------------------------------------------------
+//
+CUsbActiveMscHandler* CUsbActiveMscHandler::NewL(TUsbPersonalityParams& aPersonalityParams)
+ {
+ CUsbActiveMscHandler* self
+ = new ( ELeave ) CUsbActiveMscHandler(aPersonalityParams);
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop(); // pop self
+ return self;
+ }
+
+// ----------------------------------------------------------------------------
+// Destructor
+// ----------------------------------------------------------------------------
+//
+CUsbActiveMscHandler::~CUsbActiveMscHandler()
+ {
+ FLOG( _L( "[USBWATCHER]\tCUsbActiveMscHandler::~CUsbActiveMscHandler" ) );
+
+ if ( iMountChanged )
+ {
+ UnmountMassStorage();
+ }
+
+ RemoveMassStorageFileSystem();
+
+ Cancel();
+ delete iDismountFatTimer;
+
+ iDrives.Close();
+ iFs.Close();
+
+ delete iRepository;
+ UnloadDevEncSession();
+ }
+
+// ----------------------------------------------------------------------------
+// State machine for the class.
+// ----------------------------------------------------------------------------
+//
+void CUsbActiveMscHandler::RunL()
+ {
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler::RunL error = %d" ),
+ iStatus.Int() ) );
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler::RunL iMscState = %d" ),
+ iMscState ) );
+ switch (iMscState)
+ {
+ case EUsbMscStateMounting:
+ // DismountFatTimer is not exprired but RunL called with error
+ if (KErrNone!=iStatus.Int())
+ {
+ /* Print error code, drive name and wait for timer to be expired expired (5sec)
+ * which will call forcibly dismount*/
+ if(KErrNone!=iStatus.Int() )
+ {
+ FLOG( _L( "[USBWATCHER]\tCUsbActiveMscHandler::RunL*** Drive Dismounting failed ") );
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler::RunL*** Dismount failed on DriveIndex= %d" ),
+ iDriveIndex));
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler::RunL*** Dismount failed on Drive = %d" ),
+ iDrives[iDriveIndex]) );
+ }
+ }
+ else
+ {
+ //dismount FAT done for one drive
+ if (iDismountFatTimer)
+ {
+ iDismountFatTimer->Cancel();
+ }
+ StartDismountFat();
+ }
+ break;
+ case EUsbMscStateForciblyDismounting:
+ // If Even ForciblyDismount failed with error we cannot do much here, and just print Error message
+ if(KErrNone!=iStatus.Int() )
+ {
+ FLOG( _L( "[USBWATCHER]\tCUsbActiveMscHandler::RunL*** FS has seroius dismounting problem" ) );
+ }
+ // we change the state and continue with other drives
+ iMscState = EUsbMscStateMounting;
+ StartDismountFat();
+ break;
+ default:
+ break;
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// Not possible to come here.
+// ----------------------------------------------------------------------------
+//
+TInt CUsbActiveMscHandler::RunError( TInt /*aError*/ )
+ {
+ return KErrNone;
+ }
+
+// ----------------------------------------------------------------------------
+// This method always confirms the personality unloading.
+// ----------------------------------------------------------------------------
+//
+void CUsbActiveMscHandler::ConfirmPersonalityUnload(TRequestStatus& aStatus)
+ {
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler: ConfirmPersonalityUnload iMscState = %d" ),
+ iMscState ) );
+ iRequestStatus = &aStatus;
+ aStatus = KRequestPending;
+ CompleteRequest(KErrNone);
+ }
+
+// ----------------------------------------------------------------------------
+// Called by personality handler when personality start needs to be
+// prepared. Adds mass storage file system.
+// ----------------------------------------------------------------------------
+//
+void CUsbActiveMscHandler::PreparePersonalityStart(TRequestStatus& aStatus)
+ {
+ TInt ret = KErrNone;
+ FLOG( _L( "[USBWATCHER]\tCUsbActiveMscHandler: PreparePersonalityStart" ) );
+ iRequestStatus = &aStatus;
+ aStatus = KRequestPending;
+ iMscState = EUsbMscStateStarting;
+ ret = AddMassStorageFileSystem();
+ CompleteRequest(ret);
+ }
+
+// ----------------------------------------------------------------------------
+// Called by personality handler when personality start needs to be finished.
+// ----------------------------------------------------------------------------
+//
+void CUsbActiveMscHandler::FinishPersonalityStart(TRequestStatus& aStatus)
+ {
+ FLOG( _L( "[USBWATCHER]\tCUsbActiveMscHandler: FinishPersonalityStart" ) );
+ iRequestStatus = &aStatus;
+ aStatus = KRequestPending;
+ CompleteRequest(KErrNone);
+ }
+
+// ----------------------------------------------------------------------------
+// Called by personality handler when personality stop needs to be prepared.
+// Changes state of the personality.
+// ----------------------------------------------------------------------------
+//
+void CUsbActiveMscHandler::PreparePersonalityStop(TRequestStatus& aStatus)
+ {
+ FLOG( _L( "[USBWATCHER]\tCUsbActiveMscHandler: PreparePersonalityStop" ) );
+
+ //Mounting may be ongoing
+ iRequestStatus = NULL; //do not complete in DoCancel
+ Cancel();
+
+ iRequestStatus = &aStatus;
+ aStatus = KRequestPending;
+
+ iMscState = EUsbMscStateStopping;
+
+ CompleteRequest(KErrNone);
+ }
+
+// ----------------------------------------------------------------------------
+// Called by personality handler when personality stop needs to be finished.
+// ----------------------------------------------------------------------------
+//
+void CUsbActiveMscHandler::FinishPersonalityStop(TRequestStatus& aStatus)
+ {
+ FLOG(_L("[USBWATCHER]\tCUsbActiveMscHandler: FinishPersonalityStop"));
+
+ //Mounting may be ongoing
+ iRequestStatus = NULL; //do not complete in DoCancel
+ Cancel();
+
+ //unmount in case device state not yet Undefined
+ if (iMountChanged)
+ {
+ UnmountMassStorage();
+ }
+
+ RemoveMassStorageFileSystem();
+
+ // Remove all queries shown by this personality
+ iPersonalityParams.PersonalityNotifier().CancelQuery(KQueriesNotifier);
+
+ iMscState = EUsbMscStateIdle;
+
+ iRequestStatus = &aStatus;
+ aStatus = KRequestPending;
+ CompleteRequest(KErrNone);
+ }
+
+// ----------------------------------------------------------------------------
+// Indicates USB device state change to personality.
+// There is no need to Cancel, because Confirm unload can not be ongoing
+// before Address state.
+// ----------------------------------------------------------------------------
+//
+void CUsbActiveMscHandler::StateChangeNotify( TUsbDeviceState aState )
+ {
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler::StateChangeNotify aState = %d" ),
+ aState ) );
+ switch( aState )
+ {
+ //Note that Address state may be caused also by cable disconnection.
+ case EUsbDeviceStateAddress:
+ {
+ //Do not start mounting if already ongoing
+ //e.g. fast state changes Address-->Suspended-->Address
+ if ( !iMountChanged && (GetDrives() == KErrNone) )
+ {
+ if (iDrives.Count())
+ {
+ iDriveIndex = iDrives.Count();
+ StartDismountFat();
+ }
+ else
+ {
+ if ( GlobalSystemState() == EUsbGSStateCategoryNormal )
+ {
+ // if the error is something abnormal, note still needs to be shown
+ iQueryParams().iQuery = EUSBStorageMediaFailure;
+ iPersonalityParams.PersonalityNotifier().ShowQuery(
+ KQueriesNotifier, iQueryParams, iDummy);
+ }
+ }
+ }
+
+ }
+ break;
+ case EUsbDeviceStateUndefined:
+ {
+ if (iMountChanged)
+ {
+ UnmountMassStorage();
+ iMscState = EUsbMscStateIdle;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ FLOG(_L("[USBWATCHER]\tCUsbActiveMscHandler::StateChangeNotify completed"));
+ }
+
+// ----------------------------------------------------------------------------
+// Start FAT dismounting sequence.
+// ----------------------------------------------------------------------------
+//
+void CUsbActiveMscHandler::StartDismountFat()
+ {
+ FLOG(_L("[USBWATCHER]\tCUsbActiveMscHandler::StartDismountFat"));
+ iMountChanged = ETrue;
+
+ if (!iDriveIndex)
+ {
+ //FAT dismounted from all the drives
+ MountMassStorage();
+ //MSFS mounted to all the drives
+ iMscState = EUsbMscStateFileTransfer;
+ }
+ else
+ {
+ --iDriveIndex;
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler::StartDismountFat iDriveIndex = %d " ),
+ iDriveIndex) );
+ // see if FAT file system exists in drive and if it does, try to dismount it
+ DismountFat(iDrives[iDriveIndex]);
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// Add mass storage file system
+// ----------------------------------------------------------------------------
+//
+TInt CUsbActiveMscHandler::AddMassStorageFileSystem()
+ {
+ FLOG(_L("[USBWATCHER]\tCUsbActiveMscHandler::AddMassStorageFileSystem"));
+
+ TInt ret = KErrNone;
+
+ // To be done only once during the lifetime of this object:
+ // 5b. add Mass Storage File System to the file server.
+ // (done like this to avoid Symbian crash)
+ if (!iMsfsAdded)
+ {
+ FLOG( _L( "[USBWATCHER]\tCUsbActiveMscHandler::AddMassStorageFileSystem: Loading MSFS" ) );
+ ret = iFs.AddFileSystem(KMsFs);
+ if ((ret != KErrNone) && (ret != KErrAlreadyExists))
+ {
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler::AddMassStorageFileSystem: ERROR: MSFS loading failed. Code: %d " ),
+ ret) );
+ }
+ else
+ {
+ iMsfsAdded = ETrue;
+ if (ret == KErrAlreadyExists)
+ {
+ ret = KErrNone;
+ }
+ }
+ }
+ FTRACE(FPrint(_L("[USBWATCHER]\tCUsbActiveMscHandler::AddMassStorageFileSystem: ret=%d"), ret));
+ return ret;
+ }
+
+// ----------------------------------------------------------------------------
+// Remove mass storage file system (MSFS) from file server
+// ----------------------------------------------------------------------------
+//
+void CUsbActiveMscHandler::RemoveMassStorageFileSystem()
+ {
+ FLOG(_L("[USBWATCHER]\tCUsbActiveMscHandler::RemoveMassStorageFileSystem"));
+ if (iMsfsAdded)
+ {
+ if (iFs.RemoveFileSystem(KMsFsyName) != KErrNone)
+ {
+ FLOG( _L( "[USBWATCHER]\tCUsbActiveMscHandler: RemoveMassStorageFileSystem: MSFS not removed from file server." ) );
+ }
+ else
+ {
+ iMsfsAdded = EFalse;
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// Mount mass storage to all drives. Does not mount in charging state if device
+// locked.
+// ----------------------------------------------------------------------------
+//
+void CUsbActiveMscHandler::MountMassStorage()
+ {
+ FLOG(_L("[USBWATCHER]\tCUsbActiveMscHandler::MountMassStorage"));
+ TInt ret = KErrNone;
+ TBool locked = DeviceLocked();
+ TUsbGlobalSystemState state = GlobalSystemState();
+ FTRACE(FPrint(_L("[USBWATCHER]\tCUsbActiveMscHandler::MountMassStorage: locked=%d, state=%d"), locked, state));
+
+ if ( (state == EUsbGSStateCategoryNormal) ||
+ (!locked && (state==EUsbGSStateCharging)) )
+ {
+ for ( TInt driveIndex = iDrives.Count() - 1; driveIndex >= 0; driveIndex-- )
+ {
+ // Try mount Mass Storage File System into drive.
+ ret = TryMountMassStorage(iDrives[driveIndex]);
+ if (ret != KErrNone)
+ {
+ FTRACE(FPrint(_L("[USBWATCHER]\tCUsbActiveMscHandler::MountMassStorage: driveIndex=%d ret=%d"),
+ driveIndex, ret));
+ }
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// Return removable drives in system.
+// ----------------------------------------------------------------------------
+//
+TInt CUsbActiveMscHandler::GetDrives()
+ {
+ TInt i;
+ TInt ret = KErrNone;
+
+ // go through drives A-Z except for C and Z
+ TDriveInfo driveInfo;
+ iDrives.Reset();
+
+ for (i = EDriveA; i < EDriveZ; i++)
+ {
+ // skip drive C: and get drive info
+ if ( EDriveC == i )
+ {
+ continue;
+ }
+
+ // unmounting FAT from the card when a decrypting/encrypting operation
+ // is ongoing will corrupt the card, so it must be prevented.
+ if( ( i == EDriveE ) || ( i == EDriveF ) )
+ {
+ if(IsEncProtectionRequired(i))
+ {
+ FTRACE( FPrint( _L(" Skipping drive %d"), i));
+ continue;
+ }
+ }
+ iFs.Drive(driveInfo, i);
+
+ // if drive is not removable and local, it can be skipped
+ if ((driveInfo.iDriveAtt & (KDriveAttRemovable | KDriveAttLocal))
+ != (KDriveAttRemovable | KDriveAttLocal))
+ {
+ continue;
+ }
+
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler::GetDrives, removable drive %d: MediaAtt: %d" ),
+ i,driveInfo.iMediaAtt ) );
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler::GetDrives, removable drive %d: Media info: %d" ),
+ i, driveInfo.iType ) );
+
+ // The memory card may be locked. No memory card password query is shown.
+
+ FTRACE(FPrint(
+ _L("[USBWATCHER]\tCUsbActiveMscHandler::GetDrives: MMC inserted into drive %d"),
+ i) );
+ ret = iDrives.Append(i);
+ }
+
+ if (!iDrives.Count())
+ {
+ FLOG( _L( "[USBWATCHER]\tCUsbActiveMscHandler::GetDrives: No removable drives found." ) );
+
+ iQueryParams().iQuery = EUSBStorageMediaFailure;
+ iPersonalityParams.PersonalityNotifier().ShowQuery(KQueriesNotifier, iQueryParams, iDummy);
+
+ return KErrNotFound;
+ }
+
+ return ret;
+ }
+
+// ----------------------------------------------------------------------------
+// Dismounts FAT File System.
+// ----------------------------------------------------------------------------
+//
+void CUsbActiveMscHandler::DismountFat( TInt aDrive )
+ {
+ FLOG( _L( "[USBWATCHER]\tCUsbActiveMscHandler::DismountFat" ) );
+
+ //nothing to do if FAT file system not in aDrive
+ if ( GetDriveFileSystem(aDrive) != EFsyFat )
+ {
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler::DismountFat: FAT FSY not found in drive %d" ),
+ aDrive ) );
+ //continue to the next drive
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, KErrNotFound);
+ SetActive();
+ }
+ else
+ {
+ //FAT file system exists in aDrive -> dismount it
+ iFs.NotifyDismount(iDrives[iDriveIndex], iStatus, EFsDismountNotifyClients);
+ SetActive();
+
+ //Give some time for applications before dismounting forcefully
+ iDismountFatTimer->Start();
+ }
+
+ iMscState = EUsbMscStateMounting;
+ }
+
+// ----------------------------------------------------------------------------
+// Mounts Mass Storage File System into drive.
+// ----------------------------------------------------------------------------
+//
+TInt CUsbActiveMscHandler::TryMountMassStorage( TInt aDrive )
+ {
+ FLOG( _L( "[USBWATCHER]\tCUsbActiveMscHandler::TryMountMassStorage" ) );
+
+ TInt ret(KErrNone);
+
+ ret = iFs.MountFileSystem( KMsFsyName, aDrive );
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler::TryMountMassStorage: fs mount ret %d" ),
+ ret ) );
+
+ if ( ret == KErrNotSupported )
+ {
+ // there is an error in environment and MSFS has been mounted into
+ // drive but mounting has been unsuccessful -> remove it
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler::TryMountMassStorage: MS FSY not supported in drive %d" ),
+ aDrive ) );
+ return ret;
+ }
+ else if ((ret != KErrNone) && (ret != KErrNotReady))
+ {
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler::TryMountMassStorage: ERROR %d in MS FSY mounting in drive %d" ),
+ ret, aDrive ) );
+ return ret;
+ }
+
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler::TryMountMassStorage: MS FSY mounted in drive %d" ),
+ aDrive ) );
+
+ return KErrNone;
+ }
+
+// ----------------------------------------------------------------------------
+// Dismounts Mass Storage File System from the drive.
+// ----------------------------------------------------------------------------
+//
+TInt CUsbActiveMscHandler::TryDismountMassStorage( TInt aDrive )
+ {
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler::TryDismountMassStorage: drive %d" ),
+ aDrive ) );
+
+ // initializations
+ TInt ret = KErrNone;
+ TInt numTry = KMscDismountRetryCount; // How many times to try to dismount the drive
+
+ //only dismount if mass storage mounted
+ if ( GetDriveFileSystem(aDrive) == EFsyMassStorage )
+ {
+ while ( numTry-- )
+ {
+ ret = iFs.DismountFileSystem( KMsFsyName, aDrive );
+ if ( ret != KErrNone )
+ {
+ if ( ret == KErrInUse )
+ {
+ // It may be that USB mass storage transfer is still in use
+ // when USB File transfer mode is tried to be distangled (this
+ // method is entered). Wait for a while and try again.
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler: TryDismountMassStorage: Waiting MSFS dismounting for drive %d" ),
+ aDrive ) );
+ RTimer timer;
+ TRequestStatus timerStatus;
+ timer.CreateLocal(); // Create for this thread
+ timer.After(timerStatus, KWaitMscToComplete);
+ User::WaitForRequest( timerStatus );
+ if ( timerStatus != KErrNone )
+ {
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler::TryDismountMassStorage: ERROR: %d wait timer fails." ),
+ timerStatus.Int() ) );
+ }
+ timer.Close();
+ }
+ else
+ {
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler: TryDismountMassStorage: ERROR %d in dismounting MSFS from drive %d" ),
+ ret, aDrive ) );
+ break;
+ }
+ }
+ else
+ {
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler: TryDismountMassStorage: MSFS dismounted from drive %d" ),
+ aDrive ) );
+ break;
+ }
+ } //while
+
+ if ( ret == KErrInUse )
+ {
+ FLOG(_L("[USBWATCHER]\tCUsbActiveMscHandler::TryDismountMassStorage using force"));
+ TRequestStatus dismountStatus;
+ iFs.NotifyDismount(aDrive, dismountStatus, EFsDismountForceDismount);
+ User::WaitForRequest(dismountStatus);
+ ret = dismountStatus.Int();
+ }
+
+ }
+ else
+ {
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler: TryDismountMassStorage: No MSFS on drive %d" ),
+ aDrive ) );
+ }
+
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler::TryDismountMassStorage: returning %d" ),
+ ret ) );
+ return ret;
+ }
+
+// ----------------------------------------------------------------------------
+// Mounts FAT File System to the drive
+// ----------------------------------------------------------------------------
+//
+TInt CUsbActiveMscHandler::TryMountFat( TInt aDrive )
+ {
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler::TryMountFat: drive %d" ),
+ aDrive ) );
+
+ // initializations
+ TInt ret = KErrNone;
+
+ // Mount back FAT only if there is no mounted file system
+ if ( GetDriveFileSystem(aDrive) == EFsyNone )
+ {
+ ret = iFs.MountFileSystem( KFatFsyName, aDrive );
+
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler: TryMountFat: return %d in mounting FAT into drive %d" ),
+ ret, aDrive ) );
+
+ if (ret != KErrNone)
+ {
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler: TryMountFat: ERROR %d in mounting FAT into drive %d" ),
+ ret, aDrive ) );
+ }
+ else
+ {
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler: TryMountFat: FAT mounted into drive %d" ),
+ aDrive ) );
+ }
+ }
+
+ return ret;
+ }
+
+// ----------------------------------------------------------------------------
+// Standard active object cancellation function.
+// ----------------------------------------------------------------------------
+//
+void CUsbActiveMscHandler::DoCancel()
+ {
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler: DoCancel iMscState=%d" ),
+ iMscState ) );
+
+ //Remove all notes. The state may have changed after the confirm unload
+ //is started.
+ if (iMscState != EUsbMscStateForciblyDismounting)
+ {
+ iPersonalityParams.PersonalityNotifier().CancelAll();
+ }
+
+ switch (iMscState)
+ {
+ case EUsbMscStateStarting:
+ case EUsbMscStateStopping:
+ break;
+
+ case EUsbMscStateMounting:
+ case EUsbMscStateForciblyDismounting:
+ if (iDismountFatTimer)
+ {
+ iDismountFatTimer->Cancel();
+ }
+ iFs.NotifyDismountCancel();
+ break;
+
+ default:
+ FLOG(_L("[USBWATCHER]\tCUsbActiveMscHandler::DoCancel: ERROR"));
+ break;
+ }
+
+ CompleteRequest(KErrCancel);
+ }
+
+// ----------------------------------------------------------------------------
+// Complete request.
+// ----------------------------------------------------------------------------
+//
+void CUsbActiveMscHandler::CompleteRequest(TInt aError)
+ {
+ FLOG(_L("[USBWATCHER]\tCUsbActiveMscHandler::CompleteRequest"));
+
+ if (iRequestStatus)
+ {
+ User::RequestComplete(iRequestStatus, aError);
+ iRequestStatus = NULL;
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// If client doesn't allow us to do dismount, let's force it.
+// ----------------------------------------------------------------------------
+//
+TInt CUsbActiveMscHandler::DismountFatCallBack(TAny* aPtr)
+ {
+ FLOG(_L("[USBWATCHER]\tCUsbActiveMscHandler::DismountFatCallBack"));
+
+ CUsbActiveMscHandler* handler = static_cast<CUsbActiveMscHandler *>(aPtr);
+
+ handler->ForciblyDismountFat();
+
+ return KErrNone;
+ }
+
+// ----------------------------------------------------------------------------
+// Forced dismount is done over here.
+// ----------------------------------------------------------------------------
+//
+void CUsbActiveMscHandler::ForciblyDismountFat()
+ {
+ FLOG(_L("[USBWATCHER]\tCUsbActiveMscHandler::ForciblyDismountFat"));
+
+ //cancel won't complete, since there is no client request ongoing
+ iMscState = EUsbMscStateForciblyDismounting; //do not close mode query
+ Cancel();
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler::ForciblyDismountFat DriveIndex= %d" ),
+ iDriveIndex));
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler::ForciblyDismountFat on Drive = %d" ),
+ iDrives[iDriveIndex]) );
+ iFs.NotifyDismount(iDrives[iDriveIndex], iStatus, EFsDismountForceDismount);
+ SetActive();
+ }
+
+
+TUsbGlobalSystemState CUsbActiveMscHandler::GlobalSystemState()
+ {
+ TInt state = EUsbGSStateUnknown;
+ TUsbGlobalSystemState usbGlobalSysState = EUsbGSStateUnknown;
+ TInt error = RProperty::Get( KPSUidStartup, KPSGlobalSystemState, state );
+ FTRACE(FPrint(_L("[USBWATCHER]\tCUsbActiveMscHandler::GlobalSystemState: error %d, state %d"), error, state));
+ if ( (state == ESwStateNormalRfOn) ||
+ (state == ESwStateNormalRfOff) ||
+ (state == ESwStateNormalBTSap) )
+ {
+ usbGlobalSysState = EUsbGSStateCategoryNormal;
+ }
+ else if ( state == ESwStateCharging )
+ {
+ usbGlobalSysState = EUsbGSStateCharging;
+ }
+
+ return usbGlobalSysState;;
+ }
+
+
+// ----------------------------------------------------------------------------
+// Determine whether the device is locked or not
+// ----------------------------------------------------------------------------
+//
+TBool CUsbActiveMscHandler::DeviceLocked()
+ {
+ TBool locked(EFalse);
+ if ( GlobalSystemState() == EUsbGSStateCharging )
+ {
+ if (AutoLockTime()>0 || AutoLockStatus()>0 )
+ {
+ locked=ETrue;
+ }
+ }
+
+ return locked;
+ }
+
+// ----------------------------------------------------------------------------
+// Read Lock time settings
+// Meant to be used only in Charging mode
+// ----------------------------------------------------------------------------
+//
+TInt CUsbActiveMscHandler::AutoLockTime()
+ {
+ TInt lockTime(0);
+
+ TInt ret = iRepository->Get(KSettingsAutoLockTime, lockTime);
+ FTRACE(FPrint(_L("[USBWATCHER]\tCUsbActiveMscHandler::LockeTime: ret=%d. LockTime=%d"), ret, lockTime));
+
+ return lockTime;
+ }
+
+// ----------------------------------------------------------------------------
+// Read Lock status settings
+// Meant to be used only in Charging mode
+// ----------------------------------------------------------------------------
+//
+TInt CUsbActiveMscHandler::AutoLockStatus()
+ {
+ TInt lockStatus(0);
+
+ TInt ret = iRepository->Get(KSettingsAutolockStatus, lockStatus);
+ FTRACE(FPrint(_L("[USBWATCHER]\tCUsbActiveMscHandler::AutoLockStatus: ret=%d. lockStatus=%d"), ret, lockStatus));
+
+ return lockStatus;
+ }
+
+// ----------------------------------------------------------------------------
+// Unmount mass storage dismounts mass storage and mounts FAT for all drives.
+// ----------------------------------------------------------------------------
+//
+void CUsbActiveMscHandler::UnmountMassStorage()
+ {
+ FLOG(_L("[USBWATCHER]\tCUsbActiveMscHandler::UnmountMassStorage"));
+ //Mounting may be ongoing. Note that the confirm unload query and the mode
+ //query are closed.
+ Cancel();
+
+ TInt index = iDrives.Count();
+ while ( index > 0 )
+ {
+ --index;
+ TInt drive = iDrives[index];
+ // First dismount mounted Mass Storage File System
+ TryDismountMassStorage(iDrives[index]);
+ // Then mount back previously dismounted FAT File System
+ TryMountFat(iDrives[index]);
+ }
+ iMountChanged = EFalse;
+ }
+
+// ----------------------------------------------------------------------------
+// Return the mounted file system.
+// ----------------------------------------------------------------------------
+//
+TUsbFileSystem CUsbActiveMscHandler::GetDriveFileSystem( TInt aDrive )
+ {
+ FLOG(_L("[USBWATCHER]\tCUsbActiveMscHandler::GetDriveFileSystem"));
+ TUsbFileSystem fileSystem = EFsyNone;
+ TBuf<KMaxFullName> name;
+ TInt err = iFs.FileSystemName( name, aDrive );
+ if ( (err == KErrNone) && (name.Length() > 0) )
+ {
+
+ FTRACE( FPrint(_L( "[USBWATCHER]\tCUsbActiveMscHandler: GetDriveFileSystem: aDrive=%d name=%S" ),
+ aDrive, &name ) );
+
+ if (name.CompareF( KMsFsyName ) == 0)
+ {
+ fileSystem = EFsyMassStorage;
+ }
+ else if (name.CompareF( KFatFsyName ) == 0)
+ {
+ fileSystem = EFsyFat;
+ }
+ }
+ FTRACE( FPrint(
+ _L( "[USBWATCHER]\tCUsbActiveMscHandler: GetDriveFileSystem: filesystem %d on drive %d" ),
+ fileSystem, aDrive ) );
+
+ return fileSystem;
+ }
+
+// ----------------------------------------------------------------------------
+// Return whether device encryption is supported or not.
+// ----------------------------------------------------------------------------
+//
+TBool CUsbActiveMscHandler::IsDeviceEncryptionSupportedL()
+ {
+ FLOG(_L("[USBWATCHER]\tCUsbActiveMscHandler::IsDeviceEncryptionSupportedL >>"));
+
+ TBool ret(EFalse);
+
+ FeatureManager::InitializeLibL();
+ ret = FeatureManager::FeatureSupported(KFeatureIdFfDeviceEncryptionFeature);
+ FeatureManager::UnInitializeLib();
+
+ FTRACE(FPrint(_L("[USBWATCHER]\tCUsbActiveMscHandler::IsDeviceEncryptionSupportedL, ret = %d <<"), ret));
+ return ret;
+ }
+
+// ----------------------------------------------------------------------------
+// Return device encryption info for further protection
+// ----------------------------------------------------------------------------
+//
+TBool CUsbActiveMscHandler::IsEncProtectionRequired(const TInt& aDriveLetter)
+ {
+ TBool ret = ETrue;
+ FLOG(_L("[USBWATCHER]\tCUsbActiveMscHandler::GetEncProtectionInfo >>"));
+
+ // Is device encryption feature supported?
+ TRAPD( r, ret = ( IsDeviceEncryptionSupportedL() ) );
+ if(r)
+ {
+ ret = EFalse;
+ }
+
+ // Get the enctrytion operation code
+ if(ret)
+ {
+ FLOG(_L("Check drives for busy status"));
+
+ TInt encDriverStatus;
+
+ if(!iDevEncSession)
+ {
+ FTRACE(FPrint(_L("[USBWATCHER]\tCUsbActiveMscHandler::IsEncProtectionRequired: iDevEncSession is NULL")));
+ User::Panic(_L("[USBWATCHER]DevEncCommonUtil Not Found"), KErrNotSupported);
+ }
+ else
+ {
+ iDevEncSession->SetDrive( (TDriveNumber)aDriveLetter );
+ TInt errCode = iDevEncSession->Connect();
+ if( !errCode )
+ {
+ errCode = iDevEncSession->DiskStatus( encDriverStatus );
+ }
+ iDevEncSession->Close();
+ FTRACE(FPrint(_L("[USBWATCHER]\tCUsbActiveMscHandler::GetDrives: error %d, state %d"), errCode, encDriverStatus));
+
+ ret = ( ( errCode == KErrNone ) &&
+ ( ( encDriverStatus == EEncrypting ) || ( encDriverStatus == EDecrypting ) ) );
+ }
+ }
+
+ FTRACE(FPrint(_L("[USBWATCHER]\tCUsbActiveMscHandler::GetEncProtectionInfo, aDriveLetter= %d, ret= <<"), aDriveLetter,ret));
+
+ return ret;
+ }
+void CUsbActiveMscHandler::LoadDevEncSessionL()
+ {
+ FLOG(_L("[USBWATCHER]\tCUsbActiveMscHandler::LoadDevEncSessionL >> "));
+
+ if (!iDevEncSession)
+ {
+ TInt err = iLibrary.Load(KDevEncCommonUtils);
+ if (err != KErrNone)
+ {
+ FTRACE(FPrint(_L("Error in finding the library... %d"), err));
+ return;
+ }
+ TLibraryFunction entry = iLibrary.Lookup(1);
+
+ if (!entry)
+ {
+ FLOG(_L("Error in loading the library..."));
+ User::Leave(KErrBadLibraryEntryPoint);
+ }
+ iDevEncSession = (CDevEncSessionBase*) entry();
+ }
+ FLOG(_L("[USBWATCHER]\tCUsbActiveMscHandler::LoadDevEncSessionL << "));
+ }
+
+void CUsbActiveMscHandler::UnloadDevEncSession()
+ {
+ FLOG(_L("[USBWATCHER]\tCUsbActiveMscHandler::UnloadDevEncSession >> "));
+
+ if (iDevEncSession)
+ {
+ delete iDevEncSession;
+ iDevEncSession = NULL;
+ iLibrary.Close();
+ }
+
+ FLOG(_L("[USBWATCHER]\tCUsbActiveMscHandler::UnloadDevEncSession << "));
+ }
+// End of file