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