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