os/kernelhwsrv/userlibandfileserver/fileserver/sfat/sl_fmt.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) 1996-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_fmt.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 <e32hal.h>
sl@0
    28
sl@0
    29
sl@0
    30
sl@0
    31
sl@0
    32
//
sl@0
    33
// Returns the total available ram from UserHal:: or sets an
sl@0
    34
// arbitrary limit upon the WINS ramdisk.
sl@0
    35
//
sl@0
    36
static TInt64 GetRamDiskSizeInBytes()
sl@0
    37
    {
sl@0
    38
sl@0
    39
#if defined(__EPOC32__)
sl@0
    40
    TMemoryInfoV1Buf memInfo;
sl@0
    41
    UserHal::MemoryInfo(memInfo);
sl@0
    42
    TUint max = memInfo().iTotalRamInBytes; // not really the correct max
sl@0
    43
    return max;
sl@0
    44
#else
sl@0
    45
    const TInt KArbitraryWinsRamDiskSize=0x400000;  //-- Default size for a Ram drive, 4MB
sl@0
    46
    return(KArbitraryWinsRamDiskSize);
sl@0
    47
#endif
sl@0
    48
    }
sl@0
    49
sl@0
    50
CFatFormatCB::CFatFormatCB()
sl@0
    51
    {
sl@0
    52
    __PRINT1(_L("CFatFormatCB::CFatFormatCB() [%x]"),this);
sl@0
    53
    }
sl@0
    54
sl@0
    55
CFatFormatCB::~CFatFormatCB()
sl@0
    56
    {
sl@0
    57
    __PRINT1(_L("CFatFormatCB::~CFatFormatCB() [%x]"),this);
sl@0
    58
    iBadSectors.Close();
sl@0
    59
    iBadClusters.Close();
sl@0
    60
    }
sl@0
    61
sl@0
    62
TInt CFatFormatCB::MaxFat16Sectors() const
sl@0
    63
//
sl@0
    64
// Calculate the size of a 16 bit FAT
sl@0
    65
//
sl@0
    66
    {
sl@0
    67
    
sl@0
    68
    TInt fatSizeInBytes=(2*iMaxDiskSectors)/iSectorsPerCluster+(iBytesPerSector-1);
sl@0
    69
    return(fatSizeInBytes/iBytesPerSector);
sl@0
    70
    }
sl@0
    71
sl@0
    72
TInt CFatFormatCB::MaxFat12Sectors() const
sl@0
    73
//
sl@0
    74
// Calculate the size of a 12 bit FAT
sl@0
    75
//
sl@0
    76
    {
sl@0
    77
    
sl@0
    78
    TInt maxDiskClusters=iMaxDiskSectors/iSectorsPerCluster;
sl@0
    79
    TInt fatSizeInBytes=maxDiskClusters+(maxDiskClusters>>1)+(iBytesPerSector-1);
sl@0
    80
    return(fatSizeInBytes/iBytesPerSector);
sl@0
    81
    }
sl@0
    82
sl@0
    83
//-------------------------------------------------------------------------------------------------------------------
sl@0
    84
/**
sl@0
    85
    Fill a media range from aStartPos to aEndPos with zeroes.
sl@0
    86
    @param  aStartPos   start media position
sl@0
    87
    @param  aEndPos     end media position
sl@0
    88
*/
sl@0
    89
void CFatFormatCB::DoZeroFillMediaL(TInt64 aStartPos, TInt64 aEndPos)
sl@0
    90
    {
sl@0
    91
    ASSERT(aStartPos <= aEndPos && aStartPos >=0  && aEndPos >=0);
sl@0
    92
sl@0
    93
    RBuf8 buf;
sl@0
    94
    CleanupClosePushL(buf);
sl@0
    95
sl@0
    96
    const TInt KBufMaxSz=32768; //-- zero-buffer Maximal size, bytes
sl@0
    97
    const TInt KBufMinSz=512;   //-- zero-buffer minimal size, bytes
sl@0
    98
sl@0
    99
    if(buf.CreateMax(KBufMaxSz) != KErrNone)
sl@0
   100
        {
sl@0
   101
        buf.CreateMaxL(KBufMinSz); //-- OOM, try to create smaller buffer
sl@0
   102
        }
sl@0
   103
sl@0
   104
    buf.FillZ();
sl@0
   105
sl@0
   106
    TInt64 rem = aEndPos - aStartPos;
sl@0
   107
    while(rem)
sl@0
   108
        {
sl@0
   109
        const TUint32 bytesToWrite=(TUint32)Min(rem, buf.Size());
sl@0
   110
        TPtrC8 ptrData(buf.Ptr(), bytesToWrite);
sl@0
   111
sl@0
   112
        User::LeaveIfError(LocalDrive()->Write(aStartPos, ptrData));
sl@0
   113
sl@0
   114
        aStartPos+=bytesToWrite;
sl@0
   115
        rem-=bytesToWrite;
sl@0
   116
        }
sl@0
   117
    
sl@0
   118
    CleanupStack::PopAndDestroy(&buf); 
sl@0
   119
    }
sl@0
   120
sl@0
   121
//-------------------------------------------------------------------------------------------------------------------
sl@0
   122
sl@0
   123
static TInt DiskSizeInSectorsL(TInt64 aSizeInBytes)
sl@0
   124
    {
sl@0
   125
    const TInt64 totalSectors64=aSizeInBytes>>KDefSectorSzLog2;
sl@0
   126
    const TInt   totalSectors32=I64LOW(totalSectors64);
sl@0
   127
    __PRINT2(_L("Disk size:%LU, max disk sectors:%d"),aSizeInBytes, totalSectors32);
sl@0
   128
    return totalSectors32;
sl@0
   129
    }
sl@0
   130
sl@0
   131
sl@0
   132
/**
sl@0
   133
    suggest FAT type according to the FAT volume metrics
sl@0
   134
    @return calculated FAT type
sl@0
   135
*/
sl@0
   136
TFatType CFatFormatCB::SuggestFatType() const
sl@0
   137
{
sl@0
   138
    const TUint32 rootDirSectors = (iRootDirEntries*KSizeOfFatDirEntry + (iBytesPerSector-1)) / iBytesPerSector;
sl@0
   139
    const TUint32 dataSectors = iMaxDiskSectors - (iReservedSectors + (iNumberOfFats * iSectorsPerFat) + rootDirSectors);
sl@0
   140
    const TUint32 clusterCnt = dataSectors/ iSectorsPerCluster;
sl@0
   141
sl@0
   142
    //-- magic. see FAT specs for details.
sl@0
   143
    if(clusterCnt < 4085)
sl@0
   144
        return EFat12;
sl@0
   145
    else if(clusterCnt < 65525)
sl@0
   146
        return EFat16;
sl@0
   147
    else
sl@0
   148
        return EFat32;
sl@0
   149
}
sl@0
   150
sl@0
   151
/**
sl@0
   152
    Initialize format data.
sl@0
   153
*/
sl@0
   154
void CFatFormatCB::InitializeFormatDataL()
sl@0
   155
    {
sl@0
   156
      
sl@0
   157
    __PRINT1(_L("CFatFormatCB::InitializeFormatDataL() drv:%d"), Drive().DriveNumber());
sl@0
   158
    TLocalDriveCapsV6Buf caps;
sl@0
   159
    User::LeaveIfError(LocalDrive()->Caps(caps));
sl@0
   160
    iVariableSize=((caps().iMediaAtt)&KMediaAttVariableSize) ? (TBool)ETrue : (TBool)EFalse;
sl@0
   161
sl@0
   162
    iBytesPerSector=KDefaultSectorSize;
sl@0
   163
    iSectorSizeLog2 = Log2(iBytesPerSector);
sl@0
   164
    iHiddenSectors=caps().iHiddenSectors;   
sl@0
   165
    iNumberOfHeads=2;
sl@0
   166
    iSectorsPerTrack=16;
sl@0
   167
    
sl@0
   168
    if (iVariableSize)
sl@0
   169
        {// Variable size implies ram disk
sl@0
   170
        iMaxDiskSectors=DiskSizeInSectorsL(GetRamDiskSizeInBytes());
sl@0
   171
        InitFormatDataForVariableSizeDisk(iMaxDiskSectors);
sl@0
   172
        }
sl@0
   173
    else
sl@0
   174
        {//-- fixed-size media
sl@0
   175
        iMaxDiskSectors=DiskSizeInSectorsL(caps().iSize);
sl@0
   176
        
sl@0
   177
        __PRINT3(_L("::InitializeFormatDataL() iMode:0x%x, ilen:%d, extrai:%d"), iMode, iSpecialInfo.Length(), caps().iExtraInfo);
sl@0
   178
sl@0
   179
        if(iMode & ESpecialFormat)
sl@0
   180
            {
sl@0
   181
            if(iSpecialInfo.Length())
sl@0
   182
                {
sl@0
   183
                if (caps().iExtraInfo)  // conflict between user and media
sl@0
   184
                    User::Leave(KErrNotSupported);
sl@0
   185
                else  // User-specified
sl@0
   186
                    User::LeaveIfError(InitFormatDataForFixedSizeDiskUser(iMaxDiskSectors));
sl@0
   187
                }
sl@0
   188
            else
sl@0
   189
                {
sl@0
   190
                if (caps().iExtraInfo)
sl@0
   191
                    User::LeaveIfError(InitFormatDataForFixedSizeDiskCustom(caps().iFormatInfo));
sl@0
   192
                else
sl@0
   193
                    User::LeaveIfError(InitFormatDataForFixedSizeDiskNormal(iMaxDiskSectors, caps()));
sl@0
   194
                }
sl@0
   195
            }
sl@0
   196
        else //if(iMode & ESpecialFormat)
sl@0
   197
            {
sl@0
   198
            // Normal format with default values
sl@0
   199
            //  - Media with special format requirements will always use them
sl@0
   200
            //    even without the ESpecialFormat option.
sl@0
   201
            if(caps().iExtraInfo)
sl@0
   202
                User::LeaveIfError(InitFormatDataForFixedSizeDiskCustom(caps().iFormatInfo));
sl@0
   203
            else
sl@0
   204
                User::LeaveIfError(InitFormatDataForFixedSizeDiskNormal(iMaxDiskSectors, caps()));
sl@0
   205
            }
sl@0
   206
        
sl@0
   207
        } //else(iVariableSize)
sl@0
   208
    }
sl@0
   209
sl@0
   210
/**
sl@0
   211
    Initialize the format parameters for a variable sized disk
sl@0
   212
    
sl@0
   213
    @param  aDiskSizeInSectors volume size in sectors
sl@0
   214
    @return standard error code
sl@0
   215
*/
sl@0
   216
TInt  CFatFormatCB::InitFormatDataForVariableSizeDisk(TInt aDiskSizeInSectors)
sl@0
   217
    {
sl@0
   218
    iNumberOfFats=2; // 1 FAT 1 Indirection table (FIT)
sl@0
   219
    iReservedSectors=1;
sl@0
   220
    iRootDirEntries=2*(4*KDefaultSectorSize)/sizeof(SFatDirEntry);
sl@0
   221
    TInt minSectorsPerCluster=(aDiskSizeInSectors+KMaxFAT16Entries-1)/KMaxFAT16Entries;
sl@0
   222
    iSectorsPerCluster=1;
sl@0
   223
    while (minSectorsPerCluster>iSectorsPerCluster)
sl@0
   224
        iSectorsPerCluster<<=1;
sl@0
   225
    __PRINT1(_L("iSectorsPerCluster = %d"),iSectorsPerCluster);
sl@0
   226
    iSectorsPerFat=MaxFat16Sectors();
sl@0
   227
    __PRINT1(_L("iSectorsPerFat = %d"),iSectorsPerFat);
sl@0
   228
    iFileSystemName=KFileSystemName16;
sl@0
   229
sl@0
   230
    return KErrNone;
sl@0
   231
    }
sl@0
   232
sl@0
   233
TInt CFatFormatCB::HandleCorrupt(TInt aError)
sl@0
   234
//
sl@0
   235
// Handle disk corrupt during format. It needs media driver's support.
sl@0
   236
// Media driver should handle DLocalDrive::EGetLastErrorInfo request in
sl@0
   237
// its Request function, filling in proper error information.
sl@0
   238
// @see TErrorInfo
sl@0
   239
//
sl@0
   240
    {
sl@0
   241
    __PRINT2(_L("CFatFormatCB::HandleCorrupt(%d) drv:%d"), aError, Drive().DriveNumber());
sl@0
   242
sl@0
   243
    TPckgBuf<TErrorInfo> info;
sl@0
   244
    TInt r = LocalDrive()->GetLastErrorInfo(info);
sl@0
   245
    
sl@0
   246
    if(r != KErrNone)
sl@0
   247
        {
sl@0
   248
        __PRINT1(_L("....GetLastErrorInfo() err:%d"), r);
sl@0
   249
        }
sl@0
   250
sl@0
   251
    if (r == KErrNotSupported)
sl@0
   252
        return KErrCorrupt;
sl@0
   253
    else if (r != KErrNone)
sl@0
   254
        return r;
sl@0
   255
sl@0
   256
    __PRINT3(_L("....TErrorInfo iReasonCode:%d, iErrorPos:%LU, iOtherInfo:%d"), info().iReasonCode, info().iErrorPos, info().iOtherInfo);
sl@0
   257
    
sl@0
   258
    // if no error reported by GetLastErrorInfo(), return the original error
sl@0
   259
    if (info().iReasonCode == KErrNone)
sl@0
   260
        return aError;
sl@0
   261
sl@0
   262
    if (info().iReasonCode!=KErrNone && info().iReasonCode!=TErrorInfo::EBadSector)
sl@0
   263
        return info().iReasonCode;
sl@0
   264
sl@0
   265
    // First bad sector met
sl@0
   266
    TInt sectorsDone = (TInt)(info().iErrorPos >> iSectorSizeLog2);
sl@0
   267
    TInt badSector = iFormatInfo.i512ByteSectorsFormatted + sectorsDone;
sl@0
   268
    iBadSectors.Append(badSector);
sl@0
   269
sl@0
   270
    // Update format information
sl@0
   271
    iFormatInfo.i512ByteSectorsFormatted += sectorsDone+1;
sl@0
   272
    return KErrNone;
sl@0
   273
    }
sl@0
   274
sl@0
   275
void CFatFormatCB::TranslateL()
sl@0
   276
//
sl@0
   277
// Change bad cluster number to new value with regard to new format parameters
sl@0
   278
//
sl@0
   279
    {
sl@0
   280
    if (iDiskCorrupt || !(iMode & EQuickFormat))
sl@0
   281
        return;
sl@0
   282
sl@0
   283
    TInt size = 1 << FatMount().ClusterSizeLog2();
sl@0
   284
    TUint8* readBuf = new(ELeave) TUint8[size];
sl@0
   285
    TPtr8 readBufPtr(readBuf, size);
sl@0
   286
    RArray<TInt> newArray;
sl@0
   287
    TInt r = DoTranslate(readBufPtr, newArray);
sl@0
   288
    delete[] readBuf;
sl@0
   289
    newArray.Close();
sl@0
   290
    User::LeaveIfError(r);
sl@0
   291
    }
sl@0
   292
sl@0
   293
#define calcSector(n) (n+oFirstFreeSector-nFirstFreeSector)
sl@0
   294
TInt CFatFormatCB::DoTranslate(TPtr8& aBuf, RArray<TInt>& aArray)
sl@0
   295
    {
sl@0
   296
sl@0
   297
    TInt r = KErrNone;
sl@0
   298
sl@0
   299
    // old format parameters
sl@0
   300
    TInt oFirstFreeSector = iOldFirstFreeSector;
sl@0
   301
    TInt oSectorsPerCluster = iOldSectorsPerCluster;
sl@0
   302
    // new format parameters
sl@0
   303
    TInt nFirstFreeSector = FatMount().iFirstFreeByte>>FatMount().SectorSizeLog2();
sl@0
   304
    TInt nSectorsPerCluster = FatMount().SectorsPerCluster();
sl@0
   305
sl@0
   306
    if (oFirstFreeSector==nFirstFreeSector && oSectorsPerCluster==nSectorsPerCluster)
sl@0
   307
        return r;
sl@0
   308
sl@0
   309
    TInt i;
sl@0
   310
    for (i=0; i<iBadClusters.Count(); ++i)
sl@0
   311
        {
sl@0
   312
        /*
sl@0
   313
        Cluster boundary may change due to format parameter change.
sl@0
   314
        Old: |-- ... --|----|----|----|----|----|----|----|
sl@0
   315
                       |<-          Data area           ->|
sl@0
   316
        New: |--- ... ---|------|------|------|------|------|
sl@0
   317
                         |<-           Data area          ->|
sl@0
   318
        */
sl@0
   319
        TInt begSector = calcSector((iBadClusters[i]-2)*oSectorsPerCluster);
sl@0
   320
        begSector = Max(begSector, nFirstFreeSector);
sl@0
   321
        TInt endSector = calcSector(((iBadClusters[i]-1)*oSectorsPerCluster)-1);
sl@0
   322
        endSector = Max(endSector, nFirstFreeSector);
sl@0
   323
        TInt begCluster = (begSector/iSectorsPerCluster)+KFatFirstSearchCluster;
sl@0
   324
        TInt endCluster = (endSector/iSectorsPerCluster)+KFatFirstSearchCluster;
sl@0
   325
        if (begCluster == endCluster)  // old cluster is in a new cluster
sl@0
   326
            {
sl@0
   327
            if (aArray.Find(begCluster) == KErrNotFound)
sl@0
   328
                if ((r=aArray.Append(begCluster)) != KErrNone)
sl@0
   329
                    return r;
sl@0
   330
            continue;
sl@0
   331
            }
sl@0
   332
        // deal with old cluster cross over several new clusters
sl@0
   333
        TInt offset = (begSector-(begCluster-2)*iSectorsPerCluster)<<iSectorSizeLog2;
sl@0
   334
        TInt len = (endSector-(endCluster-2)*iSectorsPerCluster)<<iSectorSizeLog2;
sl@0
   335
        TInt j;
sl@0
   336
        for (j=begCluster; j<=endCluster; ++j)
sl@0
   337
        // Because each old bad cluster cross several new clusters,
sl@0
   338
        // we have to verify which new cluster is bad really
sl@0
   339
            {
sl@0
   340
            TInt addr = (nFirstFreeSector+(j-2)*iSectorsPerCluster)<<iSectorSizeLog2;
sl@0
   341
            TInt clusterLen = (1<<iSectorSizeLog2) * iSectorsPerCluster;
sl@0
   342
            if (j == begCluster)
sl@0
   343
                r = LocalDrive()->Read(addr+offset,clusterLen-offset,aBuf);
sl@0
   344
            else if (j == endCluster && len)
sl@0
   345
                r = LocalDrive()->Read(addr,len,aBuf);
sl@0
   346
            else
sl@0
   347
                r = LocalDrive()->Read(addr,clusterLen,aBuf);
sl@0
   348
            if (r == KErrCorrupt) // new cluster j is corrupt
sl@0
   349
                if ((r=aArray.Append(j)) != KErrNone)
sl@0
   350
                    return r;
sl@0
   351
            }
sl@0
   352
        }
sl@0
   353
    // Update iBadClusters with aArray
sl@0
   354
    iBadClusters.Reset();
sl@0
   355
    for (i=0; i<aArray.Count(); ++i)
sl@0
   356
        if ((r=iBadClusters.Append(aArray[i])) != KErrNone)
sl@0
   357
            return r;
sl@0
   358
    iBadClusters.Sort();
sl@0
   359
    return r;
sl@0
   360
    }
sl@0
   361
sl@0
   362
sl@0
   363
//-------------------------------------------------------------------------------------------------------------------
sl@0
   364
/** override from CFormatCB, additional interfaces implementation */
sl@0
   365
TInt CFatFormatCB::GetInterface(TInt aInterfaceId, TAny*& /*aInterface*/, TAny* aInput)
sl@0
   366
    {
sl@0
   367
    if(aInterfaceId == ESetFmtParameters)
sl@0
   368
        {
sl@0
   369
        return DoProcessTVolFormatParam((const TVolFormatParam_FAT*)aInput);
sl@0
   370
        }
sl@0
   371
sl@0
   372
    return KErrNotSupported;
sl@0
   373
    }
sl@0
   374
sl@0
   375
//-------------------------------------------------------------------------------------------------------------------
sl@0
   376
/** 
sl@0
   377
    Process formatting parameters passed as TVolFormatParam_FAT structure.
sl@0
   378
    @param      apVolFormatParam pointer to the formatting parameters.
sl@0
   379
    @return     standard error code
sl@0
   380
*/
sl@0
   381
TInt CFatFormatCB::DoProcessTVolFormatParam(const TVolFormatParam_FAT* apVolFormatParam)
sl@0
   382
    {
sl@0
   383
    if(apVolFormatParam->iUId != TVolFormatParam::KUId ||  apVolFormatParam->FSNameHash() != TVolFormatParam::CalcFSNameHash(KFileSystemName_FAT))
sl@0
   384
        {
sl@0
   385
        ASSERT(0);
sl@0
   386
        return KErrArgument;
sl@0
   387
        }
sl@0
   388
sl@0
   389
    //-- Populate iSpecialInfo with the data taken from apVolFormatParam.
sl@0
   390
    //-- for formatting FAT volume iSpecialInfo can hold absolutely all required data from apVolFormatParam.
sl@0
   391
    //-- if some additional data from apVolFormatParam are required for some reason, figure out youself how to store and use them.
sl@0
   392
    TLDFormatInfo& fmtInfo = iSpecialInfo();
sl@0
   393
    new(&fmtInfo) TLDFormatInfo; //-- initialise the structure in the buffer 
sl@0
   394
sl@0
   395
sl@0
   396
    //-- sectors per cluster
sl@0
   397
    fmtInfo.iSectorsPerCluster = (TUint16)apVolFormatParam->SectPerCluster();   
sl@0
   398
    
sl@0
   399
    //-- FAT type
sl@0
   400
    const TFatSubType fatSubType = apVolFormatParam->FatSubType();
sl@0
   401
    
sl@0
   402
    if(fatSubType != ENotSpecified && fatSubType != EFat12 && fatSubType != EFat16 && fatSubType != EFat32)
sl@0
   403
        return KErrArgument;
sl@0
   404
sl@0
   405
sl@0
   406
    fmtInfo.iFATBits = (TLDFormatInfo::TFATBits)fatSubType; //-- FAT12/16/32/not specified
sl@0
   407
sl@0
   408
    //-- number of FAT tables
sl@0
   409
    switch(apVolFormatParam->NumFATs())
sl@0
   410
        {
sl@0
   411
        case 0: //-- "not specified, default"
sl@0
   412
        break;
sl@0
   413
sl@0
   414
        case 1:
sl@0
   415
            fmtInfo.iFlags |= TLDFormatInfo::EOneFatTable; 
sl@0
   416
        break;
sl@0
   417
sl@0
   418
        case 2:
sl@0
   419
            fmtInfo.iFlags |= TLDFormatInfo::ETwoFatTables; 
sl@0
   420
        break;
sl@0
   421
sl@0
   422
        default: //-- more than KMaxFatTablesSupported is not supported
sl@0
   423
        return KErrArgument;
sl@0
   424
sl@0
   425
        };
sl@0
   426
sl@0
   427
    //-- number of reserved sectors
sl@0
   428
    fmtInfo.iReservedSectors = (TUint16)apVolFormatParam->ReservedSectors();
sl@0
   429
sl@0
   430
    return KErrNone;
sl@0
   431
    }
sl@0
   432
sl@0
   433
sl@0
   434
sl@0
   435
sl@0
   436
sl@0
   437
sl@0
   438
sl@0
   439
sl@0
   440
sl@0
   441
sl@0
   442