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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了写个测试程序看看磁盘映像文件中哪个扇区可以使用?相关的知识,希望对你有一定的参考价值。

在做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

效果图:

技术分享

工程预览:

 

[cpp] view plaincopy
 
  1. /// @file find_used_sectors.cpp  
  2. /// @brief 找出没有被FAT32文件系统使用扇区, 用来做boot loader实验  
  3. /// 防止U盘做实验后, 插入U盘,被Win7提示 "此U盘没有格式化, 是否现在格式化"  
  4. /// 每次插入U盘, 都被提示信息,很烦人  
  5.   
  6. #include "stdafx.h"  
  7.   
  8. /// 先用WinHex将U盘全部填0  
  9. /// 在U盘在Ultraios中格式化U盘, 参数: FAT32, 4KB  
  10. /// 写入MBR, 参数: USB-HDD  
  11. /// 用WinHex将U盘内容全部拷贝到文件  
  12. /// 用这个测试程序找到那些扇区被用了(有非0的字节)  
  13. /// 我们做U盘实验时, 就可以确定在哪个扇区写东西,不会让Win7弹出"U盘无效"提示  
  14. #define OBJ_FILE_TO_PARSE L"D:\\uDiskBk\\uDisk_format_ok_write_mbr_by_ultra_iso.bin"  
  15.   
  16. #define SECTOR_SIZE 512  
  17.   
  18. BOOL FindAndShowNoZeroContentSectorsIndex(HANDLE& hFile, LONGLONG llFileSize); ///< 查找显示有非零内容的扇区  
  19. BOOL JudgeSectorWasUsed(BYTE* pcSectorBegin, int iLenSector);  
  20.   
  21. int _tmain(int argc, _TCHAR* argv[])  
  22. {  
  23.     HANDLE hFile = INVALID_HANDLE_VALUE;  
  24.     LONGLONG llFileSize = 0;  
  25.   
  26.     do   
  27.     {  
  28.         if (!ns_base::IsFileExist(OBJ_FILE_TO_PARSE))  
  29.         {  
  30.             _tprintf(L"File not exist[%s]\r\n", OBJ_FILE_TO_PARSE);  
  31.             break;  
  32.         }  
  33.   
  34.         llFileSize = ns_base::GetFileSize(OBJ_FILE_TO_PARSE);  
  35.         if (llFileSize < 0)  
  36.         {  
  37.             _tprintf(L"File size [0x%I64x] invalid\r\n", llFileSize);  
  38.             break;  
  39.         }  
  40.   
  41.         if (0 != (llFileSize % 512))  
  42.         {  
  43.             _tprintf(L"File can‘t mod by sector size(512 bytes\r\n");  
  44.         }  
  45.   
  46.         if (!ns_base::OpenFileReadBinary(OBJ_FILE_TO_PARSE, hFile))  
  47.             break;  
  48.   
  49.         if (!FindAndShowNoZeroContentSectorsIndex(hFile, llFileSize))  
  50.         {  
  51.             _tprintf(L"FALSE FindAndShowNoZeroContentSectorsIndex()\r\n");  
  52.         }  
  53.   
  54.         SAFE_CLOSE_HANDLE(hFile);  
  55.     } while (0);  
  56.   
  57.     _tprintf(L"END, press any key to quit\r\n");  
  58.   
  59. #ifdef _DEBUG  
  60.     getwchar();  
  61. #endif  
  62.     getwchar();  
  63.     return 0;  
  64. }  
  65.   
  66. BOOL FindAndShowNoZeroContentSectorsIndex(HANDLE& hFile, LONGLONG llFileSize)  
  67. {  
  68.     BOOL bRc = FALSE;  
  69.     BYTE cBufRd[SECTOR_SIZE];  
  70.     DWORD dwRdBack = 0;  
  71.     long lSectorIndexCur = 0;  
  72.     long lSectorWasUsed = 0;  
  73.     LONGLONG llFileSizeRd = 0;  
  74.   
  75.     LONGLONG llPosBegin = 0;  
  76.     LONGLONG llPosEnd = 0;  
  77.   
  78.     do   
  79.     {  
  80.         if (INVALID_SET_FILE_POINTER == SetFilePointer(hFile, 0, 0, FILE_BEGIN))  
  81.             break;  
  82.   
  83.         do   
  84.         {  
  85.             ::ZeroMemory(cBufRd, sizeof(cBufRd)); ///< !  
  86.   
  87.             if (!::ReadFile(hFile, &cBufRd, sizeof(cBufRd), &dwRdBack, NULL))  
  88.                 break;  
  89.   
  90.             if (dwRdBack != sizeof(cBufRd))  
  91.                 break;  
  92.   
  93.             if (JudgeSectorWasUsed(cBufRd, sizeof(cBufRd)))  
  94.             {  
  95.                 lSectorWasUsed++;  
  96.                 llPosBegin = (LONGLONG)lSectorIndexCur * SECTOR_SIZE;  
  97.                 llPosEnd = llPosBegin + sizeof(cBufRd) - 1;  
  98.   
  99.                 _tprintf(L"Sector[0x%.8I64x-0x%.8I64x] sector index[%ld] was used\r\n",   
  100.                     llPosBegin,  
  101.                     llPosEnd,  
  102.                     lSectorIndexCur);  
  103.             }  
  104.   
  105.             llFileSizeRd += dwRdBack;  
  106.             if (llFileSizeRd == llFileSize)  
  107.             {  
  108.                 bRc = TRUE;  
  109.                 break;  
  110.             }  
  111.   
  112.             lSectorIndexCur++;  
  113.         } while (1);  
  114.     } while (0);  
  115.   
  116.     if (bRc)  
  117.     {  
  118.         _tprintf(L"lSectorWasUsed = %ld\r\n", lSectorWasUsed);  
  119.     }  
  120.   
  121.     return bRc;  
  122. }  
  123.   
  124. BOOL JudgeSectorWasUsed(BYTE* pcSectorBegin, int iLenSector)  
  125. {  
  126.     BOOL bRc = FALSE;  
  127.     int iIndex = 0;  
  128.   
  129.     do   
  130.     {  
  131.         if ((NULL == pcSectorBegin)   
  132.             || (SECTOR_SIZE != iLenSector))  
  133.         {  
  134.             break;  
  135.         }  
  136.   
  137.         for (iIndex = 0; iIndex < SECTOR_SIZE; iIndex++)  
  138.         {  
  139.             if (0 != *(pcSectorBegin + iIndex))  
  140.             {  
  141.                 bRc = TRUE;  
  142.                 break;  
  143.             }  
  144.         }  
  145.     } while (0);  
  146.   
  147.     return bRc;  
  148. }  

http://blog.csdn.net/lostspeed/article/details/48804455

http://download.csdn.net/detail/lostspeed/9146699

 

以上是关于写个测试程序看看磁盘映像文件中哪个扇区可以使用?的主要内容,如果未能解决你的问题,请参考以下文章

linux和windwos下的磁盘扇区数据查看

linux和windwos下的磁盘扇区数据查看

怎么删除c盘里的硬盘映像文件啊?

[Win32] 直接读写磁盘扇区(磁盘绝对读写)

怎么删除自建的磁盘映像里的文件

光盘映像文件怎么安装