第11章
进行备份
为什么要备份?
“预防胜于治疗”。进行备份也是预防数据灾难的重要组成部分,这可以帮助我们克服磁盘崩溃或任何其他类型的数据丢失。在本章中,我们将讨论如何在一些严重的磁盘崩溃后恢复数据,仅在之前进行的备份的帮助下。
以前存储的备份完成的恢复几乎总是高达 100%,但是在某些特定情况下,几种类型的磁盘崩溃可能会导致恢复结果的变化。
在备份的帮助下恢复数据非常简单、快速和可靠,并且可以提供最佳结果,而没有备份的数据恢复是一个困难、复杂的过程,可能需要很多时间,即使这样我们也担心在某些情况下无法获得 100% 的数据。
备份的时间和内容
磁盘上有几个不同的区域应该备份一次或以不同的时间间隔备份。下表给出了完整备份措施的概念,并有助于找出备份的时间和内容:
备份什么 |
何时备份 |
MBR的备份 |
在 FDISK 之后一次。 MBR 是由 DOS 的 FDISK 命令创建的。您可以在 FDISK 之后备份 MBR,但是即使在 FDISK 创建的分区格式化之后,MBR 仍然保持不变。 |
DBR 的备份 |
在 FORMAT 之后为每个逻辑驱动器备份一次 DBR。 |
FAT 和目录条目的备份。 |
每次创建删除文件或目录时,FAT 和目录条目都会更改。因此建议您每天进行备份。 |
用户数据备份 |
应定期服用。这种类型的备份会导致磁盘映像发生。然而,大多数磁盘中有非常敏感数据的公司都喜欢花时间在磁盘映像上,因为这样做他们可以备份上述所有信息。 |
除此之外,您还应该为系统制作一张紧急启动软盘。如果硬盘中的数据发生任何类型的灾难,您可以借助此软盘启动系统并分析磁盘是否有错误。
MBR(主引导记录)的备份及其使用
主引导记录 (MBR) 或有时称为主分区表 (MPT),包含一个小程序,用于从硬盘驱动器加载和启动活动(或可引导)分区。主引导记录包含有关所有四个主分区的信息。
有关 MBR 的详细研究,请参阅本书前面讨论的“磁盘和操作系统的逻辑方法”一章。
MBR 位于绝对扇区 0,或者我们可以说位于柱面 0、磁头 0 和扇区 1。它是通过执行 DOS 的 FDISK.EXE 命令在硬盘驱动器上创建的。
为什么要备份 MBR:
MBR 允许活动分区的引导扇区在系统启动时接收控制。
开机自检 (POST) 后,BIOS 将 MBR(主引导记录)从硬盘加载到内存中,然后执行。首先 MBR 检查硬盘是否有活动分区,然后将 DOS 引导记录 (DBR) 加载到内存中,并将控制权交给操作系统引导代码,然后操作系统引导记录代码将操作系统的其余部分加载到内存。
我们可以说,如果磁盘的 MBR 损坏,硬盘几乎死了,系统完全无法启动或运行操作系统。在这种情况下,存储在硬盘中的所有数据都变得无法访问。一般错误信息显示如下:
“无效的分区表” “加载操作系统时出错” “缺少操作系统”
备份 MBR 可以恢复什么?
MBR 的备份可以帮助您摆脱上述错误信息。通过备份,可以解决以下问题:
- 由于 IPL(初始程序加载器)损坏而导致加载操作系统时出错
- 丢失的主分区
- 损坏的分区信息
- 无效的幻数
编写程序备份 MBR:
/* 备份 MBR 的程序 */
#include <bios.h>
#include <stdio.h>
int main(void)
{
struct diskinfo_t dinfo; /* Structure to Hold the
information of disk Parameters */
int result;
int count=0;
char filename[80]; /* Stores the File name given by
User */
static char dbuf[512]; /* Data Buffer of 512 Bytes */
FILE *fp;
dinfo.drive = 0x80; /* drive number for First Hard
Disk */
dinfo.head = 0; /* disk head number */
dinfo.track = 0; /* track number */
dinfo.sector = 1; /* sector number */
dinfo.nsectors = 1; /* sector count */
dinfo.buffer = dbuf; /* data buffer */
printf("\n Enter The Filename and path to store the
Backup of MBR \n ");
gets(filename);
// 打开文件以存储 MBR 备份 \\
if((fp=fopen(filename,"wb"))==NULL)
{
printf("Could not Create File, Press any key to
Exit...");
getch();
exit(0);
}
printf("Attempting to read from Hard disk drive :\n");
//// 读取指定的磁盘扇区 \\\\
result = _bios_disk(_DISK_READ, &dinfo);
if ((result & 0xff00) == 0)
{
printf("Disk read from hard disk drive :
successful.\n");
/// 将 512 字节的 MBR 写入文件 \\\\
while(count<512)
{
fprintf(fp,"%c",dbuf[count] & 0xff );
count++;
}
fclose(fp);
}
else
printf("Cannot read Hard Disk drive, status = 0x%02x\n", result);
return 0;
}
程序编码评论:
在前面给出的程序编码中,基本上我们是在一步步执行以下任务:
- dinfo指向diskinfo_t结构,该结构包含_bios_disk函数执行操作所需的参数信息。
- 由于我们要读取磁盘的第一个扇区,因此该扇区的位置如下:
Parameter |
What it means |
dinfo.drive = 0x80 |
It indicates the Physical drive 80H that is the first Hard disk drive. |
dinfo.head = 0 |
It points to head number 0 |
dinfo.track = 0 |
It points to track 0 |
dinfo.sector = 1 |
First sector of the floppy that is sector 1 |
dinfo.sector = 1 |
>Number of sectors to consider for read operation = 1 |
dinfo.buffer = dbuf |
Data buffer for the operation |
- 打开用户给定文件名和路径的文件流以存储精确 512 字节的 MBR 备份。文件名和路径存储在字符数组文件名中。
- _bios_disk(_DISK_READ, &dinfo) 读取硬盘的第一个扇区 (80H),由 dinfo 指定。
- 返回的状态,存储在result中,用于显示操作成功的信息或出现错误时在屏幕上显示错误信息。
从备份中恢复 MBR 的程序:
如果 MBR 以任何方式损坏,接下来给出的程序将帮助恢复 MBR Back。
应始终牢记,非法使用或在不知情的情况下使用该程序可能会破坏您在硬盘中的数据信息,并可能使整个数据无法访问。你应该确定你将要做什么。否则问题可能会更复杂。
从备份中恢复 MBR 的程序:
程序的编码如下:
/* 从备份文件恢复 MBR 备份的程序 */
#include <bios.h>
#include <stdio.h>
int main(void)
{
struct diskinfo_t dinfo;
int result;
int count=0;
char filename[80]; /* Stores the File name given
by User */
static char dbuf[512]; /* Data Buffer of 512 Bytes
*/
FILE *fp;
/* 获取 MBR 备份文件路径的用户输入 */
printf("\n Enter The Filename and path of Backup File of
MBR \n ");
gets(filename);
if((fp=fopen(filename,"rb"))==NULL)
{
printf("Could not open Backup File, Press any key
to Exit...");
getch();
exit(1);
}
/* MBR 数据应为 512 字节 */
while(count<512)
{
fscanf(fp,"%c",&dbuf[count]);
count++;
}
fclose(fp);
printf("Attempting to Write to Hard disk drive :\n");
dinfo.drive = 0x80; /* drive number for First
Hard Disk */
dinfo.head = 0; /* disk head number */
dinfo.track = 0; /* track number */
dinfo.sector = 1; /* sector number */
dinfo.nsectors = 1; /* sector count */
dinfo.buffer = dbuf; /* data buffer */
result = _bios_disk(_DISK_WRITE, &dinfo);
if ((result & 0xff00) == 0)
{
printf("Restoring the Backup of MBR to The Disk
Sector: successful.\n");
}
else
printf("Cannot Write on Hard Disk drive, status =
0x%02x\n", result);
return 0;
}
程序编码评论:
在上面给出的程序编码中,基本上我们是在逐步执行以下任务:
- dinfo指向diskinfo_t结构,该结构包含_bios_disk函数执行操作所需的参数信息。
- 由于我们要写入磁盘的第一个扇区,因此该扇区的位置如下:
Parameter |
What it means |
dinfo.drive = 0x80 |
It indicates the Physical drive 80H that is the first Hard disk drive. |
dinfo.head = 0 |
It points to head number 0 |
dinfo.track = 0 |
It points to track 0 |
dinfo.sector = 1 |
First sector of the floppy that is sector 1 |
dinfo.sector = 1 |
Number of sectors to consider for read operation = 1 |
dinfo.buffer = dbuf |
Data buffer for the operation |
- 用户给出的 MBR 备份的文件名和路径存储在字符数组文件名中。请记住,MBR 信息应为 512 字节。
- _bios_disk(_DISK_WRITE, &dinfo) 将数据写入硬盘的第一个扇区 (80H),由 dinfo 指定。
- 返回的状态,存储在结果中,用于显示操作成功的消息,或者如果发生任何错误,在屏幕上显示错误消息。
DBR(DOS引导记录)的备份及其使用
在分区表之后,DOS 引导记录 (DBR) 或有时称为 DOS 引导扇区是硬盘驱动器上第二重要的信息。
有关 DBR 的详细研究,请参阅本书前面讨论过的章节,“磁盘和操作系统的逻辑方法”。
每个 DOS 分区的第一个逻辑扇区将包含一个 DOS 引导记录 (DBR) 或 DOS 引导扇区。 DBR 的工作是将操作系统从硬盘驱动器加载到计算机的主存中,并将系统的控制权交给加载的程序。
硬盘上第一个分区的 DOS 引导记录 (DBR) 通常位于绝对扇区 63(磁盘驱动器上的第 64 个扇区)或 CHS 形式,我们可以说 C–H–S = 0–1&ndash ;1 适用于大多数驱动器。
但是,此位置可能会因驱动器的 SPT(每磁道扇区)而异。例如,在只有 31 个 SPT 的旧 245MB 驱动器上,引导记录位于第 32 个扇区(绝对扇区 31)。
DBR 是由 DOS 的 FORMAT 命令创建的,分区是使用 FDISK 命令完成的。 DBR 所在的扇区成为 DOS 特定分区的逻辑扇区 1。 DOS 使用的扇区号从 DBR 所在的物理扇区开始。
DBR 包含一个由主引导记录 (MBR) 可执行程序执行的小程序。所有 DOS 分区都包含启动机器的程序代码,即加载操作系统,但只有该分区由分区表条目中指定为活动分区的主引导记录控制。
为什么要备份 DBR:
DBR 包含有关磁盘几何结构的一些重要信息。该信息位于每个分区的第一个扇区,如:
- 跳转代码 + NOP
- OEM 名称和版本
- 每个扇区的字节数
- 每个集群的扇区
- 保留扇区
- FAT 副本数
- 最大根目录条目(但不适用于 FAT32)
- 分区中小于 32MB 的扇区数(因此不适用于 FAT32)
- 媒体描述符(硬盘为 F8H)
- 每个 FAT 的扇区(在较旧的 FAT 系统中,不适用于 FAT32)
- 每个轨道的扇区
- 头数
- 分区中的隐藏扇区数
- 分区中的扇区数
- 每个 FAT 的扇区数
- FAT 信息描述符标志
- FAT32 驱动器版本
- 根目录开始的簇号
- 文件系统信息扇区的扇区号
- 备份引导扇区的扇区号
- 保留
- 分区的逻辑驱动器号
- 扩展签名 (29H)
- 分区序列号
- 分区卷名
- FAT 名称
- 可执行代码
- 可执行标记或幻数 (AAH 55H)
通常,屏幕上会显示以下错误信息:
“磁盘启动失败”
“非系统盘或磁盘错误”
“系统盘无效或磁盘 I/O 错误”
“更换磁盘,然后按任意键…”
备份 DBR 可以恢复什么?
备份 DBR 可以帮助您摆脱上述错误消息。这些错误信息在屏幕上等待用户将带有上述程序的可引导磁盘放入软驱并按下一个键。
如果您从可引导软盘或 CD 引导系统,该驱动器应该可以访问。虽然硬盘是不可引导的,但一般不会影响对磁盘驱动器数据的访问。用可启动盘启动系统后就可以访问数据了。
通过恢复 DBR 的备份,您可以克服产生的问题,如上所述。
制作和恢复 DBR 备份的程序:
DBR的备份和恢复程序与MBR的备份和恢复程序几乎相似。
例如,如果您要编写备份磁盘第一个逻辑驱动器的 DBR 并恢复它的程序,则 dinfo 结构指定的参数将更改如下:
Parameter |
What it means |
dinfo.drive = 0x80 |
It indicates the Physical drive 80H that is the first Hard disk drive> |
dinfo.head = 1 |
It points to head number 1 |
dinfo.track = 0 |
It points to track 0 |
dinfo.sector = 1 |
First sector of the floppy that is sector 1 |
dinfo.sector = 1 |
Number of sectors to consider for read operation = 1 |
dinfo.buffer = dbuf |
Data buffer for the operation |
在这里,我们看到只有要读/写的扇区的位置发生了变化。此处 C-H-S 为 0-1-1,因为此处存储了第一个逻辑驱动器的 DBR.
完整的磁盘映像
这种类型的备份现在越来越流行,并且最受系统中具有非常敏感数据的此类组织的青睐。他们的人不能冒任何风险,即使是百分之一的数据丢失。
此类组织定期将其备份作为整个磁盘映像。虽然这需要一些时间,但可以确保您不会错过任何东西。由于其日益普及,程序员已尽最大努力使磁盘映像软件越来越快,以尽量减少映像过程所花费的时间。
磁盘映像是一个好主意,因为只需花费几十分钟,您就可以放心地备份所有内容。 MBR、BDR、FAT、根目录等所有因素都原样复制到目标磁盘。
磁盘映像所需的是与我们拥有宝贵数据的源硬盘相同(或几乎相同)的目标硬盘。始终牢记一件事,目标磁盘不应小于源磁盘。
获取完整映像后,如果您使用已获取磁盘映像的目标磁盘引导系统,通常您将获得所有数据。
编写完整磁盘映像的程序
接下来给出了磁盘映像的程序。该程序使用 INT 13H 扩展,因此它也可以支持大磁盘。
程序将第一个物理硬盘驱动器(0x80)的映像制作到第二个物理硬盘驱动器(0x81),因此在制作备份映像之前,您应该记住目标磁盘(0x81)中的所有数据都会被源磁盘(0x80)的数据逐扇区覆盖。
下面给出程序的编码:
/* 将第一个硬盘 (0x80) 的映像制作到第二个硬盘 (0x81) 的程序 */
#include<stdio.h>
#include<dos.h>
#include<conio.h>
/* getdrivegeometry 函数使用的结构,使用 INT 13H 扩展,函数编号 0x48。 */
struct geometry
{
unsigned int size ; /* (call) size of Buffer */
unsigned int flags ; /* Information Flags */
unsigned long cyl ; /* Number of Physical
Cylinders on Drive */
unsigned long heads ;/* Number of Physical
Heads on Drive */
unsigned long spt ; /* Number of Physical
Sectors Per Track */
unsigned long sectors[2] ; /* Total Number of
Sectors on Drive */
unsigned int bps ; /* Bytes Per Sector */
} ;
/* 磁盘地址数据包格式的结构,供函数 readabsolutesectors 和 writeabsolutesectors 使用 */
struct diskaddrpacket
{
char packetsize ; /* Size of Packet, generally 10H */
char reserved ; /* Reserved (0) */
int blockcount ; /* Number of Blocks to Transfer */
char far *bufferaddress ; /* address to Transfer
Buffer */
unsigned long blocknumber[2] ; /* Starting Absolute
Block Number */
} ;
///// 获取驱动参数的函数 \\\\\
unsigned long getdrivegeometry (int drive)
{
union REGS i, o ;
struct SREGS s ;
struct geometry g = { 26, 0, 0, 0, 0, 0, 0, 0 } ;
i.h.ah = 0x48 ; /* Function Number 0x48 of INT 13H
Extensions See the Comments
Below */
i.h.dl = drive; /* Drive Number */
i.x.si = FP_OFF ( (void far*)&g ) ;
s.ds = FP_SEG ( (void far*)&g ) ;
/* 使用段寄存器值调用 INT 13H 扩展的指定功能号 */
int86x ( 0x13, &i, &o, &s ) ;
printf("\n Head = %lu, Sectors Per Track = %lu, Cylinder =
%lu\n", g.heads, g.spt, g.cyl);
/* 如果获取驱动器几何功能失败,显示错误消息并退出 */
if(g.spt==0)
{
printf("\n Get Drive Geometry Function Fails....");
printf("\n Extensions Not Supported, Press any Key to
Exit...");
getch();
exit(1);
}
return *g.sectors; /* Return The Number of Sectors
on Drive */
}
////// 主要开始 \\\\\\
void main()
{
unsigned long loop=0, Sectors_in_HDD1=0, Sectors_in_HDD2=0;
unsigned char buffer[61440]; /* Data buffer of 61440
Bytes to Read/Write 120 Sectors of 512 Bytes at a time to save time. */
char choice;
clrscr();
/* 如果总没有。连接的硬盘数少于两个 显示错误消息并退出。 */
if(((char)peekb(0x0040, 0x0075))<2)
{
printf("\n\n You Must Have At least Two Hard Disks
Attached to your Computer To Run This");
printf("\n Program. Press any Key to Exit... ");
getch();
exit(1);
}
/// 获取第一块硬盘参数(0x80) \\\
Sectors_in_HDD1 = getdrivegeometry (0x80);
printf(" Total Sectors in First Hard Disk = %lu\n\n",
Sectors_in_HDD1);
/// 获取第二块硬盘参数(0x81) \\\
Sectors_in_HDD2 = getdrivegeometry (0x81);
printf(" Total Sectors in Second Hard Disk = %lu\n\n",
Sectors_in_HDD2);
/// 先确认再继续 \\\
printf("\n All The Data in Second Hard Disk will be
lost !!!");
printf("\n Press \'Y\' to Continue, Else any key to
Exit... ");
choice = getche();
switch(choice)
{
case 'y':
case 'Y':
break;
default:
exit(0);
}
/* 目标不应小于源 */
if(Sectors_in_HDD2<Sectors_in_HDD1)
{
printf("\n\n Destination Disk should not be Smaller
than Source Disk");
printf("\n Press any Key to Exit...");
getch();
exit(0);
}
/* 如果一切正常,将源磁盘的所有扇区复制到目标硬盘 */
gotoxy(10,15);printf("Copying Absolute Sector: ");
for(loop=0;loop< =Sectors_in_HDD1;loop=loop+120)
{
readabsolutesectors ( 0x80, loop, 120, buffer );
writeabsolutesectors ( 0x81, loop, 120, buffer );
gotoxy(36,15); printf("%ld",loop);
if(kbhit())
{
exit(0);
}
}
//// 显示完成信息 \\\
printf("\n\n Disk Imaging is Now Completed, Press any Key
To Exit...");
getch();
}
//// End of main
对编码的评论:
在前面给出的程序编码中,对于磁盘映像,我们正在执行以下任务:
- 结构,几何由 getdrivegeometry 函数使用,使用 INT 13H 扩展,函数编号 0x48。有关 INT 13H 扩展的详细说明,请参阅本书前面讨论过的“处理大型硬盘”一章。
代表磁盘几个参数的Data Types有以下含义:
Data Type |
Size in Bytes |
Description |
unsigned int size |
2 Bytes |
Size of Buffer |
unsigned int flags |
2 Bytes |
Information Flags |
unsigned long cyl |
4 Bytes |
Number of Physical Cylinders on Drive |
unsigned long heads |
4 Bytes |
Number of Physical Heads on Drive |
unsigned long spt |
4 Bytes |
Number of Physical Sectors Per Track |
unsigned long sectors[2] |
8 Bytes |
Total Number of Sectors on Drive |
unsigned int bps |
2 Bytes |
Bytes Per Sector |
- 结构 diskaddrpacket 由函数 readabsolutesectors 和 writeabsolutesectors 使用。磁盘地址包的格式如下表所示:
Data Type |
Size in Bytes |
Description |
char packetsize |
1 Byte |
Size of Packet, generally 10H |
char reserved |
1 Byte |
Reserved (0) |
int blockcount |
2 Bytes |
Number of Blocks to Transfer |
char far *bufferaddress |
4 Bytes |
address to Transfer Buffer |
unsigned long blocknumber[2] |
4 Bytes |
Starting Absolute Block Number |
- getdrivegeometry函数用于获取指定Drive的参数。函数 getdrivegeometry 使用 INT 13H 扩展的函数号 0x48。
参数的含义已在下表中描述:
Parameter |
What it means |
i.h.ah = 0x48 |
Function Number 0x48 of INT 13H Extensions |
i.h.dl = drive |
Drive Number |
i.x.si = FP_OFF ( (void far*)&g ) |
ds:si address to buffer for drive parameters as discussed earlier |
s.ds = FP_SEG ( (void far*)&g ) |
ds:si address to buffer for drive parameters as discussed earlier |
int86x(0x13, &i, &o, &s) 函数使用段寄存器值调用中断 13H。 getdrivegeometry 函数返回驱动器上的总数。
- 在main()函数中,(char)peekb(0x0040, 0x0075); (函数 peekb 在 DOS.H 中定义)返回连接到系统的硬盘数量。
连接到系统的硬盘数量由存储在内存位置 0040H:0075H (Segment 0040H: Offset 0075H) 的字节表示。如果连接到系统的硬盘数量少于两个程序会显示错误信息并退出。
Sectors_in_HDD1 = getdrivegeometry (0x80);获取第一个硬盘的参数(0x80)并返回第一个硬盘上的扇区总数。
同样 Sectors_in_HDD2 = getdrivegeometry (0x81);获取第二块硬盘的参数(0x81),返回第二块硬盘的扇区总数。
在用户确认继续映像后,首先检查源硬盘大小不应大于目标硬盘大小的条件。如果目标较小,则显示错误消息并退出。
如果一切正常,请将源磁盘的扇区复制到目标磁盘。在这里,我们一次读取和写入 61440 字节(120 个扇区,每个扇区 512 字节),以加快成像过程。
如果你想一次使用更多的扇区,甚至超过 64K 的限制,你可以使用“巨大的指针”来实现。在大内存模型中。规格示例如下:
char huge array[100000L];
- 函数,readabsolutesectors(0x80,循环,120,缓冲区);从无符号长整数循环指定的扇区号开始读取第一个硬盘(0x80)的120个扇区,并将数据存储在数据缓冲区中。
- 函数,writeabsolutesectors ( 0x81, loop, 120, buffer );从无符号长整数循环指定的扇区号开始,将数据缓冲区的数据写入第二个硬盘的 120 个扇区(0x81)。
下面给出函数readabsolutesectors()和writeabsolutesectors()的编码:
//// 读取绝对扇区的函数 \\\\
int readabsolutesectors ( int drive,
unsigned long sectornumber,
int numofsectors,
void *buffer )
{
union REGS i, o ;
struct SREGS s ;
struct diskaddrpacket pp ;
pp.packetsize = 16 ; /* packet size = 10H */
pp.reserved = 0 ; /* Reserved = 0 */
pp.blockcount = numofsectors ; /* Number of sectors
to read */
/* 用于数据缓冲区 */
pp.bufferaddress = (char far*) MK_FP ( FP_SEG((void
far*)buffer), FP_OFF((void far*)buffer));
pp.blocknumber[0] = sectornumber ; /* Sector number
to read */
pp.blocknumber[1] = 0 ; /* Block number */
i.h.ah = 0x42 ; /* Function Number*/
i.h.dl = drive ; /* Physical Drive Number */
i.x.si = FP_OFF ( (void far*)&pp ) ; /* ds:si for
buffer Parameters */
s.ds = FP_SEG ( (void far*)&pp ) ; /* ds:si for
buffer Parameters */
/* 使用段寄存器值调用 INT 13H 的指定函数 */
int86x ( 0x13, &i, &o, &s ) ;
if ( o.x.cflag==1)
return 0 ; /*failure */
else
return 1 ; /* success */
}
//// 写入绝对扇区的函数 \\\\
int writeabsolutesectors ( int drive,
unsigned long sectornumber,
int numofsectors,
void *buffer )
{
union REGS i, o ;
struct SREGS s ;
struct diskaddrpacket pp ;
pp.packetsize = 16 ; /* Packet Size = 10H */
pp.reserved = 0 ; /* Reserved = 0 */
pp.blockcount = numofsectors ; /* Number of Sectors
to be written */
/* 用于数据缓冲区 */
pp.bufferaddress = (char far*) MK_FP ( FP_SEG((void
far*)buffer), FP_OFF((void far*)buffer));
pp.blocknumber[0] = sectornumber ;/* Sector number
to be written */
pp.blocknumber[1] = 0 ; /* Block number = 0 */
i.h.ah = 0x43 ; /* Function Number */
i.h.al = 0x00 ; /* Write Flags, see
comments */
i.h.dl = drive ; /* Physical Drive number*/
/* ds:si for buffer Parameters */
i.x.si = FP_OFF ( (void far*)&pp ) ;
/* ds:si for buffer Parameters */
s.ds = FP_SEG ( (void far*)&pp ) ;
/* 使用段寄存器值调用 INT 13H 的指定函数 */
int86x ( 0x13, &i, &o, &s ) ;
if ( o.x.cflag==1)
return 0 ; /* failure */
else
return 1 ; /* success */
}
对编码的评论:
这两个函数使用的参数含义如下:
Parameter |
Size in Bytes |
Description |
pp.packetsize = 16 ; |
1 Byte |
Size of packet = 10H |
pp.reserved = 0 ; |
1 Byte |
Reserved = 0 |
pp.blockcount = numofsectors ; |
2 Bytes |
Number of sectors to read |
pp.bufferaddress = (char far*) MK_FP ( FP_SEG((void far*)buffer), FP_OFF((void far*)buffer)); |
----- |
for Data buffer or Transfer Buffer |
pp.blocknumber[0] = sectornumber ; |
4 Bytes |
Sector number to read/write (generally, we need only this). Only alone This can support up to 2.1 Terabytes. |
pp.blocknumber[1] = 0 ; |
4 Bytes |
Block number. Use this, If accessing the disk of greater then 2.1 Terabytes in size. |
i.h.ah = 0x42 ; or i.h.ah = 0x43 ; |
2 Bytes |
Function Number of INT 13H Extensions |
i.h.al = 0x00 ; |
1 Byte |
Write Flags used in write function only,00H, 01H are used for Write Without Verify and 02H is used for write with verify |
i.h.dl = drive ; |
2 Bytes |
Physical Drive Number |
i.x.si = FP_OFF ( (void far*)&pp ) ; |
------ |
ds:si for buffer Parameters |
s.ds = FP_SEG ( (void far*)&pp ) ; |
------ |
ds:si for buffer Parameters |
int86x ( 0x13, &i, &o, &s ) ; |
------ |
Invoke the specified Function of INT 13H with segment register values |
Page Modified on: 15/01/2022