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

📄 fatsa.cxx

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

Routine Description:

    This routine computes the starting cluster number of the file described
    by 'FileName' by tracing through the directories leading to the file.

Arguments:

    FullPathFileName    - Supplies a full path file name that starts with
                            a '\' (i.e. no drive spec).

Return Value:

    The starting cluster for the file or 1 if the file is not found or
    0xFFFFFFFF if there was an error.

--*/
{
    CHNUM       i, j, l;
    DSTRING     component;
    ULONG       clus;
    FAT_DIRENT  the_dirent;
    PFILEDIR    filedir;
    PFAT_DIRENT dirent;
    HMEM        hmem;
    PFATDIR        _fat_dir;
    UCHAR        FatType;

    DebugAssert(_dir || _dirF32);

    if (_dir) {

        _fat_dir = _dir;
        FatType = FAT_TYPE_EAS_OKAY;

    } else {

        _fat_dir = _dirF32;
        FatType = FAT_TYPE_FAT32;
    }

    DebugAssert(_fat);

    filedir = NULL;

    if (!Hmem) {
        Hmem = &hmem;
    }

    if (DirEntry) {
        dirent = DirEntry;
    } else {
        dirent = &the_dirent;
    }

    l = FullPathFileName->QueryChCount();

    for (i = 0; i < l && FullPathFileName->QueryChAt(i) != '\\'; i++) {

        /* NOTHING */
    }

    if (i == l) {
        return 0xFFFFFFFF;
    }

    if (i == l - 1) { // root directory
        return 0;
    }

    j = ++i;
    for (; i < l && FullPathFileName->QueryChAt(i) != '\\'; i++) {
        /* NOTHING */
    }

    if (!component.Initialize(FullPathFileName, j, i - j) ||
        !component.Strupr()) {
        return 1;
    }

    if (!dirent->Initialize(_fat_dir->SearchForDirEntry(&component), FatType)) {
        return 1;
    }

    if (!(clus = dirent->QueryStartingCluster())) {
        return 0;
    }

    while (i < l) {

        if (!filedir &&
            !(filedir = NEW FILEDIR)) {
            return 0xFFFFFFFF;
        }

        if (!Hmem->Initialize() ||
            !filedir->Initialize(Hmem, _drive, this, _fat, clus)) {
            return 0xFFFFFFFF;
        }

        if (!filedir->Read()) {
            return 1;
        }

        j = ++i;
        for (; i < l && FullPathFileName->QueryChAt(i) != '\\'; i++) {
        }

        if (!component.Initialize(FullPathFileName, j, i - j) ||
            !component.Strupr()) {
            return 0xFFFFFFFF;
        }

        if (!dirent->Initialize(filedir->SearchForDirEntry(&component), FatType))
        {
            return 1;
        }

        if (!(clus = dirent->QueryStartingCluster())) {
            return 1;
        }
    }

    if (Directory) {
        if (filedir) {
            *Directory = filedir;
            if (DeleteDirectory) {
                *DeleteDirectory = TRUE;
            }
        } else {
            *Directory = _dir;
            if (DeleteDirectory) {
                *DeleteDirectory = FALSE;
            }
        }
    } else {
        DELETE(filedir);
    }

    return clus;
}


VOID
FAT_SA::Destroy(
    )
/*++

Routine Description:

    This routine cleans up the local data in the fat super area.

Arguments:

    None.

Return Value:

    None.

--*/
{
    DELETE(_fat);
    DELETE(_dir);
    DELETE(_dirF32);

}


FATTYPE
FAT_SA::ComputeFatType(
    ) CONST
/*++

Routine Description:

    Given the total number of clusters on the disk, this routine computes
    whether the FAT entries will be 12, 16, or 32 bits each.

Arguments:

    ClusterCount    - Supplies the number of clusters on the disk.

Return Value:

    SMALL   - A 12 bit FAT is required.
    LARGE16 - A 16 bit FAT is required.
    LARGE32 - A 32 bit FAT is required.

--*/
{
    PARTITION_SYSTEM_ID id;

    id = ComputeSystemId();

    if (id == SYSID_FAT12BIT) {
        return(SMALL);
    } else if (id == SYSID_FAT32BIT) {
        return(LARGE32);
    } else {
        return(LARGE16);
    }
}


PARTITION_SYSTEM_ID
FAT_SA::ComputeSystemId(
    ) CONST
/*++

Routine Description:

    This routine computes the system id for a FAT file system with
    the given number of sectors.

Arguments:

    None.

Return Value:

    The correct system id for this partition.

--*/
{
#if 1
    SECTORCOUNT           disk_size;

    switch (_drive->QueryMediaType()) {

        case F3_720_512:
        case F5_360_512:
        case F5_320_512:
        case F5_320_1024:
        case F5_180_512:
        case F5_160_512:
#if defined(FE_SB) && defined(_X86_)
        case F5_720_512:
        case F5_640_512:
        case F3_640_512:
        case F3_1Pt2_512:
        case F8_256_128:
        case F5_1Pt23_1024:
        case F3_1Pt23_1024:
#endif
        case F5_1Pt2_512:
        case F3_1Pt44_512:
        case F3_2Pt88_512:
        case F3_20Pt8_512:
            return SYSID_FAT12BIT;

        case F3_120M_512:
            return SYSID_FAT16BIT;
    }

    disk_size = QueryVirtualSectors();

    if (_ft == INVALID_FATTYPE ) {

        //
        // If the _ft member is not initialized,
        // use the sector count to determine the
        // partition class. Note that this method of
        // determining the partition class is not absolutely
        // fool-proof but this method works at least as good
        // as what we have in the past. The proper way of doing
        // the system id computation is to make sure that
        // the fat type is always computed before the
        // partition id and always uses the fat type and,
        // in some cases, the sector count to determine the
        // partition id.
        //
        if (disk_size < CSEC_FAT32BIT) {
            if ( disk_size < 65536 ) {
                return SYSID_FAT16BIT;
            } else {
                return SYSID_FAT32MEG;
            }
        } else {
            return SYSID_FAT32BIT;
        }

    } else {

        if (_ft == LARGE32 ) {
            return SYSID_FAT32BIT;
        } else {
            if ( disk_size < 65536 ) {
                return SYSID_FAT16BIT;
            } else {
                return SYSID_FAT32MEG;
            }
        }
    }

    if (_drive->IsSuperFloppy()) {
        return SYSID_FAT16BIT;    // just return something other than SYSID_NONE
    }

    return SYSID_NONE;

#else // FUTURE_CODE

    // BUGBUG for EFI we need to handle this differently

    return 0xEF;

#endif // FUTURE_CODE
}

#if !defined(_SETUP_LOADER_)

ULONG
FAT_SA::ComputeRootEntries(
    ) CONST
/*++

Routine Description:

    This routine uses the size of the disk and a standard table in
    order to compute the required number of root directory entries.

Arguments:

    None.

Return Value:

    The required number of root directory entries.

--*/
{
    switch (_drive->QueryMediaType()) {

        case F3_720_512:
        case F5_360_512:
        case F5_320_512:
        case F5_320_1024:
        case F5_180_512:
        case F5_160_512:
#if defined(FE_SB) && defined(_X86_)
        case F5_720_512:
        case F5_640_512:
        case F3_640_512:
#endif
            return 112;

        case F5_1Pt2_512:
        case F3_1Pt44_512:
#if defined(FE_SB) && defined(_X86_)
        case F3_1Pt2_512:
#endif
            return 224;

        case F3_2Pt88_512:
        case F3_20Pt8_512:
            return 240;

#if defined(FE_SB) && defined(_X86_)
        case F5_1Pt23_1024:
        case F3_1Pt23_1024:
             return 192;

        case F8_256_128:
            return 68;

        case RemovableMedia:
            return 512;
#endif
    }

    return 512;
}


USHORT
FAT_SA::ComputeSecClus(
    IN  SECTORCOUNT Sectors,
    IN  FATTYPE     FatType,
#if defined(FE_SB) && defined(_X86_)
    IN  MEDIA_TYPE  MediaType,
    IN  ULONG       SectorSize
#else
    IN  MEDIA_TYPE  MediaType
#endif
    )
/*++

Routine Description:

    This routine computes the number of sectors per cluster required
    based on the actual number of sectors.

Arguments:

    Sectors     - Supplies the total number of sectors on the disk.
    FatType     - Supplies the type of FAT.
    MediaType   - Supplies the type of the media.

Return Value:

    The required number of sectors per cluster.

--*/
{
    USHORT      sec_per_clus;
    SECTORCOUNT threshold;


    if (FatType == LARGE32) {

        if (Sectors >= 64*1024*1024) {
            sec_per_clus = 64;                  /* over 32GB -> 32K */
        } else if (Sectors >= 32*1024*1024) {
            sec_per_clus = 32;                  /* up to 32GB -> 16K */
        } else if (Sectors >= 16*1024*1024) {
            sec_per_clus = 16;                  /* up to 16GB -> 8K */
        } else {
            sec_per_clus = 8;                   /* up to 8GB -> 4K */
        }

        return sec_per_clus;
    }

    if (FatType == SMALL) {
        threshold = MIN_CLUS_BIG;
        sec_per_clus = 1;
    } else {
        threshold = MAX_CLUS_BIG;
        sec_per_clus = 1;
    }

    while (Sectors >= threshold) {
        sec_per_clus *= 2;
        threshold *= 2;
    }

    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;

    }

    return sec_per_clus;
}

#endif // _SETUP_LOADER_


BOOLEAN
FAT_SA::IsValidString(
    IN  PCWSTRING    String
    )
/*++

Routine Description:

    This routine determines whether or not the given null-terminated string
    has any invalid characters in it.

Arguments:

    String  - Supplies the string to validate.

Return Value:

    FALSE   - The string contains invalid characters.
    TRUE    - The string is free from invalid characters.

Notes:

    The list of invalid characters is stricter than HPFS requires.

--*/
{
    CHNUM   i, l;

    l = String->QueryChCount();

    for (i = 0; i < l; i++) {
        if (String->QueryChAt(i) < 32) {
            return FALSE;
        }

        switch (String->QueryChAt(i)) {
            case '*':
            case '?':
                case '/':
            case '\\':
                case '|':
                case ',':
                case ';':
                case ':':
                case '+':
                case '=':
            case '<':
            case '>':
                case '[':
                case ']':
            case '"':
            case '.':
                return FALSE;
        }
    }

    return TRUE;
}

⌨️ 快捷键说明

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