1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/userlibandfileserver/fileserver/sfat/sl_check.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,307 @@
1.4 +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// f32\sfat\sl_check.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1.22 +//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1.23 +//!!
1.24 +//!! WARNING!! DO NOT edit this file !! '\sfat' component is obsolete and is not being used. '\sfat32'replaces it
1.25 +//!!
1.26 +//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1.27 +//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1.28 +
1.29 +#include "sl_std.h"
1.30 +#include "sl_scandrv.h"
1.31 +
1.32 +const TInt KMaxBufferSize=8192;
1.33 +
1.34 +
1.35 +TBool CCheckFatTable::IsEof16Bit(TInt aCluster) const
1.36 +{
1.37 + return(aCluster>=0xFFF8 && aCluster<=0xFFFF);
1.38 +}
1.39 +
1.40 +TBool CCheckFatTable::IsEof12Bit(TInt aCluster) const
1.41 +{
1.42 + return(aCluster>=0xFF8 && aCluster<=0xFFF);
1.43 +}
1.44 +
1.45 +TInt CCheckFatTable::MaxFatIndex() const
1.46 + {
1.47 + __ASSERT_DEBUG((TUint)iMaxFatIndex>=KFatFirstSearchCluster, Fault(ECheckFatIndexZero));
1.48 + return(iMaxFatIndex);
1.49 + }
1.50 +
1.51 +
1.52 +CCheckFatTable* CCheckFatTable::NewL(CFatMountCB* aOwner)
1.53 +//
1.54 +// Create a CCheckFatTable
1.55 +//
1.56 + {
1.57 + CCheckFatTable* fatTable;
1.58 + fatTable=new(ELeave) CCheckFatTable(aOwner);
1.59 + return(fatTable);
1.60 + }
1.61 +
1.62 +
1.63 +CCheckFatTable::CCheckFatTable(CFatMountCB* aOwner)
1.64 +//
1.65 +// Constructor
1.66 +//
1.67 + {
1.68 + iOwner=aOwner;
1.69 + }
1.70 +
1.71 +CCheckFatTable::~CCheckFatTable()
1.72 +//
1.73 +// Destructor
1.74 +//
1.75 + {
1.76 + User::Free(iCheckFat);
1.77 + }
1.78 +
1.79 +
1.80 +void CCheckFatTable::InitializeL()
1.81 +//
1.82 +// Initialize the check fat table
1.83 +//
1.84 + {
1.85 + __PRINT(_L("CCheckFatTable::InitializeL"));
1.86 +
1.87 + TInt fatSize=iOwner->FatSizeInBytes();
1.88 +
1.89 + if(iCheckFat==NULL)
1.90 + iCheckFat=(TUint8*)User::AllocL(fatSize);
1.91 + else
1.92 + iCheckFat=(TUint8*)User::ReAllocL(iCheckFat,fatSize);
1.93 + Mem::FillZ(iCheckFat,fatSize);
1.94 + iMaxFatIndex=iOwner->UsableClusters()+1;
1.95 + if(iOwner->Is16BitFat())
1.96 + {
1.97 + __ASSERT_ALWAYS(iMaxFatIndex>0 && iMaxFatIndex<EOF_16Bit && !IsEof16Bit(iMaxFatIndex),User::Leave(KErrCorrupt));
1.98 + }
1.99 + else
1.100 + {
1.101 + __ASSERT_ALWAYS(iMaxFatIndex>0 && iMaxFatIndex<EOF_12Bit && !IsEof12Bit(iMaxFatIndex),User::Leave(KErrCorrupt));
1.102 + }
1.103 + WriteMediaDescriptor();
1.104 +
1.105 + __PRINT2(_L("fatSize=%d,iCheckFat=0x%x"),fatSize,iCheckFat);
1.106 + }
1.107 +
1.108 +
1.109 +/**
1.110 +@return ETrue if found errors in FAT
1.111 +*/
1.112 +TBool CCheckFatTable::FlushL()
1.113 +//
1.114 +// Flush iCheckFat to the media, comparing each sector to corresponding
1.115 +// sector in all fats (cf.CFixedCache::FlushL)
1.116 +//
1.117 + {
1.118 + TBool bErrFound = EFalse;
1.119 +
1.120 + __PRINT(_L("CCheckFatTable::FlushL()"));
1.121 + HBufC8* hBuf=HBufC8::New(KMaxBufferSize);
1.122 + if (hBuf==NULL)
1.123 + hBuf=HBufC8::NewL(KMaxBufferSize/4);
1.124 + CleanupStack::PushL(hBuf);
1.125 +
1.126 + TUint8* ptr=(TUint8*)hBuf->Ptr();
1.127 + TInt maxSize=hBuf->Des().MaxSize();
1.128 +
1.129 + TPtr8 fatBuffer(ptr,maxSize);
1.130 + TInt fatSize=iOwner->FatSizeInBytes();
1.131 + TInt remainder=fatSize;
1.132 + TInt offset=iOwner->StartOfFatInBytes();
1.133 + TUint8* dataPtr=iCheckFat;
1.134 + TFatDriveInterface& drive = iOwner->DriveInterface();
1.135 + TInt fatNumber=iOwner->NumberOfFats();
1.136 +
1.137 + while(remainder)
1.138 + {
1.139 + TInt s=Min(fatBuffer.MaxSize(),remainder);
1.140 + TInt fatCount=fatNumber;
1.141 + TInt fatPos=0;
1.142 + while(fatCount)
1.143 + {
1.144 + TInt fatOffset=offset+fatPos;
1.145 + User::LeaveIfError(drive.ReadCritical(fatOffset,s,fatBuffer));
1.146 + TInt rem2=s;
1.147 + TInt offset2=fatOffset;
1.148 + TUint8* dataPtr2=dataPtr;
1.149 + TInt bufOffset=0;
1.150 + while(rem2)
1.151 + {
1.152 + TInt s2=Min(rem2,512);
1.153 + TInt r=Mem::Compare(dataPtr2,s2,fatBuffer.Ptr()+bufOffset,s2);
1.154 + if (r!=0)
1.155 + {
1.156 + bErrFound = ETrue;
1.157 + TPtrC8 dataBuf(dataPtr2,s2);
1.158 + User::LeaveIfError(drive.WriteCritical(offset2,dataBuf));
1.159 + }
1.160 + rem2-=s2;
1.161 + offset2+=s2;
1.162 + dataPtr2+=s2;
1.163 + bufOffset+=s2;
1.164 + }
1.165 + --fatCount;
1.166 + fatPos+=fatSize;
1.167 + }
1.168 + offset+=s;
1.169 + dataPtr+=s;
1.170 + remainder-=s;
1.171 + }
1.172 +
1.173 + CleanupStack::PopAndDestroy();
1.174 +
1.175 + return bErrFound;
1.176 + }
1.177 +
1.178 +void CCheckFatTable::WriteMediaDescriptor()
1.179 +//
1.180 +// Write media descriptor to first byte and 0xFF to
1.181 +// remaining bytes of first two entries
1.182 +//
1.183 + {
1.184 + __PRINT(_L("CCheckFatTable::WriteMediaDescriptor"));
1.185 + iCheckFat[0]=KBootSectorMediaDescriptor;
1.186 + iCheckFat[1]=0xFF;
1.187 + iCheckFat[2]=0xFF;
1.188 + if (iOwner->Is16BitFat())
1.189 + iCheckFat[3]=0xFF;
1.190 + }
1.191 +
1.192 +TInt CCheckFatTable::PosInBytes(TInt aFatIndex) const
1.193 +//
1.194 +// Return number of bytes into the fat
1.195 +//
1.196 + {
1.197 + TInt fatPosInBytes;
1.198 + if (iOwner->Is16BitFat())
1.199 + fatPosInBytes=aFatIndex<<1;
1.200 + else
1.201 + // this is used since 8-bit access will be used for reading/writing
1.202 + fatPosInBytes=(aFatIndex*3>>1);
1.203 + return(fatPosInBytes);
1.204 + }
1.205 +
1.206 +
1.207 +TInt CCheckFatTable::PosInIndex(TInt aBytePos) const
1.208 +//
1.209 +// Return index given byte position in fat
1.210 +//
1.211 + {
1.212 + if(iOwner->Is16BitFat())
1.213 + return(aBytePos>>1);
1.214 + else
1.215 + return((aBytePos<<1)/3);
1.216 + }
1.217 +
1.218 +
1.219 +TInt CCheckFatTable::ReadL(TInt aFatIndex) const
1.220 +//
1.221 +// Read a value from the check fat
1.222 +//
1.223 + {
1.224 + __ASSERT_ALWAYS((TUint32)aFatIndex >=KFatFirstSearchCluster && aFatIndex<=MaxFatIndex(),User::Leave(KErrCorrupt));
1.225 + TUint clusterVal;
1.226 + if(iOwner->Is16BitFat())
1.227 + clusterVal=*(TUint16*)(iCheckFat+PosInBytes(aFatIndex));
1.228 + else
1.229 + {
1.230 + TUint8* pCluster=iCheckFat+PosInBytes(aFatIndex);
1.231 + clusterVal=pCluster[0]|(pCluster[1]<<8);
1.232 + TBool oddCluster=(aFatIndex)&1;
1.233 + if(oddCluster)
1.234 + clusterVal>>=4;
1.235 + clusterVal&=0xFFF;
1.236 + }
1.237 + return(clusterVal);
1.238 + }
1.239 +
1.240 +
1.241 +void CCheckFatTable::WriteL(TInt aFatIndex,TInt aValue)
1.242 +//
1.243 +// Write a value to the check fat
1.244 +//
1.245 + {
1.246 + if(iOwner->Is16BitFat())
1.247 + __ASSERT_ALWAYS((TUint32)aFatIndex>=KFatFirstSearchCluster && aFatIndex<=MaxFatIndex() && aValue>=0 && aValue<=0xFFFF,User::Leave(KErrCorrupt));
1.248 + else
1.249 + __ASSERT_ALWAYS((TUint32)aFatIndex>=KFatFirstSearchCluster && aFatIndex<=MaxFatIndex() && aValue>=0 && aValue<=0xFFF,User::Leave(KErrCorrupt));
1.250 + TUint8* p=(TUint8*)(iCheckFat+PosInBytes(aFatIndex));
1.251 + if (iOwner->Is16BitFat())
1.252 + {
1.253 + *(TUint16*)p=(TUint16)aValue;
1.254 + return;
1.255 + }
1.256 + TUint8 mask=0x0F;
1.257 + TBool odd=(aFatIndex)&1;
1.258 + TUint8 fatVal;
1.259 + if(odd)
1.260 + {
1.261 + mask<<=4;
1.262 + aValue<<=4;
1.263 + fatVal=p[0];
1.264 + fatVal&=~mask;
1.265 + fatVal|=(TUint8)(aValue&0xFF);
1.266 + p[0]=fatVal;
1.267 + p[1]=(TUint8)(aValue>>8);
1.268 + }
1.269 + else
1.270 + {
1.271 + p[0]=(TUint8)(aValue&0xFF);
1.272 + fatVal=p[1];
1.273 + fatVal&=~mask;
1.274 + fatVal|=(TUint8)(aValue>>8);
1.275 + p[1]=fatVal;
1.276 + }
1.277 + return;
1.278 + }
1.279 +
1.280 +
1.281 +TBool CCheckFatTable::GetNextClusterL(TInt& aCluster) const
1.282 +//
1.283 +// Get the next cluster in the chain from the check fat.
1.284 +//
1.285 + {
1.286 + __PRINT(_L("CCheckFatTable::GetNextClusterL"));
1.287 + TBool ret;
1.288 + TInt nextCluster=ReadL(aCluster);
1.289 + if (iOwner->Is16BitFat())
1.290 + ret=!IsEof16Bit(nextCluster);
1.291 + else
1.292 + ret=!IsEof12Bit(nextCluster);
1.293 + if (ret)
1.294 + aCluster=nextCluster;
1.295 + return(ret);
1.296 + }
1.297 +
1.298 +void CCheckFatTable::WriteFatEntryEofFL(TInt aCluster)
1.299 +//
1.300 +// Write EOF to aCluster
1.301 +//
1.302 + {
1.303 + __PRINT(_L("CCheckFatTable::WriteFatEntryEofF"));
1.304 + if (iOwner->Is16BitFat())
1.305 + WriteL(aCluster,EOF_16Bit);
1.306 + else
1.307 + WriteL(aCluster,EOF_12Bit);
1.308 + }
1.309 +
1.310 +