diff -r 000000000000 -r a41df078684a kerneltest/f32test/ext/t_fatext.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/f32test/ext/t_fatext.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,339 @@ +// Copyright (c) 2005-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\ext\fat_ext.cpp +// +// + +//! @SYMTestCaseID FSBASE-CR-JHAS-68YPX7 +//! @SYMTestType CT +//! @SYMREQ CR JHAS-68YPX7 +//! @SYMTestCaseDesc Test facility used by and bad disk handling test +//! @SYMTestStatus Implemented +//! @SYMTestActions Provided plug-in test extension for FAT +//! @SYMTestExpectedResults N/A +//! @SYMTestPriority Low +//! @SYMAuthor Ying Shi +//! @SYMCreationDate 20/05/2005 +//! @See EFat and EFat32 components +//! @file f32test\ext\fat_ext.cpp + +#include +#include "t_fatext.h" + +//-------------------------- CFatTestProxyDrive -------------------------- + +CFatTestProxyDrive* CFatTestProxyDrive::NewL(CProxyDrive* aProxyDrive, CMountCB* aMount) + { + __PRINT(_L("CFatTestProxyDrive::NewL")); + CFatTestProxyDrive* drive = new(ELeave) CFatTestProxyDrive(aProxyDrive,aMount); + return(drive); + } + +CFatTestProxyDrive::CFatTestProxyDrive(CProxyDrive* aProxyDrive, CMountCB* aMount) + : CTestProxyDrive(aProxyDrive,aMount) + { + __PRINT(_L("CFatTestProxyDrive::CFatTestProxyDrive")); + InitL(); + } + +TInt CFatTestProxyDrive::Read(TInt64 aPos,TInt aLength,const TAny* aTrg,TInt aMessageHandle,TInt aOffset,TInt aFlags) + { +// __PRINT(_L("CFatTestProxyDrive::Read")); + if (CheckEvent(aPos,aLength)) + return KErrCorrupt; + + return CTestProxyDrive::Read(aPos,aLength,aTrg,aMessageHandle,aOffset,aFlags); + } + +TInt CFatTestProxyDrive::Read(TInt64 aPos,TInt aLength,const TAny* aTrg,TInt aMessageHandle,TInt aOffset) + { + return Read(aPos,aLength,aTrg,aMessageHandle,aOffset,0); + } + +TInt CFatTestProxyDrive::Read(TInt64 aPos,TInt aLength,TDes8& aTrg) + { + return Read(aPos,aLength,&aTrg,KLocalMessageHandle,0,0); + } + +TInt CFatTestProxyDrive::Write(TInt64 aPos,TInt aLength,const TAny* aSrc,TInt aMessageHandle,TInt anOffset,TInt aFlags) + { +// __PRINT(_L("CFatTestProxyDrive::Write")); + if (CheckEvent(aPos,aLength)) + return KErrCorrupt; + + return CTestProxyDrive::Write(aPos,aLength,aSrc,aMessageHandle,anOffset,aFlags); + } + +TInt CFatTestProxyDrive::Write(TInt64 aPos,TInt aLength,const TAny* aSrc,TInt aMessageHandle,TInt anOffset) + { + return Write(aPos,aLength,aSrc,aMessageHandle,anOffset,0); + } + +TInt CFatTestProxyDrive::Write(TInt64 aPos,const TDesC8& aSrc) + { + return Write(aPos,aSrc.Length(),&aSrc,KLocalMessageHandle,0,0); + } + +TInt CFatTestProxyDrive::Format(TFormatInfo& anInfo) + { + //__PRINT(_L("CFatTestProxyDrive::Format")); + TInt len; + TInt64 pos = ((TInt64)anInfo.i512ByteSectorsFormatted) << KDefaultSectorLog2; + // base function call in order to get anInfo.iMaxBytesPerFormat + // for the first time + if (anInfo.iMaxBytesPerFormat == 0) + { + TInt r = CTestProxyDrive::Format(anInfo); + len = anInfo.iMaxBytesPerFormat; + if (CheckEvent(pos,len)) + { + anInfo.i512ByteSectorsFormatted = 0; + return KErrCorrupt; + } + return r; + } + len = anInfo.iMaxBytesPerFormat; + if (CheckEvent(pos,len)) + return KErrCorrupt; + return CTestProxyDrive::Format(anInfo); + } + +TInt CFatTestProxyDrive::Format(TInt64 aPos,TInt aLength) + { + __PRINT(_L("CFatTestProxyDrive::Format")); + if (CheckEvent(aPos,aLength)) + return KErrCorrupt; + + return CTestProxyDrive::Format(aPos, aLength); + } + +void CFatTestProxyDrive::DoInitL() + { + __PRINT(_L("CFatTestProxyDrive::DoInit")); + if (!CheckMount()) + User::Leave(KErrNotReady); + + + iTotalSectors = iBootSector.VolumeTotalSectorNumber(); + } + +TInt CFatTestProxyDrive::DoControlIO(const RMessagePtr2& aMessage,TInt aCommand,TAny* aParam1,TAny* aParam2) + { + __PRINT(_L("CFatTestProxyDrive::DoControlIO")); + + // read boot sector & update iFatType etc + CheckMount(); + + TInt r = KErrNone; + + // Make sure that the information is up to date. + if ((r=ReadBootSector()) != KErrNone) + { + __PRINT1(_L("ReadBootSector error: %d"), r); + return EFalse; + } + + switch(aCommand+EExtCustom) + { + case ESectorsPerCluster: + r = aMessage.Write(2, TPckgBuf(iBootSector.SectorsPerCluster())); + break; + case EFatType: + r = aMessage.Write(2, TPckgBuf(iBootSector.FatType())); + break; + + case EGetDataPosition: + { + //-- obtain 1st data sector media position. This is actually a nasty hack; + //-- we expect that the drive will be freshly formatted, thust the root dir is empty and the first file we create there + //-- will occupy the certain place. + TUint32 dataSec; + + if(iBootSector.FatType() !=EFat32) + dataSec = iBootSector.FirstDataSector(); + else + {//-- for FAT32 we assume that the root dir takes exactly 1 cluster. Another dirty trick + dataSec = iBootSector.RootDirStartSector() + 1*iBootSector.SectorsPerCluster(); + } + __PRINT1(_L("EGetDataPosition, sec:%d"), dataSec); + r = aMessage.Write(2, TPckgBuf(dataSec << KDefaultSectorLog2)); + } + break; + + default: + r = CBaseExtProxyDrive::ControlIO(aMessage,aCommand,aParam1,aParam2); + __PRINT2(_L("Get unknown command %d error %d"), aCommand, r); + } + return r; + } + +TBool CFatTestProxyDrive::DoCheckEvent(TInt64 aPos, TInt aLength) + { + //__PRINT2(_L("CFatTestProxyDrive::DoCheckEvent() pos:%d, len:%d"), (TUint32)aPos, aLength); + + if (aPos<0 || aLength<=0 || (aPos>>KDefaultSectorLog2)>=iTotalSectors) + return EFalse; + + TInt begin = (TInt)(aPos >> KDefaultSectorLog2); + TInt end = (TInt)((aPos+aLength-1) >> KDefaultSectorLog2); + end = Min(end, iTotalSectors-1); + + if (iEventType == ENext) + { + Mark(begin); + iEventType = ENone; + iLastErrorReason = TErrorInfo::EBadSector; + iSuccessBytes = 0; + return ETrue; + } + + if (iEventType == EDeterministic) + { + if (iCount <= end-begin+1) + { + iCount = 0; + Mark(begin+iCount-1); + iEventType = ENone; + iLastErrorReason = TErrorInfo::EBadSector; + iSuccessBytes = (iCount-1) << KDefaultSectorLog2; + return ETrue; + } + else + iCount -= end-begin+1; + } + + TInt i; + for (i=begin; i<=end; i++) + if (IsMarked(i)) + { + __PRINT(_L("CFatTestProxyDrive::DoCheckEvent() Sector Marked as bad!")); + iLastErrorReason = TErrorInfo::EBadSector; + iSuccessBytes = (i-begin) << KDefaultSectorLog2; + return ETrue; + } + + return EFalse; + } + +TBool CFatTestProxyDrive::CheckMount() + { + __PRINT(_L("CFatTestProxyDrive::CheckMount")); + + //-- read boot sector + if (ReadBootSector() != KErrNone) + { + __PRINT(_L("ReadBootSector error: %d")); + return EFalse; + } + + //-- validate boot sector + if(!iBootSector.IsValid()) + { + goto BadBootSector; + } + + if (iBootSector.FatType() == EFat32) // fat 32 + { + if (iBootSector.RootDirEntries() != 0 || + iBootSector.TotalSectors() != 0 || + iBootSector.HugeSectors() == 0 || + iBootSector.FatSectors32() == 0 || + iBootSector.RootClusterNum() < 2) + { + goto BadBootSector; + } + } + else // fat16/12 + { + if (iBootSector.RootDirEntries() == 0 || + (iBootSector.TotalSectors() == 0 && iBootSector.HugeSectors() == 0)) + { + goto BadBootSector; + } + } + + //-- boot sector is OK + return ETrue; + + //-- Invalid boot sector + BadBootSector: + + __PRINT(_L("Boot sector is invalid! dump:")); + iBootSector.PrintDebugInfo(); + return EFalse; + + + + } + +TInt CFatTestProxyDrive::ReadBootSector() + { + __PRINT(_L("CFatTestProxyDrive::ReadBootSector")); + + const TInt KBufSz = KSizeOfFatBootSector; + + TBuf8 bootSecBuf(KBufSz); + TInt r = CTestProxyDrive::Read(0, KBufSz, bootSecBuf); + if (r != KErrNone) + return r; + + //-- initialise TFatBootSector object + iBootSector.Internalize(bootSecBuf); + + return KErrNone; + } + + +// -------------------------- CFatTestProxyDriveFactory -------------------------- + +/** +Factory class constructor +@internalTechnology +*/ +CFatTestProxyDriveFactory::CFatTestProxyDriveFactory() + { + } + +/** +Factory class installer +@internalTechnology +*/ +TInt CFatTestProxyDriveFactory::Install() + { + __PRINT(_L("CFatTestProxyDriveFactory::Install")); + _LIT(KFatTestExt,"FatTest"); + return(SetName(&KFatTestExt)); + } + +/** +@internalTechnology +*/ +CProxyDrive* CFatTestProxyDriveFactory::NewProxyDriveL(CProxyDrive* aProxy,CMountCB* aMount) + { + __PRINT(_L("CFatTestProxyDriveFactory::NewProxyDriveL")); + return(CFatTestProxyDrive::NewL(aProxy,aMount)); + } + + + +/** +@internalTechnology +*/ +extern "C" { +EXPORT_C CProxyDriveFactory* CreateFileSystem() + { + __PRINT(_L("CreateFileSystem")); + return new CFatTestProxyDriveFactory(); + } +}