b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

在不同Windows平台下直接读写逻辑磁盘扇区

电脑杂谈  发布时间:2020-04-01 20:26:54  来源:网络整理

vc windows网络编程_vc++系列之windows服务器与网络编程_vc知识库 windows服务 vc

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

vc++系列之windows服务器与网络编程_vc windows网络编程_vc知识库 windows服务 vc

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; //缓冲区以保存读/写数据

vc++系列之windows服务器与网络编程_vc知识库 windows服务 vc_vc windows网络编程

} 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

vc知识库 windows服务 vc_vc++系列之windows服务器与网络编程_vc windows网络编程

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);

危险! !! !!不要这样! !! !!

五个,自适应磁盘读写类

vc windows网络编程_vc知识库 windows服务 vc_vc++系列之windows服务器与网络编程

从上面的示例可以看出,在不同的操作系统下,有多种读取和写入磁盘扇区的方法. 为了能够使用统一的方法在各种操作系统下读写磁盘扇区,我们设计了一个通用类. 此类的设计思想如下: 首先在各种操作系统下编写磁盘扇区访问函数,然后通过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

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      • 郑繻公姬骀
        郑繻公姬骀

        特别是以吉野舰为首的四艘新式巡洋舰组成的第一游击队

      • 师文丽
        师文丽

        光线赚的不少吧

      每日福利
      热点图片
      拼命载入中...