⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rfatsa.cxx

📁 EFI(Extensible Firmware Interface)是下一代BIOS
💻 CXX
📖 第 1 页 / 共 5 页
字号:
    USHORT      sec_per_clus = 0; //  Sectors per cluster
    ULONG       cluster_size = 0; //  Size of each cluster in bytes.
    VALIDATION_STATUS result;     //  Return code from ValidateClusterSize.
    ULONG       fat_size;         //  Size of each fat in number of
                                  //  sectors.
#if DBG
    BIG_INT     data_offset;      // the offset to first data cluster
#endif

    //
    //  Call DosSaSeetBpb to perform some very rudimentary bpb setup.
    //

    if (!DosSaSetBpb()) {
        DebugPrintTrace(("Could not do a REAL_FAT_SA::DosSaSetBpb.\n"));
        return FALSE;
    }

    //
    //  A volume cannot have more than 4gig sectors.
    //
    DebugAssert(_drive->QuerySectors().GetHighPart() == 0);

    sectors = _drive->QuerySectors().GetLowPart();
    sector_size = _drive->QuerySectorSize();

    PCHAR fattypestr;
    if (!BackwardCompatible) {

        //
        //  If BackwardCompatible is false, then the user must have
        //  specified the /fs:FAT32 switch or the existing volume
        //  must be a FAT32 volume when a quik format is performed.
        //

        _ft = LARGE32;
        fattypestr = "FAT32";

    } else {

        //
        //  At this moment, we don't know whether FAT16 or FAt12
        //  is appropriate for this volume.
        //

        _ft = INVALID_FATTYPE;
        fattypestr = "FAT16/12";

    }

    if (_drive->QuerySectors().GetHighPart() != 0) {
    Message->Set(MSG_FMT_VOL_TOO_BIG);
    Message->Display("%s", fattypestr);
    return FALSE;
    }

    //
    //  The boot area of a FAt32 volume is at least 32 sectors large
    //  and at least 32 * 512 bytes in size.
    //

    if (_ft == LARGE32) {
        _sec_per_boot = max((32 * 512) / sector_size,32);
    }

    //
    //  Set up the number of reserved sectors and the number of
    //  FATs in the boot sector. Note that ValidateClusterSize and
    //  ComputeDefaultClusterSize depend on these values so don't move
    //  the following lines to anywhere else.
    //

    _sector_zero.Bpb.ReservedSectors = (USHORT)_sec_per_boot;
    _sector_zero.Bpb.Fats = 2;

    //
    //  Try to honor the cluster size provided by the user.
    //

    if (ClusterSize) {

        //
        //  If the cluster size specified by the user is not
        //  of the form sector_size * 2^n where n is an integer
        //  then choose a cluster size which is of the form 2^n
        //  * sector size and is just bigger than the cluster
        //  size specified by the user.
        //

        cluster_size = sector_size;
        sec_per_clus = 1;

        //
        // Check that the user specified cluster size is at least as big as
        // the minimum allowed cluster size as determined by the sector size.
        //

        if (ClusterSize < cluster_size) {
            Message->Set(MSG_FMT_CLUSTER_SIZE_TOO_SMALL_MIN);
            Message->Display("%u", sector_size);
                return FALSE;
        }

        while (cluster_size < ClusterSize && sec_per_clus < 256) {
            cluster_size *= 2;
            sec_per_clus *= 2;
        }

        //
        //  Make sure that the cluster size provided by the user
        //  is not too big.
        //

        if ( sec_per_clus > MaxSecPerClus) {

            Message->Set(MSG_FMT_CLUSTER_SIZE_TOO_BIG);
            Message->Display("%s", fattypestr);
            return FALSE;
        }

        //
        //  Issue a warning if the cluster size computed is not
        //  equal to the cluster size provided by the user.
        //

        if ( cluster_size != ClusterSize ) {
            Message->Set(MSG_FMT_CLUSTER_SIZE_MISMATCH);
            Message->Display("%u", cluster_size);
            if (!Message->IsYesResponse(FALSE)) {
                return FALSE;
            }
        }
    }

    _sector_zero.Bpb.RootEntries = (USHORT)ComputeRootEntries();

    if (cluster_size) {

        //
        //  Make sure that the cluster size is valid for a
        //  FAT volume.
        //

        result = ValidateClusterSize( cluster_size,
                                      sectors,
                                      sector_size,
                                      NUMBER_OF_FATS,
                                      &_ft,
                                      &fat_size,
                                      &_ClusterCount );

        //
        //  Tell the user the cluster size specified is invalid
        //  for the FAT type chosen.
        //

        switch (result) {
            case TOO_SMALL:
                Message->Set(MSG_FMT_CLUSTER_SIZE_TOO_SMALL);
                Message->Display("%s", fattypestr);
                return FALSE;
            case TOO_BIG:
                Message->Set(MSG_FMT_CLUSTER_SIZE_TOO_BIG);
                Message->Display("%s", fattypestr);
                return FALSE;
        }

    }


    if (BackwardCompatible && _ft == INVALID_FATTYPE) {

        //
        //  Use CSEC_16BIT as a cut-off point for determining
        //  whether the FAT should be 16-bit or 12-bit.
        //

        if (sectors < CSEC_FAT16BIT) {
            _ft = SMALL;
        } else {
            _ft = LARGE16;
        }
    }

    //
    //  If the user doesn't provide a cluster size, we have
    //  to compute a default cluster size.
    //
    if (!cluster_size) {

        cluster_size = ComputeDefaultClusterSize( sectors,
                                                  sector_size,
                                                  _sector_zero.Bpb.ReservedSectors,
                                                  NUMBER_OF_FATS,
                                                  _drive->QueryMediaType(),
                                                  _ft,
                                                  &fat_size,
                                                  &_ClusterCount);
        if (cluster_size == 0) {
            Message->Set(MSG_FMT_VOL_TOO_SMALL);
            Message->Display("%s", fattypestr);
            return FALSE;

        } else if (cluster_size > 128 * sector_size) {
            Message->Set(MSG_FMT_VOL_TOO_BIG);
            Message->Display("%s", fattypestr);
            return FALSE;

        }

    }

    //
    // Check for volume limits.
    //
    //  If volume is > 32Gig, say we won't do FAT
    //  If cluster size is 64k warn about compatibility issues
    //

    if((sectors / ((1024 * 1024) / sector_size)) > (32 * 1024)) {
        Message->Set(MSG_FMT_VOL_TOO_BIG);
        Message->Display("%s", fattypestr);
        return FALSE;
    }

    if(cluster_size >= (64 * 1024)) {
        Message->Set(MSG_FMT_CLUSTER_SIZE_64K);
        Message->Display("");
        if (!Message->IsYesResponse(TRUE)) {
            return FALSE;
        }
    }

    //
    //  Compute the number of sectors per clusters.
    //

    _sector_zero.Bpb.SectorsPerCluster = (UCHAR) (cluster_size / sector_size);
    if (_ft == LARGE32) {
        _sector_zero.Bpb.SectorsPerFat = 0;
        _sector_zero.Bpb.BigSectorsPerFat = fat_size;
    } else {
        _sector_zero.Bpb.SectorsPerFat = (USHORT)fat_size;
        _sector_zero.Bpb.BigSectorsPerFat = 0;
    }

    if (_ft == SMALL) {
        memcpy(_sector_zero.SystemIdText, "FAT12   ", cSYSID);
    } else if (_ft == LARGE32) {
        memcpy(_sector_zero.SystemIdText, "FAT32   ", cSYSID);
    } else {
        memcpy(_sector_zero.SystemIdText, "FAT16   ", cSYSID);
    }

    memcpy(_sector_zero.Label, "NO NAME    ", cLABEL);

    _sector_zero.CurrentHead = 0;

    //
    //  Initialize the additional fields in the FAT32 boot
    //  sector.
    //

    if (_ft == LARGE32) {
        //
        // Recompute RootEntries, _sec_per_boot, and ReservedSectors
        // in case _ft changes
        //
        _sector_zero.Bpb.RootEntries = (USHORT)ComputeRootEntries();
        _sec_per_boot = max((32 * 512) / _drive->QuerySectorSize(), 32);
        _sector_zero.Bpb.ReservedSectors = (USHORT)_sec_per_boot;

        _sector_zero.Bpb.ExtFlags = 0;
        _sector_zero.Bpb.FS_Version = 0;
        _sector_zero.Bpb.RootDirStrtClus = 2;
        _sector_zero.Bpb.FSInfoSec = 1;
        _sector_zero.Bpb.BkUpBootSec = max(6, (USHORT)((6 * 512) / sector_size));

        DebugAssert(_AdditionalReservedSectors != MAXULONG);
        _sec_per_boot += _AdditionalReservedSectors;
        _sector_zero.Bpb.ReservedSectors = (USHORT)_sec_per_boot;
    }

#if DBG
    data_offset = ((BIG_INT)(fat_size*NUMBER_OF_FATS + _sec_per_boot))*sector_size +
                  (_sector_zero.Bpb.RootEntries*BytesPerDirent);
    DebugAssert (_drive->IsFloppy() ||
                 ((data_offset.GetLowPart() & (FAT_FIRST_DATA_CLUSTER_ALIGNMENT - 1)) == 0));
#endif

    return TRUE;

#endif // _SETUP_LOADER_
}

#if defined( _AUTOCHECK_ ) || defined( _EFICHECK_ )

#define LOCALE_STHOUSAND              0x0000000F   // thousand separator

typedef unsigned int        UINT;
typedef unsigned int        *PUINT;
typedef unsigned int        *LPUINT;

int
ChkGetLocaleInfoW(
    UINT     Locale,
    UINT     LCType,
    LPWSTR   lpLCData,
    int      cchData)
{
    //
    //  For AUTOCHK we do not do thousand seperators. The NLS APIs are not
    //  around, and the registry isn't really set up either so there is no standard
    //  language place available to determine what the thousand seperator is.
    //
    return 0;
}

UINT
ChkGetUserDefaultLCID(void)
{
    return 0;
}

#else
#define ChkGetLocaleInfoW   GetLocaleInfoW
#define ChkGetUserDefaultLCID   GetUserDefaultLCID
#endif


VOID
InsertSeparators(
    LPCWSTR OutWNumber,
    char * InANumber,
    ULONG  Width
    )
{
    WCHAR szSeparator[10];
    WCHAR Separator;
    LPWSTR lpWNumber;

    lpWNumber = (LPWSTR)OutWNumber;

    if (0 != ChkGetLocaleInfoW(
                   ChkGetUserDefaultLCID(),
                   LOCALE_STHOUSAND,
                   szSeparator,
                   10
                  ))
    {
        Separator = szSeparator[0];
    }
    else
    {
    Separator = L'\0';  // If we can't get the thousand separator, do not use one.
    }

    WCHAR Buffer[100];
    ULONG cchNumber = strlen((LPCSTR)InANumber);
    UINT Triples = 0;

    Buffer[99] = L'\0';
    PWCHAR pch = &Buffer[98];

    while (cchNumber > 0)
    {
    *pch-- = InANumber[--cchNumber];

        ++Triples;
    if ( (Separator != L'\0') && (0 == (Triples % 3)) && (cchNumber > 0) )
        {
            *pch-- = Separator;
        }
    }

    cchNumber = wcslen((pch + 1));
    if(cchNumber < Width) {
    UINT i;

    cchNumber = Width - cchNumber;
    for(i = 0; i < cchNumber; i++) {
        lpWNumber[i] = L' ';
    }
    } else {
    cchNumber = 0;
    }

    wcscpy(lpWNumber + cchNumber, pch + 1); // the Number buffer better be able to handle it!
}

#if 0
BOOLEAN
REAL_FAT_SA::Create(
    IN      PCNUMBER_SET    BadSectors,
    IN OUT  PMESSAGE        Message,
    IN      PCWSTRING       Label,
    IN      BOOLEAN         BackwardCompatible,
    IN      ULONG           ClusterSize,
    IN      ULONG           VirtualSize
    )
/*++

Routine Description:

    This routine initializes the FAT file system.

Arguments:

    BadSectors  - Supplies a list of the bad sectors on the volume.
    Message     - Supplies an outlet for messages.
    Label       - Supplies an optional label.

Return Value:

    FALSE   - Failure.
    TRUE    - Success.

Notes: FAT32 root directory uses the FILEDIR structure as
       opposed to the ROOTDIR structure used in FAT16/12.
--*/
{
#if defined( _SETUP_LOADER_ )

    return FALSE;

#else

    USHORT      sector_size;   // Number of bytes per sector, this is directly
                               // queried from the drive
    SECTORCOUNT sec_per_root;  // Number of sectors for the root directory
    CONT_MEM    cmem;          // This acts as a pointer to various
    PUSHORT     p;  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -