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

📄 rfatsa.cxx

📁 EFI(Extensible Firmware Interface)是下一代BIOS
💻 CXX
📖 第 1 页 / 共 5 页
字号:
                                    //  super area SECRUN buffer.
        ULONG       root_size;      //  Size of the root directory in number of sectors.
        ULONG       sector_size;    //  Well, it's kind of obvious isn't it.

        sector_size = _drive->QuerySectorSize();

        if (!(_dir = NEW ROOTDIR)) {

            Destroy();
            Message->Set(MSG_FMT_NO_MEMORY);
            Message->Display("");
            return FALSE;

        } else {

            ULONG   root_offset;    //  Sector offset of the root directory from the
                                    //  beginning of the disk.

            //
            //  Computes the sector offset of the root directory.
            //

            root_offset = _sector_zero.Bpb.ReservedSectors +
                          _sector_zero.Bpb.SectorsPerFat *
                          _sector_zero.Bpb.Fats;

            //
            //  Size of the root directory in number of bytes. Note that the
            //  result is rounded up to the nearest size size.
            //

            root_size = ((_sector_zero.Bpb.RootEntries * BytesPerDirent - 1)
                         / sector_size + 1) * sector_size;

            //
            //  Now it's time to initialize the root directory. Note that this operation
            //  shouldn't fail because REAL_FAT_SA::Initialize should have allocated
            //  enough memory for the root directory through REAL_FAT_SA::DosSaInit.
            //

            if(!cmem.Initialize((PCHAR) SECRUN::GetBuf() + (root_offset * sector_size), root_size) ||
               !_dir->Initialize(&cmem, _drive, root_offset, _sector_zero.Bpb.RootEntries)) {
                DebugPrintTrace(("The secrun buffer should have enough space, big bug in code.\n"));
        Message->Set(MSG_FMT_NO_MEMORY);
        Message->Display("");
        Destroy();
                return FALSE;
            }
        }
    }

    return TRUE;

}



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

Routine Description:

    This routine updates fields in sector 0.

Arguments:

    ClusterSize - Supplies the desired number of bytes per cluster.
    BackwardCompatible - Supplies whether the volume should be
                         compatible with FAT16.
    Message - Supplies an outlet for messages.

Return Value:

    TRUE  -   Success.
    FALSE -   Failure.

--*/
{
#if defined _SETUP_LOADER_

    return FALSE;

#else

    SetVolId(ComputeVolId());

    return SetBpb(ClusterSize, BackwardCompatible, Message) &&
           SetBootCode() &&
           SetPhysicalDriveType(_drive->IsRemovable() ?
                                PHYS_REMOVABLE : PHYS_FIXED) &&
           SetOemData() &&
           SetSignature();

#endif // _SETUP_LOADER_
}

VALIDATION_STATUS
REAL_FAT_SA::ValidateClusterSize(
    IN     ULONG    ClusterSize,
    IN     ULONG    Sectors,
    IN     ULONG    SectorSize,
    IN     ULONG    Fats,
    IN OUT FATTYPE  *FatType,
    OUT    PULONG   FatSize,
    OUT    PULONG   ClusterCount
    )
/*++

Routine Description:

   This routine validates whether a given cluster size is
valid for a particular FAT type. If the fat type provided is
INVALID_FATTYPE, this routine would determine whether FAT12 or
FAT16 should be used.

Arguments:

    ClusterSize - Supplies the cluster size to be validated.

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

    SectorSize - Supplies the number of bytes per sector.

    Fats - Supplies the number of FATs in the volume.

    FatType - Supplies the FAT type that the volume is going to be
        formatted. The caller will supply INVALID_FATTYPE if
        it is unsure whether the volume should be formatted
        as a FAT16 volume or a FAT12 volume and let this function
        to make the descision.

    FatSize - Supplies a location where the size of a fat in number
        of sectors can be passed back to the caller if the
        cluster size is valid.

    ClusterCounter - Supplies a location where the total number
        of clusters can be passed back to the caller if the
        given cluster size is valid.

Return Values:

   VALIDATION_STATUS

   VALID     - The given cluster size is valid.
   TOO_SMALL - The given cluster size is too small (Too many clusters).
   TOO_BIG   - The given cluster size is too big. (Too few clusters).

++*/
{
    ULONG   min_sec_req;    //  Minimum number of sectors required.
    ULONG   min_fat_size;   //  Minimum size of the FATs in number
                            //  of sectors.
    ULONG   fat_entry_size; //  Number of bytes per fat entry.
    ULONG   sec_per_clus;   //  Number of sectors per cluster.
    ULONG   clusters;       //  Number of clusters.
    FATTYPE fat_type;       //  Local fat type.

    ULONG   initial_data_sector_offset;
    ULONG   data_sector_offset;
    ULONG   pad;            // Padding to be added to the reserved sectors
                            // for data alignment

    DebugAssert(ClusterSize);

    //
    // Check for absolute minumum (one sector per cluster)
    //

    if (ClusterSize < SectorSize) {
        return TOO_SMALL;
    }

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

    sec_per_clus = ClusterSize / SectorSize;

    //
    //  Make sure that sec_per_clus <= 128
    //

    if (sec_per_clus > 128) {
        return TOO_BIG;
    }

    fat_type = *FatType;
    if (fat_type == INVALID_FATTYPE) {

        //  If the caller doesn't specify the fat type,
        //  try FAT16 first unless the volume is > 2Gig bytes
        //  in size (512 byte sectors only).

        if((SectorSize == 512) && (Sectors > (4 * 1024 * 1024))) {
            fat_type = LARGE32;
        } else {
            fat_type = LARGE16;
        }
    }

    //
    //  Compute the minimum number of sectors required by the
    //  FAT(s)
    //  The minimum number of sectors that the fats on a volume will
    //  occupy is given by: RoundUp(Number of fats * (minimum number of
    //  clusters + 2) * bytes per fat entry / sector size).
    //

    if (fat_type == LARGE32) {

        fat_entry_size = 4;
        min_fat_size = RoundUpDiv( Fats * (MIN_CLUS_BIG32 + 2) * fat_entry_size,
                                   SectorSize);
        min_sec_req = min_fat_size + MIN_CLUS_BIG32 * sec_per_clus;

        if (Sectors > min_sec_req) { // Meets the minimum requirement

            //
            //  Compute the number of clusters
            //

            initial_data_sector_offset = max(32, _sec_per_boot);

            for (pad=0; ; pad++) {

                data_sector_offset = initial_data_sector_offset + pad;

                clusters = ComputeClusters( ClusterSize,
                                            Sectors,
                                            SectorSize,
                                            data_sector_offset,
                                            Fats,
                                            fat_type);

                *FatSize = RoundUpDiv((clusters+2) * fat_entry_size , SectorSize);

                data_sector_offset += (*FatSize * Fats);

                if (_drive->IsFloppy() ||
                    ((((BIG_INT)data_sector_offset*SectorSize).GetLowPart() &
                      (FAT_FIRST_DATA_CLUSTER_ALIGNMENT-1)) == 0)) {
                    _AdditionalReservedSectors = pad;
                    break;
                }
            }

            //
            //  Check to see if the cluster size is too small
            //

            if ( clusters > MAX_CLUS_BIG32 ) {
                return TOO_SMALL;
            }

            //
            //  See if this cluster size makes the FAT too big. Win95's FAT32
            //  support does not support FATs > 16Meg - 64k bytes in size because
            //  the GUI version of SCANDISK is a 16-bit windows application that
            //  has this limit on its allocation block size. This value is also
            //  a quite reasonable lid on FAT size.
            //

            if ((clusters * 4) > ((16 * 1024 * 1024) - (64 * 1024))) {
                return TOO_SMALL;
            }

            //
            //  Return the fat type if the caller
            //  doesn't specify it.
            //

            if (*FatType == INVALID_FATTYPE) {
                *FatType = LARGE32;
            }

            //
            //  Compute the fat size and return it to the caller
            //

            *ClusterCount = clusters + FirstDiskCluster;
            return VALID;
        }

        // Volume is too small for FAT32
        return TOO_BIG;

    }

    //
    //  The code in this function may look a bit asymmetrical
    //  but that's because we treat FAT32 separately from
    //  FAT16/12.
    //

    if (fat_type == LARGE16) {

        //
        //  Again, we compute the minimum number of sectors required if the
        //  if the volume is formatted as a FAT16 volume.
        //

        fat_entry_size = 2;
        min_fat_size = RoundUpDiv( Fats * (MIN_CLUS_BIG + 2) * fat_entry_size, SectorSize);
        min_sec_req = min_fat_size + MIN_CLUS_BIG * sec_per_clus;

        if (Sectors > min_sec_req) { // Meets the minimum requirement

            //
            //  Compute the number of clusters
            //

            initial_data_sector_offset = _sec_per_boot +
                                         (_sector_zero.Bpb.RootEntries * BytesPerDirent - 1) /
                                         SectorSize + 1;

            for (pad=0; ; pad++) {

                data_sector_offset = initial_data_sector_offset + pad;

                clusters = ComputeClusters( ClusterSize,
                                            Sectors,
                                            SectorSize,
                                            data_sector_offset,
                                            Fats,
                                            fat_type );

                *FatSize = RoundUpDiv((clusters + 2) * fat_entry_size, SectorSize);

                data_sector_offset += (*FatSize * Fats);

                if (_drive->IsFloppy() ||
                    ((((BIG_INT)data_sector_offset*SectorSize).GetLowPart() &
                      (FAT_FIRST_DATA_CLUSTER_ALIGNMENT-1)) == 0)) {
                    _AdditionalReservedSectors = pad;
                    break;
                }
            }

            if (clusters > MAX_CLUS_BIG) {

                return TOO_SMALL;

            } else {

                //
                //  Return the fat type if the caller
                //  doesn't specify it.
                //

                if (*FatType == INVALID_FATTYPE) {
                    *FatType = LARGE16;
                }

                //
                //  Compute and return the fat size to the caller.
                //

                *ClusterCount = clusters + FirstDiskCluster;
                return VALID;

            }

        } else {

            //
            //  Don't bother to fall over to the FAT12 section if the
            //  volume has more that 32679 sectors.
            //

            if (*FatType == INVALID_FATTYPE && Sectors < CSEC_FAT16BIT ) {

                //
                //  Fall over to the FAT12 section
                //

                fat_type = SMALL;

            } else {

                return TOO_BIG;

            }

        }

    }

    //
    //  A volume is never too small for FAT12 so we just
    //  check whether it is too big.
    //

    if (fat_type == SMALL) {

        initial_data_sector_offset = _sec_per_boot +
                                     (_sector_zero.Bpb.RootEntries * BytesPerDirent - 1) /
                                     SectorSize + 1;

        for (pad=0; ; pad++) {

            data_sector_offset = initial_data_sector_offset + pad;

            clusters = ComputeClusters( ClusterSize,
                                        Sectors,
                                        SectorSize,
                                        data_sector_offset,
                                        Fats,
                                        fat_type );

            *FatSize = RoundUpDiv(RoundUpDiv((clusters + 2) * 3, 2), SectorSize);

            data_sector_offset += (*FatSize * Fats);

            if (_drive->IsFloppy() ||
                ((((BIG_INT)data_sector_offset*SectorSize).GetLowPart() &
                  (FAT_FIRST_DATA_CLUSTER_ALIGNMENT-1)) == 0)) {
                _AdditionalReservedSectors = pad;
                break;
            }
        }

        if (clusters > MAX_CLUS_SMALL) {
            return TOO_SMALL;
        }

        //
        //  Return fat type to caller if necessary
        //

        if (*FatType == INVALID_FATTYPE) {
            *FatType = SMALL;

⌨️ 快捷键说明

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