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