userlibandfileserver/fileserver/sfat/sl_check.cpp
changeset 0 a41df078684a
child 15 4122176ea935
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 1998-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 // f32\sfat\sl_check.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 #include "sl_std.h"
       
    19 #include "sl_scandrv.h"
       
    20 
       
    21 const TInt KMaxBufferSize=8192;
       
    22 
       
    23 
       
    24 TBool CCheckFatTable::IsEof16Bit(TInt aCluster) const
       
    25 {
       
    26     return(aCluster>=0xFFF8 && aCluster<=0xFFFF);
       
    27 }
       
    28 
       
    29 TBool CCheckFatTable::IsEof12Bit(TInt aCluster) const
       
    30 {
       
    31     return(aCluster>=0xFF8 && aCluster<=0xFFF);
       
    32 }
       
    33 
       
    34 TInt CCheckFatTable::MaxFatIndex() const
       
    35     {   
       
    36 	__ASSERT_DEBUG((TUint)iMaxFatIndex>=KFatFirstSearchCluster, Fault(ECheckFatIndexZero));
       
    37 	return(iMaxFatIndex);
       
    38 	}
       
    39 
       
    40 
       
    41 CCheckFatTable* CCheckFatTable::NewL(CFatMountCB* aOwner)
       
    42 //
       
    43 // Create a CCheckFatTable
       
    44 //
       
    45 	{
       
    46 	CCheckFatTable* fatTable;
       
    47 	fatTable=new(ELeave) CCheckFatTable(aOwner);
       
    48 	return(fatTable);
       
    49 	}
       
    50 
       
    51 
       
    52 CCheckFatTable::CCheckFatTable(CFatMountCB* aOwner)
       
    53 //
       
    54 // Constructor
       
    55 //
       
    56 	{
       
    57 	iOwner=aOwner;
       
    58 	}
       
    59 
       
    60 CCheckFatTable::~CCheckFatTable()
       
    61 //
       
    62 // Destructor
       
    63 //
       
    64 	{
       
    65 	User::Free(iCheckFat);
       
    66 	}
       
    67 
       
    68 
       
    69 void CCheckFatTable::InitializeL()
       
    70 //
       
    71 // Initialize the check fat table
       
    72 //
       
    73 	{
       
    74 	__PRINT(_L("CCheckFatTable::InitializeL"));
       
    75 
       
    76 	TInt fatSize=iOwner->FatSizeInBytes();
       
    77 
       
    78 	if(iCheckFat==NULL)
       
    79 		iCheckFat=(TUint8*)User::AllocL(fatSize);
       
    80 	else
       
    81 		iCheckFat=(TUint8*)User::ReAllocL(iCheckFat,fatSize);
       
    82 	Mem::FillZ(iCheckFat,fatSize);
       
    83 	iMaxFatIndex=iOwner->UsableClusters()+1;
       
    84 	if(iOwner->Is16BitFat())
       
    85 		{
       
    86 		__ASSERT_ALWAYS(iMaxFatIndex>0 && iMaxFatIndex<EOF_16Bit && !IsEof16Bit(iMaxFatIndex),User::Leave(KErrCorrupt));
       
    87 		}
       
    88 	else
       
    89 		{
       
    90 		__ASSERT_ALWAYS(iMaxFatIndex>0 && iMaxFatIndex<EOF_12Bit && !IsEof12Bit(iMaxFatIndex),User::Leave(KErrCorrupt));
       
    91 		}
       
    92 	WriteMediaDescriptor();
       
    93 	
       
    94 	__PRINT2(_L("fatSize=%d,iCheckFat=0x%x"),fatSize,iCheckFat);
       
    95 	}
       
    96 
       
    97 
       
    98 /**
       
    99 @return ETrue if found errors in FAT 
       
   100 */
       
   101 TBool CCheckFatTable::FlushL()
       
   102 //
       
   103 // Flush iCheckFat to the media, comparing each sector to corresponding 
       
   104 // sector in all fats (cf.CFixedCache::FlushL)
       
   105 //	
       
   106 	{
       
   107 	TBool bErrFound = EFalse;
       
   108     
       
   109     __PRINT(_L("CCheckFatTable::FlushL()"));
       
   110 	HBufC8* hBuf=HBufC8::New(KMaxBufferSize);
       
   111 	if (hBuf==NULL)
       
   112 		hBuf=HBufC8::NewL(KMaxBufferSize/4);
       
   113 	CleanupStack::PushL(hBuf);
       
   114 
       
   115 	TUint8* ptr=(TUint8*)hBuf->Ptr();
       
   116 	TInt maxSize=hBuf->Des().MaxSize();
       
   117 
       
   118 	TPtr8 fatBuffer(ptr,maxSize);
       
   119 	TInt fatSize=iOwner->FatSizeInBytes();
       
   120 	TInt remainder=fatSize;
       
   121 	TInt offset=iOwner->StartOfFatInBytes();
       
   122 	TUint8* dataPtr=iCheckFat;
       
   123     TFatDriveInterface& drive = iOwner->DriveInterface();
       
   124 	TInt fatNumber=iOwner->NumberOfFats();
       
   125 	
       
   126 	while(remainder)
       
   127 		{
       
   128 		TInt s=Min(fatBuffer.MaxSize(),remainder);
       
   129 		TInt fatCount=fatNumber;
       
   130 		TInt fatPos=0;
       
   131 		while(fatCount)
       
   132 			{
       
   133 			TInt fatOffset=offset+fatPos;
       
   134 			User::LeaveIfError(drive.ReadCritical(fatOffset,s,fatBuffer));
       
   135 			TInt rem2=s;
       
   136 			TInt offset2=fatOffset;
       
   137 			TUint8* dataPtr2=dataPtr;
       
   138 			TInt bufOffset=0;
       
   139 			while(rem2)
       
   140 				{
       
   141 				TInt s2=Min(rem2,512);
       
   142 				TInt r=Mem::Compare(dataPtr2,s2,fatBuffer.Ptr()+bufOffset,s2);
       
   143 				if (r!=0)
       
   144 					{
       
   145 					bErrFound = ETrue;
       
   146                     TPtrC8 dataBuf(dataPtr2,s2);
       
   147 					User::LeaveIfError(drive.WriteCritical(offset2,dataBuf));
       
   148 					}
       
   149 				rem2-=s2;
       
   150 				offset2+=s2;
       
   151 				dataPtr2+=s2;
       
   152 				bufOffset+=s2;
       
   153 				}
       
   154 			--fatCount;
       
   155 			fatPos+=fatSize;
       
   156 			}
       
   157 		offset+=s;
       
   158 		dataPtr+=s;
       
   159 		remainder-=s;
       
   160 		}
       
   161 
       
   162 	CleanupStack::PopAndDestroy();
       
   163 
       
   164     return bErrFound;
       
   165 	}
       
   166 
       
   167 void CCheckFatTable::WriteMediaDescriptor()
       
   168 //
       
   169 // Write media descriptor to first byte and 0xFF to
       
   170 // remaining bytes of first two entries
       
   171 //
       
   172 	{
       
   173 	__PRINT(_L("CCheckFatTable::WriteMediaDescriptor"));
       
   174 	iCheckFat[0]=KBootSectorMediaDescriptor;
       
   175 	iCheckFat[1]=0xFF;
       
   176 	iCheckFat[2]=0xFF;
       
   177 	if (iOwner->Is16BitFat())
       
   178 		iCheckFat[3]=0xFF;
       
   179 	}
       
   180 
       
   181 TInt CCheckFatTable::PosInBytes(TInt aFatIndex) const
       
   182 //
       
   183 // Return number of bytes into the fat
       
   184 //
       
   185 	{
       
   186 	TInt fatPosInBytes;
       
   187 	if (iOwner->Is16BitFat())
       
   188 		fatPosInBytes=aFatIndex<<1;
       
   189 	else
       
   190 		// this is used since 8-bit access will be used for reading/writing
       
   191 		fatPosInBytes=(aFatIndex*3>>1);
       
   192 	return(fatPosInBytes);
       
   193 	}
       
   194 
       
   195 
       
   196 TInt CCheckFatTable::PosInIndex(TInt aBytePos) const
       
   197 //
       
   198 // Return index given byte position in fat
       
   199 //
       
   200 	{
       
   201 	if(iOwner->Is16BitFat())
       
   202 		return(aBytePos>>1);
       
   203 	else
       
   204 		return((aBytePos<<1)/3);
       
   205 	}
       
   206 
       
   207 
       
   208 TInt CCheckFatTable::ReadL(TInt aFatIndex) const
       
   209 //
       
   210 // Read a value from the check fat
       
   211 //
       
   212 	{
       
   213 	__ASSERT_ALWAYS((TUint32)aFatIndex >=KFatFirstSearchCluster && aFatIndex<=MaxFatIndex(),User::Leave(KErrCorrupt));
       
   214 	TUint clusterVal;
       
   215 	if(iOwner->Is16BitFat())
       
   216 		clusterVal=*(TUint16*)(iCheckFat+PosInBytes(aFatIndex));
       
   217 	else
       
   218 		{
       
   219 		TUint8* pCluster=iCheckFat+PosInBytes(aFatIndex);
       
   220 		clusterVal=pCluster[0]|(pCluster[1]<<8);
       
   221 		TBool oddCluster=(aFatIndex)&1;
       
   222 		if(oddCluster)
       
   223 			clusterVal>>=4;
       
   224 		clusterVal&=0xFFF;
       
   225 		}
       
   226 	return(clusterVal);
       
   227 	}
       
   228 
       
   229 
       
   230 void CCheckFatTable::WriteL(TInt aFatIndex,TInt aValue)
       
   231 //
       
   232 // Write a value to the check fat
       
   233 //
       
   234 	{
       
   235 	if(iOwner->Is16BitFat())
       
   236 		__ASSERT_ALWAYS((TUint32)aFatIndex>=KFatFirstSearchCluster && aFatIndex<=MaxFatIndex() && aValue>=0 && aValue<=0xFFFF,User::Leave(KErrCorrupt));
       
   237 	else
       
   238 		__ASSERT_ALWAYS((TUint32)aFatIndex>=KFatFirstSearchCluster && aFatIndex<=MaxFatIndex() && aValue>=0 && aValue<=0xFFF,User::Leave(KErrCorrupt));
       
   239 	TUint8* p=(TUint8*)(iCheckFat+PosInBytes(aFatIndex));
       
   240 	if (iOwner->Is16BitFat())
       
   241 		{ 
       
   242 		*(TUint16*)p=(TUint16)aValue;
       
   243 		return;
       
   244 		}
       
   245 	TUint8 mask=0x0F;
       
   246 	TBool odd=(aFatIndex)&1;
       
   247 	TUint8 fatVal;
       
   248 	if(odd)
       
   249 		{
       
   250 		mask<<=4;
       
   251 		aValue<<=4;
       
   252 		fatVal=p[0];
       
   253 		fatVal&=~mask;
       
   254 		fatVal|=(TUint8)(aValue&0xFF);
       
   255 		p[0]=fatVal;
       
   256 		p[1]=(TUint8)(aValue>>8);
       
   257 		}
       
   258 	else
       
   259 		{
       
   260 		p[0]=(TUint8)(aValue&0xFF);
       
   261 		fatVal=p[1];
       
   262 		fatVal&=~mask;
       
   263 		fatVal|=(TUint8)(aValue>>8);
       
   264 		p[1]=fatVal;
       
   265 		}
       
   266 	return;
       
   267 	}
       
   268 	
       
   269 
       
   270 TBool CCheckFatTable::GetNextClusterL(TInt& aCluster) const
       
   271 //
       
   272 // Get the next cluster in the chain from the check fat.
       
   273 //
       
   274     {
       
   275 	__PRINT(_L("CCheckFatTable::GetNextClusterL"));
       
   276 	TBool ret;
       
   277 	TInt nextCluster=ReadL(aCluster);
       
   278 	if (iOwner->Is16BitFat())
       
   279 		ret=!IsEof16Bit(nextCluster);
       
   280 	else
       
   281 		ret=!IsEof12Bit(nextCluster);
       
   282 	if (ret)
       
   283 		aCluster=nextCluster;
       
   284 	return(ret);
       
   285 	}
       
   286 
       
   287 void CCheckFatTable::WriteFatEntryEofFL(TInt aCluster)
       
   288 //
       
   289 // Write EOF to aCluster
       
   290 //
       
   291 	{
       
   292 	__PRINT(_L("CCheckFatTable::WriteFatEntryEofF"));
       
   293 	if (iOwner->Is16BitFat())
       
   294 		WriteL(aCluster,EOF_16Bit);
       
   295 	else
       
   296 		WriteL(aCluster,EOF_12Bit);
       
   297 	}
       
   298 
       
   299