kerneltest/e32test/usb/t_usb_device/src/usbms.cpp
changeset 0 a41df078684a
child 253 d37db4dcc88d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/usb/t_usb_device/src/usbms.cpp	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,709 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "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:
+// USB Mass Storage Application
+// 
+//
+
+/**
+ @file
+*/
+
+#include "general.h"
+#include "config.h"
+#include "activecontrol.h"
+
+#include <usbmsshared.h>
+#include <massstorage.h>
+
+#include "usbms.h"
+
+extern CActiveControl* gActiveControl;
+extern RTest test;
+extern TBool gVerbose;
+extern TBool gSkip;
+extern TBool gTempTest;
+
+
+LOCAL_D RFs fs;
+LOCAL_D TBuf<0x40> mountList;
+
+LOCAL_D TFixedArray<TBool, KMaxDrives>                   msfsMountedList;  ///< 'true' entry corresponds to the drive with mounted MSFS.FSY
+LOCAL_D TFixedArray<CFileSystemDescriptor*, KMaxDrives>  unmountedFsList;  ///< every non-NULL entry corresponds to the unmounted original FS for the drive
+
+LOCAL_D RUsbMassStorage UsbMs;
+
+LOCAL_D CUsbWatch * usbWatch;
+
+static const TUint KNumPropWatch = 4;
+LOCAL_D CPropertyWatch * propWatch[KNumPropWatch];
+
+_LIT(KMsFsy, "MSFS.FSY");
+_LIT(KMsFs, "MassStorageFileSystem");
+_LIT(KOk,"OK");
+_LIT(KError,"Error");
+_LIT(KBytesTransferredFmt, "%c:%d/%d \n");
+_LIT(KErrFmt, "Error: %d\r");
+_LIT(KConfigured,"Configured");
+_LIT(KNotConfigured,"NOT Configured");
+
+
+_LIT8(KDefPwd,"123");
+TMediaPassword  password(KDefPwd);
+
+//-----------------------------------------------------------------------------
+
+CFileSystemDescriptor::~CFileSystemDescriptor()
+    {
+    iFsName.Close();
+    iPrimaryExtName.Close();
+    }
+
+//-----------------------------------------------------------------------------
+CFileSystemDescriptor* CFileSystemDescriptor::NewL(const TDesC& aFsName, const TDesC& aPrimaryExtName, TBool aDrvSynch)
+    {
+    CFileSystemDescriptor* pSelf = new (ELeave) CFileSystemDescriptor;
+
+    CleanupStack::PushL(pSelf);
+    
+    pSelf->iFsName.CreateMaxL(aFsName.Length());
+    pSelf->iFsName.Copy(aFsName);
+    
+    pSelf->iPrimaryExtName.CreateMaxL(aPrimaryExtName.Length());
+    pSelf->iPrimaryExtName.Copy(aPrimaryExtName);
+
+    pSelf->iDriveSynch = aDrvSynch;
+
+    CleanupStack::Pop();
+
+    return pSelf;
+    }
+
+//-----------------------------------------------------------------------------
+/**
+    Dismounts the originally mounted FS and optional primary extension from the drive and stores 
+    this information in the FS descriptor
+
+    @return on success returns a pointer to the instantinated FS descriptor
+*/
+LOCAL_C CFileSystemDescriptor* DoDismountOrginalFS(RFs& aFs, TInt aDrive)
+    {
+    TInt        nRes;
+    TBuf<128>   fsName;
+    TBuf<128>   primaryExtName;
+    TBool       bDrvSync = EFalse;
+
+    test.Printf(_L("DoDismountOrginalFS drv:%d\n"), aDrive);
+
+    //-- 1. get file system name
+    nRes = aFs.FileSystemName(fsName, aDrive);
+    if(nRes != KErrNone)
+        {//-- probably no file system installed at all
+        return NULL;
+        }
+
+    //-- 2. find out if the drive sync/async
+    TPckgBuf<TBool> drvSyncBuf;
+    nRes = aFs.QueryVolumeInfoExt(aDrive, EIsDriveSync, drvSyncBuf);
+    if(nRes == KErrNone)
+        {
+        bDrvSync = drvSyncBuf();
+        }
+
+    //-- 3. find out primary extension name if it is present; we will need to add it againt when mounting the FS
+    //-- other extensions (non-primary) are not supported yet
+    nRes = aFs.ExtensionName(primaryExtName, aDrive, 0);
+    if(nRes != KErrNone)
+        {   
+        primaryExtName.SetLength(0);
+        }
+
+    //-- 3.1 check if the drive has non-primary extensions, fail in this case, because this FS can't be mounted back normally
+    nRes = aFs.ExtensionName(primaryExtName, aDrive, 1);
+    if(nRes == KErrNone)
+        {   
+        test.Printf(_L("DoDismountOrginalFS Non-primary extensions are not supported!\n"));
+        return NULL;
+        }
+
+    test.Printf(_L("DoDismountOrginalFS FS:%S, Prim ext:%S, synch:%d\n"), &fsName, &primaryExtName, bDrvSync);
+
+    //-- create FS descriptor and dismount the FS
+    CFileSystemDescriptor* pFsDesc = NULL; 
+    
+    TRAP(nRes, pFsDesc = CFileSystemDescriptor::NewL(fsName, primaryExtName, bDrvSync));
+    if(nRes != KErrNone)
+        return NULL; //-- OOM ?
+
+    nRes = aFs.DismountFileSystem(fsName, aDrive);
+    if(nRes != KErrNone)
+        {
+        delete pFsDesc;
+        pFsDesc = NULL;
+        test.Printf(_L("DoDismountOrginalFS Dismounting Err:%d\n"), nRes);
+        }
+    
+    return pFsDesc;
+}
+
+//-----------------------------------------------------------------------------
+/**
+    Tries to restore the original FS on the drive using the FS descriptor provided
+    @return standard error code.
+*/
+LOCAL_C TInt DoRestoreFS(RFs& aFs, TInt aDrive, CFileSystemDescriptor* apFsDesc)
+    {
+    TInt nRes;
+
+    test.Printf(_L("DoRestoreFS drv:%d\n"), aDrive);
+
+    //-- 1. check that there is no FS installed
+    TBuf<128>   fsName;
+    nRes = aFs.FileSystemName(fsName, aDrive);
+    if(nRes == KErrNone)
+        {//-- there is a file system already installed
+		test.Printf(_L("DoRestoreFS This drive already has FS intalled:%S \n"), &fsName);
+        return KErrAlreadyExists;
+        }
+ 
+    TPtrC ptrN  (apFsDesc->FsName());
+    TPtrC ptrExt(apFsDesc->PrimaryExtName());
+    test.Printf(_L("DoRestoreFS Mounting FS:%S, Prim ext:%S, synch:%d\n"), &ptrN, &ptrExt, apFsDesc->DriveIsSynch());
+
+    if(ptrExt.Length() >0)
+        {//-- there is a primary extension to be mounted
+        nRes = aFs.AddExtension(ptrExt);
+        if(nRes != KErrNone && nRes != KErrAlreadyExists)
+            {
+            return nRes;
+            }
+
+        nRes = aFs.MountFileSystem(ptrN, ptrExt, aDrive, apFsDesc->DriveIsSynch());
+        }
+    else
+        {
+        nRes = aFs.MountFileSystem(ptrN, aDrive, apFsDesc->DriveIsSynch());
+        }
+
+    if(nRes != KErrNone)
+        {
+        test.Printf(_L("DoRestoreFS Mount failed! code:%d\n"),nRes);    
+        }
+
+    return nRes;
+    }
+
+
+//-----------------------------------------------------------------------------
+/**
+    Dismount the original FS from the drive and mount MsFS instead
+*/
+LOCAL_C void MountMsFs(TInt driveNumber)
+	{
+	test.Printf(_L("MountMsFs driveNumber=%d\n"), driveNumber); 
+
+    //-- 1. try dismounting the original FS
+    CFileSystemDescriptor* fsDesc = DoDismountOrginalFS(fs, driveNumber);
+    unmountedFsList[driveNumber] = fsDesc;
+
+    if(fsDesc)
+        {
+        TPtrC ptrN(fsDesc->FsName());
+        test.Printf(_L("drv:%d FS:%S Dismounted OK\n"),driveNumber, &ptrN);
+        }
+    else
+        {
+        test.Printf(_L("drv:%d Dismount FS Failed!\n"),driveNumber);
+        }
+
+    //-- 2. try to mount the "MSFS"
+    TInt error;
+    error = fs.MountFileSystem(KMsFs, driveNumber);
+	test.Printf(_L("MSFS Mount:   %S (%d)\n"), (error?&KError:&KOk), error);
+	if (!error)
+		msfsMountedList[driveNumber] = ETrue;
+
+	}
+
+//-----------------------------------------------------------------------------
+/**
+    Dismount MsFS and mount the original FS 
+*/
+LOCAL_C TInt RestoreMount(TInt driveNumber)
+	{
+	TInt err = KErrNone;
+
+    //-- 1. try dismounting the "MSFS"
+	if (msfsMountedList[driveNumber])
+		{
+		err = fs.DismountFileSystem(KMsFs, driveNumber);
+		test.Printf(_L("MSFS Dismount:%S (%d)\n"), (err?&KError:&KOk), err);
+		if (err)
+			return err;
+
+		msfsMountedList[driveNumber] = EFalse;
+        }
+
+    //-- 2. try to mount the original FS back
+    CFileSystemDescriptor* fsDesc = unmountedFsList[driveNumber];
+    if(fsDesc)
+        {
+        err = DoRestoreFS(fs, driveNumber, fsDesc);
+
+        TPtrC ptrN(fsDesc->FsName());
+        test.Printf(_L("%S Mount:    %S (%d)\n"), &ptrN, (err?&KError:&KOk), err);
+        
+        delete fsDesc;
+        unmountedFsList[driveNumber] = NULL;
+        }
+
+	return err;
+	}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// CPropertyWatch
+// An active object that tracks changes to the KUsbMsDriveState properties
+//
+//////////////////////////////////////////////////////////////////////////////
+
+CPropertyWatch* CPropertyWatch::NewLC(TUsbMsDriveState_Subkey aSubkey, PropertyHandlers::THandler aHandler)
+	{
+	CPropertyWatch* me=new(ELeave) CPropertyWatch(aHandler);
+	CleanupStack::PushL (me);
+	me->ConstructL(aSubkey);
+	CleanupStack::Pop();
+	return me;
+	}
+
+CPropertyWatch::CPropertyWatch(PropertyHandlers::THandler aHandler)
+	: CActive(0), iHandler(aHandler)
+	{}
+
+void CPropertyWatch::ConstructL(TUsbMsDriveState_Subkey aSubkey)
+	{
+	User::LeaveIfError(iProperty.Attach(KUsbMsDriveState_Category, aSubkey));
+	CActiveScheduler::Add(this);
+	// initial subscription and process current property value
+	RunL();
+	}
+
+CPropertyWatch::~CPropertyWatch()
+	{
+	Cancel();
+	iProperty.Close();
+	}
+
+void CPropertyWatch::DoCancel()
+	{
+	iProperty.Cancel();
+	}
+
+void CPropertyWatch::RunL()
+	{
+	// resubscribe before processing new value to prevent missing updates
+	iProperty.Subscribe(iStatus);
+	SetActive();
+
+	iHandler(iProperty);
+	}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// CUsbWatch
+//
+//////////////////////////////////////////////////////////////////////////////
+
+CUsbWatch* CUsbWatch::NewLC(RUsb& aUsb)
+	{
+	CUsbWatch* me=new(ELeave) CUsbWatch(aUsb);
+	CleanupStack::PushL (me);
+	me->ConstructL();
+	CleanupStack::Pop();
+	return me;
+	}
+
+CUsbWatch::CUsbWatch(RUsb& aUsb)
+	: 
+	CActive(0), 
+	iUsb(aUsb),
+	iUsbDeviceState(EUsbcDeviceStateUndefined),
+	iWasConfigured(EFalse)
+	{}
+
+void CUsbWatch::ConstructL()
+	{
+	CActiveScheduler::Add(this);
+	RunL();
+	}
+
+CUsbWatch::~CUsbWatch()
+	{
+	Cancel();
+	iUsb.AlternateDeviceStatusNotifyCancel();
+	}
+
+void CUsbWatch::DoCancel()
+	{
+	iUsb.AlternateDeviceStatusNotifyCancel();
+	}
+
+static TBool IsDriveConnected(TInt driveStatusIndex)
+	{
+	TInt driveStatus = PropertyHandlers::allDrivesStatus[2*driveStatusIndex+1];
+	return driveStatus >= EUsbMsDriveState_Connected ? ETrue : EFalse;
+	}
+
+static TChar DriveNumberToLetter(TInt driveNumber)
+	{
+	TChar driveLetter = '?';
+	fs.DriveToChar(driveNumber, driveLetter);
+	return driveLetter;
+	}
+	
+static TBool IsDriveInMountList(TUint driveLetter)
+	{
+	TUint16 driveLetter16 = static_cast<TUint16>(driveLetter);
+	return(!mountList.Length() || KErrNotFound != mountList.Find(&driveLetter16, 1));
+	}
+
+void CUsbWatch::RunL()
+	{
+	gActiveControl->SetMSFinished(EFalse);
+	if (gVerbose)
+		{
+		switch (iUsbDeviceState)
+			{
+			case EUsbcDeviceStateUndefined : 					// 0
+				test.Printf(_L(">> CUSBWatch:Undefined %S\n"), iWasConfigured ? &KConfigured : &KNotConfigured);
+				break;
+			
+			case EUsbcDeviceStateAttached :						// 1
+				test.Printf(_L(">> CUSBWatch:Attached %S\n"), iWasConfigured ? &KConfigured : &KNotConfigured);
+				break;
+			
+			case EUsbcDeviceStatePowered :						// 2
+				test.Printf(_L(">> CUSBWatch:Powered %S\n"), iWasConfigured ? &KConfigured : &KNotConfigured);
+				break;
+	
+			case EUsbcDeviceStateDefault :						// 3
+				test.Printf(_L(">> CUSBWatch:Default %S\n"), iWasConfigured ? &KConfigured : &KNotConfigured);
+				break;
+			
+			case EUsbcDeviceStateAddress :						// 4
+				test.Printf(_L(">> CUSBWatch:Address %S\n"), iWasConfigured ? &KConfigured : &KNotConfigured);
+				break;
+			
+			case EUsbcDeviceStateConfigured :					// 5
+				test.Printf(_L(">> CUSBWatch:Configured %S\n"), iWasConfigured ? &KConfigured : &KNotConfigured);
+				break;
+			
+			case EUsbcDeviceStateSuspended : 					// 6
+				test.Printf(_L(">> CUSBWatch:Suspended %S\n"), iWasConfigured ? &KConfigured : &KNotConfigured);
+				break;
+			
+			default :
+				test.Printf(_L(">> CUSBWatch:UNKNOWN %S\n"), iWasConfigured ? &KConfigured : &KNotConfigured);
+				break;
+		
+			}
+		}
+	iUsb.AlternateDeviceStatusNotify(iStatus, iUsbDeviceState);
+	SetActive();
+
+	// If the cable is disconnected, unmount all the connected drives.
+	if(iWasConfigured && iUsbDeviceState == EUsbcDeviceStateUndefined)
+		{
+		for(TInt i=0; i<PropertyHandlers::allDrivesStatus.Length()/2; i++)
+			{
+			if(IsDriveConnected(i))
+				{
+				RDebug::Print(_L("CUsbWatch calling RestoreMount"));
+				RestoreMount(PropertyHandlers::allDrivesStatus[2*i]);
+				}
+			}
+
+		iWasConfigured = EFalse;
+		}
+
+	// If cable is connected, mount all drives in the auto-mount list.
+	// This is done for performance, since if this is not done here,
+	// mounting will happen later after each drive enters the 
+	// Connecting state.
+	if(iUsbDeviceState == EUsbcDeviceStateConfigured)
+		{
+		for(TInt i=0; i<PropertyHandlers::allDrivesStatus.Length()/2; i++)
+			{
+			TInt driveNumber = PropertyHandlers::allDrivesStatus[2*i];
+			if(!IsDriveConnected(i) && IsDriveInMountList(DriveNumberToLetter(driveNumber)))
+				{
+				RDebug::Print(_L("CUsbWatch calling MountMsFs"));
+				MountMsFs(driveNumber);
+				}
+			}
+
+		iWasConfigured = ETrue;
+		}
+	}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// PropertyHandlers
+//
+//////////////////////////////////////////////////////////////////////////////
+
+TBuf8<16> PropertyHandlers::allDrivesStatus;
+TUsbMsBytesTransferred PropertyHandlers::iKBytesRead;
+TUsbMsBytesTransferred PropertyHandlers::iKBytesWritten;
+TInt PropertyHandlers::iMediaError;
+
+void PropertyHandlers::Read(RProperty& aProperty)
+	{
+	Transferred(aProperty, iKBytesRead);
+	}
+
+void PropertyHandlers::Written(RProperty& aProperty)
+	{
+	Transferred(aProperty, iKBytesWritten);
+	}
+
+void PropertyHandlers::Transferred(RProperty& aProperty, TUsbMsBytesTransferred& aReadOrWritten)
+	{
+	TInt err = aProperty.Get(aReadOrWritten);
+	if(err == KErrNone)
+		{
+		for(TInt i = 0; i < allDrivesStatus.Length()/2; i++)
+			{
+			if (gVerbose)
+				{
+				test.Printf(KBytesTransferredFmt, 
+						(char)DriveNumberToLetter(allDrivesStatus[2*i]), iKBytesRead[i], iKBytesWritten[i]);
+				}
+			}
+		}
+	else
+		{
+		test.Printf(KErrFmt, err);
+		}
+	}
+	
+void PropertyHandlers::DriveStatus(RProperty& aProperty)
+	{
+	if (gVerbose)
+		{
+		test.Printf(_L(">> PropertyHandlers::DriveStatus"));
+		}
+	TInt err = aProperty.Get(allDrivesStatus);
+	if(err == KErrNone)
+		{
+		if (gVerbose)
+			{
+			test.Printf(_L(" Status:  "));
+			}
+		for(TInt i = 0; i < allDrivesStatus.Length()/2; i++)
+			{
+			TInt driveNumber = allDrivesStatus[2*i];
+			TInt driveStatus = allDrivesStatus[2*i+1];
+			TChar driveLetter = DriveNumberToLetter(driveNumber);
+
+			if (gVerbose)
+				{
+				switch(driveStatus)
+					{
+					case EUsbMsDriveState_Disconnected:
+						{
+						test.Printf(_L("%c:%d:Disconnected\n"), (char)driveLetter, driveStatus);
+						break;
+						}
+					case EUsbMsDriveState_Connecting:
+						{
+						test.Printf(_L("%c:%d:Connecting\n"), (char)driveLetter, driveStatus);
+						break;
+						}
+					case EUsbMsDriveState_Connected:
+						{
+						test.Printf(_L("%c:%d:Connected\n"), (char)driveLetter, driveStatus);
+						break;
+						}
+					case EUsbMsDriveState_Disconnecting:
+						{
+						test.Printf(_L("%c:%d:Disconnecting\n"), (char)driveLetter, driveStatus);
+						break;
+						}
+					case EUsbMsDriveState_Active:
+						{
+						test.Printf(_L("%c:%d:Active\n"), (char)driveLetter, driveStatus);
+						break;
+						}
+					case EUsbMsDriveState_Locked:
+						{
+						test.Printf(_L("%c:%d:Locked\n"), (char)driveLetter, driveStatus);
+						break;
+						}
+					case EUsbMsDriveState_MediaNotPresent:
+						{
+						test.Printf(_L("%c:%d:Not Present\n"), (char)driveLetter, driveStatus);
+						break;
+						}
+					case EUsbMsDriveState_Removed:
+						{
+						test.Printf(_L("%c:%d:Removed\n"), (char)driveLetter, driveStatus);
+						break;
+						}
+					case EUsbMsDriveState_Error:
+						{
+						test.Printf(_L("%c:%d:Error\n"), (char)driveLetter, driveStatus);
+						break;
+						}
+					default :
+						{
+						test.Printf(_L("%c:%d:Unknown\n"), (char)driveLetter, driveStatus);
+						break;
+						}
+					}
+				}
+
+			if (driveStatus == EUsbMsDriveState_Connected)
+				{
+				gActiveControl->SetMSFinished(EFalse);				
+				}
+			if (driveStatus == EUsbMsDriveState_Disconnected)
+				{
+				gActiveControl->SetMSFinished(ETrue);				
+				}
+			if(IsDriveInMountList(driveLetter))
+				{
+				if (driveStatus == EUsbMsDriveState_Connecting)
+					{
+					MountMsFs(driveNumber);
+					}
+				else if (driveStatus == EUsbMsDriveState_Disconnecting)
+					{
+					RestoreMount(driveNumber);
+					}
+				else
+					{
+					//RDebug::Print(_L("PropertyHandlers::DriveStatus: nothing to do"));
+					}
+				}
+			else
+				{
+				//RDebug::Print(_L("PropertyHandlers::DriveStatus: %c: is not in mountList\n"), driveLetter);
+				}
+			}
+		}
+	else
+		{
+		test.Printf(KErrFmt, err);
+		}
+
+	}
+
+void PropertyHandlers::MediaError(RProperty& aProperty)
+	{
+	TInt r = aProperty.Get(iMediaError);
+	if(r != KErrNone)
+		{
+		return;
+		}
+
+	test.Printf(_L("Media Error %x\n"), iMediaError);
+	if (iMediaError > 0)
+		{
+		gActiveControl->SetMSFinished(ETrue);
+		}
+	}
+
+
+void StartMassStorage(RDEVCLIENT* aPort)
+	{
+    TInt r = KErrUnknown;
+
+	test.Start (_L("Start Mass Storage"));
+
+	fs.Connect();
+
+	// Add MS file system
+	test.Next (_L("Add MS File System"));
+	r = fs.AddFileSystem(KMsFsy);
+	test(r == KErrNone || r == KErrAlreadyExists);
+
+#ifdef USB_SC
+	aPort->FinalizeInterface();
+#endif
+
+
+	test.Next (_L("Create active objects\n"));
+	propWatch[0] = CPropertyWatch::NewLC(EUsbMsDriveState_KBytesRead, PropertyHandlers::Read);
+	propWatch[1] = CPropertyWatch::NewLC(EUsbMsDriveState_KBytesWritten, PropertyHandlers::Written);
+	propWatch[2] = CPropertyWatch::NewLC(EUsbMsDriveState_DriveStatus, PropertyHandlers::DriveStatus);
+	propWatch[3] = CPropertyWatch::NewLC(EUsbMsDriveState_MediaError, PropertyHandlers::MediaError);
+	usbWatch = CUsbWatch::NewLC(*aPort);
+
+	TBuf<8>  t_vendorId(_L("vendor"));
+	TBuf<16> t_productId(_L("product"));
+	TBuf<4>  t_productRev(_L("1.00"));
+
+	TMassStorageConfig msConfig;
+	msConfig.iVendorId.Copy(t_vendorId);
+	msConfig.iProductId.Copy(t_productId);
+	msConfig.iProductRev.Copy(t_productRev);
+
+ 	test.Next(_L("Connect to Mass Storage"));
+	r = UsbMs.Connect();
+	test_KErrNone (r);
+
+	test.Next(_L("Start Mass Storage"));
+	r = UsbMs.Start(msConfig);
+	test_KErrNone (r);
+
+	test.End();
+	}
+	
+void StopMassStorage(RDEVCLIENT* aPort)
+	{
+    TInt r = KErrUnknown;
+	
+	test.Start (_L("Stop Mass Storage"));
+
+	r = UsbMs.Stop();
+	test_KErrNone (r);
+	UsbMs.Close();
+
+	for (TInt driveNumber = 0; driveNumber < KMaxDrives; driveNumber++)
+		{
+		if (msfsMountedList[driveNumber])
+			{
+			r = fs.DismountFileSystem(KMsFs, driveNumber);
+			test_KErrNone (r);
+
+			msfsMountedList[driveNumber] = EFalse;
+			}
+		}
+
+	r = fs.RemoveFileSystem(KMsFs);
+	test_KErrNone (r);
+
+	fs.Close();
+	
+	delete usbWatch;
+	for (TUint i =0; i < KNumPropWatch; i++)
+		{
+		delete propWatch[i];
+		}
+	
+	aPort->Close();
+		
+	test.End();
+	}
+