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

📄 fatsachk.cxx

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

        // We need to re-initialize the fatsa object to include the whole
        // super area

        if (!Initialize(_drive, Message, TRUE)) {
            Message->Set(MSG_CHK_NO_MEMORY);
            Message->Display();
            *ExitStatus = CHKDSK_EXIT_COULD_NOT_CHK;
            _Verbose = FALSE;
            _pvfMessage = NULL;
            return FALSE;
        }

        if (!Read(Message)) {
            Message->Set(MSG_CHK_NO_MEMORY);
            Message->Display();
            *ExitStatus = CHKDSK_EXIT_COULD_NOT_CHK;
            _Verbose = FALSE;
            _pvfMessage = NULL;
            return FALSE;
        }

        // If the second bit of the dirty byte is set then
        // also perform a full recovery of the free and allocated
        // space.

        if (dirty_byte & FAT_BPB_RESERVED_TEST_SURFACE) {
            RecoverFree = TRUE;
            RecoverAlloc = TRUE;
        }
    }

    //
    // NOTE that this check must follow the above "if (OnlyIfDirty)" because in the
    //      OnlyIfDirty case only the first part of the FAT_SA object is in memory
    //      until the above if gets executed.
    //
    if (QueryLength() <= SecPerBoot()) {
        Message->Set(MSG_NOT_FAT);
        Message->Display();
        _Verbose = FALSE;
        _pvfMessage = NULL;
        return FALSE;
    }

    //
    // The volume is not clean, so if we're autochecking we want to
    // make sure that we're printing real messages on the console
    // instead of just dots.
    //

#if defined(_AUTOCHECK_)

    if (Message->SetDotsOnly(FALSE)) {

        Message->SetLoggingEnabled(FALSE);
        if (NULL != DriveLetter) {
            Message->Set(MSG_CHK_RUNNING);
            Message->Display("%W", DriveLetter);
        }

        Message->Set(MSG_FILE_SYSTEM_TYPE);
        Message->Display("%s", _ft == LARGE32 ? "FAT32" : "FAT");
        Message->SetLoggingEnabled();

    }

    if (Message->IsInAutoChk()) {

        ULONG   timeout;

        if (!VOL_LIODPDRV::QueryAutochkTimeOut(&timeout)) {
            timeout = AUTOCHK_TIMEOUT;
        }

        if (timeout > MAX_AUTOCHK_TIMEOUT_VALUE)
            timeout = AUTOCHK_TIMEOUT;

        if (timeout != 0) {
            if (dirty_byte & (FAT_BPB_RESERVED_DIRTY | FAT_BPB_RESERVED_TEST_SURFACE))
                Message->Set(MSG_CHK_AUTOCHK_SKIP_WARNING);
            else
                Message->Set(MSG_CHK_USER_AUTOCHK_SKIP_WARNING);
            Message->Display();
            if (Message->IsKeyPressed(MSG_CHK_ABORT_AUTOCHK, timeout)) {
                Message->SetLoggingEnabled(FALSE);
                Message->Set(MSG_CHK_AUTOCHK_ABORTED);
                Message->Display();
                *ExitStatus = CHKDSK_EXIT_SUCCESS;
                return TRUE;
            } else {
                Message->Set(MSG_CHK_AUTOCHK_RESUMED);
                Message->Display();
            }
        } else if ((dirty_byte & (FAT_BPB_RESERVED_DIRTY | FAT_BPB_RESERVED_TEST_SURFACE))) {
            Message->Set(MSG_CHK_VOLUME_IS_DIRTY);
            Message->Display();
        }
    } else {
        DebugAssert(Message->IsInSetup());
        if (dirty_byte & (FAT_BPB_RESERVED_DIRTY | FAT_BPB_RESERVED_TEST_SURFACE)) {
            Message->Set(MSG_CHK_VOLUME_IS_DIRTY);
            Message->Display();
        }
    }

#endif  // _AUTOCHECK_

    //
    // The BPB's Media Byte must be in the set accepted
    // by the file system.
    //
    media_byte = QueryMediaByte();

#if defined(FE_SB) && defined(_X86_)
    if ((media_byte != 0x00) &&  /* FMR */
        (media_byte != 0x01) &&  /* FMR */
        (media_byte != 0xf0) &&
#else
    if ((media_byte != 0xf0) &&
#endif
        (media_byte != 0xf8) &&
        (media_byte != 0xf9) &&
#if defined(FE_SB) && defined(_X86_)
        (media_byte != 0xfa) &&  /* FMR */
        (media_byte != 0xfb) &&  /* FMR */
#endif
        (media_byte != 0xfc) &&
        (media_byte != 0xfd) &&
        (media_byte != 0xfe) &&
        (media_byte != 0xff)) {

        SetMediaByte(_drive->QueryMediaByte());
    }

    // First print out the label and volume serial number.

    // We won't bother printing this message under autocheck.
#if !defined( _AUTOCHECK_ ) && !defined( _SETUP_LOADER_ ) && !defined( _EFICHECK_ )

    TIMEINFO        timeinfo;

    if ((QueryLabel(&label, &timeinfo) || label.Initialize("")) &&
        label.QueryChCount() &&
        timeinfo.QueryDate(&date) &&
        timeinfo.QueryTime(&time)) {

        Message->Set(MSG_VOLUME_LABEL_AND_DATE);
        Message->Display("%W%W%W", &label, &date, &time);
    }

#else
#if defined(_EFICHECK_)

    if (QueryLabel(&label) && label.QueryChCount() > 0) {
        Message->Set(MSG_VOLUME_LABEL_AND_DATE); // date is !!not!! displayed for EFI, since timeinfo is not implemented.
        Message->Display("%W", &label);
    }

#endif
#endif // !_AUTOCHECK_ && !_SETUP_LOADER_


    if (volid = QueryVolId()) {
        p = (PUSHORT) &volid;
        Message->Set(MSG_VOLUME_SERIAL_NUMBER);
        Message->Display("%04X%04X", p[1], p[0]);
    }

    // Validate the FAT.

    if (_dirF32 == NULL)
        _fat->Scrub(&changes);

    if (changes) {
        dofmsg(Message, &fmsg);
        Message->Set(MSG_CHK_ERRORS_IN_FAT);
        Message->Display();
    }


    //
    // Make sure that the media type in the BPB is the same as at
    // the beginning of the FAT.
    //

    if (QueryMediaByte() != _fat->QueryMediaByte()) {
#if defined(FE_SB) // MO & OEM FAT Support
        BOOLEAN bPrintError = TRUE;

#if defined(_X86_)
        if (IsPC98_N()) {

            // PC98 Nov.01.1994
            // to help the early NEC DOS

            if(_drive->QueryMediaType() == FixedMedia &&
                       QueryMediaByte() == 0xf8 && _fat->QueryMediaByte() == 0xfe) {

                bPrintError = FALSE;

            }
        }
#endif

        if (bPrintError == TRUE  &&
            (_drive->QueryMediaType() == F3_128Mb_512 ||
             _drive->QueryMediaType() == F3_230Mb_512   )) {

            // We won't to recognized as illegal in following case.
            //
            // Some OpticalDisk might have 0xf0 as media in BPB, but it also has 0xF8 in FAT.
            //

            if (QueryMediaByte() == 0xf0 && _fat->QueryMediaByte() == 0xf8) {

                bPrintError = FALSE;
            }
        }

        if( bPrintError ) {
#endif

            dofmsg(Message, &fmsg);
            Message->Set(MSG_PROBABLE_NON_DOS_DISK);
            Message->Display();
            if (!Message->IsYesResponse(FALSE)) {
                report.ExitStatus = CHKDSK_EXIT_SUCCESS;
                _Verbose = FALSE;
                _pvfMessage = NULL;
                return TRUE;
            }

#if defined(FE_SB) // REAL_FAT_SA::Create():Optical disk support
            //
            // Here is a table of Optical Disk (MO) format on OEM DOS.
            //
            //   128MB    |  NEC  |  IBM  | Fujitsu |
            // -----------+-------+-------+---------+
            // BPB.Media  | 0xF0  | 0xF0  | 0xF0    |
            // -----------+-------+-------+---------+
            // FAT.DiskID | 0xF0  | 0xF8  | 0xF8    |
            // -----------+-------+-------+---------+
            //
            //   230MB    |  NEC  |  IBM  | Fujitsu |
            // -----------+-------+-------+---------+
            // BPB.Media  | 0xF0  | 0xF0  | 0xF0    |
            // -----------+-------+-------+---------+
            // FAT.DiskID | 0xF8  | 0xF8  | 0xF8    |
            // -----------+-------+-------+---------+
            //
            // We will take NEC's way....

            if (_drive->QueryMediaType() == F3_230Mb_512) {

                DebugAssert(QueryMediaByte() == (UCHAR) 0xF0);

                _fat->SetEarlyEntries((UCHAR) 0xF8);
            } else {
                _fat->SetEarlyEntries(QueryMediaByte());
            }
        }
#else
        _fat->SetEarlyEntries(QueryMediaByte());
#endif
    }


    // Compute the cluster size and the number of clusters on disk.

    cluster_size = _drive->QuerySectorSize()*QuerySectorsPerCluster();
    cluster_count = QueryClusterCount();


    // No EAs have been detected yet.

    ea_infos = NULL;
    num_eas = 0;


    // Create an EA file name string.

    if (!eafilename.Initialize("EA DATA. SF") ||
        !eafilepath.Initialize("\\EA DATA. SF")) {
        _Verbose = FALSE;
        _pvfMessage = NULL;
        return FALSE;
    }


    //
    // This bitmap will be reinitialized before 'WalkDirectoryTree'.
    // Its contents will be ignored until then.
    //

    if (!fat_bitmap.Initialize(cluster_count)) {
        Message->Set(MSG_CHK_NO_MEMORY);
        Message->Display();
        _Verbose = FALSE;
        _pvfMessage = NULL;
        return FALSE;
    }

    // If there is an EA file on disk then...

    // FAT32 volume does not support EA.
    if (_dir != NULL && // <-- If this is not a FAT32 volume.
        eadent.Initialize(_dir->SearchForDirEntry(&eafilename), FAT_TYPE_EAS_OKAY)) {

        // Validate the EA file directory entry.

        if (!ValidateDirent(&eadent, &eafilepath, FixLevel, FALSE, Message,
                            &fmsg, &fat_bitmap, &tmp_bool, &tmp_ulong,
                            ExitStatus)) {
            _Verbose = FALSE;
            _pvfMessage = NULL;
            return FALSE;
        }


        // If the EA file directory entry was valid then...

        // FATDIR::SearchForDirEntry will not return an erased dirent, but whatever...
        if (!eadent.IsErased()) {

            // The EA file should not have an EA handle.
            if (eadent.QueryEaHandle()) {
                dofmsg(Message, &fmsg);
                Message->Set(MSG_CHK_EAFILE_HAS_HANDLE);
                Message->Display();
                eadent.SetEaHandle(0);
                *ExitStatus = CHKDSK_EXIT_ERRS_FIXED;
            }

            // Compute the EA file's starting cluster.
            ea_clus_num = eadent.QueryStartingCluster();

            //
            // Perform any log operations recorded at the beginning
            // of the EA file.
            //

            if (!PerformEaLogOperations(ea_clus_num, FixLevel,
                                        Message, &fmsg)) {
                _Verbose = FALSE;
                _pvfMessage = NULL;
                return FALSE;
            }

            //
            // Validate the EA file's EA sets and return an array of
            // information about them.
            //
            ea_infos = RecoverEaSets(ea_clus_num, &num_eas, FixLevel,
                                     Message, &fmsg);

            //
            // If there are no valid EAs in the EA file then erase
            // the EA file.
            //
            if (!ea_infos) {

                if (num_eas) {
                    _Verbose = FALSE;
                    _pvfMessage = NULL;
                    return FALSE;
                }

                eadent.SetErased();

                dofmsg(Message, &fmsg);
                Message->Set(MSG_CHK_EMPTY_EA_FILE);
                Message->Display();
                *ExitStatus = CHKDSK_EXIT_ERRS_FIXED;
            }
        }
    }


    // Initialize FAT bitmap to be used in detection of cross-links.

    if (!fat_bitmap.Initialize(cluster_count)) {
        Message->Set(MSG_CHK_NO_MEMORY);
        Message->Display();
        // DELETE(ea_infos);
        delete [] ea_infos; ea_infos = NULL;
        _Verbose = FALSE;
        _pvfMessage = NULL;
        return FALSE;
    }

    if (!CheckSectorHeapAllocation(FixLevel, Message, &fmsg)) {
        // DELETE(ea_infos);
        delete [] ea_infos; ea_infos = NULL;
        _Verbose = FALSE;
        _pvfMessage = NULL;
        return FALSE;
    }

    if (!VerifyFatExtensions(FixLevel, Message, &fmsg)) {
        // DELETE(ea_infos);
        delete [] ea_infos; ea_infos = NULL;
        _Verbose = FALSE;
        _pvfMessage = NULL;
        return FALSE;
    }


    //
    // Should probably add another function to perform the following task.
    //

    if (_dirF32 != NULL)  {

        if (!VerifyAndFixFat32RootDir( &fat_bitmap, Message, &report, &fmsg)) {
            _Verbose = FALSE;
            _pvfMessage = NULL;
            return FALSE;
        }

    }

    // Validate all of the files on the disk.
    save_num_eas = num_eas;

    if (!WalkDirectoryTree(ea_infos, &num_eas, &fat_bitmap, &report,
                           FixLevel, RecoverAlloc, Message, Verbose, &fmsg)) {
       // DELETE(ea_infos);
       delete [] ea_infos; ea_infos = NULL;
       _Verbose = FALSE;
       _pvfMessage = NULL;
       return FALSE;
    }

    if (save_num_eas != num_eas && ea_infos) {

        if (!EraseEaHandle(ea_infos, num_eas, save_num_eas, FixLevel, Message)) {
            _Verbose = FALSE;
            _pvfMessage = NULL;
            return FALSE;
        }

        if (!num_eas) {

            delete [] ea_infos;
            ea_infos = NULL;

            //
            // Note that the following two steps cause the EA file chain to get recovered
            //  as a lost cluster chain since all this does is erase the dirent, not the
            //  cluster chain.
            //
            eadent.SetErased();
            FreeSpaceInBitmap(eadent.QueryStartingCluster(), _fat,
                              &fat_bitmap);

            dofmsg(Message, &fmsg);
            Message->Set(MSG_CHK_EMPTY_EA_FILE);
            Message->Display();
            *ExitStatus = CHKDSK_EXIT_ERRS_FIXED;
        }
    }

    // If there are EAs on the disk then...

    if (ea_infos) {

⌨️ 快捷键说明

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