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

📄 rfatsa.cxx

📁 EFI(Extensible Firmware Interface)是下一代BIOS
💻 CXX
📖 第 1 页 / 共 5 页
字号:
        }

        //
        //  Compute and return the FAT size
        //

        *ClusterCount = clusters + FirstDiskCluster;
        return VALID;

    }

    DebugAbort("This line should never be executed.\n");
    return TOO_BIG;

}

ULONG
ComputeClusters(
    IN  ULONG        ClusterSize,
    IN  ULONG        Sectors,
    IN  ULONG        SectorSize,
    IN  ULONG        ReservedSectors,
    IN  ULONG        Fats,
    IN  FATTYPE      FatType
    )
/*++

Routine Description:

    This routine computes the number of clusters on a volume given
    the cluster size, volume size and the fat type.

Arguments:

    ClusterSize - Supplies the size of a cluster in number of bytes.

    Sectors - Supplies the total number of sectors in the volume.

    SectorSize - Supplies the size of a sector in number of bytes.

    ReservedSectors - Supplies the number of reserved sectors.

    Fats - Supplies the number of copies of fat for this volume.

    FatType - Supplies the fat type.

Return Value:

    ULONG - The total number of clusters for the given configuration.

++*/
{
    ULONG entries_per_sec; //  Number of FAT entries per sector.
    ULONG fat_entry_size;  //  Size of each FAT entry in number of BITS.
    ULONG sectors_left;    //  Number of sectors left for consideration.
    ULONG residue;         //  The residue number of bits per sector.
    ULONG acc_residue = 0; //  The accumulated residue number of FAT entry
                           //  bits.
    ULONG sec_per_clus;    //  Sectors per cluster.
    ULONG increment = 1;   //  Increment step size in number of FAT sectors.
    ULONG additional_clus; //  Number of additional clusters possible due to
                           //  the accumulated residue bits in the fat.
    ULONG clusters = 0;    //  Number of clusters in total.
    ULONG temp;            //  Temporary place-holder for optimizing certain
                           //  computations.

    sectors_left = Sectors - ReservedSectors;
    sec_per_clus = ClusterSize / SectorSize;

    //
    //  Determine the Fat entry size in number of bits based on the
    //  fat type.
    //

    switch (FatType) {
        case SMALL:
            fat_entry_size = 12;
            break;
        case LARGE16:
            fat_entry_size = 16;
            break;
        case LARGE32:
            fat_entry_size = 32;
            break;
    }

    //
    //  Compute the number of FAT entries a sector can hold.
    //    NOTE that fat_entry_size is the size in BITS,
    //    this is the reason for the "* 8" (bits per byte).
    //

    entries_per_sec = (SectorSize * 8) / fat_entry_size;

    //
    //  If the FAT entry size doesn't divide the sector
    //  size evenly, we want to know the residue.
    //

    residue = (SectorSize * 8) % fat_entry_size;

    //
    //  Compute a sensible increment step size to begin with.
    //

    while (Sectors / (increment * entries_per_sec * sec_per_clus) > 1) {
        increment *= 2;
    }

    //
    //  We have to handle the first sector of FAT entries
    //  separately because the first two entries are reserved.
    //

    temp = Fats + ((entries_per_sec - 2) * sec_per_clus);
    if (sectors_left < temp) {

        return (sectors_left - Fats) / sec_per_clus;

    } else {

        sectors_left -= temp;
        acc_residue += residue;
        clusters += entries_per_sec - 2;

        while (increment && sectors_left) {

            additional_clus = (acc_residue + (increment * residue)) / fat_entry_size;
            temp = (Fats + entries_per_sec * sec_per_clus) * increment + additional_clus * sec_per_clus;

            if (sectors_left < temp) {

                //
                //  If the increment step is only one, try to utilize the remaining sectors
                //  as much as possible.
                //

                if (increment == 1) {

                    //
                    // Exhaust the residue fat entries first
                    //

                    temp = acc_residue / fat_entry_size;
                    if (temp <= sectors_left / sec_per_clus) {

                        clusters += temp;
                        sectors_left -= temp * sec_per_clus;

                    } else {

                        clusters += sectors_left / sec_per_clus;
                        sectors_left -= sectors_left / sec_per_clus;

                    }

                    //
                    // Additional clusters may be possible after allocating
                    // one more sector of fat.
                    //
                    if ( sectors_left > Fats) {
                        temp = (sectors_left - Fats) / sec_per_clus;
                        if (temp > 0) {
                            clusters += temp;
                        }
                    }

                }

                //
                // Cut the increment step by half if it is too big.
                //

                increment /= 2;

            } else {

                if (additional_clus) {
                    acc_residue = (acc_residue + (increment * residue)) % (additional_clus * fat_entry_size);
                } else {
                    acc_residue += increment * residue;
                }
                sectors_left -= temp;
                clusters += increment * entries_per_sec + additional_clus;

            }

        }
        return clusters;
    }

    DebugAbort("This line should never be executed.");
    return 0;
}

ULONG
REAL_FAT_SA::ComputeDefaultClusterSize(
    IN  ULONG        Sectors,
    IN  ULONG        SectorSize,
    IN  ULONG        ReservedSectors,
    IN  ULONG        Fats,
    IN  MEDIA_TYPE   MediaType,
    IN  FATTYPE      FatType,
    OUT PULONG       FatSize,
    OUT PULONG       ClusterCount
    )
/*++

Routine Description:

    This routine computes a default cluster size given the total number
    of free sectors and fat type.

Arguments:

    Sectors - Supplies the total number of sectors on the volume.

    SectorSize - Supplies the size of a sector in bytes.

    ReservedSectors - Supplies the number of reserved sectors.

    Fats - Supplies the number of fats.

    MediaType - Supplies the media type.

    FatType - Supplies the fat type.

    FatSize - Supplies a location for this routine to pass back the
        size of a FAT in number of sectors back to the caller.

    ClusterCount - Supplies a location for this routine to pass back
        the total number of clusters on the volume.


Return Values:

    ULONG - The number of clusters that should on the volume computed
            by the default algorithm.

++*/
{
    ULONG             fat_size;      //  Number of sectors per fat.
    ULONG             sec_per_clus;  //  Number of sectors per cluster.
    VALIDATION_STATUS result;        //  Result after validating
                                     //  the cluster size.

    //
    //  Assign a reasonable value to sec_per_clus
    //  base on the number of sectors in total.
    //

    switch (FatType) {
        case LARGE32:
        //
        // The numbers in this may look a bit odd and arbitrary, they are.
        // They match the ones that MS-DOS/Win95 use for FAT32 drives, at least
        // for 512 byte sectors. NOTE than in the case of other sector sizes
        //
        if (Sectors >= 64*1024*1024) {    // >= 32GB
        sec_per_clus = 64;        //   32k cluster @ 512 byt/sec
        } else if (Sectors >= 32*1024*1024) { // >= 16GB
        sec_per_clus = 32;        //   16k cluster @ 512 byt/sec
        } else if (Sectors >= 16*1024*1024) { // >=  8GB
        sec_per_clus = 16;        //    8k cluster @ 512 byt/sec
        } else {                  // else
        sec_per_clus = 8;         //    4k cluster @ 512 byt/sec
        }
            break;

        case LARGE16:
            sec_per_clus = 1;
            break;

        case SMALL:
            sec_per_clus = 1;
            break;

        default:
            DebugAbort("This cannot happen.");
    }

    //
    //  If this is a floppy disk, we just choose a default value.
    //

    switch (MediaType) {

        case F5_320_512:
        case F5_360_512:
        case F3_720_512:
        case F3_2Pt88_512:
#if defined(FE_SB) && defined(_X86_)
        case F5_640_512:
        case F3_640_512:
        case F5_720_512:
#endif
            sec_per_clus = 2;
            break;

        case F3_20Pt8_512:
#if defined(FE_SB)
        case F3_128Mb_512:
#if defined(_X86_)
        case F8_256_128:
#endif
#endif
            sec_per_clus = 4;
            break;

#if defined(FE_SB)
        case F3_230Mb_512:
            sec_per_clus = 8;
            break;
#endif

        default:
            break;

    }

    //
    // Validate the assigned number of sectors per
    // cluster and readjust them if necessary.
    //

    result = ValidateClusterSize( sec_per_clus * SectorSize,
                                  Sectors,
                                  SectorSize,
                                  Fats,
                                  &_ft,
                                  &fat_size,
                                  ClusterCount);

    switch (result) {

        case TOO_SMALL:

            //
            //  If the cluster size is too small, keep enlarging
            //  it by a factor of 2 until it is valid.
            //

            do {
                sec_per_clus *= 2;
                if ( sec_per_clus > 128 ) {
                    return (sec_per_clus * SectorSize);
                }
            } while (ValidateClusterSize( sec_per_clus * SectorSize,
                                          Sectors,
                                          SectorSize,
                                          Fats,
                                          &_ft,
                                          &fat_size,
                                          ClusterCount) != VALID);

            break;

        case TOO_BIG:

            //
            //  If the cluster size is too big, keep reducing it
            //  by half until it is valid.
            //

            do {
                sec_per_clus /= 2;
                if ( sec_per_clus == 0 ) {
                    return (sec_per_clus * SectorSize);
                }
            } while (ValidateClusterSize( sec_per_clus * SectorSize,
                                          Sectors,
                                          SectorSize,
                                          Fats,
                                          &_ft,
                                          &fat_size,
                                          ClusterCount) != VALID);

            break;

        case VALID:
            break;
        default:
            DebugAbort("This should never happen.");
            break;
    }

    *FatSize = fat_size;
    return (sec_per_clus * SectorSize);

}


BOOLEAN
REAL_FAT_SA::SetBpb(
     )
{
   DebugAbort("This method should never be called.");
   return FALSE;
}

BOOLEAN
REAL_FAT_SA::SetBpb(
    IN  ULONG    ClusterSize,
    IN  BOOLEAN  BackwardCompatible,
    IN  PMESSAGE Message
    )
/*++

Routine Description:

    This routine sets up the BPB from scratch for the FAT file system.

Arguments:

    ClusterSize - Supplies the desired number of bytes per cluster.

    BackwardCompatible - Supplies whether the volume should remain
        FAT16/12 compatible.

    Message - Supplies an outlet for messages.

Return Value:

    FALSE   - Failure.
    TRUE    - Success.

--*/
{
#if defined( _SETUP_LOADER_ )

    return FALSE;

#else // _SETUP_LOADER_

    SECTORCOUNT sectors;          //  Total number of sectors.
    ULONG       sector_size;      //  Size of each sector in bytes.

⌨️ 快捷键说明

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