
I. 概述
在DOS操作系统下,通过BIOS的INT13,DOS的INT25(绝对读取),INT26(绝对写入),C等函数调用来读写磁盘的逻辑扇区或物理扇区非常方便. 语言也有与上述功能相对应的功能: biosdisk,absread,abswrite等. 但是,当在WINDOWS操作系统下编写WIN32应用程序时,上述中断调用或功能将无法再使用. 那么,是否可以在Windows操作系统下直接读写磁盘扇区?如何读写磁盘扇区?为了解决这些问题,在查阅了一些相关信息后,作者发现WINDOWS操作系统还提供了一种读写磁盘扇区的方法,但是在不同版本中存在不同的方式和使用限制. 最后,作者编写了一个磁盘扇区直接读写类. 我不敢一个人提供. 希望对大家有帮助.
注意: INT13在这里表示INT 13H,其他类似.
第二,读取软盘扇区的示例
WINDOWS操作系统实现所有存储设备的统一管理,并且出于安全原因,该操作系统不允许直接调用WIN32应用程序(在Ring3级别工作)中的中断函数,例如INT13,INT21,INT25,INT26等待. 但是它也提供了一些服务来弥补这一不足. 在WIN95 / 98中,VWIN32服务就是其中之一. VWIN32服务是通过VXD实现的. 它提供设备IO功能. 通过它,API函数DeviceIoControl可以用于实现WIN32应用程序和磁盘设备驱动程序之间的通信,从而实现磁盘访问. VWIN32提供的服务是一系列控制命令字. 它们在DOS操作系统下实现INT13,INT25,INT26和INT21之类的功能. 这是它定义的一些控制命令字:
VWIN32_DIOC_DOS_IOCTL(1)实现INT21功能
VWIN32_DIOC_DOS_INT25(2)实现INT25功能
VWIN32_DIOC_DOS_INT26(3)实现INT26功能
VWIN32_DIOC_DOS_INT13(4)实现INT13功能
VWIN32_DIOC_DOS_DRIVEINFO(6)实现INT21 730x功能
如果要读取和写入磁盘,只需使用DeviceIoControl执行相应的命令. 以下示例用于读取软盘的扇区(使用INT13):
步骤1: 打开VWIN32服务,HANDLE hDev = CreateFile(“ \\\\. \\ VWIN32”,0、0、0、0,FILE_FLAG_DELETE_ON_CLOSE,NULL);
第2步: 填充中断使用的相关寄存器. 寄存器在此处放置在一个结构中,并且结构定义如下(有关INT13使用的寄存器,请参阅相关信息):
typedef struct INT13Regs {
PVOID缓冲区; // ebx寄存器
BYTE驱动器; //磁盘编号dl
BYTE头; //头号dh
WORD EDX_High; // edx寄存器
BYTE部门; //开始扇区cl
BYTE曲目; //音轨编号ch
WORD ECX_High; //注册
BYTE号码;读写风扇编号al
BYTE CMD;顺序: 2读,3写,5格式ah
WORD EAX_High;注册
DWORD EDI; // edi注册
DWORD ESI; // esi
DWORD EFLAG; //标志
} INT13_REGISTERS;
无符号字符缓冲区[512]; //定义缓冲区并放置读取的扇区数据
INT13_REGISTERS reg = {0}; //定义寄存器结构变量
reg.buffer =(void *)缓冲区;
reg.Drive = 0; // 0张软盘1张软盘0 0x80硬盘c
reg.Head = 0;
reg.Track = 0;
reg.Sector = 1;
reg.Number = 1;
reg.CMD = 2;拿
第3步: 调用设备IO API函数DeviceIoControl执行命令号4(即VWIN32_DIOC_DOS_INT13),BOOL b_ret = DeviceIoControl(hDev,4和reg,sizeof(INT13_REGISTERS),&reg,sizeof(INT13_REGISTERS),&lpRet, 0);
如果返回值不为零,则调用成功,并进行进一步处理...否则调用失败.
第4步: 关闭服务CloseHandle(hDev);
三,限制或局限性
以上是使用INT13读取软盘扇区的完整过程. 它可以在WIN95 / 98下工作. 那么,可以将上述寄存器结构中的驱动器设置为0x80来读取逻辑硬盘C的扇区吗?答案是不. Windows中将忽略用于访问硬盘的INT13功能. 此外,尽管INT25和INT26可以访问硬盘,但是它们不能在FAT32格式的硬盘上工作. 以下列表将详细描述与磁盘操作有关的中断调用的限制(未指定,它是指WIN95 / 98操作系统):
中断功能限制和使用情况
INT13无法读取或写入硬盘,仅支持软盘
INT25 / INT26无法读取/写入FAT32硬盘,支持FAT12,FAT16
INT21(440DH-41H / 61H)不可用(文档说它支持FAT12,FAT16,FAT32,但实际上并未实现)
INT21(7305H)可以读写软盘和硬盘,支持FAT12,FAT16,FAT32,但需要WIN95OSR2和更高版本
值得一提的是,上表中的INT21--7305H功能是专门为支持FAT32而提供的,用于代替INT25 / INT26. 相应的控制命令字为6(即VWIN32_DIOC_DOS_DRIVEINFO). INT25,INT26和其他中断功能之间的显着区别是它不使用寄存器来传递参数(INT21--440DH-41H / 61H相似),但是使用了称为DISKIO的结构,并且寄存器EBX用于存储指针到结构的地址. DISKIO的定义如下:
typedef struct _DISKIO {
DWORD dwStartSector; //开始读取和写入的扇区号
WORD wSectors; //读取和写入的扇区数
DWORD dwBuffer; //缓冲区以保存读/写数据

} DISKIO,* PDISKIO;
此外,使用此功能时需要设置一些寄存器. 例如,ECX必须为-1,并且ESI用于指示读取和写入. 下面的示例使用此函数来实现上述示例功能,即读取软盘A的扇区. 首先为该示例定义一个新的寄存器结构:
typedef struct _DIOC_REGISTERS {
DWORD EBX;
DWORD EDX;
DWORD ECX;
DWORD EAX;
DWORD EDI;
DWORD ESI;
DWORD标志;
} DIOC_REGISTERS;
实际上,该结构与上面的INT13_REGISTERS相同,不同之处在于INT13_REGISTERS分解了寄存器并且更易读. 在步骤方面vc知识库 windows服务 vc,该示例与上述示例相同. 仅寄存器设置步骤的内容不同.
步骤1: 打开VWIN32服务.
第2步: 设置寄存器.
DIOC_REGISTERS reg = {0};
DISKIO dio;
无符号字符缓冲区[512];
参数结构
dio.dwStartSector = 0; //注意: 与上面的示例不同,它不是1,而是从0开始.
dio.wSectors = 1;
dio.dwBuffer =(DWORD)缓冲区;
设置寄存器
reg.EAX = 0x7305;可以类似于INT25,绝对读
reg.EBX =(DWORD)&dio; //参数结构的地址
reg ECX = -1; //必须为-1
reg.EDX = 1;含义: 与上面的示例不同,驱动器号已更改,0--默认1--A,2--B,3--C

reg.ESI = 0; bit0表示读写,0-读取,1-写入
在写入状态下,SI的位1-位12和位15必须为0,并且位13,位14和位15共同指示写入的数据类型. 有关详细信息,请参见下表:
15 14 13类型说明
0 0 0其他或未知.
0 0 1 FAT数据
0 1 0目录数据
0 1 1常规数据
1 x x保留. bit15必须为0
第3步: 调用API. BOOL b_ret = DeviceIoControl(hDev,6,&reg,sizeof(DIOC_REGISTERS),&reg,sizeof(DIOC_REGISTERS),&cb,0);
第4步: 关闭服务.
可以发现两种方法读取的数据完全相同.
在WIN2000中读写四个磁盘扇区
在WINNT和WIN2000中,磁盘被视为标准设备. 您可以使用CreateFile打开并像访问文件一样对其进行访问. CreateFile支持两种类型的磁盘设备-逻辑磁盘(格式为“ \\. \ C: ”)和物理磁盘(格式为“ \\. \ PHYSICALDRIVEx”,其中x为数字),例如,open A: 读取操作,就是这样:
HANDLE hDev = CreateFile(“ \\\\. \\ A: ”,GENERIC_READ,FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0);
如果获取的句柄有效,则可以使用ReadFile读取它,
ReadFile(hDev,Buffer,512和dwRet,0);
阅读后关闭手柄,
CloseHandle(hDev);
这比在WIN95 / 98下读取磁盘扇区方便得多.
此外,上面的示例处理逻辑磁盘,其中包括软盘驱动器,硬盘分区等. 物理磁盘是指实际的硬盘. 不在乎将硬盘分为几个区域. 硬盘号从0开始. “ \\. \ PHYSICALDRIVE0”表示第一个硬盘,依此类推. 您可能会立即记住,使用此机制,您可以访问硬盘分区表. 这是真的. 此时,可以操作硬盘的主引导扇区(一个包含分区表信息的独立扇区,该分区表信息与磁盘分区的BOOT区域不同).
无符号字符缓冲区[512] = {0};
HANDLE hDev = CreateFile(“ \\\\. \\ PHYSICALDRIVE0”,GENERIC_WRITE,FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0);
WriteFile(hDev,Buffer,512和dwRet,0);
CloseHandle(hDev);
危险! !! !!不要这样! !! !!
五个,自适应磁盘读写类

从上面的示例可以看出,在不同的操作系统下,有多种读取和写入磁盘扇区的方法. 为了能够使用统一的方法在各种操作系统下读写磁盘扇区,我们设计了一个通用类. 此类的设计思想如下: 首先在各种操作系统下编写磁盘扇区访问函数,然后通过GetVersionEx确定操作系统,然后选择相应的函数来读写磁盘扇区. 从以上分析可以看出,WINDOWS操作系统最不支持INT13,因此仅使用INT25,INT26,INT21--7305和其他中断调用来实现. 该类的定义如下:
CDiskInfo类{
公开
:
CDiskInfo();
〜CDiskInfo();
私人:
HANDLE hDev;
DWORD dwCurrentPlatform;
void GetPlatform();获取操作系统并将其保存到变量dwCurrentPlatform
BOOL Win2000_AccessSectors(WORD CMD,BYTE bDrive,DWORD dwStartSector,WORD wSectors,LPBYTE lpSectBuff); //用于WIN2000,WINNT等操作系统.
BOOL Int25_ReadSectors(BYTE bDrive,DWORD dwStartSector,WORD wSectors,LPBYTE lpSectBuff);
BOOL Int26_WriteSectors(BYTE bDrive,DWORD dwStartSector,WORD wSectors,LPBYTE lpSectBuff); //对于WIN95之前的操作系统
BOOL Int21_AccessSectors(WORD CMD,BYTE bDrive,DWORD dwStartSector,WORD wSectors,LPBYTE lpSectBuff); //用于WIN95OSR2,WIN98和其他操作系统的7305功能实现
公开
:
读写操作在外部统一提供,并根据平台在类中选择适当的函数调用
BOOL ReadSectors(BYTE bDrive,DWORD dwStartSector,WORD wSectors,LPBYTE lpSectBuff);
BOOL WriteSectors(BYTE bDrive,DWORD dwStartSector,WORD wSectors,LPBYTE lpSectBuff);
};
此类提供两个外部接口,即ReadSectors和WriteSectors. 参数相同,即要读取和写入的磁盘号bDrive,要访问磁盘的起始扇区号dwStartSector和要读取的扇区数. wSectors和缓冲区lpSectBuff用于读取和写入扇区数据. 此处,磁盘号从1开始,即1代表A: ,2代表B: ,3代表C :,依此类推. 扇区从0开始编号. 使用也非常简单,只需进行以下声明即可:
BYTE缓冲区[1024];
CDiskInfo A;
BOOL bRet = A.ReadSectors(1,0,2,缓冲区);
有关详细信息,请参阅随附的类文件和测试过程.
六条补充说明
严格来说,在对磁盘进行读写时,应遵循以下顺序: 打开设备(WIN95 / 98下为VWIN32服务,WIN2000下为磁盘设备),锁定该卷,验证该卷的有效性,进行读取/写入vc知识库 windows服务 vc,解锁音量,关闭设备. 为了简洁起见,忽略了锁定卷/解锁卷以及验证有效性的操作. 有兴趣的朋友可以自己添加.
此外,此类仅实现逻辑驱动器的读取和写入. 如果要读写物理硬盘的主引导扇区,还需要其他技术,例如thunk技术,即编写两个动态库,一种是WIN32动态库,一种是WIN16动态库(thunk技术). (只能通过动态库实现),其中WIN16动态库已转换为DPMI模式,并调用INT13(或扩展的INT13)来实现物理磁盘扇区的读写. 有关相关的thunk技术,请参阅相关文档.
(引自)
--------------------下一个---------------------
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-160428-1.html
光线赚的不少吧
特别是以吉野舰为首的四艘新式巡洋舰组成的第一游击队