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