sl@0: // Copyright (c) 2004-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: // Component test of registration and deregistration sl@0: // 1. Test registering MS FS sl@0: // Test actions: sl@0: // a. Load MS Server/File system and start it. sl@0: // b. Select a drive, say, Y, format it using FAT FS sl@0: // c. Read and store the boot sector of Y sl@0: // d. Unmount FAT FS from Y sl@0: // e. Mount MS FS on Y sl@0: // f. Read the boot sector of Y by passing SCSI command through TestLdd sl@0: // g. Compare the two boot sectors, which are obtained under FAT MS and MS FS repectively sl@0: // h. Try to read Y (assuming it's a removable media) using RFs API. sl@0: // Expected results: sl@0: // This test should be run for different drives. sl@0: // Mounting non-removable media (step b) should fail. sl@0: // For removable media: steps from c to g should complete successfully sl@0: // Read boot sector should be the same as the saved. sl@0: // Step h should fail (KErrNotSupported). sl@0: // 2. Test deregistering MS FS sl@0: // Test actions: sl@0: // a. Try to unmount MS FS from Y while SCSI is writing to it sl@0: // b. Wait for access completion. sl@0: // c. Unmount MS FS from Y. sl@0: // d. Try to read from Y using RFs API. sl@0: // e. Remount FAT FS on Y. sl@0: // f. Issue UnitReady and Read SCSI command through test LDD. sl@0: // g. Try to read from Y using RFs API. sl@0: // h. Unmount FAT FS from Y and mount MS FS on it sl@0: // Expected results: sl@0: // Deregister request (step a) should return an appropriate error code when media is in use. sl@0: // Next deregistering (step c) should be successful. sl@0: // Attempt (step d) should fail. sl@0: // SCSI commands (step f) should report error when MS FS is unmounted. sl@0: // File server read request (step g) should be successful when FAT FS is mounted sl@0: // sl@0: // sl@0: sl@0: /** sl@0: @file sl@0: @internalTechnology sl@0: */ sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include "t_ms_main.h" sl@0: #include "testusbc.h" sl@0: sl@0: #define CBW_LENGTH 31 sl@0: #define CSW_LENGTH 13 sl@0: #define SCSI_READ_LEN 10 sl@0: #define SCSI_WRITE_LEN 10 sl@0: #define SCSI_UNIT_READY_LEN 6 sl@0: #define SCSI_MED_RMVL_LEN 6 sl@0: #define BOOTSECTOR_SIZE 512 sl@0: sl@0: _LIT(KMsFsyName, "MassStorageFileSystem"); sl@0: sl@0: const TUint KMBRFirstPartitionSectorOffset = 0x1BE + 8; sl@0: const TUint KBootRecordSignature = 0xAA55; sl@0: sl@0: LOCAL_D TChar driveLetter[2]; sl@0: LOCAL_D TInt nonRemovalDrvNo; sl@0: LOCAL_D TInt removalDrvNo; sl@0: LOCAL_D TUint8 testLun(0); // Use MMC card for testing sl@0: sl@0: #define LOG_AND_TEST(a, e) {if (a!=e) {test.Printf(_L("lvalue %d, rvalue%d\n\r"), a,e); test(EFalse);}} sl@0: LOCAL_C void ParseCommandArguments() sl@0: // sl@0: // Parses the command line arguments sl@0: // We expect 3 parameters: sl@0: // - Drive letter for non-removable drive sl@0: // - Drive letter for removable drive sl@0: // - LUN for removable drive (0-7) sl@0: // sl@0: { sl@0: TBuf<0x100> cmd; sl@0: User::CommandLine(cmd); sl@0: TLex lex(cmd); sl@0: TPtrC token; sl@0: TBool cmdOk= ETrue; sl@0: for (int i = 0; i < 3; i++) // sl@0: { sl@0: token.Set(lex.NextToken()); sl@0: if (token.Length() != 0) sl@0: { sl@0: if (i <2) sl@0: { sl@0: driveLetter[i] = token[0]; sl@0: driveLetter[i].UpperCase(); sl@0: test.Printf(_L("CmdLine Param=%S\r\n"),&token); sl@0: } sl@0: else sl@0: { sl@0: TChar cLun = token[0]; sl@0: TInt lun = TInt(cLun) - 0x30; sl@0: if (lun>=0 && lun <8) sl@0: { sl@0: testLun = TUint8(lun); sl@0: } sl@0: else sl@0: { sl@0: cmdOk= EFalse; sl@0: } sl@0: } sl@0: } sl@0: else sl@0: { sl@0: cmdOk= EFalse; sl@0: break; sl@0: } sl@0: } sl@0: sl@0: sl@0: if (!cmdOk) sl@0: { sl@0: test.Printf(_L("No or not enough command line arguments - using default arguments\r\n")); sl@0: // code drive letters based on platform sl@0: TInt uid; sl@0: TInt r=HAL::Get(HAL::EMachineUid,uid); sl@0: LOG_AND_TEST(r,KErrNone); sl@0: sl@0: switch(uid) sl@0: { sl@0: case HAL::EMachineUid_Lubbock: sl@0: driveLetter[0] = 'C'; sl@0: driveLetter[1] = 'F'; sl@0: test.Printf(_L("Test is running on Lubbock\r\n")); sl@0: testLun = 2; sl@0: break; sl@0: case HAL::EMachineUid_Win32Emulator: sl@0: driveLetter[0] = 'Y'; sl@0: driveLetter[1] = 'X'; sl@0: test.Printf(_L("Test is running on Win32 Emulator\r\n")); sl@0: testLun = 1; sl@0: break; sl@0: case HAL::EMachineUid_OmapH4: sl@0: driveLetter[0] = 'C'; sl@0: driveLetter[1] = 'D'; sl@0: test.Printf(_L("Test is running on H4 board\r\n")); sl@0: testLun = 0; sl@0: break; sl@0: default: sl@0: // Assume it's a H2 board for now as no relevant Enum is found sl@0: driveLetter[0] = 'C'; sl@0: driveLetter[1] = 'D'; sl@0: test.Printf(_L("Test is running on H2 board\r\n")); sl@0: testLun = 0; sl@0: break; sl@0: } sl@0: sl@0: test.Printf(_L("Parameters used for test:\r\n\tfixed drive\t\t%c\r\n\tremovable drive\t\t%c\r\n\tLUN\t\t\t%d\r\n"), sl@0: (TUint) driveLetter[0], (TUint) driveLetter[1], testLun); sl@0: } sl@0: } sl@0: sl@0: LOCAL_C void fillInt(TUint8* dest, TInt source) sl@0: // sl@0: // Copy an int. Little endian sl@0: // sl@0: { sl@0: for (TInt i = 0; i < 4; i++) sl@0: { sl@0: *dest++ = TUint8((source >> i*8) & 0xFF); sl@0: } sl@0: } sl@0: sl@0: LOCAL_C TInt extractInt(const TUint8* aBuf) sl@0: // sl@0: // Extract an integer from a buffer. Assume little endian sl@0: // sl@0: { sl@0: return aBuf[0] + (aBuf[1] << 8) + (aBuf[2] << 16) + (aBuf[3] << 24); sl@0: } sl@0: sl@0: LOCAL_C void createReadCmd(TDes8& aRead10Buf, TInt aLogicalBlkAddr, TInt aTotalBlocks) sl@0: // sl@0: // Prepare SCSI read(10) command sl@0: // sl@0: { sl@0: // Zero out the whole buffer sl@0: aRead10Buf.FillZ(SCSI_READ_LEN); sl@0: // operation code sl@0: aRead10Buf[0] = 0x28; sl@0: // Fill in logical block address. Big endian sl@0: aRead10Buf[2] = TUint8((aLogicalBlkAddr >> 24) & 0xFF); sl@0: aRead10Buf[3] = TUint8((aLogicalBlkAddr >> 16) & 0xFF); sl@0: aRead10Buf[4] = TUint8((aLogicalBlkAddr >> 8) & 0xFF); sl@0: aRead10Buf[5] = TUint8(aLogicalBlkAddr & 0xFF); sl@0: sl@0: // Data transfer length (# of sectors). Big endian sl@0: aRead10Buf[7] = TUint8((aTotalBlocks >> 8) & 0xFF); sl@0: aRead10Buf[8] = TUint8((aTotalBlocks & 0xFF)); sl@0: } sl@0: sl@0: LOCAL_C void createCBW(TDes8& aCbw, TInt aDCBWTag, TInt aDataTransferLen, TUint8 aInOutFlag, TUint8 aCBLength, TDes8& aCBWCB) sl@0: // sl@0: // aCbw: stores CBW sl@0: // aDCBWTag: a command block tag sent by the host. Used to associates a CSW sl@0: // with corresponding CBW sl@0: // aDataTranferLen: the number of bytes the host expects to transfer sl@0: // aInOutFlag: value for bmCBWFlags field, indicating the direction of transfer sl@0: // aCBLengh: valid length of CBWCB field in bytes sl@0: // aCBWCB the actual command to be wrapped sl@0: { sl@0: // Zero out aCbw sl@0: aCbw.FillZ(CBW_LENGTH); sl@0: sl@0: // dCBWSignature field, the value comes from spec sl@0: TInt dCBWSignature = 0x43425355; sl@0: fillInt(&aCbw[0], dCBWSignature); sl@0: // dCBWTag field sl@0: fillInt(&aCbw[4], aDCBWTag); sl@0: // dCBWDataTransferLength field sl@0: fillInt(&aCbw[8], aDataTransferLen); sl@0: // bmCBWFlags field sl@0: aCbw[12] = aInOutFlag; sl@0: aCbw[13] = testLun; sl@0: // bCBWCBLength field sl@0: aCbw[14] = aCBLength; sl@0: sl@0: // CBWCB field sl@0: for (TInt i = 0; i < aCBLength; ++i) sl@0: { sl@0: aCbw[15 + i] = aCBWCB[i]; sl@0: } sl@0: } sl@0: sl@0: LOCAL_C void doComponentTest() sl@0: // sl@0: // Do the component test sl@0: // sl@0: { sl@0: __UHEAP_MARK; sl@0: sl@0: TInt ret; sl@0: test.Next(_L("Start MountStart test. Be sure MMC card is inserted.")); sl@0: sl@0: // Connect to the server sl@0: RFs fs; sl@0: LOG_AND_TEST(KErrNone, fs.Connect()); sl@0: sl@0: // Convert drive letters to their numerical equivalent sl@0: ret = fs.CharToDrive(driveLetter[0],nonRemovalDrvNo); sl@0: LOG_AND_TEST(ret, KErrNone); sl@0: ret = fs.CharToDrive(driveLetter[1],removalDrvNo); sl@0: LOG_AND_TEST(ret, KErrNone); sl@0: sl@0: sl@0: // Load the logical device sl@0: _LIT(KDriverFileName,"TESTUSBC.LDD"); sl@0: ret = User::LoadLogicalDevice(KDriverFileName); sl@0: test(ret == KErrNone || ret == KErrAlreadyExists); sl@0: sl@0: // Add MS file system sl@0: _LIT(KMsFs, "MSFS.FSY"); sl@0: ret = fs.AddFileSystem(KMsFs); sl@0: test(ret == KErrNone || ret == KErrAlreadyExists); sl@0: sl@0: // DEF080979: RFs::AddFileSystem, wrong error code when re-adding sl@0: // the mass storage file system. Confirm that RFs::AddFileSystem sl@0: // returns the correct error code if the file system already exists. sl@0: // Also confirm that the mass storage file system is usable after such sl@0: // a failed attempt to re-add the file system. sl@0: ret = fs.AddFileSystem(KMsFs); sl@0: test(ret == KErrAlreadyExists); sl@0: sl@0: // Start Ms file system sl@0: RUsbMassStorage usbMs; sl@0: sl@0: TMassStorageConfig config; sl@0: sl@0: config.iVendorId.Copy(_L("vendorId")); sl@0: config.iProductId.Copy(_L("productId")); sl@0: config.iProductRev.Copy(_L("rev")); sl@0: sl@0: sl@0: ret = usbMs.Connect(); sl@0: LOG_AND_TEST(KErrNone, ret); sl@0: sl@0: // Start usb mass storage device sl@0: LOG_AND_TEST(KErrNone , usbMs.Start(config)); sl@0: sl@0: TBuf<128> fsName; sl@0: sl@0: #if defined(__WINS__) //we have no "free" non-removable drive at hardware to run this, sl@0: sl@0: // Get the file system name on non-removable drive sl@0: sl@0: LOG_AND_TEST(KErrNone ,fs.FileSystemName(fsName, nonRemovalDrvNo)); sl@0: sl@0: // Mount MS FS on to non-removable drive. This should fail sl@0: test(KErrNone != fs.MountFileSystem(KMsFsyName, nonRemovalDrvNo)); sl@0: sl@0: // Unmount MS FS from non-removable drive sl@0: LOG_AND_TEST(KErrNone, fs.DismountFileSystem(KMsFsyName, nonRemovalDrvNo)); sl@0: sl@0: // Mount FAT FS on to drive (restoring) sl@0: LOG_AND_TEST(KErrNone, fs.MountFileSystem(fsName, nonRemovalDrvNo)); sl@0: #endif //WINS sl@0: sl@0: // Format removable drive using FAT FS sl@0: RFormat format; sl@0: sl@0: TBuf<2> removalDrive; sl@0: removalDrive.Append(driveLetter[1]); sl@0: removalDrive.Append(':'); sl@0: TInt tracksRemaining; sl@0: test.Next(_L("Start MMC card formatting")); sl@0: LOG_AND_TEST(KErrNone, format.Open(fs, removalDrive, EHighDensity || EQuickFormat, tracksRemaining)); sl@0: while (tracksRemaining) sl@0: { sl@0: test.Printf(_L(".")); sl@0: LOG_AND_TEST(KErrNone, format.Next(tracksRemaining)); sl@0: } sl@0: format.Close(); sl@0: test.Printf(_L("\nDone!\n")); sl@0: // Get the boot sector info using FAT FS and save it for later comparison sl@0: TBuf8<512> fatBootSector; sl@0: RRawDisk fatDiskF; sl@0: LOG_AND_TEST(KErrNone, fatDiskF.Open(fs, removalDrvNo)); sl@0: LOG_AND_TEST(KErrNone, fatDiskF.Read(0, fatBootSector)); sl@0: fatDiskF.Close(); sl@0: sl@0: LOG_AND_TEST(KErrNone, fs.FileSystemName(fsName, removalDrvNo)); sl@0: sl@0: // Set up sessions for dismount API tests sl@0: sl@0: const TInt KNumClients = 10; sl@0: RFs clientFs[KNumClients]; sl@0: RFs dismountFs1; sl@0: TRequestStatus trsClientNotify[KNumClients]; sl@0: TRequestStatus trsClientComplete; sl@0: TRequestStatus trsClientComplete1; sl@0: sl@0: LOG_AND_TEST(KErrNone, dismountFs1.Connect()); sl@0: sl@0: TInt i = 0; sl@0: for(i=0; i< KNumClients; i++) sl@0: { sl@0: LOG_AND_TEST(KErrNone, clientFs[i].Connect()); sl@0: } sl@0: sl@0: // Test invalid mode argument to RFs::NotifyDismount sl@0: sl@0: test.Next(_L("Test invalid mode argument to RFs::NotifyDismount")); sl@0: for(i=0; i< KNumClients; i++) sl@0: { sl@0: clientFs[i].NotifyDismount(removalDrvNo, trsClientNotify[i], (TNotifyDismountMode)0xFEEDFACE); sl@0: test(trsClientNotify[i] == KErrArgument); sl@0: } sl@0: sl@0: // Register for notification of pending media removal and check status sl@0: sl@0: test.Next(_L("Register for notification of pending media removal and check status")); sl@0: for(i=0; i< KNumClients; i++) sl@0: { sl@0: clientFs[i].NotifyDismount(removalDrvNo, trsClientNotify[i]); sl@0: test(trsClientNotify[i] == KRequestPending); sl@0: } sl@0: sl@0: // Notify clients of pending media removal and check status sl@0: sl@0: test.Next(_L("Notify clients of pending media removal and check status")); sl@0: fs.NotifyDismount(removalDrvNo, trsClientComplete, EFsDismountNotifyClients); sl@0: test(trsClientComplete == KRequestPending); sl@0: sl@0: // Check that client has notification of pending media removal sl@0: sl@0: test.Next(_L("Check that client has notification of pending media removal")); sl@0: for(i=0; i< KNumClients; i++) sl@0: { sl@0: test(trsClientNotify[i] == KErrNone); sl@0: } sl@0: sl@0: // Respond to the dismount using RFs::AllowDismount (only 2 clients) sl@0: sl@0: LOG_AND_TEST(KErrNone, clientFs[0].AllowDismount(removalDrvNo)); sl@0: test(trsClientComplete == KRequestPending); sl@0: LOG_AND_TEST(KErrNone, clientFs[1].AllowDismount(removalDrvNo)); sl@0: test(trsClientComplete == KRequestPending); sl@0: sl@0: // Check that file system can't be dismounted as all clients haven't responded sl@0: sl@0: test.Next(_L("Check that file system can't be dismounted as all clients haven't responded")); sl@0: LOG_AND_TEST(KErrInUse, fs.DismountFileSystem(fsName, removalDrvNo)); sl@0: sl@0: // Before all clients have completed, cancel the dismount sl@0: sl@0: test.Next(_L("Before all clients have completed, cancel the dismount")); sl@0: fs.NotifyDismountCancel(trsClientComplete); sl@0: test(trsClientComplete == KErrCancel); sl@0: sl@0: for(i=2; i< KNumClients; i++) sl@0: { sl@0: LOG_AND_TEST(KErrNone, clientFs[i].AllowDismount(removalDrvNo)); sl@0: LOG_AND_TEST(KErrNotFound, clientFs[i].AllowDismount(removalDrvNo)); sl@0: test(trsClientComplete == KErrCancel); sl@0: } sl@0: sl@0: // Check that file system can be dismounted after cancelling async dismount sl@0: sl@0: test.Next(_L("Check that file system can be dismounted after cancelling async dismount")); sl@0: LOG_AND_TEST(KErrNone, fs.DismountFileSystem(fsName, removalDrvNo)); sl@0: sl@0: // ...remount FAT sl@0: sl@0: test.Next(_L("Mount FAT FS on to the removal drive")); sl@0: LOG_AND_TEST(KErrNone, fs.MountFileSystem(fsName, removalDrvNo)); sl@0: sl@0: for(i=0; i< KNumClients; i++) sl@0: clientFs[i].Close(); sl@0: sl@0: dismountFs1.Close(); sl@0: sl@0: // sl@0: // Test dismounting while resourses are open sl@0: // sl@0: sl@0: _LIT(KFileName, ":\\foo"); sl@0: TBuf<7> fileName; sl@0: fileName.Append(driveLetter[1]); sl@0: fileName.Append(KFileName); sl@0: sl@0: RFile file; sl@0: test.Next(_L("Attempting to open a file\n\r")); sl@0: ret = file.Create(fs, fileName, EFileRead | EFileReadDirectIO | EFileWriteDirectIO); sl@0: test(ret == KErrNone || ret == KErrAlreadyExists); sl@0: LOG_AND_TEST(KErrNone, file.Write(0,_L8("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"))); sl@0: file.Close(); sl@0: sl@0: TBuf<7> dirName; sl@0: dirName.Append(driveLetter[1]); sl@0: dirName.Append(KFileName); sl@0: sl@0: RDir dir; sl@0: TEntry dirEntry; sl@0: test.Next(_L("Attempting to open a directory\n\r")); sl@0: LOG_AND_TEST(KErrNone, dir.Open(fs, dirName, KEntryAttNormal)); sl@0: LOG_AND_TEST(KErrNone, dir.Read(dirEntry)); sl@0: dir.Close(); sl@0: sl@0: fs.Close(); sl@0: sl@0: TInt pass; sl@0: for(pass=0; pass<5; pass++) sl@0: { sl@0: LOG_AND_TEST(KErrNone, fs.Connect()); sl@0: LOG_AND_TEST(KErrNone, dismountFs1.Connect()); sl@0: sl@0: TInt i = 0; sl@0: for(i=0; i< KNumClients; i++) sl@0: { sl@0: LOG_AND_TEST(KErrNone, clientFs[i].Connect()); sl@0: } sl@0: sl@0: // Open a file on the removable drive sl@0: sl@0: RFile file; sl@0: LOG_AND_TEST(KErrNone, file.Open(fs, fileName, EFileRead | EFileReadDirectIO | EFileWriteDirectIO)); sl@0: TBuf8<0x40> buf1; sl@0: LOG_AND_TEST(KErrNone, file.Read(0, buf1)); sl@0: LOG_AND_TEST(36, buf1.Length()); sl@0: test(buf1 == _L8("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")); sl@0: sl@0: // Unmount FAT FS from the removable drive - this should fail with a file open sl@0: sl@0: LOG_AND_TEST(KErrInUse, fs.DismountFileSystem(fsName, removalDrvNo)); sl@0: sl@0: // Open a directory on the removable drive sl@0: sl@0: test.Next(_L("Attempting to open a directory\n\r")); sl@0: LOG_AND_TEST(KErrNone, dir.Open(fs, dirName, KEntryAttNormal)); sl@0: LOG_AND_TEST(KErrNone, dir.Read(dirEntry)); sl@0: sl@0: // Check simple client dismount notification and cancel (before issuing a dismount request) sl@0: sl@0: test.Next(_L("Register for notification of pending media removal and check status")); sl@0: for(i=0; i< KNumClients; i++) sl@0: { sl@0: clientFs[i].NotifyDismount(removalDrvNo, trsClientNotify[i]); sl@0: test(trsClientNotify[i] == KRequestPending); sl@0: } sl@0: sl@0: test.Next(_L("Cancel notification of pending media removal and check status")); sl@0: for(i=0; i< KNumClients; i++) sl@0: { sl@0: clientFs[i].NotifyDismountCancel(trsClientNotify[i]); sl@0: test(trsClientNotify[i] == KErrCancel); sl@0: } sl@0: sl@0: // Check issuing and cancelling a dismount request while clients are responding sl@0: sl@0: test.Next(_L("Register for notification of pending media removal (again) and check status")); sl@0: for(i=0; i< KNumClients; i++) sl@0: { sl@0: clientFs[i].NotifyDismount(removalDrvNo, trsClientNotify[i]); sl@0: test(trsClientNotify[i] == KRequestPending); sl@0: } sl@0: sl@0: test.Next(_L("Notify clients of pending media removal and check status")); sl@0: fs.NotifyDismount(removalDrvNo, trsClientComplete, EFsDismountNotifyClients); sl@0: test(trsClientComplete == KRequestPending); sl@0: sl@0: test.Next(_L("Check that client has notification of pending media removal")); sl@0: for(i=0; i< KNumClients; i++) sl@0: { sl@0: test(trsClientNotify[i] == KErrNone); sl@0: } sl@0: sl@0: LOG_AND_TEST(KErrNone, clientFs[0].AllowDismount(removalDrvNo)); sl@0: test(trsClientComplete == KRequestPending); sl@0: LOG_AND_TEST(KErrNone, clientFs[1].AllowDismount(removalDrvNo)); sl@0: test(trsClientComplete == KRequestPending); sl@0: test.Next(_L("Before all clients have completed, cancel the dismount")); sl@0: fs.NotifyDismountCancel(trsClientComplete); sl@0: test(trsClientComplete == KErrCancel); sl@0: sl@0: for(i=2; i< KNumClients; i++) sl@0: { sl@0: LOG_AND_TEST(KErrNone, clientFs[i].AllowDismount(removalDrvNo)); sl@0: test(trsClientComplete == KErrCancel); sl@0: } sl@0: sl@0: // Check dismounting, responding, cancelling and forced remounting sl@0: sl@0: test.Next(_L("Register for notification of pending media removal (again) and check status")); sl@0: for(i=0; i< KNumClients; i++) sl@0: { sl@0: clientFs[i].NotifyDismount(removalDrvNo, trsClientNotify[i]); sl@0: test(trsClientNotify[i] == KRequestPending); sl@0: } sl@0: sl@0: test.Next(_L("Notify clients of pending media removal and check status")); sl@0: fs.NotifyDismount(removalDrvNo, trsClientComplete, EFsDismountNotifyClients); sl@0: test(trsClientComplete == KRequestPending); sl@0: sl@0: test.Next(_L("Check that client has notification of pending media removal")); sl@0: for(i=0; i< KNumClients; i++) sl@0: { sl@0: test(trsClientNotify[i] == KErrNone); sl@0: } sl@0: sl@0: test.Next(_L("Notify clients of pending media removal with another session and check status")); sl@0: fs.NotifyDismount(removalDrvNo, trsClientComplete1, EFsDismountNotifyClients); sl@0: test(trsClientComplete1 == KErrInUse); sl@0: sl@0: TInt expectedAllowDismountRet = KErrNone; sl@0: TInt expectedCompletionCode = KRequestPending; sl@0: if(pass & 0x01) sl@0: { sl@0: test.Next(_L("No response from clients - Force a dismount")); sl@0: test.Next(_L("...cancelling original request")); sl@0: fs.NotifyDismountCancel(trsClientComplete); sl@0: test(trsClientComplete == KErrCancel); sl@0: test.Next(_L("...issuing a forced dismount request")); sl@0: fs.NotifyDismount(removalDrvNo, trsClientComplete, EFsDismountForceDismount); sl@0: test(trsClientComplete == KErrNone); sl@0: expectedAllowDismountRet = KErrNotReady; sl@0: expectedCompletionCode = KErrNone; sl@0: } sl@0: sl@0: test.Next(_L("Allow dismount and check response")); sl@0: for(i=0; i < KNumClients; i++) sl@0: { sl@0: LOG_AND_TEST(expectedAllowDismountRet, clientFs[i].AllowDismount(removalDrvNo)); sl@0: if(i == KNumClients-1) sl@0: test(trsClientComplete == KErrNone); sl@0: else sl@0: test(trsClientComplete == expectedCompletionCode); sl@0: } sl@0: sl@0: // The last test should have dismounted the file system sl@0: sl@0: LOG_AND_TEST(KErrNotReady, file.Read(0,buf1)); sl@0: LOG_AND_TEST(KErrNotReady, dir.Read(dirEntry)); sl@0: sl@0: test.Next(_L("FAT File System should now be dismounted from the drive")); sl@0: LOG_AND_TEST(KErrNotReady, fs.DismountFileSystem(fsName, removalDrvNo)); sl@0: sl@0: test.Next(_L("Mount MS FS on to the removable drive")); sl@0: LOG_AND_TEST(KErrNone, fs.MountFileSystem(KMsFsyName, removalDrvNo)); sl@0: sl@0: LOG_AND_TEST(KErrDisMounted, file.Read(0,buf1)); sl@0: LOG_AND_TEST(KErrDisMounted, dir.Read(dirEntry)); sl@0: sl@0: test.Next(_L("Dismount MSFS normally")); sl@0: LOG_AND_TEST(KErrNone, fs.DismountFileSystem(KMsFsyName, removalDrvNo)); sl@0: sl@0: test.Next(_L("Mount FAT FS on to the removal drive")); sl@0: LOG_AND_TEST(KErrNone, fs.MountFileSystem(fsName, removalDrvNo)); sl@0: sl@0: LOG_AND_TEST(KErrNone, file.Read(0,buf1)); sl@0: LOG_AND_TEST(KErrEof, dir.Read(dirEntry)); // drive freshly formatted, so only root dir exists sl@0: sl@0: // Test multiple notifiers on a single session sl@0: sl@0: test.Next(_L("Register several notifiers for a single session and check status")); sl@0: for(i=0; i< KNumClients; i++) sl@0: { sl@0: clientFs[0].NotifyDismount(removalDrvNo, trsClientNotify[i]); sl@0: test(trsClientNotify[i] == KRequestPending); sl@0: } sl@0: sl@0: test.Next(_L("Notify clients and verify all requests signalled")); sl@0: fs.NotifyDismount(removalDrvNo, trsClientComplete, EFsDismountNotifyClients); sl@0: sl@0: test.Next(_L("Allow dismount 3 times from same session")); sl@0: for(i=0; i< KNumClients; i++) sl@0: { sl@0: test(trsClientComplete == KRequestPending); sl@0: test(trsClientNotify[i] == KErrNone); sl@0: LOG_AND_TEST(KErrNone, clientFs[0].AllowDismount(removalDrvNo)); sl@0: } sl@0: sl@0: test.Next(_L("Verify that file system has been dismounted")); sl@0: test(trsClientComplete == KErrNone); sl@0: sl@0: test.Next(_L("Mount FAT FS on to the removal drive")); sl@0: LOG_AND_TEST(KErrNone, fs.MountFileSystem(fsName, removalDrvNo)); sl@0: sl@0: // Test multiple notifiers on different drives sl@0: sl@0: const TInt KNumDrives = 1; sl@0: sl@0: test.Next(_L("Register several notifiers for different drives and check status")); sl@0: for(i=0; i < KNumDrives; i++) sl@0: { sl@0: clientFs[0].NotifyDismount(removalDrvNo + i, trsClientNotify[i]); sl@0: test(trsClientNotify[i] == KRequestPending); sl@0: } sl@0: sl@0: test.Next(_L("Notify clients and verify all requests signalled")); sl@0: fs.NotifyDismount(removalDrvNo, trsClientComplete, EFsDismountNotifyClients); sl@0: test(trsClientComplete == KRequestPending); sl@0: sl@0: test(trsClientNotify[0] == KErrNone); sl@0: LOG_AND_TEST(KErrNone, clientFs[0].AllowDismount(removalDrvNo)); sl@0: for(i=1; i< KNumDrives; i++) sl@0: { sl@0: test(trsClientNotify[i] == KRequestPending); sl@0: } sl@0: sl@0: test.Next(_L("Verify that file system has been dismounted")); sl@0: test(trsClientComplete == KErrNone); sl@0: sl@0: test.Next(_L("Check that file can be closed when filesystem is dismounted")); sl@0: file.Close(); sl@0: dir.Close(); sl@0: sl@0: test.Next(_L("Mount FAT FS on to the removal drive")); sl@0: LOG_AND_TEST(KErrNone, fs.MountFileSystem(fsName, removalDrvNo)); sl@0: sl@0: test.Next(_L("Cancel all outstanding notifiers for this session")); sl@0: clientFs[0].NotifyDismountCancel(); sl@0: for(i=1; i< KNumDrives; i++) sl@0: { sl@0: test(trsClientNotify[i] == KErrCancel); sl@0: } sl@0: sl@0: // Test session disconnect sl@0: test.Next(_L("Register for notification of pending media removal (again) and check status")); sl@0: for(i=0; i< KNumClients; i++) sl@0: { sl@0: clientFs[i].NotifyDismount(removalDrvNo, trsClientNotify[i]); sl@0: test(trsClientNotify[i] == KRequestPending); sl@0: } sl@0: sl@0: test.Next(_L("Close client sessions with outstanding notifiers")); sl@0: for(i=0; i< KNumClients; i++) sl@0: clientFs[i].Close(); sl@0: sl@0: // Since all clients have been closed, the next stage should result in a dismount sl@0: test.Next(_L("Notify clients of pending media removal and check status")); sl@0: fs.NotifyDismount(removalDrvNo, trsClientComplete, EFsDismountNotifyClients); sl@0: test(trsClientComplete == KErrNone); sl@0: sl@0: test.Next(_L("Mount FAT FS on to the removal drive")); sl@0: LOG_AND_TEST(KErrNone, fs.MountFileSystem(fsName, removalDrvNo)); sl@0: sl@0: TRequestStatus trs1; sl@0: dismountFs1.NotifyDismount(removalDrvNo, trs1); sl@0: test(trs1 == KRequestPending); sl@0: sl@0: fs.NotifyDismount(removalDrvNo, trsClientComplete, EFsDismountNotifyClients); sl@0: test(trsClientComplete == KRequestPending); sl@0: sl@0: fs.Close(); sl@0: dismountFs1.Close(); sl@0: } sl@0: sl@0: // Check that files/directories can't be opened on Mass Storage sl@0: sl@0: LOG_AND_TEST(KErrNone, fs.Connect()); sl@0: sl@0: test.Next(_L("Dismount FAT File System")); sl@0: LOG_AND_TEST(KErrNone, fs.DismountFileSystem(fsName, removalDrvNo)); sl@0: sl@0: test.Next(_L("Mount MS FS on to the removable drive")); sl@0: LOG_AND_TEST(KErrNone, fs.MountFileSystem(KMsFsyName, removalDrvNo)); sl@0: sl@0: test.Next(_L("Attempting to open a file\n\r")); sl@0: LOG_AND_TEST(KErrNotReady, file.Open(fs, fileName, EFileRead)); sl@0: sl@0: test.Next(_L("Attempting to open a directory\n\r")); sl@0: LOG_AND_TEST(KErrNotReady, dir.Open(fs, fileName, KEntryAttNormal)); sl@0: sl@0: // Test fix for DEF058681 - Mass Storage reports VolumeName incorrectly. sl@0: // Before the fix, CMassStorageMountCB::MountL() did not set the volume sl@0: // name, resulting in a panic when attempting to copy a null descriptor. sl@0: // Note that the volume name is still not returned client-side, since sl@0: // CMassStorageMountCB::VolumeL() returns KErrNotReady sl@0: TVolumeInfo volInfo; sl@0: ret = fs.Volume(volInfo, removalDrvNo); sl@0: LOG_AND_TEST(ret, KErrNotReady); sl@0: LOG_AND_TEST(volInfo.iName.Length(), 0); sl@0: sl@0: // ------------------------------------------------- sl@0: sl@0: // Get the boot sector info using MS FS and save it for later comparison sl@0: TBuf8 cbwBuf; sl@0: TInt dCBWTag = 1234567; // arbitrary, any number would do for this test. sl@0: sl@0: RDevTestUsbcClient usbcClient; sl@0: sl@0: // Open a session to LDD sl@0: test.Next(_L("Open LDD")); sl@0: LOG_AND_TEST(KErrNone, usbcClient.Open(0)); sl@0: sl@0: // Build SCSI command test unit ready sl@0: TBuf8 unitReadyBuf; sl@0: // Zero out the buf sl@0: unitReadyBuf.FillZ(SCSI_UNIT_READY_LEN); sl@0: sl@0: createCBW(cbwBuf, dCBWTag, 0, 0, SCSI_UNIT_READY_LEN, unitReadyBuf); sl@0: sl@0: // Send test unit ready command sl@0: test.Next(_L("Sending CBW with 'Unit Ready' cmd")); sl@0: TRequestStatus status; sl@0: usbcClient.HostWrite(status, EEndpoint1, cbwBuf, CBW_LENGTH); sl@0: User::WaitForRequest(status); sl@0: LOG_AND_TEST(KErrNone, status.Int()); sl@0: sl@0: // Read CSW sl@0: test.Next(_L("Reading CSW")); sl@0: TBuf8 cswBuf; sl@0: usbcClient.HostRead(status, EEndpoint2, cswBuf, CSW_LENGTH); sl@0: User::WaitForRequest(status); sl@0: LOG_AND_TEST(KErrNone, status.Int()); sl@0: sl@0: // Check dCSWTag sl@0: TInt recvedCBWTag = extractInt(&cswBuf[4]); sl@0: LOG_AND_TEST(dCBWTag, recvedCBWTag); sl@0: sl@0: // Check bCSWStatus sl@0: TInt bCSWStatus = cswBuf[CSW_LENGTH - 1]; sl@0: test.Printf(_L("CSW status: %d\n"), bCSWStatus); sl@0: LOG_AND_TEST(bCSWStatus, 1); sl@0: sl@0: //============================================ sl@0: sl@0: // Create a CBW for SCSI read (10) command to read the boot sector via MS FS sl@0: TBuf8 readBuf; sl@0: // 0: starting sector; 1: total blocks sl@0: createReadCmd(readBuf, 0, 1); sl@0: sl@0: // 0x80: data-in to the host; 10: read (10) command length sl@0: createCBW(cbwBuf, ++dCBWTag, BOOTSECTOR_SIZE, 0x80, 10, readBuf); sl@0: sl@0: sl@0: // Send CBW to the LDD sl@0: test.Next(_L("Send CBW with 'Read' Command")); sl@0: usbcClient.HostWrite(status, EEndpoint1, cbwBuf, CBW_LENGTH); sl@0: User::WaitForRequest(status); sl@0: LOG_AND_TEST(KErrNone, status.Int()); sl@0: sl@0: sl@0: sl@0: test.Next(_L("Reading bootsector data")); sl@0: // Read the boot sector sl@0: TBuf8 msBootSector; sl@0: usbcClient.HostRead(status, EEndpoint2, msBootSector, BOOTSECTOR_SIZE); sl@0: User::WaitForRequest(status); sl@0: LOG_AND_TEST(KErrNone, status.Int()); sl@0: sl@0: // Read CSW sl@0: test.Next(_L("Reading CSW")); sl@0: usbcClient.HostRead(status, EEndpoint2, cswBuf, CSW_LENGTH); sl@0: User::WaitForRequest(status); sl@0: LOG_AND_TEST(KErrNone, status.Int()); sl@0: sl@0: // Check dCBWTag sl@0: recvedCBWTag = extractInt(&cswBuf[4]); sl@0: LOG_AND_TEST(dCBWTag, recvedCBWTag); sl@0: sl@0: // Check bCSWStatus sl@0: bCSWStatus = cswBuf[CSW_LENGTH - 1]; sl@0: test.Printf(_L("CSW status: %d\n"), bCSWStatus); sl@0: sl@0: LOG_AND_TEST(bCSWStatus, 0); sl@0: sl@0: // Compare FAT FS boot sector with MS FS boot sector sl@0: // When accessing the medium through USB, it is accessed raw. That means sl@0: // we have to find the boot record (BPB), which may be in sector 0 if the sl@0: // medium has no MBR or elsewhere if it is has a MBR. (Details of the sl@0: // identification can be found in the FAT32 specification) sl@0: TUint16 signature; sl@0: sl@0: signature = (TUint16) (msBootSector[KMBRSignatureOffset] | sl@0: msBootSector[KMBRSignatureOffset + 1] << 8); sl@0: sl@0: LOG_AND_TEST(signature, KBootRecordSignature); sl@0: sl@0: if(((msBootSector[0] == 0xEB && msBootSector[2] == 0x90) || (msBootSector[0] == 0xE9)) && sl@0: (msBootSector[16] >= 1) && ((msBootSector[21] == 0xF0) || (msBootSector[21] >= 0xF8))) sl@0: { sl@0: test.Printf(_L("BPB identified in sector 0.\r\n")); sl@0: } sl@0: else sl@0: { sl@0: test.Printf(_L("Assume sector 0 to be MBR - attempting to locate BPB\r\n")); sl@0: // Read the offset to the first partition to find the boot record... sl@0: // 32bit int stored as little endian sl@0: TUint32 bootSectorLocation; sl@0: bootSectorLocation = msBootSector[KMBRFirstPartitionSectorOffset] | sl@0: msBootSector[KMBRFirstPartitionSectorOffset + 1] << 8 | sl@0: msBootSector[KMBRFirstPartitionSectorOffset + 2] << 16 | sl@0: msBootSector[KMBRFirstPartitionSectorOffset + 3] << 24; sl@0: sl@0: test.Printf(_L("Reading Boot Sector from offset %d\r\n"), bootSectorLocation); sl@0: sl@0: // Create a CBW for SCSI read (10) command to read the boot sector via MS FS sl@0: TBuf8 readBuf; sl@0: // 0: starting sector; 1: total blocks sl@0: createReadCmd(readBuf, bootSectorLocation, 1); sl@0: sl@0: // 0x80: data-in to the host; 10: read (10) command length sl@0: createCBW(cbwBuf, ++dCBWTag, BOOTSECTOR_SIZE, 0x80, 10, readBuf); sl@0: sl@0: // Send CBW to the LDD sl@0: test.Next(_L("Send CBW with 'Read' Command")); sl@0: usbcClient.HostWrite(status, EEndpoint1, cbwBuf, CBW_LENGTH); sl@0: User::WaitForRequest(status); sl@0: LOG_AND_TEST(KErrNone, status.Int()); sl@0: sl@0: // Read the boot sector sl@0: usbcClient.HostRead(status, EEndpoint2, msBootSector, BOOTSECTOR_SIZE); sl@0: User::WaitForRequest(status); sl@0: LOG_AND_TEST(KErrNone, status.Int()); sl@0: sl@0: // Read CSW sl@0: test.Next(_L("Reading CSW")); sl@0: usbcClient.HostRead(status, EEndpoint2, cswBuf, CSW_LENGTH); sl@0: User::WaitForRequest(status); sl@0: LOG_AND_TEST(KErrNone, status.Int()); sl@0: sl@0: // Check dCBWTag sl@0: recvedCBWTag = extractInt(&cswBuf[4]); sl@0: LOG_AND_TEST(dCBWTag, recvedCBWTag); sl@0: sl@0: // Check bCSWStatus sl@0: bCSWStatus = cswBuf[CSW_LENGTH - 1]; sl@0: test.Printf(_L("CSW status: %d\n"), bCSWStatus); sl@0: sl@0: LOG_AND_TEST(bCSWStatus, 0); sl@0: } sl@0: sl@0: test (0 == fatBootSector.Compare(msBootSector)); sl@0: sl@0: // sl@0: // Create a CBW to prevent medium removal sl@0: // sl@0: TBuf8 tBuf; sl@0: // Zero out the buf sl@0: tBuf.FillZ(SCSI_MED_RMVL_LEN); sl@0: tBuf[0] = 0x1E; sl@0: tBuf[4] = 1; // prevent medium removal sl@0: sl@0: cbwBuf.FillZ(CBW_LENGTH); sl@0: createCBW(cbwBuf, ++dCBWTag, 0, 0, SCSI_MED_RMVL_LEN, tBuf); sl@0: sl@0: // Send prevent medium removal command sl@0: test.Next(_L("Sending CBW with 'Prevent media removal' cmd")); sl@0: usbcClient.HostWrite(status, EEndpoint1, cbwBuf, CBW_LENGTH); sl@0: User::WaitForRequest(status); sl@0: LOG_AND_TEST(KErrNone, status.Int()); sl@0: sl@0: // Read CSW sl@0: test.Next(_L("Reading CSW")); sl@0: usbcClient.HostRead(status, EEndpoint2, cswBuf, CSW_LENGTH); sl@0: User::WaitForRequest(status); sl@0: LOG_AND_TEST(KErrNone, status.Int()); sl@0: sl@0: // Check dCSWTag sl@0: recvedCBWTag = extractInt(&cswBuf[4]); sl@0: LOG_AND_TEST(dCBWTag, recvedCBWTag); sl@0: sl@0: // Check bCSWStatus sl@0: bCSWStatus = cswBuf[CSW_LENGTH - 1]; sl@0: test.Printf(_L("CSW status: %d\n"), bCSWStatus); sl@0: sl@0: if(bCSWStatus == 0) sl@0: { sl@0: sl@0: // Try to unmount MS FS. This should fail as medium removal is disallowed sl@0: test.Next(_L("Dismounting MSFS")); sl@0: test(KErrNone != fs.DismountFileSystem(KMsFsyName, removalDrvNo)); sl@0: sl@0: // sl@0: // Create a CBW to allow medium removal sl@0: // sl@0: // Zero out the buf sl@0: tBuf.FillZ(SCSI_MED_RMVL_LEN); sl@0: tBuf[0] = 0x1E; sl@0: tBuf[4] = 0; // allow medium removal sl@0: sl@0: createCBW(cbwBuf, ++dCBWTag, 0, 0, SCSI_MED_RMVL_LEN, tBuf); sl@0: sl@0: // Send allow medium removal command sl@0: test.Next(_L("Sending CBW with 'Allow media removal' cmd")); sl@0: usbcClient.HostWrite(status, EEndpoint1, cbwBuf, CBW_LENGTH); sl@0: User::WaitForRequest(status); sl@0: LOG_AND_TEST(KErrNone, status.Int()); sl@0: sl@0: // Read CSW sl@0: test.Next(_L("Reading CSW")); sl@0: usbcClient.HostRead(status, EEndpoint2, cswBuf, CSW_LENGTH); sl@0: User::WaitForRequest(status); sl@0: LOG_AND_TEST(KErrNone, status.Int()); sl@0: sl@0: // Check dCSWTag sl@0: recvedCBWTag = extractInt(&cswBuf[4]); sl@0: LOG_AND_TEST(dCBWTag, recvedCBWTag); sl@0: sl@0: // Check bCSWStatus sl@0: bCSWStatus = cswBuf[CSW_LENGTH - 1]; sl@0: test.Printf(_L("CSW status: %d\n"), bCSWStatus); sl@0: LOG_AND_TEST(bCSWStatus, 0); sl@0: sl@0: } sl@0: else sl@0: test.Printf(_L("Prevent Media Removal command not supported, skipping appropriate tests")); sl@0: sl@0: sl@0: // Try to unmount MS FS again. This time it should succeed sl@0: LOG_AND_TEST(KErrNone, fs.DismountFileSystem(KMsFsyName, removalDrvNo)); sl@0: sl@0: // Read the boot sector while MS FS is unmounted, this should fail sl@0: test(KErrNone != fatDiskF.Open(fs, removalDrvNo)); sl@0: fatDiskF.Close(); sl@0: sl@0: // Mount FAT FS on to the removal drive sl@0: LOG_AND_TEST(KErrNone, fs.MountFileSystem(fsName, removalDrvNo)); sl@0: sl@0: // Additional step for DEF079149: File server crash when re-adding sl@0: // MSFS.FSY. Before the fix was applied this call to RFs::AddFileSystem sl@0: // would cause a crash. sl@0: LOG_AND_TEST(KErrAlreadyExists,fs.AddFileSystem(KMsFs)); sl@0: sl@0: // Read the boot sector after FAT MS is mounted on to the removal drive sl@0: LOG_AND_TEST(KErrNone, fatDiskF.Open(fs, removalDrvNo)); sl@0: LOG_AND_TEST(KErrNone, fatDiskF.Read(0, fatBootSector)); sl@0: fatDiskF.Close(); sl@0: sl@0: createCBW(cbwBuf, ++dCBWTag, 0, 0, SCSI_UNIT_READY_LEN, unitReadyBuf); sl@0: sl@0: // Send test unit ready command sl@0: test.Next(_L("Sending CBW with 'Unit Ready' cmd")); sl@0: usbcClient.HostWrite(status, EEndpoint1, cbwBuf, CBW_LENGTH); sl@0: User::WaitForRequest(status); sl@0: LOG_AND_TEST(KErrNone, status.Int()); sl@0: sl@0: // Read CSW sl@0: usbcClient.HostRead(status, EEndpoint2, cswBuf, CSW_LENGTH); sl@0: User::WaitForRequest(status); sl@0: LOG_AND_TEST(KErrNone, status.Int()); sl@0: sl@0: // Check dCSWTag sl@0: recvedCBWTag = extractInt(&cswBuf[4]); sl@0: LOG_AND_TEST(dCBWTag, recvedCBWTag); sl@0: sl@0: // Check bCSWStatus sl@0: bCSWStatus = cswBuf[CSW_LENGTH - 1]; sl@0: test.Printf(_L("CSW status: %d\n"), bCSWStatus); sl@0: LOG_AND_TEST(bCSWStatus, 1); sl@0: sl@0: // sl@0: // Read MS FS using SCSI read command, this should fail as sl@0: // FAT FS is mounted instead sl@0: // sl@0: sl@0: // 0x80: data-in to the host; 10: read (10) command length sl@0: sl@0: createCBW(cbwBuf, ++dCBWTag, BOOTSECTOR_SIZE, 0x80, 10, readBuf); sl@0: sl@0: // Send CBW to the LDD sl@0: test.Next(_L("SEnding CBW with 'Read'")); sl@0: usbcClient.HostWrite(status, EEndpoint1, cbwBuf, CBW_LENGTH); sl@0: User::WaitForRequest(status); sl@0: LOG_AND_TEST(KErrNone, status.Int()); sl@0: sl@0: // Read the sector sl@0: usbcClient.HostRead(status, EEndpoint2, msBootSector, BOOTSECTOR_SIZE); sl@0: User::WaitForRequest(status); sl@0: LOG_AND_TEST(KErrNone, status.Int()); sl@0: sl@0: sl@0: // Read CSW sl@0: usbcClient.HostRead(status, EEndpoint2, cswBuf, CSW_LENGTH); sl@0: User::WaitForRequest(status); sl@0: LOG_AND_TEST(KErrNone, status.Int()); sl@0: sl@0: // Check dCSWTag sl@0: recvedCBWTag = extractInt(&cswBuf[4]); sl@0: LOG_AND_TEST(dCBWTag , recvedCBWTag); sl@0: sl@0: // Check bCSWStatus sl@0: bCSWStatus = cswBuf[CSW_LENGTH - 1]; sl@0: test.Printf(_L("CSW status: %d\n"), bCSWStatus); sl@0: test(bCSWStatus != 0); sl@0: sl@0: sl@0: // Read FAT FS using RFs API sl@0: LOG_AND_TEST(KErrNone, fatDiskF.Open(fs, removalDrvNo)); sl@0: LOG_AND_TEST(KErrNone, fatDiskF.Read(0, fatBootSector)); sl@0: fatDiskF.Close(); sl@0: sl@0: // Stop usb mass storage device sl@0: LOG_AND_TEST(KErrNone, usbMs.Stop()); sl@0: usbMs.Close(); sl@0: User::After(1000000); sl@0: sl@0: ret = fs.RemoveFileSystem(KMsFsyName); sl@0: fs.Close(); sl@0: sl@0: usbcClient.Close(); sl@0: ret = User::FreeLogicalDevice(_L("USBC")); sl@0: LOG_AND_TEST(ret, KErrNone); sl@0: sl@0: test.Printf(_L("Exiting test\r\n")); sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: sl@0: sl@0: GLDEF_C void CallTestsL() sl@0: // sl@0: // Do all tests sl@0: // sl@0: { sl@0: // Parse the CommandLine arguments: removal drive and non-removal drive sl@0: ParseCommandArguments(); sl@0: sl@0: // Run test sl@0: test.Start( _L("Test mountstart") ); sl@0: doComponentTest(); sl@0: test.End(); sl@0: }