kerneltest/f32test/shostmassstorage/testclient/usbtestmsclient/drivemanager.cpp
changeset 300 1d28c8722707
parent 0 a41df078684a
equal deleted inserted replaced
293:0659d0e1a03c 300:1d28c8722707
     1 // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
     1 // Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
    10 //
    10 //
    11 // Contributors:
    11 // Contributors:
    12 //
    12 //
    13 // Description:
    13 // Description:
    14 // Class implementation of CDriveManager and CMassStorageDrive.
    14 // Class implementation of CDriveManager and CMassStorageDrive.
    15 // 
    15 //
    16 //
    16 //
    17 
    17 
    18 
    18 
    19 
    19 
    20 /**
    20 /**
    30 #include "msctypes.h"
    30 #include "msctypes.h"
    31 
    31 
    32 #include "drivepublisher.h"
    32 #include "drivepublisher.h"
    33 #include "drivemanager.h"
    33 #include "drivemanager.h"
    34 #include "debug.h"
    34 #include "debug.h"
    35 #include "msdebug.h"
       
    36 
    35 
    37 
    36 
    38 void TMediaParams::Init(TLocalDriveCapsV4& aCaps)
    37 void TMediaParams::Init(TLocalDriveCapsV4& aCaps)
    39     {
    38     {
    40     iSize = aCaps.MediaSizeInBytes();
    39     iSize = aCaps.MediaSizeInBytes();
    68         }
    67         }
    69     }
    68     }
    70 
    69 
    71 
    70 
    72 TInt TLocalDriveRef::Read(const TInt64& aPos, TInt aLength, TDes8& aBuf, TBool aWholeMedia)
    71 TInt TLocalDriveRef::Read(const TInt64& aPos, TInt aLength, TDes8& aBuf, TBool aWholeMedia)
    73 	{
    72     {
    74     __MSFNLOG
    73     TInt err = KErrUnknown; // never return this
    75 
    74 
    76 	TInt err = KErrUnknown; // never return this
    75     if(aWholeMedia)
    77 
    76         {
    78 	if(aWholeMedia)
    77         err = iProxyDrive.Read(aPos, aLength, &aBuf, KLocalMessageHandle, 0, RLocalDrive::ELocDrvWholeMedia);
    79 		{
    78         }
    80 		err = iProxyDrive.Read(aPos, aLength, &aBuf, KLocalMessageHandle, 0, RLocalDrive::ELocDrvWholeMedia);
    79     else
    81 		}
    80         {
    82 	else
    81         err = iProxyDrive.Read(aPos, aLength, aBuf);
    83 		{
    82         }
    84 		err = iProxyDrive.Read(aPos, aLength, aBuf);
    83 
    85 		}
    84     if (err == KErrLocked)
    86 
    85         {
    87 	if (err == KErrLocked)
    86         SetDriveState(TLocalDriveRef::ELocked);
    88 		{
    87         }
    89 		SetDriveState(TLocalDriveRef::ELocked);
    88 
    90 		}
    89     return err;
    91 
    90     }
    92 	return err;
       
    93 	}
       
    94 
    91 
    95 
    92 
    96 TInt TLocalDriveRef::Write(const TInt64& aPos, TDesC8& aBuf, TBool aWholeMedia)
    93 TInt TLocalDriveRef::Write(const TInt64& aPos, TDesC8& aBuf, TBool aWholeMedia)
    97     {
    94     {
    98 	TInt err = KErrNone;
    95     TInt err = KErrNone;
    99 
    96 
   100 	TDriveState oldState = iDriveState;
    97     TDriveState oldState = iDriveState;
   101 	if (oldState != EActive)
    98     if (oldState != EActive)
   102         {
    99         {
   103 		// SCSI hasn't called SetCritical
   100         // SCSI hasn't called SetCritical
   104 		SetDriveState(EActive);
   101         SetDriveState(EActive);
   105 		}
   102         }
   106 
   103 
   107 	if (aWholeMedia)
   104     if (aWholeMedia)
   108 		{
   105         {
   109 		err = iProxyDrive.Write(aPos, aBuf.Length(), &aBuf, KLocalMessageHandle, 0, RLocalDrive::ELocDrvWholeMedia);
   106         err = iProxyDrive.Write(aPos, aBuf.Length(), &aBuf, KLocalMessageHandle, 0, RLocalDrive::ELocDrvWholeMedia);
   110 		}
   107         }
   111 	else
   108     else
   112 		{
   109         {
   113 		err = iProxyDrive.Write(aPos,aBuf);
   110         err = iProxyDrive.Write(aPos,aBuf);
   114 		}
   111         }
   115 
   112 
   116 	if (err == KErrLocked)
   113     if (err == KErrLocked)
   117 		{
   114         {
   118 		SetDriveState(ELocked);
   115         SetDriveState(ELocked);
   119 		}
   116         }
   120 	else if (oldState != EActive)
   117     else if (oldState != EActive)
   121 		{
   118         {
   122 		SetDriveState(oldState);
   119         SetDriveState(oldState);
   123 		}
   120         }
   124     return err;
   121     return err;
   125     }
   122     }
   126 
   123 
   127 
   124 
   128 /**
   125 /**
   129 Checks the Media Changed flag, and optionally resets it.
   126 Checks the Media Changed flag, and optionally resets it.
   130 @return The state of the Media Changed flag.
   127 @return The state of the Media Changed flag.
   131 @param aReset If true, the Media Changed flag is reset to EFalse.
   128 @param aReset If true, the Media Changed flag is reset to EFalse.
   132 */
   129 */
   133 TBool TLocalDriveRef::IsMediaChanged(TBool aReset)
   130 TBool TLocalDriveRef::IsMediaChanged(TBool aReset)
   134 	{
   131     {
   135     __MSFNLOG
   132     TBool mediaChanged = iMediaChanged;
   136 	TBool mediaChanged = iMediaChanged;
   133     if (aReset)
   137 	if (aReset)
   134         {
   138         {
   135         iMediaChanged = EFalse;
   139 	   	iMediaChanged = EFalse;
   136         }
   140 	   	}
   137     return mediaChanged;
   141 	return mediaChanged;
   138     }
   142 	}
       
   143 
   139 
   144 
   140 
   145 /**
   141 /**
   146 Set the Drive State to Active or Idle.
   142 Set the Drive State to Active or Idle.
   147 @return KErrNone on success, KErrNotReady if media not present, KErrDisMounted if not mounted
   143 @return KErrNone on success, KErrNotReady if media not present, KErrDisMounted if not mounted
   148 @param aCritical ETrue for Active, EFalse for Idle
   144 @param aCritical ETrue for Active, EFalse for Idle
   149 */
   145 */
   150 TInt TLocalDriveRef::SetCritical(TBool aCritical)
   146 TInt TLocalDriveRef::SetCritical(TBool aCritical)
   151 	{
   147     {
   152     __MSFNLOG
   148     TInt err = KErrNone;
   153 	TInt err = KErrNone;
       
   154     if (iDriveState == EMediaNotPresent)
   149     if (iDriveState == EMediaNotPresent)
   155 		{
   150         {
   156 		err = KErrNotReady;
   151         err = KErrNotReady;
   157 		}
   152         }
   158 	else
   153     else
   159 		{
   154         {
   160         SetDriveState(aCritical ? EActive : EIdle);
   155         SetDriveState(aCritical ? EActive : EIdle);
   161 		}
   156         }
   162 	return err;
   157     return err;
   163 	}
   158     }
   164 
   159 
   165 
   160 
   166 /**
   161 /**
   167 Provides an interface to CProxyDrive::Caps that hides the
   162 Provides an interface to CProxyDrive::Caps that hides the
   168 package buffer.
   163 package buffer.
   169 @return KErrNone on success, otherwise system wide error code
   164 @return KErrNone on success, otherwise system wide error code
   170 @param aInfo
   165 @param aInfo
   171 */
   166 */
   172 TInt TLocalDriveRef::Caps(TLocalDriveCapsV4& aInfo)
   167 TInt TLocalDriveRef::Caps(TLocalDriveCapsV4& aInfo)
   173 	{
   168     {
   174     __MSFNLOG
   169     TLocalDriveCapsV4Buf buf;
   175 	TLocalDriveCapsV4Buf buf;
   170     buf.FillZ();
   176 	buf.FillZ();
   171 
   177 
   172     __PRINT(_L("CMassStorageDrive::DoCaps calling Caps\n"));
   178 	__PRINT(_L("CMassStorageDrive::DoCaps calling Caps\n"));
   173     TInt err = iProxyDrive.Caps(buf);
   179 	TInt err = iProxyDrive.Caps(buf);
   174     __PRINT1(_L("CMassStorageDrive::DoCaps: Caps returned %d\n"), err);
   180 	__PRINT1(_L("CMassStorageDrive::DoCaps: Caps returned %d\n"), err);
   175 
   181 
   176     if (err == KErrNone)
   182 	if (err == KErrNone)
   177         {
   183 		{
   178         // Invoke function call operator to cast to TLocalDriveCapsV4&
   184 		// Invoke function call operator to cast to TLocalDriveCapsV4&
   179         aInfo = buf();
   185 		aInfo = buf();
   180         }
   186 		}
   181 
   187 
   182     return err;
   188 	return err;
   183     }
   189 	}
       
   190 
   184 
   191 
   185 
   192 ///////////////////////////////////////////////////////////////////////////////
   186 ///////////////////////////////////////////////////////////////////////////////
   193 
   187 
   194 /**
   188 /**
   195 @param aCritSec A Critical Section object shared by all drives.
   189 @param aCritSec A Critical Section object shared by all drives.
   196 @param aDrives Reference to the list of CMassStorageDrive objects.
   190 @param aDrives Reference to the list of CMassStorageDrive objects.
   197 @param aDriveMap Reference to array mapping lun to drive number for supported
   191 @param aDriveMap Reference to array mapping lun to drive number for supported
   198 	   mass storage drives.
   192        mass storage drives.
   199 @post Object is fully constructed
   193 @post Object is fully constructed
   200  */
   194  */
   201 CMassStorageDrive* CMassStorageDrive::NewL(RCriticalSection& aCritSec,
   195 CMassStorageDrive* CMassStorageDrive::NewL(RCriticalSection& aCritSec,
   202                                            RDriveStateChangedPublisher& aDriveStateChangedPublisher)
   196                                            RDriveStateChangedPublisher& aDriveStateChangedPublisher)
   203     {
   197     {
   204     __MSFNSLOG
   198     CMassStorageDrive* self = new (ELeave) CMassStorageDrive(aCritSec, aDriveStateChangedPublisher);
   205 	CMassStorageDrive* self = new (ELeave) CMassStorageDrive(aCritSec, aDriveStateChangedPublisher);
   199     CleanupStack::PushL(self);
   206 	CleanupStack::PushL(self);
   200     self->ConstructL();
   207 	self->ConstructL();
   201     CleanupStack::Pop();
   208 	CleanupStack::Pop();
   202     return self;
   209 	return self;
       
   210     }
   203     }
   211 
   204 
   212 
   205 
   213 CMassStorageDrive::CMassStorageDrive(RCriticalSection& aCritSec,
   206 CMassStorageDrive::CMassStorageDrive(RCriticalSection& aCritSec,
   214 									 RDriveStateChangedPublisher& aDriveStateChangedPublisher)
   207                                      RDriveStateChangedPublisher& aDriveStateChangedPublisher)
   215 :   iCritSec(aCritSec),
   208 :   iCritSec(aCritSec),
   216 	iMountState(EDisconnected),
   209     iMountState(EDisconnected),
   217 	iDriveStateChangedPublisher(aDriveStateChangedPublisher)
   210     iDriveStateChangedPublisher(aDriveStateChangedPublisher)
   218 	{
   211     {
   219     __MSFNLOG
   212     }
   220 	}
       
   221 
   213 
   222 
   214 
   223 void CMassStorageDrive::ConstructL()
   215 void CMassStorageDrive::ConstructL()
   224     {
   216     {
   225     __MSFNLOG
       
   226     iDriveMediaErrorPublisher = new (ELeave) RDriveMediaErrorPublisher();
   217     iDriveMediaErrorPublisher = new (ELeave) RDriveMediaErrorPublisher();
   227     }
   218     }
   228 
   219 
   229 
   220 
   230 CMassStorageDrive::~CMassStorageDrive()
   221 CMassStorageDrive::~CMassStorageDrive()
   231 	{
   222     {
   232     __MSFNLOG
       
   233     delete iDriveMediaErrorPublisher;
   223     delete iDriveMediaErrorPublisher;
   234 	delete iLocalDrive;
   224     delete iLocalDrive;
   235 	}
   225     }
   236 
   226 
   237 /**
   227 /**
   238 Read from the target drive unit.
   228 Read from the target drive unit.
   239 @return KErrNone on success, otherwise system wide error code
   229 @return KErrNone on success, otherwise system wide error code
   240 */
   230 */
   241 TInt CMassStorageDrive::Read(const TInt64& aPos, TInt aLength, TDes8& aBuf, TBool aWholeMedia)
   231 TInt CMassStorageDrive::Read(const TInt64& aPos, TInt aLength, TDes8& aBuf, TBool aWholeMedia)
   242 	{
   232     {
   243     __MSFNLOG
   233 
   244 
   234     TInt err = KErrUnknown; // never return this
   245 	TInt err = KErrUnknown; // never return this
   235     iCritSec.Wait();
   246 	iCritSec.Wait();
   236 
   247 
   237     if(iMountState != EConnected)
   248 	if(iMountState != EConnected)
   238         {
   249 		{
   239         err = KErrDisconnected;
   250 		err = KErrDisconnected;
   240         }
   251 		}
   241     else
   252 	else
   242         {
   253 		{
       
   254         err = iLocalDrive->Read(aPos, aLength, aBuf, aWholeMedia);
   243         err = iLocalDrive->Read(aPos, aLength, aBuf, aWholeMedia);
   255 		}
   244         }
   256 
   245 
   257 	iCritSec.Signal();
   246     iCritSec.Signal();
   258 	return err;
   247     return err;
   259 	}
   248     }
   260 
   249 
   261 
   250 
   262 /**
   251 /**
   263 Write to the target drive unit.
   252 Write to the target drive unit.
   264 @return KErrNone on success, otherwise system wide error code
   253 @return KErrNone on success, otherwise system wide error code
   265 */
   254 */
   266 TInt CMassStorageDrive::Write(const TInt64& aPos, TDesC8& aBuf, TBool aWholeMedia)
   255 TInt CMassStorageDrive::Write(const TInt64& aPos, TDesC8& aBuf, TBool aWholeMedia)
   267 	{
   256     {
   268     __MSFNLOG
   257     TInt err = KErrNone;
   269 
   258     iCritSec.Wait();
   270 	TInt err = KErrNone;
   259 
   271 	iCritSec.Wait();
   260     if (iMountState != EConnected)
   272 
   261         {
   273 	if (iMountState != EConnected)
   262         err = KErrDisconnected;
   274 		{
   263         }
   275 		err = KErrDisconnected;
   264     else
   276 		}
   265         {
   277 	else
   266         __ASSERT_DEBUG(iLocalDrive, User::Invariant());
   278 		{
       
   279 		__ASSERT_DEBUG(iLocalDrive, User::Invariant());
       
   280         err = iLocalDrive->Write(aPos, aBuf, aWholeMedia);
   267         err = iLocalDrive->Write(aPos, aBuf, aWholeMedia);
   281 		}
   268         }
   282 
   269 
   283 	iCritSec.Signal();
   270     iCritSec.Signal();
   284 	return err;
   271     return err;
   285 	}
   272     }
   286 
   273 
   287 
   274 
   288 /**
   275 /**
   289 Provides an interface to CProxyDrive::Caps that hides the
   276 Provides an interface to CProxyDrive::Caps that hides the
   290 package buffer.
   277 package buffer.
   291 @return KErrNone on success, otherwise system wide error code
   278 @return KErrNone on success, otherwise system wide error code
   292 @param aInfo
   279 @param aInfo
   293 */
   280 */
   294 TInt CMassStorageDrive::DoCaps(TLocalDriveCapsV4& aInfo)
   281 TInt CMassStorageDrive::DoCaps(TLocalDriveCapsV4& aInfo)
   295 	{
   282     {
   296     __MSFNLOG
       
   297     TInt err = KErrDisMounted;
   283     TInt err = KErrDisMounted;
   298 
   284 
   299     if (iLocalDrive)
   285     if (iLocalDrive)
   300         {
   286         {
   301         err = iLocalDrive->Caps(aInfo);
   287         err = iLocalDrive->Caps(aInfo);
   302         }
   288         }
   303 	return err;
   289     return err;
   304 	}
   290     }
   305 
   291 
   306 
   292 
   307 /**
   293 /**
   308 Publish media error, user should reinsert the memory card.
   294 Publish media error, user should reinsert the memory card.
   309 Similar to FAT32's TDriver::HandleCriticalError.
   295 Similar to FAT32's TDriver::HandleCriticalError.
   310 Note: User notification is not implemented, instead we abort and dismount.
   296 Note: User notification is not implemented, instead we abort and dismount.
   311 */
   297 */
   312 TInt CMassStorageDrive::HandleCriticalError()
   298 TInt CMassStorageDrive::HandleCriticalError()
   313 	{
   299     {
   314     __MSFNLOG
   300     TRAPD(err, iDriveMediaErrorPublisher->PublishErrorL(ETrue));
   315 	TRAPD(err, iDriveMediaErrorPublisher->PublishErrorL(ETrue));
       
   316     // ignore leave
   301     // ignore leave
   317     err = err;
   302     err = err;
   318 	return KErrAbort;
   303     return KErrAbort;
   319 	}
   304     }
   320 
   305 
   321 
   306 
   322 TInt CMassStorageDrive::ClearCriticalError()
   307 TInt CMassStorageDrive::ClearCriticalError()
   323 	{
   308     {
   324     __MSFNLOG
   309     TRAPD(err, iDriveMediaErrorPublisher->PublishErrorL(EFalse));
   325 	TRAPD(err, iDriveMediaErrorPublisher->PublishErrorL(EFalse));
       
   326     // ignore leave
   310     // ignore leave
   327     err = err;
   311     err = err;
   328 	return KErrNone;
   312     return KErrNone;
   329 	}
   313     }
   330 
   314 
   331 
   315 
   332 /**
   316 /**
   333 Checks the Media Changed flag, and optionally resets it.
   317 Checks the Media Changed flag, and optionally resets it.
   334 @return The state of the Media Changed flag.
   318 @return The state of the Media Changed flag.
   335 @param aReset If true, the Media Changed flag is reset to EFalse.
   319 @param aReset If true, the Media Changed flag is reset to EFalse.
   336 */
   320 */
   337 TBool CMassStorageDrive::IsMediaChanged(TBool aReset)
   321 TBool CMassStorageDrive::IsMediaChanged(TBool aReset)
   338 	{
   322     {
   339     __MSFNLOG
   323     iCritSec.Wait();
   340 
   324 
   341 	iCritSec.Wait();
   325     TBool mediaChanged = EFalse;
   342 
   326     if (iLocalDrive)
   343 	TBool mediaChanged = EFalse;
   327         {
   344 	if (iLocalDrive)
   328         mediaChanged = iLocalDrive->IsMediaChanged(aReset);
   345 		{
   329         }
   346 		mediaChanged = iLocalDrive->IsMediaChanged(aReset);
   330 
   347         }
   331     iCritSec.Signal();
   348 
   332 
   349 	iCritSec.Signal();
   333     __PRINT1(_L("CMassStorageDrive::IsMediaChanged: returning %d\n"), mediaChanged);
   350 
   334     return mediaChanged;
   351 	__PRINT1(_L("CMassStorageDrive::IsMediaChanged: returning %d\n"), mediaChanged);
   335     }
   352 	return mediaChanged;
       
   353 	}
       
   354 
   336 
   355 /**
   337 /**
   356 Set the Drive State to Active or Idle.
   338 Set the Drive State to Active or Idle.
   357 @return KErrNone on success, KErrNotReady if media not present, KErrDisMounted if not mounted
   339 @return KErrNone on success, KErrNotReady if media not present, KErrDisMounted if not mounted
   358 @param aCritical ETrue for Active, EFalse for Idle
   340 @param aCritical ETrue for Active, EFalse for Idle
   359 */
   341 */
   360 TInt CMassStorageDrive::SetCritical(TBool aCritical)
   342 TInt CMassStorageDrive::SetCritical(TBool aCritical)
   361 	{
   343     {
   362     __MSFNLOG
   344     TInt err = KErrDisMounted;
   363 
   345     iCritSec.Wait();
   364 	TInt err = KErrDisMounted;
   346     if (iLocalDrive)
   365 	iCritSec.Wait();
   347         {
   366 	if (iLocalDrive)
       
   367 		{
       
   368         err = iLocalDrive->SetCritical(aCritical);
   348         err = iLocalDrive->SetCritical(aCritical);
   369 		}
   349         }
   370 
   350 
   371 	iCritSec.Signal();
   351     iCritSec.Signal();
   372 	return err;
   352     return err;
   373 	}
   353     }
   374 
   354 
   375 /**
   355 /**
   376 Set the mount state
   356 Set the mount state
   377 */
   357 */
   378 void CMassStorageDrive::SetMountConnectedL(CProxyDrive& aProxyDrive,
   358 void CMassStorageDrive::SetMountConnectedL(CProxyDrive& aProxyDrive,
   379                                            TBool& aMediaChanged,
   359                                            TBool& aMediaChanged,
   380                                            RDriveStateChangedPublisher& aDriveStateChangedPublisher)
   360                                            RDriveStateChangedPublisher& aDriveStateChangedPublisher)
   381 	{
   361     {
   382     __MSFNLOG
   362     TLocalDriveRef* localDrive = NULL;
   383 	TLocalDriveRef* localDrive = NULL;
   363 
   384 
   364     __PRINT(_L("SetMountConnectedL entering critical section\n"));
   385 	__PRINT(_L("SetMountConnectedL entering critical section\n"));
   365     iCritSec.Wait(); // note: signalled in SetMountState
   386 	iCritSec.Wait(); // note: signalled in SetMountState
   366 
   387 
   367     TRAPD(err, localDrive = new (ELeave) TLocalDriveRef(aProxyDrive,
   388    	TRAPD(err, localDrive = new (ELeave) TLocalDriveRef(aProxyDrive,
       
   389                                                         aMediaChanged,
   368                                                         aMediaChanged,
   390                                                         aDriveStateChangedPublisher));
   369                                                         aDriveStateChangedPublisher));
   391    	if (err)
   370     if (err)
   392    		{
   371         {
   393    		iCritSec.Signal();
   372         iCritSec.Signal();
   394    		User::Leave(err);
   373         User::Leave(err);
   395    		}
   374         }
   396 	iLocalDrive = localDrive;
   375     iLocalDrive = localDrive;
   397 	SetMountState(EConnected, ETrue);
   376     SetMountState(EConnected, ETrue);
   398 	}
   377     }
   399 
   378 
   400 /**
   379 /**
   401 @return KErrNone
   380 @return KErrNone
   402 @param aNewState
   381 @param aNewState
   403 @param aLocalDrive Only provide this if aNewState is EConnected.
   382 @param aLocalDrive Only provide this if aNewState is EConnected.
   404 */
   383 */
   405 void CMassStorageDrive::SetMountState(TMountState aNewState, TBool aCriticalSection/*=EFalse*/)
   384 void CMassStorageDrive::SetMountState(TMountState aNewState, TBool aCriticalSection/*=EFalse*/)
   406 	{
   385     {
   407     __MSFNLOG
   386     if(iMountState == aNewState)
   408 	if(iMountState == aNewState)
   387         {
   409 		{
   388         __PRINT(_L("SetMountState: No change\n"));
   410 		__PRINT(_L("SetMountState: No change\n"));
   389         }
   411 		}
   390     else
   412 	else
   391         {
   413 		{
   392         // If called from SetMountConnected, already in critical section,
   414 		// If called from SetMountConnected, already in critical section,
       
   415         // otherwise, must enter it here.
   393         // otherwise, must enter it here.
   416         if (!aCriticalSection)
   394         if (!aCriticalSection)
   417             {
   395             {
   418 			iCritSec.Wait();
   396             iCritSec.Wait();
   419             }
   397             }
   420 
   398 
   421 		switch(aNewState)
   399         switch(aNewState)
   422 			{
   400             {
   423 			case EDisconnected:
   401             case EDisconnected:
   424 				delete iLocalDrive;
   402                 delete iLocalDrive;
   425 				iLocalDrive = NULL;
   403                 iLocalDrive = NULL;
   426 				break;
   404                 break;
   427 
   405 
   428 			case EConnected:
   406             case EConnected:
   429 			case EDisconnecting:
   407             case EDisconnecting:
   430 			case EConnecting:
   408             case EConnecting:
   431 				// Do not change iLocalDrive for these state changes
   409                 // Do not change iLocalDrive for these state changes
   432 				break;
   410                 break;
   433 			}
   411             }
   434 
   412 
   435 		iMountState = aNewState;
   413         iMountState = aNewState;
   436 		__PRINT1(_L("SetMountState: state=%d\n"), iMountState);
   414         __PRINT1(_L("SetMountState: state=%d\n"), iMountState);
   437 
   415 
   438 		iDriveStateChangedPublisher.DriveStateChanged();
   416         iDriveStateChangedPublisher.DriveStateChanged();
   439 		iCritSec.Signal();
   417         iCritSec.Signal();
   440 		__PRINT(_L("SetMountState has left the critical section\n"));
   418         __PRINT(_L("SetMountState has left the critical section\n"));
   441 		}
   419         }
   442 	}
   420     }
   443 
   421 
   444 /**
   422 /**
   445 @return Current drive media state
   423 @return Current drive media state
   446 */
   424 */
   447 TLocalDriveRef::TDriveState CMassStorageDrive::DriveState() const
   425 TLocalDriveRef::TDriveState CMassStorageDrive::DriveState() const
   448 	{
   426     {
   449     __MSFNSLOG
   427     return iLocalDrive ? iLocalDrive->DriveState() : TLocalDriveRef::EErrDisMounted;
   450 	return iLocalDrive ? iLocalDrive->DriveState() : TLocalDriveRef::EErrDisMounted;
   428     }
   451 	}
       
   452 
   429 
   453 /**
   430 /**
   454 Check for media not present, and return the drive state.
   431 Check for media not present, and return the drive state.
   455 @return Current drive media state
   432 @return Current drive media state
   456 */
   433 */
   457 TLocalDriveRef::TDriveState CMassStorageDrive::CheckDriveState()
   434 TLocalDriveRef::TDriveState CMassStorageDrive::CheckDriveState()
   458 	{
   435     {
   459     __MSFNLOG
   436     TLocalDriveRef::TDriveState state = TLocalDriveRef::EErrDisMounted;
   460 	TLocalDriveRef::TDriveState state = TLocalDriveRef::EErrDisMounted;
   437     iCritSec.Wait();
   461 	iCritSec.Wait();
   438 
   462 
   439     if (iLocalDrive)
   463 	if (iLocalDrive)
   440         {
   464 		{
   441         TInt err = KErrGeneral;
   465 		TInt err = KErrGeneral;
       
   466         TLocalDriveCapsV4 caps;
   442         TLocalDriveCapsV4 caps;
   467 
   443 
   468 		FOREVER
   444         FOREVER
   469 			{
   445             {
   470 			// Initialise in case Caps() fails
   446             // Initialise in case Caps() fails
   471 			caps.iType = ::EMediaNotPresent;
   447             caps.iType = ::EMediaNotPresent;
   472 			err = DoCaps(caps);
   448             err = DoCaps(caps);
   473 
   449 
   474 			__PRINTERR(_L("CheckDriveState: DoCaps err=%d\n"), err);
   450             __PRINTERR(_L("CheckDriveState: DoCaps err=%d\n"), err);
   475 			if (err == KErrNotReady || (err == KErrNone && caps.iType == ::EMediaNotPresent))
   451             if (err == KErrNotReady || (err == KErrNone && caps.iType == ::EMediaNotPresent))
   476 				{
   452                 {
   477 				__PRINT(_L("CheckDriveState: detected MediaNotPresent\n"));
   453                 __PRINT(_L("CheckDriveState: detected MediaNotPresent\n"));
   478 
   454 
   479 				SetDriveState(TLocalDriveRef::EMediaNotPresent);
   455                 SetDriveState(TLocalDriveRef::EMediaNotPresent);
   480 
   456 
   481 				if (HandleCriticalError() == KErrAbort)
   457                 if (HandleCriticalError() == KErrAbort)
   482 					break;
   458                     break;
   483 				}
   459                 }
   484 			else
   460             else
   485 				{
   461                 {
   486 				ClearCriticalError();
   462                 ClearCriticalError();
   487 				break;
   463                 break;
   488 				}
   464                 }
   489 			}
   465             }
   490 
   466 
   491 		if (err == KErrNone && caps.iType != ::EMediaNotPresent)
   467         if (err == KErrNone && caps.iType != ::EMediaNotPresent)
   492 			{
   468             {
   493             iMediaParams.Init(caps);
   469             iMediaParams.Init(caps);
   494             TLocalDriveRef::TDriveState driveState = TLocalDriveRef::EIdle;
   470             TLocalDriveRef::TDriveState driveState = TLocalDriveRef::EIdle;
   495 
   471 
   496 			if (iLocalDrive->DriveState() == TLocalDriveRef::EMediaNotPresent)
   472             if (iLocalDrive->DriveState() == TLocalDriveRef::EMediaNotPresent)
   497 				{
   473                 {
   498 				__PRINT(_L("CheckDriveState: detected media inserted\n"));
   474                 __PRINT(_L("CheckDriveState: detected media inserted\n"));
   499 				}
   475                 }
   500 			else if (iLocalDrive->DriveState() == TLocalDriveRef::ELocked &&
   476             else if (iLocalDrive->DriveState() == TLocalDriveRef::ELocked &&
   501 					 !(caps.iMediaAtt & KMediaAttLocked))
   477                      !(caps.iMediaAtt & KMediaAttLocked))
   502 				{
   478                 {
   503 				__PRINT(_L("CheckDriveState: detected media unlocked\n"));
   479                 __PRINT(_L("CheckDriveState: detected media unlocked\n"));
   504 				}
   480                 }
   505 			else if (caps.iMediaAtt & KMediaAttLocked)
   481             else if (caps.iMediaAtt & KMediaAttLocked)
   506 				{
   482                 {
   507 				__PRINT(_L("CheckDriveState: detected media locked\n"));
   483                 __PRINT(_L("CheckDriveState: detected media locked\n"));
   508 				driveState = TLocalDriveRef::ELocked;
   484                 driveState = TLocalDriveRef::ELocked;
   509 				}
   485                 }
   510             SetDriveState(driveState);
   486             SetDriveState(driveState);
   511 			}
   487             }
   512 
   488 
   513 		// Get the current state
   489         // Get the current state
   514 		state = iLocalDrive->DriveState();
   490         state = iLocalDrive->DriveState();
   515 		}
   491         }
   516 
   492 
   517 	iCritSec.Signal();
   493     iCritSec.Signal();
   518 
   494 
   519 	return state;
   495     return state;
   520 	}
   496     }
   521 
   497 
   522 
   498 
   523 /**
   499 /**
   524 @param aNewState
   500 @param aNewState
   525 */
   501 */
   526 void CMassStorageDrive::SetDriveState(TLocalDriveRef::TDriveState aNewState)
   502 void CMassStorageDrive::SetDriveState(TLocalDriveRef::TDriveState aNewState)
   527 	{
   503     {
   528     __MSFNLOG
   504     __ASSERT_DEBUG(aNewState == TLocalDriveRef::EIdle ||
   529 	__ASSERT_DEBUG(aNewState == TLocalDriveRef::EIdle ||
       
   530                    (iMountState == EConnected && NULL != iLocalDrive) ||
   505                    (iMountState == EConnected && NULL != iLocalDrive) ||
   531                    (iMountState == EDisconnecting && NULL != iLocalDrive),
   506                    (iMountState == EDisconnecting && NULL != iLocalDrive),
   532         User::Invariant());
   507         User::Invariant());
   533 
   508 
   534 	if (!iLocalDrive)
   509     if (!iLocalDrive)
   535 		{
   510         {
   536 		__PRINT(_L("SetDriveState: Drive not mounted.\n"));
   511         __PRINT(_L("SetDriveState: Drive not mounted.\n"));
   537 		}
   512         }
   538 	else
   513     else
   539 		{
   514         {
   540         iLocalDrive->SetDriveState(aNewState);
   515         iLocalDrive->SetDriveState(aNewState);
   541 		__PRINT2(_L("SetDriveState: %d->%d\n"), iLocalDrive->iDriveState, aNewState);
   516         __PRINT2(_L("SetDriveState: %d->%d\n"), iLocalDrive->iDriveState, aNewState);
   542 		}
   517         }
   543 	}
   518     }
   544 
   519 
   545 
   520 
   546 /////////////////////////////////////////////////////////////////
   521 /////////////////////////////////////////////////////////////////
   547 
   522 
   548 /**
   523 /**
   549 Construct a CDriveManager object.
   524 Construct a CDriveManager object.
   550 @param aDriveMap Reference to array mapping lun to drive number for supported
   525 @param aDriveMap Reference to array mapping lun to drive number for supported
   551 	   mass storage drives.
   526        mass storage drives.
   552 */
   527 */
   553 CDriveManager* CDriveManager::NewL(const TLunToDriveMap& aDriveMap)
   528 CDriveManager* CDriveManager::NewL(const TLunToDriveMap& aDriveMap)
   554 	{
   529     {
   555     __MSFNSLOG
   530     __PRINT1(_L("CDriveManager::NewL - %d drives\n"), aDriveMap.Count());
   556 	__PRINT1(_L("CDriveManager::NewL - %d drives\n"), aDriveMap.Count());
   531 
   557 
   532     CDriveManager* self = new (ELeave) CDriveManager(aDriveMap.Count() -1);
   558 	CDriveManager* self = new (ELeave) CDriveManager(aDriveMap.Count() -1);
   533     CleanupStack::PushL(self);
   559 	CleanupStack::PushL(self);
   534     self->ConstructL(aDriveMap);
   560 	self->ConstructL(aDriveMap);
   535     CleanupStack::Pop();
   561 	CleanupStack::Pop();
   536     return self;
   562 	return self;
   537     }
   563 	}
       
   564 
   538 
   565 CDriveManager::CDriveManager(TLun aMaxLun)
   539 CDriveManager::CDriveManager(TLun aMaxLun)
   566 :   iMaxLun(aMaxLun)
   540 :   iMaxLun(aMaxLun)
   567 	{
   541     {
   568     __MSFNLOG
       
   569     }
   542     }
   570 
   543 
   571 /**
   544 /**
   572 Construct a CDriveManager object.
   545 Construct a CDriveManager object.
   573 */
   546 */
   574 void CDriveManager::ConstructL(const TLunToDriveMap& aDriveMap)
   547 void CDriveManager::ConstructL(const TLunToDriveMap& aDriveMap)
   575 	{
   548     {
   576     __MSFNLOG
   549     User::LeaveIfError(iDriveCritSec.CreateLocal());
   577 	User::LeaveIfError(iDriveCritSec.CreateLocal());
       
   578 
   550 
   579     iDriveStateChangedPublisher = new (ELeave) RDriveStateChangedPublisher(iDrives, aDriveMap);
   551     iDriveStateChangedPublisher = new (ELeave) RDriveStateChangedPublisher(iDrives, aDriveMap);
   580 
   552 
   581     iDrives.Reserve(iMaxLun + 1);
   553     iDrives.Reserve(iMaxLun + 1);
   582 
   554 
   583 	for (TLun lun = 0; lun < iMaxLun + 1; lun++)
   555     for (TLun lun = 0; lun < iMaxLun + 1; lun++)
   584 		{
   556         {
   585 		iDrives.Append(CMassStorageDrive::NewL(iDriveCritSec,
   557         iDrives.Append(CMassStorageDrive::NewL(iDriveCritSec,
   586                                                *iDriveStateChangedPublisher));
   558                                                *iDriveStateChangedPublisher));
   587 		}
   559         }
   588 
   560 
   589 	// Publish initial drive state
   561     // Publish initial drive state
   590 	if (iDrives.Count() > 0)
   562     if (iDrives.Count() > 0)
   591 		{
   563         {
   592 		iDriveStateChangedPublisher->DriveStateChanged();
   564         iDriveStateChangedPublisher->DriveStateChanged();
   593 		}
   565         }
   594 	}
   566     }
   595 
   567 
   596 /**
   568 /**
   597 Destructor
   569 Destructor
   598 */
   570 */
   599 CDriveManager::~CDriveManager()
   571 CDriveManager::~CDriveManager()
   600 	{
   572     {
   601     __MSFNLOG
   573     iDrives.ResetAndDestroy();
   602 	iDrives.ResetAndDestroy();
   574     delete iDriveStateChangedPublisher;
   603 	delete iDriveStateChangedPublisher;
   575     iDriveCritSec.Close();
   604 	iDriveCritSec.Close();
   576     }
   605 	}
       
   606 
   577 
   607 /**
   578 /**
   608 Set the mount state to Connected and specify the Proxy Drive.
   579 Set the mount state to Connected and specify the Proxy Drive.
   609 @return KErrNone on success, otherwise system wide error code
   580 @return KErrNone on success, otherwise system wide error code
   610 @param aDrive The mounted Proxy Drive
   581 @param aDrive The mounted Proxy Drive
   612 @pre If the Mount State is Connected, then aDrive must be the
   583 @pre If the Mount State is Connected, then aDrive must be the
   613      same as it was the last time this function was called.
   584      same as it was the last time this function was called.
   614 @post The Mount State will be Connected.
   585 @post The Mount State will be Connected.
   615 */
   586 */
   616 void CDriveManager::RegisterDriveL(CProxyDrive& aProxyDrive, TBool& aMediaChanged, TLun aLun)
   587 void CDriveManager::RegisterDriveL(CProxyDrive& aProxyDrive, TBool& aMediaChanged, TLun aLun)
   617 	{
   588     {
   618     __MSFNLOG
   589     __PRINT1(_L("Lun=%d \n"),aLun);
   619 	__PRINT1(_L("Lun=%d \n"),aLun);
   590     CMassStorageDrive* drive = Drive(aLun);
   620 	CMassStorageDrive* drive = Drive(aLun);
   591     drive->SetMountConnectedL(aProxyDrive, aMediaChanged, *iDriveStateChangedPublisher);
   621 	drive->SetMountConnectedL(aProxyDrive, aMediaChanged, *iDriveStateChangedPublisher);
   592     }
   622 	}
       
   623 
   593 
   624 /**
   594 /**
   625 Set the mount state to Disconnected.
   595 Set the mount state to Disconnected.
   626 @return KErrNone on success, otherwise system wide error code
   596 @return KErrNone on success, otherwise system wide error code
   627 @param aLun The Logical Drive Unit identifier (0..numDrives-1)
   597 @param aLun The Logical Drive Unit identifier (0..numDrives-1)
   628 @post The Mount State will be Disconnected.
   598 @post The Mount State will be Disconnected.
   629 */
   599 */
   630 void CDriveManager::DeregisterDrive(TLun aLun)
   600 void CDriveManager::DeregisterDrive(TLun aLun)
   631 	{
   601     {
   632     __MSFNLOG
       
   633     CMassStorageDrive* drive = Drive(aLun);
   602     CMassStorageDrive* drive = Drive(aLun);
   634 	drive->SetMountDisconnected();
   603     drive->SetMountDisconnected();
   635 	}
   604     }
   636 
   605 
   637 /**
   606 /**
   638 Return a pointer to the drive specified aLun, or NULL if aLun is invalid.
   607 Return a pointer to the drive specified aLun, or NULL if aLun is invalid.
   639 
   608 
   640 @return Pointer to the specified drive, or NULL.
   609 @return Pointer to the specified drive, or NULL.
   641 @param aLun The Logical Drive Unit identifier (0..numDrives-1)
   610 @param aLun The Logical Drive Unit identifier (0..numDrives-1)
   642 @param aError KErrNone on success, KErrArgument if NULL is returned.
   611 @param aError KErrNone on success, KErrArgument if NULL is returned.
   643 */
   612 */
   644 CMassStorageDrive* CDriveManager::Drive(TLun aLun) const
   613 CMassStorageDrive* CDriveManager::Drive(TLun aLun) const
   645 	{
   614     {
   646     __MSFNSLOG
   615     __ASSERT_DEBUG(aLun < iDrives.Count(), User::Invariant());
   647 	__ASSERT_DEBUG(aLun < iDrives.Count(), User::Invariant());
       
   648     return iDrives[aLun];
   616     return iDrives[aLun];
   649 	}
   617     }
   650 
   618 
   651 /**
   619 /**
   652 Checks the Media Changed flag, and optionally resets it.
   620 Checks the Media Changed flag, and optionally resets it.
   653 @return The state of the Media Changed flag.
   621 @return The state of the Media Changed flag.
   654 @param aLun The Logical Drive Unit identifier (0..numDrives-1)
   622 @param aLun The Logical Drive Unit identifier (0..numDrives-1)
   655 @param aReset If true, the Media Changed flag is reset to EFalse.
   623 @param aReset If true, the Media Changed flag is reset to EFalse.
   656 */
   624 */
   657 TBool CDriveManager::IsMediaChanged(TLun aLun, TBool aReset)
   625 TBool CDriveManager::IsMediaChanged(TLun aLun, TBool aReset)
   658 	{
   626     {
   659     __MSFNLOG
   627     CMassStorageDrive* drive = Drive(aLun);
   660 	CMassStorageDrive* drive = Drive(aLun);
   628     return drive->IsMediaChanged(aReset);
   661 	return drive->IsMediaChanged(aReset);
   629     }
   662 	}
       
   663 
   630 
   664 /**
   631 /**
   665 Set the Drive State to Active or Idle.
   632 Set the Drive State to Active or Idle.
   666 Ref: 3.6.3.2 - PREVENT_MEDIUM_REMOVAL
   633 Ref: 3.6.3.2 - PREVENT_MEDIUM_REMOVAL
   667 @return KErrNone on success, otherwise system wide error code
   634 @return KErrNone on success, otherwise system wide error code
   668 @param aLun The Logical Drive Unit identifier (0..numDrives-1)
   635 @param aLun The Logical Drive Unit identifier (0..numDrives-1)
   669 @param aCritical ETrue for Active, EFalse for Idle
   636 @param aCritical ETrue for Active, EFalse for Idle
   670 */
   637 */
   671 TInt CDriveManager::SetCritical(TLun aLun, TBool aCritical)
   638 TInt CDriveManager::SetCritical(TLun aLun, TBool aCritical)
   672 	{
   639     {
   673     __MSFNLOG
   640     TInt err = KErrUnknown; // never return this
   674 	TInt err = KErrUnknown; // never return this
   641 
   675 
   642     TLun i = aLun;
   676 	TLun i = aLun;
   643     TLun cnt = aLun + 1;
   677 	TLun cnt = aLun + 1;
   644 
   678 
   645     if (aLun == KAllLuns)
   679 	if (aLun == KAllLuns)
   646         {
   680 		{
   647         i = 0;
   681 		i = 0;
   648         cnt = iMaxLun + 1;
   682 		cnt = iMaxLun + 1;
   649         }
   683 		}
   650 
   684 
   651     for(; i < cnt; i++)
   685 	for(; i < cnt; i++)
   652         {
   686 		{
   653         CMassStorageDrive* drive = Drive(i);
   687 		CMassStorageDrive* drive = Drive(i);
   654         err = drive->SetCritical(aCritical);
   688 		err = drive->SetCritical(aCritical);
   655         }
   689 		}
   656     return err;
   690 	return err;
   657     }
   691 	}
       
   692 
   658 
   693 void CDriveManager::Connect()
   659 void CDriveManager::Connect()
   694 	{
   660     {
   695 	__FNLOG("CDriveManager::Connect");
       
   696     TLun lun = iMaxLun;
   661     TLun lun = iMaxLun;
   697     do
   662     do
   698         {
   663         {
   699         Connect(lun);
   664         Connect(lun);
   700         }
   665         }
   706 @return KErrNone on success, otherwise system wide error code
   671 @return KErrNone on success, otherwise system wide error code
   707 @param aLun The Logical Drive Unit identifier (0..numDrives-1)
   672 @param aLun The Logical Drive Unit identifier (0..numDrives-1)
   708 @post The Mount State will be Connected or Connecting.
   673 @post The Mount State will be Connected or Connecting.
   709 */
   674 */
   710 void CDriveManager::Connect(TLun aLun)
   675 void CDriveManager::Connect(TLun aLun)
   711 	{
   676     {
   712     __MSFNLOG
   677     CMassStorageDrive* drive = Drive(aLun);
   713 	CMassStorageDrive* drive = Drive(aLun);
   678 
   714 
   679     __PRINT2(_L("CDriveManager::Connect lun=%d, mountState=%d\n"), aLun, drive->MountState());
   715 	__PRINT2(_L("CDriveManager::Connect lun=%d, mountState=%d\n"), aLun, drive->MountState());
   680 
   716 
   681     switch(drive->MountState())
   717    	switch(drive->MountState())
   682         {
   718    		{
   683     case CMassStorageDrive::EDisconnected:
   719  	case CMassStorageDrive::EDisconnected:
   684         drive->SetMountConnecting();
   720  		drive->SetMountConnecting();
   685         break;
   721  		break;
   686     case CMassStorageDrive::EDisconnecting:
   722  	case CMassStorageDrive::EDisconnecting:
   687         drive->SetMountConnected();
   723  		drive->SetMountConnected();
   688         break;
   724  		break;
   689     case CMassStorageDrive::EConnected:
   725  	case CMassStorageDrive::EConnected:
   690     case CMassStorageDrive::EConnecting:
   726  	case CMassStorageDrive::EConnecting:
       
   727     default:
   691     default:
   728  		// do nothing
   692         // do nothing
   729  		break;
   693         break;
   730 		}
   694         }
   731 	}
   695     }
   732 
   696 
   733 void CDriveManager::Disconnect()
   697 void CDriveManager::Disconnect()
   734 	{
   698     {
   735 	__FNLOG("CDriveManager::Disconnect");
       
   736     TLun lun = iMaxLun;
   699     TLun lun = iMaxLun;
   737     do
   700     do
   738         {
   701         {
   739         Disconnect(lun);
   702         Disconnect(lun);
   740         }
   703         }
   746 @return KErrNone on success, otherwise system wide error code
   709 @return KErrNone on success, otherwise system wide error code
   747 @param aLun The Logical Drive Unit identifier (0..numDrives-1)
   710 @param aLun The Logical Drive Unit identifier (0..numDrives-1)
   748 @post The Mount State will be Disconnected or Disconnecting.
   711 @post The Mount State will be Disconnected or Disconnecting.
   749 */
   712 */
   750 void CDriveManager::Disconnect(TLun aLun)
   713 void CDriveManager::Disconnect(TLun aLun)
   751 	{
   714     {
   752     __MSFNLOG
   715     CMassStorageDrive* drive = Drive(aLun);
   753 	CMassStorageDrive* drive = Drive(aLun);
   716     switch (drive->MountState())
   754    	switch (drive->MountState())
   717         {
   755    		{
   718     case CMassStorageDrive::EConnected:
   756    	case CMassStorageDrive::EConnected:
   719         drive->SetMountDisconnecting();
   757    		drive->SetMountDisconnecting();
   720         break;
   758    		break;
   721     case CMassStorageDrive::EConnecting:
   759    	case CMassStorageDrive::EConnecting:
   722         drive->SetMountDisconnected();
   760    		drive->SetMountDisconnected();
   723         break;
   761    		break;
   724     case CMassStorageDrive::EDisconnected:
   762    	case CMassStorageDrive::EDisconnected:
   725     case CMassStorageDrive::EDisconnecting:
   763    	case CMassStorageDrive::EDisconnecting:
   726         // do nothing
   764    		// do nothing
   727         break;
   765    		break;
   728         }
   766    		}
   729     }
   767 	}