os/kernelhwsrv/kerneltest/f32test/ext/t_fatext.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // f32test\ext\fat_ext.cpp
    15 // 
    16 //
    17 
    18 //! @SYMTestCaseID FSBASE-CR-JHAS-68YPX7
    19 //! @SYMTestType CT
    20 //! @SYMREQ CR JHAS-68YPX7
    21 //! @SYMTestCaseDesc Test facility used by and bad disk handling test
    22 //! @SYMTestStatus Implemented
    23 //! @SYMTestActions Provided plug-in test extension for FAT
    24 //! @SYMTestExpectedResults N/A
    25 //! @SYMTestPriority Low
    26 //! @SYMAuthor Ying Shi
    27 //! @SYMCreationDate 20/05/2005
    28 //! @See EFat and EFat32 components
    29 //! @file f32test\ext\fat_ext.cpp
    30 
    31 #include <e32math.h>
    32 #include "t_fatext.h"
    33 
    34 //--------------------------  CFatTestProxyDrive  --------------------------
    35 
    36 CFatTestProxyDrive* CFatTestProxyDrive::NewL(CProxyDrive* aProxyDrive, CMountCB* aMount)
    37     {
    38     __PRINT(_L("CFatTestProxyDrive::NewL"));
    39     CFatTestProxyDrive* drive = new(ELeave) CFatTestProxyDrive(aProxyDrive,aMount);
    40     return(drive);
    41     }
    42 
    43 CFatTestProxyDrive::CFatTestProxyDrive(CProxyDrive* aProxyDrive, CMountCB* aMount)
    44     : CTestProxyDrive(aProxyDrive,aMount)
    45     {
    46     __PRINT(_L("CFatTestProxyDrive::CFatTestProxyDrive"));
    47     InitL();
    48     }
    49 
    50 TInt CFatTestProxyDrive::Read(TInt64 aPos,TInt aLength,const TAny* aTrg,TInt aMessageHandle,TInt aOffset,TInt aFlags)
    51     {
    52 //    __PRINT(_L("CFatTestProxyDrive::Read"));
    53     if (CheckEvent(aPos,aLength))
    54         return KErrCorrupt;
    55 
    56     return CTestProxyDrive::Read(aPos,aLength,aTrg,aMessageHandle,aOffset,aFlags);
    57     }
    58 
    59 TInt CFatTestProxyDrive::Read(TInt64 aPos,TInt aLength,const TAny* aTrg,TInt aMessageHandle,TInt aOffset)
    60     {
    61     return Read(aPos,aLength,aTrg,aMessageHandle,aOffset,0);
    62     }
    63 
    64 TInt CFatTestProxyDrive::Read(TInt64 aPos,TInt aLength,TDes8& aTrg)
    65     {
    66     return Read(aPos,aLength,&aTrg,KLocalMessageHandle,0,0);
    67     }
    68 
    69 TInt CFatTestProxyDrive::Write(TInt64 aPos,TInt aLength,const TAny* aSrc,TInt aMessageHandle,TInt anOffset,TInt aFlags)
    70     {
    71 //    __PRINT(_L("CFatTestProxyDrive::Write"));
    72     if (CheckEvent(aPos,aLength))
    73         return KErrCorrupt;
    74 
    75     return CTestProxyDrive::Write(aPos,aLength,aSrc,aMessageHandle,anOffset,aFlags);
    76     }
    77 
    78 TInt CFatTestProxyDrive::Write(TInt64 aPos,TInt aLength,const TAny* aSrc,TInt aMessageHandle,TInt anOffset)
    79     {
    80     return Write(aPos,aLength,aSrc,aMessageHandle,anOffset,0);
    81     }
    82 
    83 TInt CFatTestProxyDrive::Write(TInt64 aPos,const TDesC8& aSrc)
    84     {
    85     return Write(aPos,aSrc.Length(),&aSrc,KLocalMessageHandle,0,0);
    86     }
    87 
    88 TInt CFatTestProxyDrive::Format(TFormatInfo& anInfo)
    89     {
    90     //__PRINT(_L("CFatTestProxyDrive::Format"));
    91     TInt len;
    92     TInt64 pos = ((TInt64)anInfo.i512ByteSectorsFormatted) << KDefaultSectorLog2;
    93     // base function call in order to get anInfo.iMaxBytesPerFormat
    94     // for the first time
    95     if (anInfo.iMaxBytesPerFormat == 0)
    96         {
    97         TInt r = CTestProxyDrive::Format(anInfo);
    98         len = anInfo.iMaxBytesPerFormat;
    99         if (CheckEvent(pos,len))
   100             {
   101             anInfo.i512ByteSectorsFormatted = 0;
   102             return KErrCorrupt;
   103             }
   104         return r;
   105         }
   106     len = anInfo.iMaxBytesPerFormat;
   107     if (CheckEvent(pos,len))
   108         return KErrCorrupt;
   109     return CTestProxyDrive::Format(anInfo);
   110     }
   111 
   112 TInt CFatTestProxyDrive::Format(TInt64 aPos,TInt aLength)
   113     {
   114     __PRINT(_L("CFatTestProxyDrive::Format"));
   115     if (CheckEvent(aPos,aLength))
   116         return KErrCorrupt;
   117 
   118     return CTestProxyDrive::Format(aPos, aLength);
   119     }
   120 
   121 void CFatTestProxyDrive::DoInitL()
   122     {
   123     __PRINT(_L("CFatTestProxyDrive::DoInit"));
   124     if (!CheckMount())
   125         User::Leave(KErrNotReady);
   126 
   127    
   128     iTotalSectors = iBootSector.VolumeTotalSectorNumber();
   129     }
   130 
   131 TInt CFatTestProxyDrive::DoControlIO(const RMessagePtr2& aMessage,TInt aCommand,TAny* aParam1,TAny* aParam2)
   132     {
   133     __PRINT(_L("CFatTestProxyDrive::DoControlIO"));
   134 
   135 	// read boot sector & update iFatType etc
   136 	CheckMount();
   137 
   138     TInt r = KErrNone;
   139 
   140 	// Make sure that the information is up to date.
   141     if ((r=ReadBootSector()) != KErrNone)
   142         {
   143         __PRINT1(_L("ReadBootSector error: %d"), r);
   144         return EFalse;
   145         }
   146 
   147     switch(aCommand+EExtCustom)
   148         {
   149         case ESectorsPerCluster:
   150             r = aMessage.Write(2, TPckgBuf<TInt>(iBootSector.SectorsPerCluster()));
   151             break;
   152         case EFatType:
   153             r = aMessage.Write(2, TPckgBuf<TInt>(iBootSector.FatType()));
   154             break;
   155         
   156         case EGetDataPosition:
   157             {
   158                 //-- obtain 1st data sector media position. This is actually a nasty hack;
   159                 //-- we expect that the drive will be freshly formatted, thust the root dir is empty and the first file we create there
   160                 //-- will occupy the certain place.
   161                 TUint32 dataSec; 
   162                 
   163                 if(iBootSector.FatType() !=EFat32)
   164                    dataSec = iBootSector.FirstDataSector();
   165                 else
   166                   {//-- for FAT32 we assume that the root dir takes exactly 1 cluster. Another dirty trick
   167                    dataSec = iBootSector.RootDirStartSector() + 1*iBootSector.SectorsPerCluster(); 
   168                   }
   169                 __PRINT1(_L("EGetDataPosition, sec:%d"), dataSec);
   170                 r = aMessage.Write(2, TPckgBuf<TInt>(dataSec << KDefaultSectorLog2));
   171             }
   172             break;
   173 
   174         default:
   175             r = CBaseExtProxyDrive::ControlIO(aMessage,aCommand,aParam1,aParam2);
   176             __PRINT2(_L("Get unknown command %d error %d"), aCommand, r);
   177         }
   178     return r;
   179     }
   180 
   181 TBool CFatTestProxyDrive::DoCheckEvent(TInt64 aPos, TInt aLength)
   182     {
   183     //__PRINT2(_L("CFatTestProxyDrive::DoCheckEvent() pos:%d, len:%d"), (TUint32)aPos, aLength);
   184 
   185     if (aPos<0 || aLength<=0 || (aPos>>KDefaultSectorLog2)>=iTotalSectors)
   186         return EFalse;
   187 
   188     TInt begin = (TInt)(aPos >> KDefaultSectorLog2);
   189     TInt end = (TInt)((aPos+aLength-1) >> KDefaultSectorLog2);
   190     end = Min(end, iTotalSectors-1);
   191 
   192     if (iEventType == ENext)
   193         {
   194         Mark(begin);
   195         iEventType = ENone;
   196         iLastErrorReason = TErrorInfo::EBadSector;
   197         iSuccessBytes = 0;
   198         return ETrue;
   199         }
   200 
   201     if (iEventType == EDeterministic)
   202         {
   203         if (iCount <= end-begin+1)
   204             {
   205             iCount = 0;
   206             Mark(begin+iCount-1);
   207             iEventType = ENone;
   208             iLastErrorReason = TErrorInfo::EBadSector;
   209             iSuccessBytes = (iCount-1) << KDefaultSectorLog2;
   210             return ETrue;
   211             }
   212         else
   213             iCount -= end-begin+1;
   214         }
   215 
   216     TInt i;
   217     for (i=begin; i<=end; i++)
   218         if (IsMarked(i))
   219             {
   220             __PRINT(_L("CFatTestProxyDrive::DoCheckEvent() Sector Marked as bad!"));
   221             iLastErrorReason = TErrorInfo::EBadSector;
   222             iSuccessBytes = (i-begin) << KDefaultSectorLog2;
   223             return ETrue;
   224             }
   225 
   226     return EFalse;
   227     }
   228 
   229 TBool CFatTestProxyDrive::CheckMount()
   230     {
   231     __PRINT(_L("CFatTestProxyDrive::CheckMount"));
   232 
   233     //-- read boot sector
   234     if (ReadBootSector() != KErrNone)
   235         {
   236         __PRINT(_L("ReadBootSector error: %d"));
   237         return EFalse;
   238         }
   239 
   240     //-- validate boot sector
   241     if(!iBootSector.IsValid())
   242     {
   243         goto BadBootSector;
   244     }
   245 
   246     if (iBootSector.FatType() == EFat32)   // fat 32
   247         {
   248         if (iBootSector.RootDirEntries() != 0   ||
   249             iBootSector.TotalSectors() != 0     ||
   250             iBootSector.HugeSectors() == 0      ||
   251             iBootSector.FatSectors32() == 0     ||
   252             iBootSector.RootClusterNum() < 2)
   253             {
   254                 goto BadBootSector;
   255             }
   256         }
   257     else // fat16/12
   258         {
   259         if (iBootSector.RootDirEntries() == 0 ||
   260             (iBootSector.TotalSectors() == 0 && iBootSector.HugeSectors() == 0))
   261             {
   262                 goto BadBootSector;
   263             }
   264         }
   265 
   266     //-- boot sector is OK
   267     return ETrue;
   268 
   269     //-- Invalid boot sector
   270     BadBootSector:
   271         
   272         __PRINT(_L("Boot sector is invalid! dump:"));
   273         iBootSector.PrintDebugInfo();
   274         return EFalse;
   275 
   276 
   277 
   278     }
   279 
   280 TInt CFatTestProxyDrive::ReadBootSector()
   281     {
   282     __PRINT(_L("CFatTestProxyDrive::ReadBootSector"));
   283 
   284     const TInt KBufSz = KSizeOfFatBootSector;
   285     
   286     TBuf8<KBufSz> bootSecBuf(KBufSz);
   287     TInt r = CTestProxyDrive::Read(0, KBufSz, bootSecBuf);
   288 	if (r != KErrNone)
   289 		return r;
   290 
   291     //-- initialise TFatBootSector object
   292     iBootSector.Internalize(bootSecBuf);
   293 
   294     return KErrNone;
   295     }
   296 
   297 
   298 // --------------------------  CFatTestProxyDriveFactory  --------------------------
   299 
   300 /**
   301 Factory class constructor
   302 @internalTechnology
   303 */
   304 CFatTestProxyDriveFactory::CFatTestProxyDriveFactory()
   305     {
   306     }
   307 
   308 /**
   309 Factory class installer
   310 @internalTechnology
   311 */
   312 TInt CFatTestProxyDriveFactory::Install()
   313     {
   314     __PRINT(_L("CFatTestProxyDriveFactory::Install"));
   315     _LIT(KFatTestExt,"FatTest");
   316     return(SetName(&KFatTestExt));
   317     }
   318 
   319 /**
   320 @internalTechnology
   321 */
   322 CProxyDrive* CFatTestProxyDriveFactory::NewProxyDriveL(CProxyDrive* aProxy,CMountCB* aMount)
   323     {
   324     __PRINT(_L("CFatTestProxyDriveFactory::NewProxyDriveL"));
   325     return(CFatTestProxyDrive::NewL(aProxy,aMount));
   326     }
   327 
   328 
   329 
   330 /**
   331 @internalTechnology
   332 */
   333 extern "C" {
   334 EXPORT_C CProxyDriveFactory* CreateFileSystem()
   335     {
   336     __PRINT(_L("CreateFileSystem"));
   337     return new CFatTestProxyDriveFactory();
   338     }
   339 }