kerneltest/f32test/filesystem/fat/t_mount.cpp
changeset 43 96e5fb8b040d
child 199 189ece41fa29
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/f32test/filesystem/fat/t_mount.cpp	Thu Dec 17 09:24:54 2009 +0200
@@ -0,0 +1,1312 @@
+// Copyright (c) 1996-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:
+// f32test\server\t_mount.cpp
+// Testing some issues connected with mounting/dismounting file fystems, drives finalisation etc.
+//
+//
+
+/**
+ @file
+*/
+
+#define __E32TEST_EXTENSION__
+
+#include <f32file.h>
+#include <e32test.h>
+#include <e32math.h>
+#include <e32property.h>
+#include <f32dbg.h>
+
+#include "t_server.h"
+#include "fat_utils.h"
+
+using namespace Fat_Test_Utils;
+
+#ifdef __VC32__
+    // Solve compilation problem caused by non-English locale
+    #pragma setlocale("english")
+#endif
+
+RTest test(_L("T_Mount"));
+
+static TInt     gDriveNum=-1; ///< drive number we are dealing with
+static TInt64   gRndSeed;
+
+
+const TInt KBM_Repetitions = 5;     ///< number of repetitions for BM testing
+const TUint32 KCheckFileSize = 533; ///< size of the small file to be deleted
+
+_LIT(KFileNameFirst,  "\\FIRST%d.DAT");
+_LIT(KFileNameMiddle, "\\MID%d.DAT");
+_LIT(KFileNameLast,   "\\LAST%d.DAT");
+_LIT(KFileNameFiller, "\\FILL%d.DAT");
+
+typedef void (*TStressFN)(TInt);    //-- pointer to the FAT mount stress function
+
+
+//-------------------------------------------------------------------
+//-- debug bit flags that may be set in the property which controls FAT volume mounting
+
+const TUid KThisTestSID={0x10210EB3}; ///< this EXE SID
+
+const TUint32 KMntProp_EnableALL    = 0x00000000; //-- enable all operations
+
+#ifdef _DEBUG
+
+const TUint32 KMntProp_DisableALL   = 0xFFFFFFFF; //-- disable all operations
+const TUint32 KMntProp_Disable_FsInfo       = 0x00000001; //-- mask for disabling/enabling FSInfo information
+const TUint32 KMntProp_Disable_FatBkGndScan = 0x00000002; //-- mask for disabling/enabling FAT background scanner
+
+#endif
+
+//-------------------------------------------------------------------
+
+/** set a debug property value, which then wiil be read by FAT fsy */
+void SetFsyDebugFlag(TInt aDriveNo, TUint32 aFlags)
+{
+    TInt nRes;
+
+    nRes = RProperty::Set(KThisTestSID, aDriveNo, aFlags);
+    test_KErrNone(nRes);
+}
+
+//-------------------------------------------------------------------
+/**
+    format the volume and read the boot sector
+*/
+static void FormatVolume(TBool aQuickFormat)
+{
+    TInt nRes;
+
+    #if 0
+    //-- FAT32 SPC:1; for the FAT32 testing on the emulator
+    (void)aQuickFormat;
+
+    #ifdef  __EPOC32__
+    test.Printf(_L("This is emulator configuration!!!!\n"));
+    test(0);
+    #endif
+
+    TFatFormatParam fp;
+    fp.iFatType = EFat32;
+    fp.iSecPerCluster = 1;
+    nRes = FormatFatDrive(TheFs, CurrentDrive(), ETrue, &fp); //-- always quick; doesn't matter for the emulator
+    #else
+    nRes = FormatFatDrive(TheFs, CurrentDrive(), aQuickFormat);
+    #endif
+
+    test_KErrNone(nRes);
+
+}
+
+//-------------------------------------------------------------------
+
+/**
+    Prepare FAT volume for mounting performance testing
+
+    1. quick format the drive
+    2. create KBM_Repetitions files in the beginning (first files)
+    3. create KMaxFillFiles/2 large files (they take about 40% of the volume);
+    4. create KBM_Repetitions files (middle files)
+    5. create KMaxFillFiles/2 large files (they take other 40% of the volume);
+    6. create KBM_Repetitions files (last files)
+
+    @return ETrue if everythis is OK
+*/
+TBool PrepareVolumeForBM()
+{
+    test.Printf(_L("Prepare the volume for BM testing...\n"));
+
+    TInt nRes;
+    TInt i;
+
+    //-- 1. quick format the drive
+    FormatVolume(ETrue);
+
+
+    if(!Is_Fat32(TheFs, gDriveNum))
+    {
+        test.Printf(_L("This test requires FAT32 ! Skipping.\n"));
+        return EFalse;
+    }
+
+    TVolumeInfo volInfo;
+    nRes = TheFs.Volume(volInfo, gDriveNum);
+    test_KErrNone(nRes);
+
+    //-- the files will take 80% of the drive space
+    const TInt    KMaxFillFiles = 100;
+    const TUint32 KFillFileSz = (TUint32)((volInfo.iFree*8) / (10*KMaxFillFiles));
+
+    //-- 2. create KBM_Repetitions files in the very begining (occupies first FAT entries)
+    TBuf<64> buf;
+
+    for(i=0; i<KBM_Repetitions; ++i)
+    {
+        buf.Format(KFileNameFirst, i);
+        nRes = CreateCheckableStuffedFile(TheFs, buf, KCheckFileSize);
+        test_KErrNone(nRes);
+    }
+
+    //-- 3. Fill the FAT with entries and cteate a file in the middle
+    const TInt nHalf1 = KMaxFillFiles / 2;
+
+    for(i=0; i<nHalf1; ++i)
+    {
+        buf.Format(KFileNameFiller, i);
+        nRes = CreateEmptyFile(TheFs, buf, KFillFileSz);
+        test_KErrNone(nRes);
+    }
+
+    //-- 4. create a files in the middle
+    for(i=0; i<KBM_Repetitions; ++i)
+    {
+        buf.Format(KFileNameMiddle, i);
+        nRes = CreateCheckableStuffedFile(TheFs, buf, KCheckFileSize);
+        test_KErrNone(nRes);
+    }
+
+    //-- 5. fill second half FAT
+    for(i=nHalf1; i<KMaxFillFiles; ++i)
+    {
+        buf.Format(KFileNameFiller, i);
+        nRes = CreateEmptyFile(TheFs, buf, KFillFileSz);
+        test_KErrNone(nRes);
+    }
+
+
+    //-- 6. create files in the very end (occupiy last FAT entries)
+    for(i=0; i<KBM_Repetitions; ++i)
+    {
+        buf.Format(KFileNameLast, i);
+        nRes = CreateCheckableStuffedFile(TheFs, buf, KCheckFileSize);
+        test_KErrNone(nRes);
+    }
+
+    return ETrue;
+}
+
+/**
+    Mounts and dismounts FAT volume several times calculating average time taken to mount.
+    Also can stress FS by calling stress function that can do some work on the volume.
+
+    @param  apStressFN pointer to the stressing function which can be called just after mounting. Can be NULL.
+    @return time in milliseconds taken to mout the volume
+*/
+static TUint32 DoMeasureMountTime(TStressFN apStressFN)
+{
+
+    TInt nRes;
+
+    TTime   timeStart;
+    TTime   timeEnd;
+
+    TInt64   usMountTime=0;      //-- total time taken by "Mount"
+
+    //-- disable FAT test utils print out, it can affects measured time
+    EnablePrintOutput(EFalse);
+
+    for(TInt i=0; i<KBM_Repetitions; ++i)
+    {
+
+        //-- A. remount FS taking the time when mounting starts
+        nRes = RemountFS(TheFs, gDriveNum, &timeStart);
+        test_KErrNone(nRes);
+
+        //-- B. call a given stress function
+        if(apStressFN)
+            apStressFN(i);
+
+        //-- C. take end time
+        timeEnd.UniversalTime();
+        test_KErrNone(nRes);
+
+        usMountTime += (timeEnd.MicroSecondsFrom(timeStart)).Int64();
+     }
+
+    const TUint32 msMountTime = (TUint32)usMountTime / (K1mSec*KBM_Repetitions);
+
+    EnablePrintOutput(ETrue); //-- Enable FAT test utils print out
+
+    return msMountTime;
+}
+
+//-------------------------------------------------------------------
+
+/**
+    Stress function.
+    Use case: read access to the first file on the volume in root dir.
+*/
+static void FirstReadAccess_FirstFile_Stress(TInt aRepNo)
+{
+    TBuf<64> buf;
+    buf.Format(KFileNameFirst, aRepNo);
+
+    TInt nRes = VerifyCheckableFile(TheFs, buf);
+    test_KErrNone(nRes);
+}
+
+
+/**
+    Stress function.
+    Use case: read access to the middle file on the volume in root dir.
+*/
+static void FirstReadAccess_MiddleFile_Stress(TInt aRepNo)
+{
+    TBuf<64> buf;
+    buf.Format(KFileNameMiddle, aRepNo);
+
+    TInt nRes = VerifyCheckableFile(TheFs, buf);
+    test_KErrNone(nRes);
+}
+
+/**
+    Stress function.
+    Use case: read access to the last file on the volume in root dir.
+*/
+static void FirstReadAccess_LastFile_Stress(TInt aRepNo)
+{
+    TBuf<64> buf;
+    buf.Format(KFileNameLast, aRepNo);
+
+    TInt nRes = VerifyCheckableFile(TheFs, buf);
+    test_KErrNone(nRes);
+}
+
+/**
+    Stress function.
+    Use case: Getting volume information SYNCHRONOUSLY.
+*/
+static void GetVolInfo_Synch_Stress(TInt)
+{
+    TVolumeInfo volInfo;
+    TInt nRes = TheFs.Volume(volInfo, gDriveNum);
+    test_KErrNone(nRes);
+}
+
+/**
+    Stress function.
+    Use case: Getting volume information _ASYNCHRONOUSLY_, i.e. do not wait until
+    FAT32 free space scan thread finishes
+*/
+static void GetVolInfo_Asynch_Stress(TInt)
+{
+    TVolumeInfo volInfo;
+
+    //-- let's use special version of the RFS API
+    TRequestStatus rqStat;
+    TheFs.Volume(volInfo, gDriveNum, rqStat);
+
+    User::WaitForRequest(rqStat);
+    test(rqStat.Int()==KErrNone);
+
+}
+
+//-------------------------------------------------------------------
+
+/**
+    Stress function.
+    Use case: deletes files in the beginning of the volume (or FAT table)
+*/
+static void DeleteFirstFile_Stress(TInt aRepNo)
+{
+    TBuf<64> buf;
+    buf.Format(KFileNameFirst, aRepNo);
+
+    TInt nRes = TheFs.Delete(buf);
+    test_KErrNone(nRes);
+}
+
+
+/**
+    Stress function.
+    Use case: deletes files in the middle of the volume (or FAT table)
+*/
+static void DeleteMiddleFile_Stress(TInt aRepNo)
+{
+    TBuf<64> buf;
+    buf.Format(KFileNameMiddle, aRepNo);
+
+    TInt nRes = TheFs.Delete(buf);
+    test_KErrNone(nRes);
+}
+
+/**
+    Stress function.
+    Use case: deletes files in the end of the volume (or FAT table)
+*/
+static void DeleteLastFile_Stress(TInt aRepNo)
+{
+    TBuf<64> buf;
+    buf.Format(KFileNameLast, aRepNo);
+
+    TInt nRes = TheFs.Delete(buf);
+    test_KErrNone(nRes);
+}
+
+
+//-------------------------------------------------------------------
+
+/**
+    perform series of tests that measure and print out FAT volume mount time for different secenarios
+*/
+void MeasureMountTime()
+{
+    TUint32 msTime;
+
+    if(!PrepareVolumeForBM()) //-- prepare the volume for BM tests: format it, create file structure etc.
+        return;
+
+    //-- 1. no stress function, measure just pure mount time
+    msTime = DoMeasureMountTime(NULL);
+    test.Printf(_L("#--> Pure mount:%d ms\n"), msTime);
+
+    //-- 2.1 measure mount time with a read-acess to the first file on the volume
+    msTime = DoMeasureMountTime(FirstReadAccess_FirstFile_Stress);
+    test.Printf(_L("#--> mount and read access to 1st file:%d ms\n"), msTime);
+
+    //-- 2.2 measure mount time with a read-acess to the middle file on the volume
+    msTime = DoMeasureMountTime(FirstReadAccess_MiddleFile_Stress);
+    test.Printf(_L("#--> mount and read access to middle file:%d ms\n"), msTime);
+
+    //-- 2.3 measure mount time with a read-acess to the last file on the volume
+    msTime = DoMeasureMountTime(FirstReadAccess_LastFile_Stress);
+    test.Printf(_L("#--> mount and read access to last file:%d ms\n"), msTime);
+
+    //-- 2.4 measure mount time with getting a volume information
+    msTime = DoMeasureMountTime(GetVolInfo_Synch_Stress);
+    test.Printf(_L("#--> mount and getting volInfo (synch):%d ms\n"), msTime);
+
+    msTime = DoMeasureMountTime(GetVolInfo_Asynch_Stress);
+    test.Printf(_L("#--> mount and getting volInfo (Asynch):%d ms\n"), msTime);
+
+
+    //-- 2.4 measure mount time with deleting file in the beginning (write access to the first entries of the FAT32)
+    msTime = DoMeasureMountTime(DeleteFirstFile_Stress);
+    test.Printf(_L("#--> mount and delete first file:%d ms\n"), msTime);
+
+    //-- 2.5 measure mount time with deleting file in the middle (write access to the middle entries of the FAT32)
+    msTime = DoMeasureMountTime(DeleteMiddleFile_Stress);
+    test.Printf(_L("#--> mount and delete middle file:%d ms\n"), msTime);
+
+    //-- 2.6 measure mount time with deleting file in the end (write access to the last entries of the FAT32)
+    msTime = DoMeasureMountTime(DeleteLastFile_Stress);
+    test.Printf(_L("#--> mount and delete last file:%d ms\n"), msTime);
+
+    test.Printf(_L("---\n"), msTime);
+}
+
+//----------------------------------------------------------------------------------------------
+//! @SYMTestCaseID      PBASE-T_MOUNT-0521
+//! @SYMTestType        PT
+//! @SYMPREQ            PREQ1721
+//! @SYMTestCaseDesc    Testing FAT volume mount performance for various scenarios
+//!
+//! @SYMTestActions
+//!             0   Prepare the volume by formatting it and creating 100 files to occupy the space.
+//!             1   Turn OFF all mount enhancements
+//!             2   Measure and print out volume mount time for the next scenarios:
+//!                   a.  simple mount
+//!                   b.  mount and read access to the media (reading the last file in the root dir.)
+//!                   c.  mount and write access to the media (writing data into the last file in the root dir)
+//!                   d.  mount getting volume information
+//!
+//!
+//!             3     Turn ON using FSInfo.
+//!             4     Repeat step 2 for this case.
+//! @SYMTestExpectedResults Finishes ok.
+//! @SYMTestPriority        High
+//! @SYMTestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+void TestFAT_Mounting_Performance()
+{
+    test.Next(_L("\n#--> Measuring FAT volumes mount performance.\n"));
+#ifndef _DEBUG
+    test.Printf(_L("Skipping the test in the Release build! \n"));
+    return;
+#else
+
+   //-- 1. turn OFF all mount enhancements like using FSInfo, backround FAT scan etc.
+   test.Printf(_L("#--> ==== All mount enhancements are disabled ====\n"));
+   SetFsyDebugFlag(gDriveNum, KMntProp_DisableALL);
+   MeasureMountTime();
+
+   //-- 2. Turn ON using FSInfo
+   test.Printf(_L("#--> ==== Enabled Using FSInfo ====\n"));
+   SetFsyDebugFlag(gDriveNum, KMntProp_DisableALL & ~KMntProp_Disable_FsInfo);
+   MeasureMountTime();
+
+   //-- 2. Turn OFF using FSInfo and ON FAT32 bacground scanning
+   test.Printf(_L("#--> ==== Enabled FAT32 BkGnd scan, FSInfo disabled ====\n"));
+   SetFsyDebugFlag(gDriveNum, KMntProp_DisableALL & ~KMntProp_Disable_FatBkGndScan);
+   MeasureMountTime();
+
+   //-- restore mounting mechanism
+   SetFsyDebugFlag(gDriveNum, KMntProp_EnableALL);
+
+#endif //_DEBUG
+}
+
+
+
+//-------------------------------------------------------------------
+
+/**
+    Check if the drive aDriveNo is finalised or not.
+    The "CleanShutDown" is obtained by QueryVolumeInfoExt API and by reading 2 FATs directly with checking their consistence.
+
+    @param  aDriveNo drive number to query.
+    @return ETrue if the drive if finalised
+*/
+static TBool DoCheckVolumeFinalised(TInt aDriveNo)
+{
+    TInt nRes;
+    TPckgBuf<TBool> boolPckg;
+
+    //-- 1. get "Finalised" state by using the API
+    nRes = TheFs.QueryVolumeInfoExt(aDriveNo, EIsDriveFinalised, boolPckg);
+    test_KErrNone(nRes);
+
+    //-- N.B. for FAT12 the result can be either OK or "NotSupported"
+    //-- If FAT12 is in explicit "finalised" state, the result will be OK
+    //-- if not, we can't query the volume state, because FAT12 doesn't support flags in FAT[1]
+
+    const TBool bFinalised_From_API = boolPckg() >0;
+          TBool bFinalised_From_FAT1 = bFinalised_From_API;
+
+    TBuf8<32> fatBuf(32);
+    TFatBootSector  bootSec;
+    const TUint32 posMainBootSec = KBootSectorNum << KDefaultSectorLog2;
+
+    nRes = ReadBootSector(TheFs, gDriveNum, posMainBootSec, bootSec);
+    test_KErrNone(nRes);
+
+    test(bootSec.IsValid());
+
+    const TUint32 Fat1StartPos = bootSec.FirstFatSector() * bootSec.BytesPerSector();
+
+    if(bootSec.FatType() == EFat16)
+    {//-- FAT16
+        TUint16 fatEntry;
+        const TUint16 KClnShtdnMask = 0x8000; //-- "ClnShutBitMask", see FAT specs
+
+        //-- read "CleanShutDown" flag directly from the 1st FAT
+        nRes = MediaRawRead(TheFs, gDriveNum, Fat1StartPos, fatBuf.Size(), fatBuf);
+        test_KErrNone(nRes);
+
+        Mem::Copy(&fatEntry, (fatBuf.Ptr()+sizeof(fatEntry)), sizeof(fatEntry));
+        bFinalised_From_FAT1 = (fatEntry & KClnShtdnMask) >0;
+
+
+        for(TInt i=1; i<bootSec.NumberOfFats(); ++i)
+        {
+            //-- read a flag from the next FAT
+            const TUint32 currFatStartPos = (bootSec.FirstFatSector() + i*bootSec.TotalFatSectors())*bootSec.BytesPerSector();
+
+            nRes = MediaRawRead(TheFs, gDriveNum, currFatStartPos, fatBuf.Size(), fatBuf);
+            test_KErrNone(nRes);
+
+            Mem::Copy(&fatEntry, (fatBuf.Ptr()+sizeof(fatEntry)), sizeof(fatEntry));
+            const TBool bFinalised_From_currFAT = (fatEntry & KClnShtdnMask)>0;
+
+            test(bFinalised_From_currFAT == bFinalised_From_FAT1);
+        }
+
+    }
+    else if(bootSec.FatType() == EFat32)
+    {//-- FAT32
+        TUint32 fatEntry;
+        const TUint32 KClnShtdnMask = 0x08000000; //-- "ClnShutBitMask", see FAT specs
+
+        //-- read "CleanShutDown" flag directly from the 1st FAT
+        nRes = MediaRawRead(TheFs, gDriveNum, Fat1StartPos, fatBuf.Size(), fatBuf);
+        test_KErrNone(nRes);
+
+        Mem::Copy(&fatEntry, (fatBuf.Ptr()+sizeof(fatEntry)), sizeof(fatEntry));
+        bFinalised_From_FAT1 = (fatEntry & KClnShtdnMask) >0;
+
+        for(TInt i=1; i<bootSec.NumberOfFats(); ++i)
+        {
+            //-- read a flag from the next FAT
+            const TUint32 currFatStartPos = (bootSec.FirstFatSector() + i*bootSec.TotalFatSectors())*bootSec.BytesPerSector();
+
+            nRes = MediaRawRead(TheFs, gDriveNum, currFatStartPos, fatBuf.Size(), fatBuf);
+            test_KErrNone(nRes);
+
+            Mem::Copy(&fatEntry, (fatBuf.Ptr()+sizeof(fatEntry)), sizeof(fatEntry));
+            const TBool bFinalised_From_currFAT = (fatEntry & KClnShtdnMask) >0;
+
+            test(bFinalised_From_currFAT == bFinalised_From_FAT1);
+        }
+
+    }
+    else  //-- FAT12
+    {//-- FAT12 doesn't have flags in FAT[1]
+     bFinalised_From_FAT1 = bFinalised_From_API;
+    }
+
+    test(bFinalised_From_FAT1 == bFinalised_From_API);
+
+    return bFinalised_From_API;
+}
+
+
+
+//----------------------------------------------------------------------------------------------
+//! @SYMTestCaseID      PBASE-T_MOUNT-0522
+//! @SYMTestType        UT
+//! @SYMPREQ            PREQ1721
+//! @SYMTestCaseDesc    RFs::FinaliseDrive() and RFs::FinaliseDrives() API
+//!
+//! @SYMTestActions
+//!             0   Finalise the drive in RW mode and check the result.
+//!             1   Finalise the drive in RW mode once again and check the result.
+//!             2   Create a file and check that the volume has become unfinalised.
+//!             3   Open a file, try to finalise the volume; it shall fail with KErrInUse
+//!             4   close the file, finalise, check that the result is OK.
+//!             5   "Unfinalise" the volume; check that the volume is not finalised any longer.
+//!             6   Finalise the drive in RO mode and check the result.
+//!             7   Try to create a file, shall fail with KErrAccessDenied
+//!             8   Try to finalise into RW mode, shall fail with KErrAccessDenied
+//!             9   Try to unfinalise volume, it shall remain RO
+//!             10  Remount the drive, it shall become RW and finalised
+//!             11  Test transition "Not finalised" -> EFinal_RW (expected: KErrNone)
+//!             12  Test transition EFinal_RW -> EFinal_RO  (expected: KErrNone)
+//!             13  Test transition EFinal_RO -> EFinal_RW  (expected: KErrAccessDenied)
+//!             14  Remount the volume to reset RO flag
+//!             15  test old RFs::FinaliseDrives() API by finalising all drives in the system
+//!
+//! @SYMTestExpectedResults finishes if the volume finalisation works correctly. panics otherwise
+//! @SYMTestPriority        High
+//! @SYMTestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+static void TestFinaliseFS()
+{
+    test.Next(_L("Testing RFs::FinaliseDrives() API\n"));
+
+    if(!Is_Fat16(TheFs, gDriveNum) && !Is_Fat32(TheFs, gDriveNum))
+    {
+        test.Printf(_L("This step requires FAT16 or FAT32 ! Skipping.\n"));
+        return;
+    }
+
+    TInt  nRes;
+    TBool bDriveFinalised;
+
+    //============= 1. finalise the drive (RW mode) and check the result
+    nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW);
+    test_KErrNone(nRes);
+
+    bDriveFinalised = DoCheckVolumeFinalised(gDriveNum);
+    test(bDriveFinalised);
+
+    //-- 1.1 finalise the drive second time EFinal_RW -> EFinal_RW shall work
+    nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW);
+    test_KErrNone(nRes);
+
+    bDriveFinalised = DoCheckVolumeFinalised(gDriveNum);
+    test(bDriveFinalised);
+
+    //============= 2. create a file. Shall succeed (EFinal_RW), the volume shall become unfinalised
+
+    RFile file;
+    _LIT(KFileName, "\\my_file1.dat");
+
+    nRes = CreateEmptyFile(TheFs, KFileName, 128000);
+    test_KErrNone(nRes);
+
+    bDriveFinalised = DoCheckVolumeFinalised(gDriveNum);
+    test(!bDriveFinalised); //-- the volume has become "unfinalised"
+
+    //-- 2.1 open a file, try to finalise; Shall dail with KErrInUse
+    nRes = file.Replace(TheFs, KFileName, EFileWrite | EFileRead);
+    test_KErrNone(nRes);
+
+    nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW);
+    test(nRes==KErrInUse); //-- can't finalise drives with opened objects
+
+    file.Close();
+
+    nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW);
+    test_KErrNone(nRes);
+
+    bDriveFinalised = DoCheckVolumeFinalised(gDriveNum);
+    test(bDriveFinalised);
+
+    //============= 3. test "unfinalise API"
+    nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EForceUnfinalise);
+    test_KErrNone(nRes);
+
+    bDriveFinalised = DoCheckVolumeFinalised(gDriveNum);
+    test(!bDriveFinalised); //-- the volume has become "unfinalised"
+
+    //============= 4. test finalisation into RO mode
+    nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RO); //-- the volume becomes RO
+    test_KErrNone(nRes);
+
+    //-- try to write a file on RO volume; it shall fail with KErrAccessDenied
+    nRes = CreateEmptyFile(TheFs, KFileName, 128000);
+    test(nRes == KErrAccessDenied);
+    file.Close();
+
+    //-- 4.1 try to finalise into EFinal_RW mode, shall fail with KErrAccessDenied
+    nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW);
+    test(nRes == KErrAccessDenied);
+
+    //-- 4.2 "unfinalise" the volume, it still shall remain RO
+    nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EForceUnfinalise);
+    test_KErrNone(nRes);
+
+    //-- try to write a file on RO volume; it shall fail with KErrAccessDenied
+    nRes = CreateEmptyFile(TheFs, KFileName, 128000);
+    test(nRes == KErrAccessDenied);
+    file.Close();
+
+    //-- remount FS, the drive shall become RW
+    nRes = RemountFS(TheFs, gDriveNum);
+    test_KErrNone(nRes);
+
+    bDriveFinalised = DoCheckVolumeFinalised(gDriveNum);
+    test(bDriveFinalised);
+
+    //-- try to write a file on RW volume, shall be OK
+    nRes = CreateEmptyFile(TheFs, KFileName, 128000);
+    test(nRes == KErrNone);
+    file.Close();
+
+    bDriveFinalised = DoCheckVolumeFinalised(gDriveNum);
+    test(!bDriveFinalised);
+
+    //============= 5. test various finalisation modes
+
+    //-- 5.1  Not finalised -> EFinal_RW (KErrNone)
+    nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW);
+    test(nRes == KErrNone);
+    bDriveFinalised = DoCheckVolumeFinalised(gDriveNum);
+    test(bDriveFinalised);
+
+    //-- 5.2  EFinal_RW -> EFinal_RO (KErrNone)
+    nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RO);
+    test(nRes == KErrNone);
+    bDriveFinalised = DoCheckVolumeFinalised(gDriveNum);
+    test(bDriveFinalised);
+
+    //-- 5.2  EFinal_RO -> EFinal_RW  (KErrAccessDenied)
+    nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW);
+    test(nRes == KErrAccessDenied);
+    bDriveFinalised = DoCheckVolumeFinalised(gDriveNum);
+    test(bDriveFinalised);
+
+    //-- 5.3 restore
+    nRes = RemountFS(TheFs, gDriveNum);
+    test_KErrNone(nRes);
+
+
+    //============= 6. test old RFs::FinaliseDrives API
+
+    nRes = CreateEmptyFile(TheFs, KFileName, 128000);
+    test(nRes == KErrNone);
+
+    bDriveFinalised = DoCheckVolumeFinalised(gDriveNum);
+    test(!bDriveFinalised);
+
+    TheFs.FinaliseDrives(); //-- shall work as TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW) but for ALL drives
+
+    bDriveFinalised = DoCheckVolumeFinalised(gDriveNum);
+    test(bDriveFinalised);
+
+    nRes = CreateEmptyFile(TheFs, KFileName, 128000);
+    test(nRes == KErrNone);
+
+}
+
+//----------------------------------------------------------------------------------------------
+//! @SYMTestCaseID      PBASE-T_MOUNT-0523
+//! @SYMTestType        UT
+//! @SYMPREQ            PREQ1721
+//! @SYMTestCaseDesc    testing boot and backup boot sectors on FAT32 volume
+//!
+//! @SYMTestActions
+//!             0   Quick format the drive
+//!             1   read main and backup boot & fsinfo sectors and check their validity
+//!             2   corrupt main boot sector and check that the drive can be mounted (backup boot sector is used)
+//!             3   corrupt backup boot sector and check that the drive can not be mounted.
+//!             4   Quick format the drive to restore test environment
+//!
+//! @SYMTestExpectedResults finishes if the boot sector and backup boot sector functionality compliant with the FAT specs. panics otherwise
+//! @SYMTestPriority        High
+//! @SYMTestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+static void TestBackupBootSector()
+{
+    test.Next(_L("Testing Backup Boot Sector.\n"));
+
+    TInt nRes;
+
+    //-- quick format the drive
+    FormatVolume(ETrue);
+
+    if(!Is_Fat32(TheFs, gDriveNum))
+    {
+        test.Printf(_L("This step requires FAT32 ! Skipping.\n"));
+        return;
+    }
+
+    TFatBootSector  mainBootSec, backupBootSec;
+    TFSInfo         mainFSInfo, backupFSInfo;
+
+    const TUint32 posMainBootSec = KBootSectorNum << KDefaultSectorLog2;
+    const TUint32 posBkBootSec   = KBkBootSectorNum << KDefaultSectorLog2;
+
+    //-- read main and backup boot & fsinfo sectors and check their validity
+    nRes = ReadBootSector(TheFs, gDriveNum, posMainBootSec, mainBootSec);
+    test_KErrNone(nRes);
+
+    //-- backup boot sector # must be 6
+    nRes = ReadBootSector(TheFs, gDriveNum, posBkBootSec, backupBootSec);
+    test_KErrNone(nRes);
+
+    test(mainBootSec.IsValid());
+    test(backupBootSec.IsValid());
+    test(mainBootSec == backupBootSec);
+
+    //-- read fsinfo sectors
+    const TUint32 posMainFSInfo = mainBootSec.FSInfoSectorNum() << KDefaultSectorLog2;
+    const TUint32 posBkFSInfo   = (KBkBootSectorNum + mainBootSec.FSInfoSectorNum()) << KDefaultSectorLog2;
+
+    test(posMainFSInfo != 0);
+    test(posBkFSInfo != 0);
+
+    nRes = ReadFSInfoSector(TheFs, gDriveNum, posMainFSInfo, mainFSInfo);
+    test_KErrNone(nRes);
+
+    nRes = ReadFSInfoSector(TheFs, gDriveNum, posBkFSInfo, backupFSInfo);
+    test_KErrNone(nRes);
+
+    test(mainFSInfo.IsValid());
+    test(backupFSInfo.IsValid());
+    test(mainFSInfo == backupFSInfo);
+
+    //-- corrupt main boot sector and check that the drive can be mounted
+    test.Printf(_L("Corrupting main boot sector...\n"));
+
+
+    //-- A1. corrupt main boot sector starting from the pos:0
+    nRes = FillMedia(TheFs, gDriveNum, posMainBootSec, posMainBootSec+KDefaultSectorSize, 0xaa);
+
+    //-- A2. remount FS, it shall be OK because of the using backup boot sector
+    nRes = RemountFS(TheFs, gDriveNum);
+    test_KErrNone(nRes);
+
+
+    //-- B1. corrupt BACKUP boot sector starting from the sec:6
+    nRes = FillMedia(TheFs, gDriveNum, posBkBootSec, posBkBootSec+KDefaultSectorSize, 0xbb);
+
+    //-- B2. remount FS, unable to mount.
+    nRes = RemountFS(TheFs, gDriveNum);
+    test(nRes == KErrCorrupt);
+
+
+    //-- quick format the drive
+    FormatVolume(ETrue);
+
+}
+
+//----------------------------------------------------------------------------------------------
+//! @SYMTestCaseID      PBASE-T_MOUNT-0524
+//! @SYMTestType        UT
+//! @SYMPREQ            PREQ1721
+//! @SYMTestCaseDesc    testing FSInfo sector functionality.
+//!
+//! @SYMTestActions
+//!             0   Quick format the drive
+//!             1   finalise the drive to write correct data to the FSInfo & its backup copy.
+//!             2   read FSInfo sector, its backup copy and check that they are both valid, identical and contain correct data
+//!             3   check that after the formatting FS info values are the same as real, obtained from the FAT scanning.
+//!             4   create a random - sized file, check that after finalisation the number of free clusters is identical to the FSinfo
+//!             5   Quick format the drive to restore test environment
+//!
+//! @SYMTestExpectedResults finishes if the FSInfo sectors functionality compliant with the FAT specs. panics otherwise
+//! @SYMTestPriority        High
+//! @SYMTestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+static void TestFSInfoSector()
+{
+    test.Next(_L("Testing FSInfo Sector.\n"));
+
+#ifndef _DEBUG
+    test.Printf(_L("Skipping the test in the Release build! \n"));
+    return;
+#else
+
+    TInt nRes;
+
+    //-- quick format the drive
+    FormatVolume(ETrue);
+
+    if(!Is_Fat32(TheFs, gDriveNum))
+    {
+        test.Printf(_L("This step requires FAT32 ! Skipping.\n"));
+        return;
+    }
+
+    TFatBootSector  bootSec;
+    const TUint32 posMainBootSec = KBootSectorNum << KDefaultSectorLog2;
+    nRes = ReadBootSector(TheFs, gDriveNum, posMainBootSec, bootSec);
+    test_KErrNone(nRes);
+
+    const TUint32 bytesPerSector = bootSec.BytesPerSector();
+    const TUint32 secPerClust = bootSec.SectorsPerCluster();
+
+    //-- finalise the drive, just in case
+    nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW);
+    test_KErrNone(nRes);
+
+    //============= 1. read FSInfo sector and its backup copy and compare them
+    TFSInfo fsInfoSec;
+
+    //-- main FSInfo
+    nRes = ReadFSInfoSector(TheFs, gDriveNum, KFSInfoSectorNum*bytesPerSector, fsInfoSec);
+    test_KErrNone(nRes);
+    test(fsInfoSec.IsValid());
+
+    TUint32 freeClusters_FSInfo = fsInfoSec.FreeClusterCount();
+    TUint32 nextFree_FSInfo = fsInfoSec.NextFreeCluster();
+
+    //-- backup FSInfo
+    nRes = ReadFSInfoSector(TheFs, gDriveNum, KBkFSInfoSectorNum*bytesPerSector, fsInfoSec);
+    test_KErrNone(nRes);
+    test(fsInfoSec.IsValid());
+
+    //-- both copies must be identical
+    test(freeClusters_FSInfo == fsInfoSec.FreeClusterCount());
+    test(nextFree_FSInfo == fsInfoSec.NextFreeCluster());
+
+    //-- FAT[0] and FAT[1] are not used; FAT[2] is taken by the 1st cluster of the FAT32 Root directory.
+    test(nextFree_FSInfo == (2+1));
+
+    //============= 2. check that after the formatting FS info values are the same as real.
+
+    //-- 2.1 disable using FSInfo and other stuff
+    SetFsyDebugFlag(gDriveNum, KMntProp_Disable_FsInfo);
+
+    //-- remount FAT; using FSInfo is disabled. FAT will be explicitly scanned.
+    nRes = RemountFS(TheFs, gDriveNum);
+    test_KErrNone(nRes);
+
+    //-- restore mounting mechanism
+    SetFsyDebugFlag(gDriveNum, KMntProp_EnableALL);
+
+    //-- get free clusters number from the FSY, which in turn had counted them explicitly
+    TVolumeInfo volInfo;
+    nRes = TheFs.Volume(volInfo, gDriveNum);
+    test_KErrNone(nRes);
+
+    TUint32 freeClusters = (TUint32)(volInfo.iFree / (bytesPerSector * secPerClust));
+    test(freeClusters == freeClusters_FSInfo);
+
+    //============= 3. create a random - sized file, check that after finalisation the number of free clusters is identical to the FSinfo
+    _LIT(KFileName, "\\FILE1.DAT");
+    const TUint32 rndClusters = 7+((TUint32)Math::Rand(gRndSeed)) % 5000;
+    const TUint32 fileSz = rndClusters * bytesPerSector * secPerClust;
+    nRes = CreateEmptyFile(TheFs, KFileName, fileSz);
+    test_KErrNone(nRes);
+
+    //-- 3.1 get data from FS
+    nRes = TheFs.Volume(volInfo, gDriveNum);
+    test_KErrNone(nRes);
+    freeClusters = (TUint32)(volInfo.iFree / (bytesPerSector * secPerClust));
+
+    //-- 3.2 finalise the volume and get data from FSInfo
+    nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW);
+    test_KErrNone(nRes);
+
+    //-- main FSInfo
+    nRes = ReadFSInfoSector(TheFs, gDriveNum, KFSInfoSectorNum*bytesPerSector, fsInfoSec);
+    test_KErrNone(nRes);
+    test(fsInfoSec.IsValid());
+
+    freeClusters_FSInfo = fsInfoSec.FreeClusterCount();
+    nextFree_FSInfo = fsInfoSec.NextFreeCluster();
+
+    //-- backup FSInfo
+    nRes = ReadFSInfoSector(TheFs, gDriveNum, KBkFSInfoSectorNum*bytesPerSector, fsInfoSec);
+    test_KErrNone(nRes);
+    test(fsInfoSec.IsValid());
+
+    //-- both copies must be identical
+    test(freeClusters_FSInfo == fsInfoSec.FreeClusterCount());
+    test(nextFree_FSInfo == fsInfoSec.NextFreeCluster());
+
+    //-- the information in FSInfo must be the same as in FAT
+    test(freeClusters == freeClusters_FSInfo);
+
+    TBool bDriveFinalised = DoCheckVolumeFinalised(gDriveNum);
+    test(bDriveFinalised);
+
+    TheFs.Delete(KFileName);
+
+    //-- restore mounting mechanism
+    SetFsyDebugFlag(gDriveNum, KMntProp_EnableALL);
+
+#endif //_DEBUG
+}
+
+//-------------------------------------------------------------------
+
+/** initialise test global objects */
+static void InitGlobals()
+{
+    TInt nRes;
+
+    //-- define a propery which will control mount process in the fsy.
+    //-- The property key is a drive number being tested
+
+    _LIT_SECURITY_POLICY_PASS(KTestPropPolicy);
+    nRes = RProperty::Define(KThisTestSID, gDriveNum, RProperty::EInt, KTestPropPolicy, KTestPropPolicy);
+    test(nRes == KErrNone || nRes == KErrAlreadyExists);
+
+    nRes = RProperty::Set(KThisTestSID, gDriveNum, KMntProp_EnableALL);
+    test_KErrNone(nRes);
+
+    gRndSeed = Math::Random();
+    (void)&gRndSeed; //-- get rid of warning
+}
+
+/** destroy test global objects */
+static void DestroyGlobals()
+{
+    //-- delete test property
+    RProperty::Delete(KThisTestSID, gDriveNum);
+
+    TVolumeInfo v;
+    TheFs.Volume(v);
+}
+
+//-------------------------------------------------------------------
+/**
+    Manual test. Requires manual removing and putting back the media.
+    On the emulator one can use pressing (and holding) F5 key to simulate media removal.
+*/
+void Manual_TestRemount_On_MediaRemoval()
+{
+    TInt nRes;
+
+    _LIT(KFileName, "\\my_file1.dat");
+    const TUint32 KFileSz = K1MegaByte;
+
+    //-- 1. create a file
+    nRes = CreateEmptyFile(TheFs, KFileName, KFileSz);
+    test_KErrNone(nRes);
+
+    RFile file;
+
+    nRes = file.Open(TheFs, KFileName, EFileRead | EFileWrite);
+    test_KErrNone(nRes);
+
+    TBuf8<512> buf(512);
+    TVolumeInfo vi;
+    buf.FillZ();
+
+    TKeyCode key;
+
+    for(;;)
+    {
+        TheFs.SetDebugRegister(0x00);
+
+        nRes = file.Read(0, buf);
+
+        test.Printf(_L("Remove the media and press a key.\n"));
+        key = test.Getch();
+        if(key == EKeyEscape)
+                break;
+
+        TheFs.SetDebugRegister(KFSYS | KFSERV);
+        nRes = file.Read(0, buf);
+
+        if(nRes != KErrNone)
+        {
+
+            test.Printf(_L("ReadFile: %d!\n"), nRes);
+
+            key = test.Getch();
+            if(key == EKeyEscape)
+                break;
+
+            nRes = TheFs.Volume(vi,gDriveNum);
+            test.Printf(_L("Volume: %d!\n"), nRes);
+
+            key = test.Getch();
+            if(key == EKeyEscape)
+                break;
+
+            nRes = file.Write(0, buf);
+            test.Printf(_L("WriteFile: %d!\n"), nRes);
+
+            key = test.Getch();
+            if(key == EKeyEscape)
+                break;
+
+        }
+
+    }
+
+
+    file.Close();
+}
+
+
+//-------------------------------------------------------------------
+/**
+    Wait for the request aRqStat to be completed with timeout.
+
+    @param  aRqStat         request status object we need to wait to complete
+    @param  aTimeout_uS     timeout in microseconds
+
+    @return ETrue   if the aRqStat is completed before time is out
+            EFalse  if aTimeout_uS has passed. And the state of the aRqStat not changed.
+*/
+TBool WaitForRequestWithTimeout(TRequestStatus& aRqStat, TUint32 aTimeout_uS)
+{
+    TRequestStatus  rqStatTimeout(KRequestPending);
+    RTimer          tmrTimeOut;
+    TInt            nRes;
+    TBool           bReqCompleted;
+
+    if(aRqStat.Int() != KRequestPending)
+        return ETrue; //-- nothing to wait for.
+
+    //-- set up a timeout timer
+    nRes = tmrTimeOut.CreateLocal();
+    test(nRes == KErrNone);
+
+    tmrTimeOut.After(rqStatTimeout, aTimeout_uS);
+
+    User::WaitForRequest(aRqStat, rqStatTimeout);
+
+    if(aRqStat == KRequestPending)
+        {//-- timeout.
+        bReqCompleted = EFalse;
+        }
+        else
+        {//-- the main request has been completed, cancel timer
+            bReqCompleted = ETrue;
+            if(rqStatTimeout.Int() == KRequestPending)
+                {
+                tmrTimeOut.Cancel();
+                User::WaitForRequest(rqStatTimeout);
+                }
+        }
+
+    tmrTimeOut.Close();
+
+    return bReqCompleted;
+}
+
+//-------------------------------------------------------------------
+
+void TestNotifyDiskSpace()
+{
+    test.Next(_L("Testing NotifyDiskSpace() on asynchronous mounting\n"));
+
+#ifndef _DEBUG
+    test.Printf(_L("Skipping the test in the Release build! \n"));
+    return;
+#else
+
+    TInt nRes;
+    TRequestStatus rqStat;
+    TVolumeInfo volInfo;
+
+    //-- quick format the drive
+    FormatVolume(ETrue);
+
+    if(!Is_Fat32(TheFs, gDriveNum))
+    {//-- only FAT32 supports asynch mounting;
+        test.Printf(_L("This test step requires FAT32!\n"));
+        return;
+    }
+
+    //-- FAT32 free space threshold that is supposed to be triggered by notifiers
+    const TInt64 KFreeSpaceThreshold = 300*K1MegaByte;
+
+    //-- Turn OFF using FSInfo and ON FAT32 background scanning; it will cause compulsory FAT32 background free clusters scan.
+    //-- if FAT32 background free clusters scan is disabled in config, this test can hang on waiting for free space notifications.
+    test.Printf(_L("==== Enabled FAT32 BkGnd scan, FSInfo disabled ====\n"));
+    SetFsyDebugFlag(gDriveNum, KMntProp_DisableALL & ~KMntProp_Disable_FatBkGndScan);
+
+
+    //===== create a big file in the beginning in order to avoid freeSpaceThreshold being reached too fast
+    nRes = CreateEmptyFile(TheFs, _L("\\big_empty_file.bin"), 10*K1MegaByte);
+    test_KErrNone(nRes);
+
+//TheFs.SetDebugRegister(0x03);
+
+    //===== Test that FAT32 free space scanning thread updates File Server free space notifiers
+    test.Printf(_L("Testing FAT32 free space scanning thread triggers notifiers..."));
+
+    nRes = RemountFS(TheFs, gDriveNum); //-- remount FS; it must cause FAT32 free space scan in background
+    test_KErrNone(nRes);
+
+    test.Printf(_L("Waiting for %LU bytes available on the volume...\n"), KFreeSpaceThreshold);
+
+    //-- check if we can use the notifiers at all... If free space is >= KFreeSpaceThreshold, the notifier won't be triggered
+    //-- get _current_ amount of free space asynchronously
+    TheFs.Volume(volInfo, gDriveNum, rqStat);
+    User::WaitForRequest(rqStat);
+    test(rqStat.Int()==KErrNone);
+
+    if(volInfo.iSize <= KFreeSpaceThreshold)
+    {
+    test.Printf(_L("The volume is too small for %LU bytes notify ...\n"), KFreeSpaceThreshold);
+    test.Printf(_L("The test is inconclusive ...\n"));
+    return;
+    }
+
+    if(volInfo.iFree >= KFreeSpaceThreshold)
+    {
+    test.Printf(_L("The volume already has %LU free bytes...\n"), volInfo.iFree);
+    test.Printf(_L("The test is inconclusive ...\n"));
+    return;
+    }
+
+
+    TheFs.NotifyDiskSpace(KFreeSpaceThreshold, gDriveNum, rqStat);
+    test(rqStat.Int()==KRequestPending);
+
+    //-- wait for notification for 30 seconds; If for some reason FAT32 background scanning for free clusters doesn't
+    //-- work (e.g. configued out in FAT), this test is inconclusive.
+    TBool bCompleted = WaitForRequestWithTimeout(rqStat, 30*K1Sec);
+
+    if(!bCompleted)
+    {
+        test.Printf(_L("Wait timeout! something is wrong...\n"));
+        test(0);
+    }
+
+    test_KErrNone(rqStat.Int());
+
+    //-- get _current_ amount of free space asynchronously
+    TheFs.Volume(volInfo, gDriveNum, rqStat);
+    User::WaitForRequest(rqStat);
+    test(rqStat.Int()==KErrNone);
+    test.Printf(_L("Current amount of free space on the volume: %LU \n"), volInfo.iFree);
+
+
+    //===== Test that aborting FAT32 free space scanning thread will trigger notifiers
+    test.Printf(_L("Testing aborting FAT32 free space scanning thread..."));
+
+    nRes = RemountFS(TheFs, gDriveNum); //-- remount FS; it must cause FAT32 free space scan in background
+    test_KErrNone(nRes);
+
+    TheFs.NotifyDiskSpace(KFreeSpaceThreshold, gDriveNum, rqStat);
+    test(rqStat.Int()==KRequestPending);
+
+    nRes = RemountFS(TheFs, gDriveNum); //-- remount FS; it will abort the scanning thread
+    test_KErrNone(nRes);
+
+    test(rqStat.Int() != KRequestPending);
+
+    //-- get _current_ amount of free space asynchronously
+    TheFs.Volume(volInfo, gDriveNum, rqStat);
+    User::WaitForRequest(rqStat);
+    test(rqStat.Int()==KErrNone);
+    test.Printf(_L("Current amount of free space on the volume: %LU \n"), volInfo.iFree);
+
+
+    //-- find out free space on the volume; it will also blocks until FAT32 free space scanning finishes.
+    nRes = TheFs.Volume(volInfo);
+    test(nRes==KErrNone);
+    test.Printf(_L("free space on the volume: %LU \n"), volInfo.iFree);
+
+
+//TheFs.SetDebugRegister(0x00);
+
+    //-- restore mounting mechanism
+    SetFsyDebugFlag(gDriveNum, KMntProp_EnableALL);
+
+#endif  //_DEBUG
+}
+
+//-------------------------------------------------------------------
+
+void CallTestsL()
+    {
+    //-- set up console output
+    Fat_Test_Utils::SetConsole(test.Console());
+
+    TInt nRes=TheFs.CharToDrive(gDriveToTest, gDriveNum);
+    test(nRes==KErrNone);
+
+    //-- check if this is FAT
+    if(!Is_Fat(TheFs, gDriveNum) || Is_Automounter(TheFs, gDriveNum))
+    {//-- it doesn't make much sense to run this test under automounter+FAT. The automounter can't easily handle formatting corrupted media
+     //-- and the mounting permaormance measurements don't make much sense in this case as well.
+
+        test.Printf(_L("Skipping. This test requires explicitly mounted FAT file system.\n"));
+        return;
+    }
+
+    //-- check this is not the internal ram drive
+    TVolumeInfo v;
+
+    nRes = TheFs.Volume(v);
+    test(nRes==KErrNone);
+    if(v.iDrive.iMediaAtt & KMediaAttVariableSize)
+        {
+        test.Printf(_L("Skipping. Internal ram drive not tested.\n"));
+        return;
+        }
+
+    //-------------------------------------
+
+    PrintDrvInfo(TheFs, gDriveNum);
+    InitGlobals();
+
+
+    TestNotifyDiskSpace();
+
+    //-------------------------------------
+    TestBackupBootSector();
+    TestFSInfoSector();
+    TestFinaliseFS();
+
+    //-------------------------------------
+    TestFAT_Mounting_Performance();
+    //-------------------------------------
+    //-- manual test
+    //Manual_TestRemount_On_MediaRemoval();
+
+    //-------------------------------------
+    DestroyGlobals();
+
+    }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+