os/kernelhwsrv/kerneltest/e32test/usb/t_usb_device/src/usbms.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // USB Mass Storage Application
    15 // 
    16 //
    17 
    18 /**
    19  @file
    20 */
    21 
    22 #include "general.h"
    23 #include "config.h"
    24 #include "activecontrol.h"
    25 
    26 #include <usbmsshared.h>
    27 #include <massstorage.h>
    28 
    29 #include "usbms.h"
    30 
    31 extern CActiveControl* gActiveControl;
    32 extern RTest test;
    33 extern TBool gVerbose;
    34 extern TBool gSkip;
    35 extern TBool gTempTest;
    36 
    37 
    38 LOCAL_D RFs fs;
    39 LOCAL_D TBuf<0x40> mountList;
    40 
    41 LOCAL_D TFixedArray<TBool, KMaxDrives>                   msfsMountedList;  ///< 'true' entry corresponds to the drive with mounted MSFS.FSY
    42 LOCAL_D TFixedArray<CFileSystemDescriptor*, KMaxDrives>  unmountedFsList;  ///< every non-NULL entry corresponds to the unmounted original FS for the drive
    43 
    44 LOCAL_D RUsbMassStorage UsbMs;
    45 
    46 LOCAL_D CUsbWatch * usbWatch;
    47 
    48 static const TUint KNumPropWatch = 4;
    49 LOCAL_D CPropertyWatch * propWatch[KNumPropWatch];
    50 
    51 _LIT(KMsFsy, "MSFS.FSY");
    52 _LIT(KMsFs, "MassStorageFileSystem");
    53 _LIT(KOk,"OK");
    54 _LIT(KError,"Error");
    55 _LIT(KBytesTransferredFmt, "%c:%d/%d \n");
    56 _LIT(KErrFmt, "Error: %d\r");
    57 _LIT(KConfigured,"Configured");
    58 _LIT(KNotConfigured,"NOT Configured");
    59 
    60 
    61 _LIT8(KDefPwd,"123");
    62 TMediaPassword  password(KDefPwd);
    63 
    64 //-----------------------------------------------------------------------------
    65 
    66 CFileSystemDescriptor::~CFileSystemDescriptor()
    67     {
    68     iFsName.Close();
    69     iPrimaryExtName.Close();
    70     }
    71 
    72 //-----------------------------------------------------------------------------
    73 CFileSystemDescriptor* CFileSystemDescriptor::NewL(const TDesC& aFsName, const TDesC& aPrimaryExtName, TBool aDrvSynch)
    74     {
    75     CFileSystemDescriptor* pSelf = new (ELeave) CFileSystemDescriptor;
    76 
    77     CleanupStack::PushL(pSelf);
    78     
    79     pSelf->iFsName.CreateMaxL(aFsName.Length());
    80     pSelf->iFsName.Copy(aFsName);
    81     
    82     pSelf->iPrimaryExtName.CreateMaxL(aPrimaryExtName.Length());
    83     pSelf->iPrimaryExtName.Copy(aPrimaryExtName);
    84 
    85     pSelf->iDriveSynch = aDrvSynch;
    86 
    87     CleanupStack::Pop();
    88 
    89     return pSelf;
    90     }
    91 
    92 //-----------------------------------------------------------------------------
    93 /**
    94     Dismounts the originally mounted FS and optional primary extension from the drive and stores 
    95     this information in the FS descriptor
    96 
    97     @return on success returns a pointer to the instantinated FS descriptor
    98 */
    99 LOCAL_C CFileSystemDescriptor* DoDismountOrginalFS(RFs& aFs, TInt aDrive)
   100     {
   101     TInt        nRes;
   102     TBuf<128>   fsName;
   103     TBuf<128>   primaryExtName;
   104     TBool       bDrvSync = EFalse;
   105 
   106     test.Printf(_L("DoDismountOrginalFS drv:%d\n"), aDrive);
   107 
   108     //-- 1. get file system name
   109     nRes = aFs.FileSystemName(fsName, aDrive);
   110     if(nRes != KErrNone)
   111         {//-- probably no file system installed at all
   112         return NULL;
   113         }
   114 
   115     //-- 2. find out if the drive sync/async
   116     TPckgBuf<TBool> drvSyncBuf;
   117     nRes = aFs.QueryVolumeInfoExt(aDrive, EIsDriveSync, drvSyncBuf);
   118     if(nRes == KErrNone)
   119         {
   120         bDrvSync = drvSyncBuf();
   121         }
   122 
   123     //-- 3. find out primary extension name if it is present; we will need to add it againt when mounting the FS
   124     //-- other extensions (non-primary) are not supported yet
   125     nRes = aFs.ExtensionName(primaryExtName, aDrive, 0);
   126     if(nRes != KErrNone)
   127         {   
   128         primaryExtName.SetLength(0);
   129         }
   130 
   131     //-- 3.1 check if the drive has non-primary extensions, fail in this case, because this FS can't be mounted back normally
   132     nRes = aFs.ExtensionName(primaryExtName, aDrive, 1);
   133     if(nRes == KErrNone)
   134         {   
   135         test.Printf(_L("DoDismountOrginalFS Non-primary extensions are not supported!\n"));
   136         return NULL;
   137         }
   138 
   139     test.Printf(_L("DoDismountOrginalFS FS:%S, Prim ext:%S, synch:%d\n"), &fsName, &primaryExtName, bDrvSync);
   140 
   141     //-- create FS descriptor and dismount the FS
   142     CFileSystemDescriptor* pFsDesc = NULL; 
   143     
   144     TRAP(nRes, pFsDesc = CFileSystemDescriptor::NewL(fsName, primaryExtName, bDrvSync));
   145     if(nRes != KErrNone)
   146         return NULL; //-- OOM ?
   147 
   148     nRes = aFs.DismountFileSystem(fsName, aDrive);
   149     if(nRes != KErrNone)
   150         {
   151         delete pFsDesc;
   152         pFsDesc = NULL;
   153         test.Printf(_L("DoDismountOrginalFS Dismounting Err:%d\n"), nRes);
   154         }
   155     
   156     return pFsDesc;
   157 }
   158 
   159 //-----------------------------------------------------------------------------
   160 /**
   161     Tries to restore the original FS on the drive using the FS descriptor provided
   162     @return standard error code.
   163 */
   164 LOCAL_C TInt DoRestoreFS(RFs& aFs, TInt aDrive, CFileSystemDescriptor* apFsDesc)
   165     {
   166     TInt nRes;
   167 
   168     test.Printf(_L("DoRestoreFS drv:%d\n"), aDrive);
   169 
   170     //-- 1. check that there is no FS installed
   171     TBuf<128>   fsName;
   172     nRes = aFs.FileSystemName(fsName, aDrive);
   173     if(nRes == KErrNone)
   174         {//-- there is a file system already installed
   175 		test.Printf(_L("DoRestoreFS This drive already has FS intalled:%S \n"), &fsName);
   176         return KErrAlreadyExists;
   177         }
   178  
   179     TPtrC ptrN  (apFsDesc->FsName());
   180     TPtrC ptrExt(apFsDesc->PrimaryExtName());
   181     test.Printf(_L("DoRestoreFS Mounting FS:%S, Prim ext:%S, synch:%d\n"), &ptrN, &ptrExt, apFsDesc->DriveIsSynch());
   182 
   183     if(ptrExt.Length() >0)
   184         {//-- there is a primary extension to be mounted
   185         nRes = aFs.AddExtension(ptrExt);
   186         if(nRes != KErrNone && nRes != KErrAlreadyExists)
   187             {
   188             return nRes;
   189             }
   190 
   191         nRes = aFs.MountFileSystem(ptrN, ptrExt, aDrive, apFsDesc->DriveIsSynch());
   192         }
   193     else
   194         {
   195         nRes = aFs.MountFileSystem(ptrN, aDrive, apFsDesc->DriveIsSynch());
   196         }
   197 
   198     if(nRes != KErrNone)
   199         {
   200         test.Printf(_L("DoRestoreFS Mount failed! code:%d\n"),nRes);    
   201         }
   202 
   203     return nRes;
   204     }
   205 
   206 
   207 //-----------------------------------------------------------------------------
   208 /**
   209     Dismount the original FS from the drive and mount MsFS instead
   210 */
   211 LOCAL_C void MountMsFs(TInt driveNumber)
   212 	{
   213 	test.Printf(_L("MountMsFs driveNumber=%d\n"), driveNumber); 
   214 
   215     //-- 1. try dismounting the original FS
   216     CFileSystemDescriptor* fsDesc = DoDismountOrginalFS(fs, driveNumber);
   217     unmountedFsList[driveNumber] = fsDesc;
   218 
   219     if(fsDesc)
   220         {
   221         TPtrC ptrN(fsDesc->FsName());
   222         test.Printf(_L("drv:%d FS:%S Dismounted OK\n"),driveNumber, &ptrN);
   223         }
   224     else
   225         {
   226         test.Printf(_L("drv:%d Dismount FS Failed!\n"),driveNumber);
   227         }
   228 
   229     //-- 2. try to mount the "MSFS"
   230     TInt error;
   231     error = fs.MountFileSystem(KMsFs, driveNumber);
   232 	test.Printf(_L("MSFS Mount:   %S (%d)\n"), (error?&KError:&KOk), error);
   233 	if (!error)
   234 		msfsMountedList[driveNumber] = ETrue;
   235 
   236 	}
   237 
   238 //-----------------------------------------------------------------------------
   239 /**
   240     Dismount MsFS and mount the original FS 
   241 */
   242 LOCAL_C TInt RestoreMount(TInt driveNumber)
   243 	{
   244 	TInt err = KErrNone;
   245 
   246     //-- 1. try dismounting the "MSFS"
   247 	if (msfsMountedList[driveNumber])
   248 		{
   249 		err = fs.DismountFileSystem(KMsFs, driveNumber);
   250 		test.Printf(_L("MSFS Dismount:%S (%d)\n"), (err?&KError:&KOk), err);
   251 		if (err)
   252 			return err;
   253 
   254 		msfsMountedList[driveNumber] = EFalse;
   255         }
   256 
   257     //-- 2. try to mount the original FS back
   258     CFileSystemDescriptor* fsDesc = unmountedFsList[driveNumber];
   259     if(fsDesc)
   260         {
   261         err = DoRestoreFS(fs, driveNumber, fsDesc);
   262 
   263         TPtrC ptrN(fsDesc->FsName());
   264         test.Printf(_L("%S Mount:    %S (%d)\n"), &ptrN, (err?&KError:&KOk), err);
   265         
   266         delete fsDesc;
   267         unmountedFsList[driveNumber] = NULL;
   268         }
   269 
   270 	return err;
   271 	}
   272 
   273 //////////////////////////////////////////////////////////////////////////////
   274 //
   275 // CPropertyWatch
   276 // An active object that tracks changes to the KUsbMsDriveState properties
   277 //
   278 //////////////////////////////////////////////////////////////////////////////
   279 
   280 CPropertyWatch* CPropertyWatch::NewLC(TUsbMsDriveState_Subkey aSubkey, PropertyHandlers::THandler aHandler)
   281 	{
   282 	CPropertyWatch* me=new(ELeave) CPropertyWatch(aHandler);
   283 	CleanupStack::PushL (me);
   284 	me->ConstructL(aSubkey);
   285 	CleanupStack::Pop();
   286 	return me;
   287 	}
   288 
   289 CPropertyWatch::CPropertyWatch(PropertyHandlers::THandler aHandler)
   290 	: CActive(0), iHandler(aHandler)
   291 	{}
   292 
   293 void CPropertyWatch::ConstructL(TUsbMsDriveState_Subkey aSubkey)
   294 	{
   295 	User::LeaveIfError(iProperty.Attach(KUsbMsDriveState_Category, aSubkey));
   296 	CActiveScheduler::Add(this);
   297 	// initial subscription and process current property value
   298 	RunL();
   299 	}
   300 
   301 CPropertyWatch::~CPropertyWatch()
   302 	{
   303 	Cancel();
   304 	iProperty.Close();
   305 	}
   306 
   307 void CPropertyWatch::DoCancel()
   308 	{
   309 	iProperty.Cancel();
   310 	}
   311 
   312 void CPropertyWatch::RunL()
   313 	{
   314 	// resubscribe before processing new value to prevent missing updates
   315 	iProperty.Subscribe(iStatus);
   316 	SetActive();
   317 
   318 	iHandler(iProperty);
   319 	}
   320 
   321 //////////////////////////////////////////////////////////////////////////////
   322 //
   323 // CUsbWatch
   324 //
   325 //////////////////////////////////////////////////////////////////////////////
   326 
   327 CUsbWatch* CUsbWatch::NewLC(RUsb& aUsb)
   328 	{
   329 	CUsbWatch* me=new(ELeave) CUsbWatch(aUsb);
   330 	CleanupStack::PushL (me);
   331 	me->ConstructL();
   332 	CleanupStack::Pop();
   333 	return me;
   334 	}
   335 
   336 CUsbWatch::CUsbWatch(RUsb& aUsb)
   337 	: 
   338 	CActive(0), 
   339 	iUsb(aUsb),
   340 	iUsbDeviceState(EUsbcDeviceStateUndefined),
   341 	iWasConfigured(EFalse)
   342 	{}
   343 
   344 void CUsbWatch::ConstructL()
   345 	{
   346 	CActiveScheduler::Add(this);
   347 	RunL();
   348 	}
   349 
   350 CUsbWatch::~CUsbWatch()
   351 	{
   352 	Cancel();
   353 	iUsb.AlternateDeviceStatusNotifyCancel();
   354 	}
   355 
   356 void CUsbWatch::DoCancel()
   357 	{
   358 	iUsb.AlternateDeviceStatusNotifyCancel();
   359 	}
   360 
   361 static TBool IsDriveConnected(TInt driveStatusIndex)
   362 	{
   363 	TInt driveStatus = PropertyHandlers::allDrivesStatus[2*driveStatusIndex+1];
   364 	return driveStatus >= EUsbMsDriveState_Connected ? ETrue : EFalse;
   365 	}
   366 
   367 static TChar DriveNumberToLetter(TInt driveNumber)
   368 	{
   369 	TChar driveLetter = '?';
   370 	fs.DriveToChar(driveNumber, driveLetter);
   371 	return driveLetter;
   372 	}
   373 	
   374 static TBool IsDriveInMountList(TUint driveLetter)
   375 	{
   376 	TUint16 driveLetter16 = static_cast<TUint16>(driveLetter);
   377 	return(!mountList.Length() || KErrNotFound != mountList.Find(&driveLetter16, 1));
   378 	}
   379 
   380 void CUsbWatch::RunL()
   381 	{
   382 	gActiveControl->SetMSFinished(EFalse);
   383 	if (gVerbose)
   384 		{
   385 		switch (iUsbDeviceState)
   386 			{
   387 			case EUsbcDeviceStateUndefined : 					// 0
   388 				test.Printf(_L(">> CUSBWatch:Undefined %S\n"), iWasConfigured ? &KConfigured : &KNotConfigured);
   389 				break;
   390 			
   391 			case EUsbcDeviceStateAttached :						// 1
   392 				test.Printf(_L(">> CUSBWatch:Attached %S\n"), iWasConfigured ? &KConfigured : &KNotConfigured);
   393 				break;
   394 			
   395 			case EUsbcDeviceStatePowered :						// 2
   396 				test.Printf(_L(">> CUSBWatch:Powered %S\n"), iWasConfigured ? &KConfigured : &KNotConfigured);
   397 				break;
   398 	
   399 			case EUsbcDeviceStateDefault :						// 3
   400 				test.Printf(_L(">> CUSBWatch:Default %S\n"), iWasConfigured ? &KConfigured : &KNotConfigured);
   401 				break;
   402 			
   403 			case EUsbcDeviceStateAddress :						// 4
   404 				test.Printf(_L(">> CUSBWatch:Address %S\n"), iWasConfigured ? &KConfigured : &KNotConfigured);
   405 				break;
   406 			
   407 			case EUsbcDeviceStateConfigured :					// 5
   408 				test.Printf(_L(">> CUSBWatch:Configured %S\n"), iWasConfigured ? &KConfigured : &KNotConfigured);
   409 				break;
   410 			
   411 			case EUsbcDeviceStateSuspended : 					// 6
   412 				test.Printf(_L(">> CUSBWatch:Suspended %S\n"), iWasConfigured ? &KConfigured : &KNotConfigured);
   413 				break;
   414 			
   415 			default :
   416 				test.Printf(_L(">> CUSBWatch:UNKNOWN %S\n"), iWasConfigured ? &KConfigured : &KNotConfigured);
   417 				break;
   418 		
   419 			}
   420 		}
   421 	iUsb.AlternateDeviceStatusNotify(iStatus, iUsbDeviceState);
   422 	SetActive();
   423 
   424 	// If the cable is disconnected, unmount all the connected drives.
   425 	if(iWasConfigured && iUsbDeviceState == EUsbcDeviceStateUndefined)
   426 		{
   427 		for(TInt i=0; i<PropertyHandlers::allDrivesStatus.Length()/2; i++)
   428 			{
   429 			if(IsDriveConnected(i))
   430 				{
   431 				RDebug::Print(_L("CUsbWatch calling RestoreMount"));
   432 				RestoreMount(PropertyHandlers::allDrivesStatus[2*i]);
   433 				}
   434 			}
   435 
   436 		iWasConfigured = EFalse;
   437 		}
   438 
   439 	// If cable is connected, mount all drives in the auto-mount list.
   440 	// This is done for performance, since if this is not done here,
   441 	// mounting will happen later after each drive enters the 
   442 	// Connecting state.
   443 	if(iUsbDeviceState == EUsbcDeviceStateConfigured)
   444 		{
   445 		for(TInt i=0; i<PropertyHandlers::allDrivesStatus.Length()/2; i++)
   446 			{
   447 			TInt driveNumber = PropertyHandlers::allDrivesStatus[2*i];
   448 			if(!IsDriveConnected(i) && IsDriveInMountList(DriveNumberToLetter(driveNumber)))
   449 				{
   450 				RDebug::Print(_L("CUsbWatch calling MountMsFs"));
   451 				MountMsFs(driveNumber);
   452 				}
   453 			}
   454 
   455 		iWasConfigured = ETrue;
   456 		}
   457 	}
   458 
   459 //////////////////////////////////////////////////////////////////////////////
   460 //
   461 // PropertyHandlers
   462 //
   463 //////////////////////////////////////////////////////////////////////////////
   464 
   465 TBuf8<16> PropertyHandlers::allDrivesStatus;
   466 TUsbMsBytesTransferred PropertyHandlers::iKBytesRead;
   467 TUsbMsBytesTransferred PropertyHandlers::iKBytesWritten;
   468 TInt PropertyHandlers::iMediaError;
   469 
   470 void PropertyHandlers::Read(RProperty& aProperty)
   471 	{
   472 	Transferred(aProperty, iKBytesRead);
   473 	}
   474 
   475 void PropertyHandlers::Written(RProperty& aProperty)
   476 	{
   477 	Transferred(aProperty, iKBytesWritten);
   478 	}
   479 
   480 void PropertyHandlers::Transferred(RProperty& aProperty, TUsbMsBytesTransferred& aReadOrWritten)
   481 	{
   482 	TInt err = aProperty.Get(aReadOrWritten);
   483 	if(err == KErrNone)
   484 		{
   485 		for(TInt i = 0; i < allDrivesStatus.Length()/2; i++)
   486 			{
   487 			if (gVerbose)
   488 				{
   489 				test.Printf(KBytesTransferredFmt, 
   490 						(char)DriveNumberToLetter(allDrivesStatus[2*i]), iKBytesRead[i], iKBytesWritten[i]);
   491 				}
   492 			}
   493 		}
   494 	else
   495 		{
   496 		test.Printf(KErrFmt, err);
   497 		}
   498 	}
   499 	
   500 void PropertyHandlers::DriveStatus(RProperty& aProperty)
   501 	{
   502 	if (gVerbose)
   503 		{
   504 		test.Printf(_L(">> PropertyHandlers::DriveStatus"));
   505 		}
   506 	TInt err = aProperty.Get(allDrivesStatus);
   507 	if(err == KErrNone)
   508 		{
   509 		if (gVerbose)
   510 			{
   511 			test.Printf(_L(" Status:  "));
   512 			}
   513 		for(TInt i = 0; i < allDrivesStatus.Length()/2; i++)
   514 			{
   515 			TInt driveNumber = allDrivesStatus[2*i];
   516 			TInt driveStatus = allDrivesStatus[2*i+1];
   517 			TChar driveLetter = DriveNumberToLetter(driveNumber);
   518 
   519 			if (gVerbose)
   520 				{
   521 				switch(driveStatus)
   522 					{
   523 					case EUsbMsDriveState_Disconnected:
   524 						{
   525 						test.Printf(_L("%c:%d:Disconnected\n"), (char)driveLetter, driveStatus);
   526 						break;
   527 						}
   528 					case EUsbMsDriveState_Connecting:
   529 						{
   530 						test.Printf(_L("%c:%d:Connecting\n"), (char)driveLetter, driveStatus);
   531 						break;
   532 						}
   533 					case EUsbMsDriveState_Connected:
   534 						{
   535 						test.Printf(_L("%c:%d:Connected\n"), (char)driveLetter, driveStatus);
   536 						break;
   537 						}
   538 					case EUsbMsDriveState_Disconnecting:
   539 						{
   540 						test.Printf(_L("%c:%d:Disconnecting\n"), (char)driveLetter, driveStatus);
   541 						break;
   542 						}
   543 					case EUsbMsDriveState_Active:
   544 						{
   545 						test.Printf(_L("%c:%d:Active\n"), (char)driveLetter, driveStatus);
   546 						break;
   547 						}
   548 					case EUsbMsDriveState_Locked:
   549 						{
   550 						test.Printf(_L("%c:%d:Locked\n"), (char)driveLetter, driveStatus);
   551 						break;
   552 						}
   553 					case EUsbMsDriveState_MediaNotPresent:
   554 						{
   555 						test.Printf(_L("%c:%d:Not Present\n"), (char)driveLetter, driveStatus);
   556 						break;
   557 						}
   558 					case EUsbMsDriveState_Removed:
   559 						{
   560 						test.Printf(_L("%c:%d:Removed\n"), (char)driveLetter, driveStatus);
   561 						break;
   562 						}
   563 					case EUsbMsDriveState_Error:
   564 						{
   565 						test.Printf(_L("%c:%d:Error\n"), (char)driveLetter, driveStatus);
   566 						break;
   567 						}
   568 					default :
   569 						{
   570 						test.Printf(_L("%c:%d:Unknown\n"), (char)driveLetter, driveStatus);
   571 						break;
   572 						}
   573 					}
   574 				}
   575 
   576 			if (driveStatus == EUsbMsDriveState_Connected)
   577 				{
   578 				gActiveControl->SetMSFinished(EFalse);				
   579 				}
   580 			if (driveStatus == EUsbMsDriveState_Disconnected)
   581 				{
   582 				gActiveControl->SetMSFinished(ETrue);				
   583 				}
   584 			if(IsDriveInMountList(driveLetter))
   585 				{
   586 				if (driveStatus == EUsbMsDriveState_Connecting)
   587 					{
   588 					MountMsFs(driveNumber);
   589 					}
   590 				else if (driveStatus == EUsbMsDriveState_Disconnecting)
   591 					{
   592 					RestoreMount(driveNumber);
   593 					}
   594 				else
   595 					{
   596 					//RDebug::Print(_L("PropertyHandlers::DriveStatus: nothing to do"));
   597 					}
   598 				}
   599 			else
   600 				{
   601 				//RDebug::Print(_L("PropertyHandlers::DriveStatus: %c: is not in mountList\n"), driveLetter);
   602 				}
   603 			}
   604 		}
   605 	else
   606 		{
   607 		test.Printf(KErrFmt, err);
   608 		}
   609 
   610 	}
   611 
   612 void PropertyHandlers::MediaError(RProperty& aProperty)
   613 	{
   614 	TInt r = aProperty.Get(iMediaError);
   615 	if(r != KErrNone)
   616 		{
   617 		return;
   618 		}
   619 
   620 	test.Printf(_L("Media Error %x\n"), iMediaError);
   621 	if (iMediaError > 0)
   622 		{
   623 		gActiveControl->SetMSFinished(ETrue);
   624 		}
   625 	}
   626 
   627 
   628 void StartMassStorage(RDEVCLIENT* aPort)
   629 	{
   630     TInt r = KErrUnknown;
   631 
   632 	test.Start (_L("Start Mass Storage"));
   633 
   634 	fs.Connect();
   635 
   636 	// Add MS file system
   637 	test.Next (_L("Add MS File System"));
   638 	r = fs.AddFileSystem(KMsFsy);
   639 	test(r == KErrNone || r == KErrAlreadyExists);
   640 
   641 #ifdef USB_SC
   642 	aPort->FinalizeInterface();
   643 #endif
   644 
   645 
   646 	test.Next (_L("Create active objects\n"));
   647 	propWatch[0] = CPropertyWatch::NewLC(EUsbMsDriveState_KBytesRead, PropertyHandlers::Read);
   648 	propWatch[1] = CPropertyWatch::NewLC(EUsbMsDriveState_KBytesWritten, PropertyHandlers::Written);
   649 	propWatch[2] = CPropertyWatch::NewLC(EUsbMsDriveState_DriveStatus, PropertyHandlers::DriveStatus);
   650 	propWatch[3] = CPropertyWatch::NewLC(EUsbMsDriveState_MediaError, PropertyHandlers::MediaError);
   651 	usbWatch = CUsbWatch::NewLC(*aPort);
   652 
   653 	TBuf<8>  t_vendorId(_L("vendor"));
   654 	TBuf<16> t_productId(_L("product"));
   655 	TBuf<4>  t_productRev(_L("1.00"));
   656 
   657 	TMassStorageConfig msConfig;
   658 	msConfig.iVendorId.Copy(t_vendorId);
   659 	msConfig.iProductId.Copy(t_productId);
   660 	msConfig.iProductRev.Copy(t_productRev);
   661 
   662  	test.Next(_L("Connect to Mass Storage"));
   663 	r = UsbMs.Connect();
   664 	test_KErrNone (r);
   665 
   666 	test.Next(_L("Start Mass Storage"));
   667 	r = UsbMs.Start(msConfig);
   668 	test_KErrNone (r);
   669 
   670 	test.End();
   671 	}
   672 	
   673 void StopMassStorage(RDEVCLIENT* aPort)
   674 	{
   675     TInt r = KErrUnknown;
   676 	
   677 	test.Start (_L("Stop Mass Storage"));
   678 
   679 	r = UsbMs.Stop();
   680 	test_KErrNone (r);
   681 	UsbMs.Close();
   682 
   683 	for (TInt driveNumber = 0; driveNumber < KMaxDrives; driveNumber++)
   684 		{
   685 		if (msfsMountedList[driveNumber])
   686 			{
   687 			r = fs.DismountFileSystem(KMsFs, driveNumber);
   688 			test_KErrNone (r);
   689 
   690 			msfsMountedList[driveNumber] = EFalse;
   691 			}
   692 		}
   693 
   694 	r = fs.RemoveFileSystem(KMsFs);
   695 	test_KErrNone (r);
   696 
   697 	fs.Close();
   698 	
   699 	delete usbWatch;
   700 	for (TUint i =0; i < KNumPropWatch; i++)
   701 		{
   702 		delete propWatch[i];
   703 		}
   704 	
   705 	aPort->Close();
   706 		
   707 	test.End();
   708 	}
   709