--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/src/msmmdismountusbdrives.cpp Tue Aug 31 17:01:47 2010 +0300
@@ -0,0 +1,283 @@
+/*
+* Copyright (c) 2007-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: Active Object to dismount usb drives
+*
+*/
+
+
+#include <usb/usblogger.h>
+#include <usb/hostms/srverr.h>
+#include <usb/hostms/msmmpolicypluginbase.h>
+
+#include "msmmdismountusbdrives.h"
+#include "OstTraceDefinitions.h"
+#ifdef OST_TRACE_COMPILER_IN_USE
+#include "msmmdismountusbdrivesTraces.h"
+#endif
+
+
+const TInt KDismountTimeOut = 6000000; // 6 seconds
+
+
+CMsmmDismountUsbDrives::~CMsmmDismountUsbDrives()
+ {
+ OstTraceFunctionEntry0( CMSMMDISMOUNTUSBDRIVES_CMSMMDISMOUNTUSBDRIVES_DES_ENTRY );
+
+ Cancel();
+ delete iDismountTimer;
+ iRFs.Close();
+ OstTraceFunctionExit0( CMSMMDISMOUNTUSBDRIVES_CMSMMDISMOUNTUSBDRIVES_DES_EXIT );
+ }
+
+/**
+ * Symbian two phase constructor
+ */
+CMsmmDismountUsbDrives* CMsmmDismountUsbDrives::NewL()
+ {
+ OstTraceFunctionEntry0( CMSMMDISMOUNTUSBDRIVES_NEWL_ENTRY );
+
+ CMsmmDismountUsbDrives* self = CMsmmDismountUsbDrives::NewLC();
+ CleanupStack::Pop(self);
+ OstTraceFunctionExit0( CMSMMDISMOUNTUSBDRIVES_NEWL_EXIT );
+ return self;
+ }
+
+/**
+ * Symbian two phase constructor. Object pushed to cleanup stack
+ */
+CMsmmDismountUsbDrives* CMsmmDismountUsbDrives::NewLC()
+ {
+ OstTraceFunctionEntry0( CMSMMDISMOUNTUSBDRIVES_NEWLC_ENTRY );
+
+ CMsmmDismountUsbDrives* self = new (ELeave) CMsmmDismountUsbDrives();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ OstTraceFunctionExit0( CMSMMDISMOUNTUSBDRIVES_NEWLC_EXIT );
+ return self;
+ }
+
+/**
+ * Check the status of current dismount request and continue issuing next if no error
+ */
+void CMsmmDismountUsbDrives::RunL()
+ {
+ OstTraceFunctionEntry0( CMSMMDISMOUNTUSBDRIVES_RUNL_ENTRY );
+
+ iDismountTimer->CancelTimer();
+
+ // Indicates there has been an error dismounting a usb drive, report immediately to MSMM plugin and
+ // abort the process
+ if ( iStatus != KErrNone )
+ {
+ CompleteDismountRequest( iStatus.Int() );
+ }
+ // Indicates we have reached the end of all usb drives dismounting, in other words a success condition
+ else if ( iDriveIndex == KMaxDrives )
+ {
+ CompleteDismountRequest( KErrNone );
+ }
+ // We still have more drives to traverse
+ else if ( iDriveIndex < KMaxDrives )
+ {
+ DoDismount();
+ }
+ OstTraceFunctionExit0( CMSMMDISMOUNTUSBDRIVES_RUNL_EXIT );
+ }
+
+/**
+ * Cancel pending notifier and those in queue
+ */
+void CMsmmDismountUsbDrives::DoCancel()
+ {
+ OstTraceFunctionEntry0( CMSMMDISMOUNTUSBDRIVES_DOCANCEL_ENTRY );
+
+ iRFs.NotifyDismountCancel(iStatus);
+ OstTraceFunctionExit0( CMSMMDISMOUNTUSBDRIVES_DOCANCEL_EXIT );
+ }
+
+CMsmmDismountUsbDrives::CMsmmDismountUsbDrives()
+ : CActive(EPriorityStandard)
+ {
+ OstTraceFunctionEntry0( CMSMMDISMOUNTUSBDRIVES_CMSMMDISMOUNTUSBDRIVES_ENTRY );
+
+ CActiveScheduler::Add(this);
+ OstTraceFunctionExit0( CMSMMDISMOUNTUSBDRIVES_CMSMMDISMOUNTUSBDRIVES_EXIT );
+ }
+
+void CMsmmDismountUsbDrives::ConstructL()
+ {
+ OstTraceFunctionEntry0( CMSMMDISMOUNTUSBDRIVES_CONSTRUCTL_ENTRY );
+
+ User::LeaveIfError( iRFs.Connect());
+ iDismountTimer = CDismountTimer::NewL(this);
+ OstTraceFunctionExit0( CMSMMDISMOUNTUSBDRIVES_CONSTRUCTL_EXIT );
+ }
+
+/**
+ * Dismount usb drives
+ */
+void CMsmmDismountUsbDrives::DismountUsbDrives(CMsmmPolicyPluginBase& aPlugin, TUSBMSDeviceDescription& aDevice)
+ {
+ OstTraceFunctionEntry0( CMSMMDISMOUNTUSBDRIVES_DISMOUNTUSBDRIVES_ENTRY );
+
+ Cancel();
+ iPlugin = &aPlugin;
+ TUSBMSDeviceDescription& device = iDevicePkgInfo();
+ device = aDevice;
+ iDriveIndex = 0;
+ iRFs.DriveList( iDriveList );
+ DoDismount();
+ OstTraceFunctionExit0( CMSMMDISMOUNTUSBDRIVES_DISMOUNTUSBDRIVES_EXIT );
+ }
+
+/**
+ * Callback to CMsmmPolicyPluginBase with either success or failure message
+ */
+void CMsmmDismountUsbDrives::CompleteDismountRequest(const TInt aResult)
+ {
+ THostMsErrData data;
+ if( aResult == KErrNone )
+ data.iError = EHostMsErrNone;
+ else
+ data.iError = EHostMsErrInUse;
+ data.iE32Error = aResult;
+ data.iManufacturerString = iDevicePkgInfo().iManufacturerString;
+ data.iProductString = iDevicePkgInfo().iProductString;
+ data.iDriveName = 0x0;
+
+ TRAP_IGNORE(iPlugin->SendErrorNotificationL(data));
+ }
+
+/**
+ * Dismount next usb drive
+ */
+void CMsmmDismountUsbDrives::DoDismount()
+ {
+ OstTraceFunctionEntry0( CMSMMDISMOUNTUSBDRIVES_DODISMOUNT_ENTRY );
+
+ TDriveInfo info;
+ TInt err = KErrNone;
+ for ( ; iDriveIndex < KMaxDrives; iDriveIndex++ )
+ {
+ if ( iDriveList[iDriveIndex] )
+ {
+ err = iRFs.Drive( info , iDriveIndex );
+ if ( info.iConnectionBusType == EConnectionBusUsb &&
+ info.iDriveAtt & KDriveAttExternal &&
+ err == KErrNone )
+ {
+ OstTrace0( TRACE_NORMAL, CMSMMDISMOUNTUSBDRIVES_DODISMOUNT,
+ "CMsmmDismountUsbDrives::DoDismount Dismount notify request" );
+ iRFs.NotifyDismount( iDriveIndex, iStatus, EFsDismountNotifyClients );
+ iDismountTimer->StartTimer();
+ SetActive();
+ OstTraceFunctionExit0( CMSMMDISMOUNTUSBDRIVES_DODISMOUNT_EXIT );
+ return;
+ }
+ }
+ }
+ // Indicates we have gone through all the drives and no more usb drives left to request dismount
+ CompleteDismountRequest( KErrNone );
+ OstTraceFunctionExit0( CMSMMDISMOUNTUSBDRIVES_DODISMOUNT_EXIT_DUP1 );
+ }
+
+
+/**
+ * Callback function from CDismountTimer after 6 seconds indicating a usb drive is not released by another process, report it as an error
+ */
+void CMsmmDismountUsbDrives::TimerExpired()
+ {
+ OstTraceFunctionEntry0( CMSMMDISMOUNTUSBDRIVES_TIMEREXPIRED_ENTRY );
+
+ Cancel();
+ iDismountTimer->CancelTimer();
+ CompleteDismountRequest( KErrInUse );
+ OstTraceFunctionExit0( CMSMMDISMOUNTUSBDRIVES_TIMEREXPIRED_EXIT );
+ }
+
+//CDismountTimer
+
+CDismountTimer* CDismountTimer::NewL( MTimerNotifier* aTimeOutNotify)
+ {
+ OstTraceFunctionEntry0( CDISMOUNTTIMER_NEWL_ENTRY );
+
+ CDismountTimer* self = CDismountTimer::NewLC( aTimeOutNotify );
+ CleanupStack::Pop(self);
+ OstTraceFunctionExit0( CDISMOUNTTIMER_NEWL_EXIT );
+ return self;
+ }
+
+CDismountTimer* CDismountTimer::NewLC( MTimerNotifier* aTimeOutNotify )
+ {
+ OstTraceFunctionEntry0( CDISMOUNTTIMER_NEWLC_ENTRY );
+
+ CDismountTimer* self = new (ELeave) CDismountTimer( aTimeOutNotify );
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ OstTraceFunctionExit0( CDISMOUNTTIMER_NEWLC_EXIT );
+ return self;
+ }
+
+CDismountTimer::CDismountTimer( MTimerNotifier* aTimeOutNotify):
+ CTimer(EPriorityStandard),
+ iNotify(aTimeOutNotify)
+ {
+ OstTraceFunctionEntry0( CDISMOUNTTIMER_CDISMOUNTTIMER_CONS_ENTRY );
+ }
+
+CDismountTimer::~CDismountTimer()
+ {
+ OstTraceFunctionEntry0( CDISMOUNTTIMER_CDISMOUNTTIMER_DES_ENTRY );
+
+ Cancel();
+ OstTraceFunctionExit0( CDISMOUNTTIMER_CDISMOUNTTIMER_DES_EXIT );
+ }
+
+void CDismountTimer::ConstructL()
+ {
+ OstTraceFunctionEntry0( CDISMOUNTTIMER_CONSTRUCTL_ENTRY );
+
+ if ( !iNotify )
+ {
+ User::Leave(KErrArgument);
+ }
+ CTimer::ConstructL();
+ CActiveScheduler::Add(this);
+ OstTraceFunctionExit0( CDISMOUNTTIMER_CONSTRUCTL_EXIT );
+ }
+
+void CDismountTimer::RunL()
+ {
+ OstTraceFunctionEntry0( CDISMOUNTTIMER_RUNL_ENTRY );
+
+ // Timer request has completed, so notify the timer's owner
+ iNotify->TimerExpired();
+ OstTraceFunctionExit0( CDISMOUNTTIMER_RUNL_EXIT );
+ }
+void CDismountTimer::CancelTimer()
+ {
+ OstTraceFunctionEntry0( CDISMOUNTTIMER_CANCELTIMER_ENTRY );
+
+ Cancel();
+ OstTraceFunctionExit0( CDISMOUNTTIMER_CANCELTIMER_EXIT );
+ }
+
+void CDismountTimer::StartTimer()
+ {
+ OstTraceFunctionEntry0( CDISMOUNTTIMER_STARTTIMER_ENTRY );
+
+ After( KDismountTimeOut );
+ OstTraceFunctionExit0( CDISMOUNTTIMER_STARTTIMER_EXIT );
+ }
+// End of File