usbclasses/usbmscpersonality/src/CUsbActiveMscHandlerMdrv.cpp
changeset 35 9d8b04ca6939
child 63 ef2686f7597e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbclasses/usbmscpersonality/src/CUsbActiveMscHandlerMdrv.cpp	Fri Jun 04 10:27:39 2010 +0100
@@ -0,0 +1,1024 @@
+/*
+* Copyright (c) 2006-2010 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),
+      iIsQueryNoteShown(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();
+
+    if (iIsQueryNoteShown)
+        {
+        // Remove all queries shown by this personality
+        iPersonalityParams.PersonalityNotifier().CancelQuery(KQueriesNotifier);
+        iIsQueryNoteShown = EFalse;
+        }
+        
+    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 )
+                        {
+                        iIsQueryNoteShown = ETrue;
+                        // 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." ) );
+
+        iIsQueryNoteShown = ETrue;
+        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