sl@0: // Copyright (c) 1998-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: // f32\sfat\sl_check.cpp sl@0: // sl@0: // sl@0: sl@0: //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! sl@0: //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! sl@0: //!! sl@0: //!! WARNING!! DO NOT edit this file !! '\sfat' component is obsolete and is not being used. '\sfat32'replaces it sl@0: //!! sl@0: //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! sl@0: //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! sl@0: sl@0: #include "sl_std.h" sl@0: #include "sl_scandrv.h" sl@0: sl@0: const TInt KMaxBufferSize=8192; sl@0: sl@0: sl@0: TBool CCheckFatTable::IsEof16Bit(TInt aCluster) const sl@0: { sl@0: return(aCluster>=0xFFF8 && aCluster<=0xFFFF); sl@0: } sl@0: sl@0: TBool CCheckFatTable::IsEof12Bit(TInt aCluster) const sl@0: { sl@0: return(aCluster>=0xFF8 && aCluster<=0xFFF); sl@0: } sl@0: sl@0: TInt CCheckFatTable::MaxFatIndex() const sl@0: { sl@0: __ASSERT_DEBUG((TUint)iMaxFatIndex>=KFatFirstSearchCluster, Fault(ECheckFatIndexZero)); sl@0: return(iMaxFatIndex); sl@0: } sl@0: sl@0: sl@0: CCheckFatTable* CCheckFatTable::NewL(CFatMountCB* aOwner) sl@0: // sl@0: // Create a CCheckFatTable sl@0: // sl@0: { sl@0: CCheckFatTable* fatTable; sl@0: fatTable=new(ELeave) CCheckFatTable(aOwner); sl@0: return(fatTable); sl@0: } sl@0: sl@0: sl@0: CCheckFatTable::CCheckFatTable(CFatMountCB* aOwner) sl@0: // sl@0: // Constructor sl@0: // sl@0: { sl@0: iOwner=aOwner; sl@0: } sl@0: sl@0: CCheckFatTable::~CCheckFatTable() sl@0: // sl@0: // Destructor sl@0: // sl@0: { sl@0: User::Free(iCheckFat); sl@0: } sl@0: sl@0: sl@0: void CCheckFatTable::InitializeL() sl@0: // sl@0: // Initialize the check fat table sl@0: // sl@0: { sl@0: __PRINT(_L("CCheckFatTable::InitializeL")); sl@0: sl@0: TInt fatSize=iOwner->FatSizeInBytes(); sl@0: sl@0: if(iCheckFat==NULL) sl@0: iCheckFat=(TUint8*)User::AllocL(fatSize); sl@0: else sl@0: iCheckFat=(TUint8*)User::ReAllocL(iCheckFat,fatSize); sl@0: Mem::FillZ(iCheckFat,fatSize); sl@0: iMaxFatIndex=iOwner->UsableClusters()+1; sl@0: if(iOwner->Is16BitFat()) sl@0: { sl@0: __ASSERT_ALWAYS(iMaxFatIndex>0 && iMaxFatIndex0 && iMaxFatIndexPtr(); sl@0: TInt maxSize=hBuf->Des().MaxSize(); sl@0: sl@0: TPtr8 fatBuffer(ptr,maxSize); sl@0: TInt fatSize=iOwner->FatSizeInBytes(); sl@0: TInt remainder=fatSize; sl@0: TInt offset=iOwner->StartOfFatInBytes(); sl@0: TUint8* dataPtr=iCheckFat; sl@0: TFatDriveInterface& drive = iOwner->DriveInterface(); sl@0: TInt fatNumber=iOwner->NumberOfFats(); sl@0: sl@0: while(remainder) sl@0: { sl@0: TInt s=Min(fatBuffer.MaxSize(),remainder); sl@0: TInt fatCount=fatNumber; sl@0: TInt fatPos=0; sl@0: while(fatCount) sl@0: { sl@0: TInt fatOffset=offset+fatPos; sl@0: User::LeaveIfError(drive.ReadCritical(fatOffset,s,fatBuffer)); sl@0: TInt rem2=s; sl@0: TInt offset2=fatOffset; sl@0: TUint8* dataPtr2=dataPtr; sl@0: TInt bufOffset=0; sl@0: while(rem2) sl@0: { sl@0: TInt s2=Min(rem2,512); sl@0: TInt r=Mem::Compare(dataPtr2,s2,fatBuffer.Ptr()+bufOffset,s2); sl@0: if (r!=0) sl@0: { sl@0: bErrFound = ETrue; sl@0: TPtrC8 dataBuf(dataPtr2,s2); sl@0: User::LeaveIfError(drive.WriteCritical(offset2,dataBuf)); sl@0: } sl@0: rem2-=s2; sl@0: offset2+=s2; sl@0: dataPtr2+=s2; sl@0: bufOffset+=s2; sl@0: } sl@0: --fatCount; sl@0: fatPos+=fatSize; sl@0: } sl@0: offset+=s; sl@0: dataPtr+=s; sl@0: remainder-=s; sl@0: } sl@0: sl@0: CleanupStack::PopAndDestroy(); sl@0: sl@0: return bErrFound; sl@0: } sl@0: sl@0: void CCheckFatTable::WriteMediaDescriptor() sl@0: // sl@0: // Write media descriptor to first byte and 0xFF to sl@0: // remaining bytes of first two entries sl@0: // sl@0: { sl@0: __PRINT(_L("CCheckFatTable::WriteMediaDescriptor")); sl@0: iCheckFat[0]=KBootSectorMediaDescriptor; sl@0: iCheckFat[1]=0xFF; sl@0: iCheckFat[2]=0xFF; sl@0: if (iOwner->Is16BitFat()) sl@0: iCheckFat[3]=0xFF; sl@0: } sl@0: sl@0: TInt CCheckFatTable::PosInBytes(TInt aFatIndex) const sl@0: // sl@0: // Return number of bytes into the fat sl@0: // sl@0: { sl@0: TInt fatPosInBytes; sl@0: if (iOwner->Is16BitFat()) sl@0: fatPosInBytes=aFatIndex<<1; sl@0: else sl@0: // this is used since 8-bit access will be used for reading/writing sl@0: fatPosInBytes=(aFatIndex*3>>1); sl@0: return(fatPosInBytes); sl@0: } sl@0: sl@0: sl@0: TInt CCheckFatTable::PosInIndex(TInt aBytePos) const sl@0: // sl@0: // Return index given byte position in fat sl@0: // sl@0: { sl@0: if(iOwner->Is16BitFat()) sl@0: return(aBytePos>>1); sl@0: else sl@0: return((aBytePos<<1)/3); sl@0: } sl@0: sl@0: sl@0: TInt CCheckFatTable::ReadL(TInt aFatIndex) const sl@0: // sl@0: // Read a value from the check fat sl@0: // sl@0: { sl@0: __ASSERT_ALWAYS((TUint32)aFatIndex >=KFatFirstSearchCluster && aFatIndex<=MaxFatIndex(),User::Leave(KErrCorrupt)); sl@0: TUint clusterVal; sl@0: if(iOwner->Is16BitFat()) sl@0: clusterVal=*(TUint16*)(iCheckFat+PosInBytes(aFatIndex)); sl@0: else sl@0: { sl@0: TUint8* pCluster=iCheckFat+PosInBytes(aFatIndex); sl@0: clusterVal=pCluster[0]|(pCluster[1]<<8); sl@0: TBool oddCluster=(aFatIndex)&1; sl@0: if(oddCluster) sl@0: clusterVal>>=4; sl@0: clusterVal&=0xFFF; sl@0: } sl@0: return(clusterVal); sl@0: } sl@0: sl@0: sl@0: void CCheckFatTable::WriteL(TInt aFatIndex,TInt aValue) sl@0: // sl@0: // Write a value to the check fat sl@0: // sl@0: { sl@0: if(iOwner->Is16BitFat()) sl@0: __ASSERT_ALWAYS((TUint32)aFatIndex>=KFatFirstSearchCluster && aFatIndex<=MaxFatIndex() && aValue>=0 && aValue<=0xFFFF,User::Leave(KErrCorrupt)); sl@0: else sl@0: __ASSERT_ALWAYS((TUint32)aFatIndex>=KFatFirstSearchCluster && aFatIndex<=MaxFatIndex() && aValue>=0 && aValue<=0xFFF,User::Leave(KErrCorrupt)); sl@0: TUint8* p=(TUint8*)(iCheckFat+PosInBytes(aFatIndex)); sl@0: if (iOwner->Is16BitFat()) sl@0: { sl@0: *(TUint16*)p=(TUint16)aValue; sl@0: return; sl@0: } sl@0: TUint8 mask=0x0F; sl@0: TBool odd=(aFatIndex)&1; sl@0: TUint8 fatVal; sl@0: if(odd) sl@0: { sl@0: mask<<=4; sl@0: aValue<<=4; sl@0: fatVal=p[0]; sl@0: fatVal&=~mask; sl@0: fatVal|=(TUint8)(aValue&0xFF); sl@0: p[0]=fatVal; sl@0: p[1]=(TUint8)(aValue>>8); sl@0: } sl@0: else sl@0: { sl@0: p[0]=(TUint8)(aValue&0xFF); sl@0: fatVal=p[1]; sl@0: fatVal&=~mask; sl@0: fatVal|=(TUint8)(aValue>>8); sl@0: p[1]=fatVal; sl@0: } sl@0: return; sl@0: } sl@0: sl@0: sl@0: TBool CCheckFatTable::GetNextClusterL(TInt& aCluster) const sl@0: // sl@0: // Get the next cluster in the chain from the check fat. sl@0: // sl@0: { sl@0: __PRINT(_L("CCheckFatTable::GetNextClusterL")); sl@0: TBool ret; sl@0: TInt nextCluster=ReadL(aCluster); sl@0: if (iOwner->Is16BitFat()) sl@0: ret=!IsEof16Bit(nextCluster); sl@0: else sl@0: ret=!IsEof12Bit(nextCluster); sl@0: if (ret) sl@0: aCluster=nextCluster; sl@0: return(ret); sl@0: } sl@0: sl@0: void CCheckFatTable::WriteFatEntryEofFL(TInt aCluster) sl@0: // sl@0: // Write EOF to aCluster sl@0: // sl@0: { sl@0: __PRINT(_L("CCheckFatTable::WriteFatEntryEofF")); sl@0: if (iOwner->Is16BitFat()) sl@0: WriteL(aCluster,EOF_16Bit); sl@0: else sl@0: WriteL(aCluster,EOF_12Bit); sl@0: } sl@0: sl@0: