写个测试程序看看磁盘映像文件中哪个扇区可以使用?

本文介绍了一种通过检测U盘扇区使用情况,以避免Win7在插入U盘时提示“此U盘未格式化,是否现在格式化”的方法。通过使用测试程序和特定步骤,实验者可以确保在进行Bootloader实验时不触发格式化提示,提高实验效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在做boot loader的实验, 但是要在格式化为FAT32的U盘上使用.

 

* 用WinHex将U盘全部字节都填成0.

* 用UltraIso中的格式化功能, 将U盘格式化成FAT32, 分配单元为4KB

* 用UltraIso提供的写入MBR功能,向U盘写入可引导的MBR, 参数为USB-HDD.

这问题就来了,MBR在0扇区,我们可以通过逆向ultraIso写入的MBR, 重写MBR + U盘格式化好之后的分区表(16 * 4字节),形成自己的MBR.

但是其他被用到的扇区, 我们不能改。否则破坏了分区信息,U盘插入后,Win7提示"此U盘未格式化,是否现在格式化"。

一次两次还行,我们可以点击关掉这个提示。做实验时间长了,还真受不了这个提示.

解决的方法有2个:

* 研究分区表信息, 做成像老毛桃那样的自启动U盘. 但是我的目标仅仅是做boot loader实验, 现在的时间和能力都不允许这么搞

* 查找不用的扇区(全0的扇区),  在我们自己的MBR执行完成后,直接跳到我们自定义的的第一个扇区(也是没有被Windows分区判断使用的扇区), 由这个扇区来加载我们做实验的后续扇区到内存. 这个方法可操作性强,可以回避那个恼人的提示. 

到底能不能在做实验的U盘插入时,让Win7不弹出提示,我还没实验.

现在先写个测试程序找找到底那些扇区被用了, 被用到的扇区数量,用WinHex手工查看,数量还是比较少的。

怕看的眼花,用测试程序来找.

测试程序下载点: src_find_used_sectors.zip

效果图:

工程预览:

/// @file find_used_sectors.cpp
/// @brief 找出没有被FAT32文件系统使用扇区, 用来做boot loader实验
/// 防止U盘做实验后, 插入U盘,被Win7提示 "此U盘没有格式化, 是否现在格式化"
/// 每次插入U盘, 都被提示信息,很烦人

#include "stdafx.h"

/// 先用WinHex将U盘全部填0
/// 在U盘在UltraIos中格式化U盘, 参数: FAT32, 4KB
/// 写入MBR, 参数: USB-HDD
/// 用WinHex将U盘内容全部拷贝到文件
/// 用这个测试程序找到那些扇区被用了(有非0的字节)
/// 我们做U盘实验时, 就可以确定在哪个扇区写东西,不会让Win7弹出"U盘无效"提示
#define OBJ_FILE_TO_PARSE L"D:\\uDiskBk\\uDisk_format_ok_write_mbr_by_ultra_iso.bin"

#define SECTOR_SIZE 512

BOOL FindAndShowNoZeroContentSectorsIndex(HANDLE& hFile, LONGLONG llFileSize); ///< 查找显示有非零内容的扇区
BOOL JudgeSectorWasUsed(BYTE* pcSectorBegin, int iLenSector);

int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE hFile = INVALID_HANDLE_VALUE;
    LONGLONG llFileSize = 0;

    do 
    {
        if (!ns_base::IsFileExist(OBJ_FILE_TO_PARSE))
        {
            _tprintf(L"File not exist[%s]\r\n", OBJ_FILE_TO_PARSE);
            break;
        }

        llFileSize = ns_base::GetFileSize(OBJ_FILE_TO_PARSE);
        if (llFileSize < 0)
        {
            _tprintf(L"File size [0x%I64x] invalid\r\n", llFileSize);
            break;
        }

        if (0 != (llFileSize % 512))
        {
            _tprintf(L"File can't mod by sector size(512 bytes\r\n");
        }

        if (!ns_base::OpenFileReadBinary(OBJ_FILE_TO_PARSE, hFile))
            break;

        if (!FindAndShowNoZeroContentSectorsIndex(hFile, llFileSize))
        {
            _tprintf(L"FALSE FindAndShowNoZeroContentSectorsIndex()\r\n");
        }

        SAFE_CLOSE_HANDLE(hFile);
    } while (0);

    _tprintf(L"END, press any key to quit\r\n");

#ifdef _DEBUG
    getwchar();
#endif
    getwchar();
	return 0;
}

BOOL FindAndShowNoZeroContentSectorsIndex(HANDLE& hFile, LONGLONG llFileSize)
{
    BOOL bRc = FALSE;
    BYTE cBufRd[SECTOR_SIZE];
    DWORD dwRdBack = 0;
    long lSectorIndexCur = 0;
    long lSectorWasUsed = 0;
    LONGLONG llFileSizeRd = 0;

    LONGLONG llPosBegin = 0;
    LONGLONG llPosEnd = 0;

    do 
    {
        if (INVALID_SET_FILE_POINTER == SetFilePointer(hFile, 0, 0, FILE_BEGIN))
            break;

        do 
        {
            ::ZeroMemory(cBufRd, sizeof(cBufRd)); ///< !

            if (!::ReadFile(hFile, &cBufRd, sizeof(cBufRd), &dwRdBack, NULL))
                break;

            if (dwRdBack != sizeof(cBufRd))
                break;

            if (JudgeSectorWasUsed(cBufRd, sizeof(cBufRd)))
            {
                lSectorWasUsed++;
                llPosBegin = (LONGLONG)lSectorIndexCur * SECTOR_SIZE;
                llPosEnd = llPosBegin + sizeof(cBufRd) - 1;

                _tprintf(L"Sector[0x%.8I64x-0x%.8I64x] sector index[%ld] was used\r\n", 
                    llPosBegin,
                    llPosEnd,
                    lSectorIndexCur);
            }

            llFileSizeRd += dwRdBack;
            if (llFileSizeRd == llFileSize)
            {
                bRc = TRUE;
                break;
            }

            lSectorIndexCur++;
        } while (1);
    } while (0);

    if (bRc)
    {
        _tprintf(L"lSectorWasUsed = %ld\r\n", lSectorWasUsed);
    }

    return bRc;
}

BOOL JudgeSectorWasUsed(BYTE* pcSectorBegin, int iLenSector)
{
    BOOL bRc = FALSE;
    int iIndex = 0;

    do 
    {
        if ((NULL == pcSectorBegin) 
            || (SECTOR_SIZE != iLenSector))
        {
            break;
        }

        for (iIndex = 0; iIndex < SECTOR_SIZE; iIndex++)
        {
            if (0 != *(pcSectorBegin + iIndex))
            {
                bRc = TRUE;
                break;
            }
        }
    } while (0);

    return bRc;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值