| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4453 人关注过本帖, 1 人收藏
标题:[分享]读取硬盘绝对扇区的函数(纯DOS)
只看楼主 加入收藏
grub2linux
Rank: 1
等 级:新手上路
帖 子:335
专家分:0
注 册:2004-12-25
收藏(1)
 问题点数:0 回复次数:11 
[分享]读取硬盘绝对扇区的函数(纯DOS)

(刚写的,有8.4G限制,谁有读取137G以上的函数,贴出来学习一下,据说是扩展13终端)

#include <bios.h>
#include <conio.h>
#include <stdio.h>

/*将读取的硬盘扇区以相应的扇区数为单位存到文件的函数(每次的读取数必须在65535字节内,否则无效)*/
void writeFile(unsigned char *buffer, unsigned int sector, char *filename)
{
FILE *f;

if((f=fopen(filename,"ab+"))==NULL)
{
printf("File Error\n");
return;
}
fwrite(buffer,512,sector,f);
fclose(f);

}

/*读取硬盘绝对扇区的函数(在8.4G内)*/
void readLBA(unsigned char hardDisk,
unsigned long startSector,
unsigned long nSector,
char *filename)
{
unsigned char head=0;
unsigned int cylinder=0;
unsigned char sector=0;
unsigned char pBuffer[32256]; /*63个扇区的字节数 */
FILE *f;
unsigned int allowednSector=0;
unsigned int doReadSector=0;
unsigned long sectorWrite=0;
unsigned int x=0,y=0;

/*获取当前光标 */
x=wherex();
y=wherey();

if((f=fopen(filename,"wb+"))==NULL)
{
printf("File Error\n");
return;
}
fclose(f);


/*把硬盘绝对扇区转换成CHS物理位置(柱面,磁头,扇区)*/
cylinder=startSector/(255*63);
head=(startSector/63)%255;
sector=startSector%63+1;

/*算出刚开始时可有效读取的最大扇区数 */
allowednSector=63-sector+1;

/*如果小的一次可以读完 */
if(nSector<=allowednSector)
doReadSector=nSector;

/*否则读可有效读取的最大扇区数 */
else doReadSector= allowednSector;

while(sectorWrite<nSector)
{

/*读到缓冲 */
biosdisk(2,hardDisk,head,cylinder,sector,doReadSector,pBuffer);
/*写到文件 */
writeFile(pBuffer,doReadSector,filename);
sectorWrite+= doReadSector;
/*显示已读的扇区数百分比 */
gotoxy(x,y);
cprintf("%lu%c sectors read.",sectorWrite*100/nSector,'%');

/*磁头归为0,准备每次读63扇区(一磁道的扇区数,也正好适合fwrite()函数的范围)*/
head++;sector=1;
if (head>254) {cylinder++; head=0; sector=1;}
if (cylinder>1023)
{printf("out of hard disk's cylinder range(0-1023)\n");
return;}
doReadSector=63;

/*快要读完了,不足63扇区了 */
if(nSector-sectorWrite<63) doReadSector=nSector-sectorWrite;

}
printf("\nDone.");
}

*****************************

/*以读取硬盘C盘 FAT32的FAT为例,来调用读取硬盘绝对扇区的函数 */
#include "readlba.h"

/*获取FAT参数(FAT前距离DBR的扇区数,FAT所占的扇区数)*/
void getFATinfo(unsigned int hardDisk,
unsigned int *reservedSector,
unsigned long *sectorPerFAT)
{
unsigned char buffer[512];
/*获取DBR,以便 获取FAT参数 */
biosdisk(2,hardDisk,1,0,1,1,buffer);
/* 获取FAT前距离DBR的扇区数 */
*reservedSector=*((unsigned int *)&buffer[0xE]);
/* 获取FAT所占的扇区数 */
*sectorPerFAT=*((unsigned long *)&buffer[0x24]);
}

void main()
{
unsigned int reservedSector;
unsigned long sectorPerFAT;

/* 获取FAT参数 */
getFATinfo(0x80,&reservedSector,&sectorPerFAT);
/*保存FAT到文件 */
readLBA(0x80,63+reservedSector,sectorPerFAT,"d:\\cfat.dat");
}


有缘相识! 我中文系的
半个月拿下基本C
一个月拿下基本C++
两个月拿下基本VC
一星期拿下一半基本JAVA
五天写DOS游戏
两个月写DOS游戏系统
年后一个月拿下VFP
过一下 ACCESS, SQL SERVER
与大家一起加油啊! 很喜欢这句
"拿下!"
http://mykool.go2.icpcn.com
搜索更多相关主题的帖子: 函数 DOS 硬盘 sector include 
2006-06-28 01:00
yuki
Rank: 2
等 级:新手上路
威 望:5
帖 子:508
专家分:0
注 册:2005-2-4
收藏
得分:0 
很好的帖子,不要让它沉了,有很多地方值得学习的。

我们都在命运湖上荡舟划桨,波浪起伏使我们无法逃离孤行;如果我们迷失方向,波浪将指引我们穿过另一天曙光
2006-06-29 18:05
mechanics
Rank: 1
等 级:新手上路
帖 子:87
专家分:0
注 册:2006-5-16
收藏
得分:0 

好东西啊


2006-06-29 19:00
grub2linux
Rank: 1
等 级:新手上路
帖 子:335
专家分:0
注 册:2004-12-25
收藏
得分:0 

多谢关注啊:

刚刚把 写的 功能也加进去了, 合并在一起。
(已经过测试,改了几个BUG,目前还没发现新BUG,
谁发现了,贴出来)

读写硬盘(和软盘)绝对扇区的函数:
“dolba.h”

#include <bios.h>
#include <io.h>
#include <conio.h>
#include <stdio.h>


void doFile(unsigned int cmd, char *doMode, unsigned char *buffer, unsigned int sector, char *filename, unsigned long sectorDone)
{
FILE *f;
long move=sectorDone*512;
if((f=fopen(filename,doMode))==NULL)
{
printf("File Error\n");
return;
}

if(cmd==2)
fwrite(buffer,512,sector,f);
else if(cmd==3)
{
fseek(f,move,0);
fread(buffer,512,sector,f);
}

fclose(f);

}

void doLBA(unsigned int cmd,
unsigned int hardDisk,
unsigned long startSector,
unsigned long nSectorVar,
char *filename)
{
unsigned int head=0;
unsigned int cylinder=0;
unsigned int sector=0;
unsigned char pBuffer[32256];
FILE *f;
unsigned int allowednSector=0;
unsigned int doReadSector=0;
unsigned long sectorWrite=0;
unsigned int x=0,y=0;

unsigned long nSector=nSectorVar;

long filesize;
FILE *checkFile;

x=wherex();
y=wherey();

//printf("%lu,%lu\n",startSector,nSectorVar);
cylinder=((startSector+nSector-1)/(255*63));
if(cylinder>1022)
{
printf("\n%u out of hard disk's cylinder range(0-1022)\n",cylinder);
return;
}

if(cmd==2)
{
if((f=fopen(filename,"wb+"))==NULL)
{
printf("File Error\n");
return;
}
fclose(f);
}

else if(cmd==3)
{
checkFile=fopen(filename,"rb");
filesize=filelength(fileno(checkFile));
fclose(checkFile);
if((filesize==0) || (filesize % 512)!=0)
{printf("the size of the file is 0 or not an integer in sectors!\n");
return;
}
else nSector=filesize/512;
}

cylinder=startSector/(255*63);
head=(startSector/63)%255;
sector=startSector%63+1;

allowednSector=63-sector+1;

if(nSector<=allowednSector)
doReadSector=nSector;

else doReadSector= allowednSector;

while(sectorWrite<nSector)
{
if(bioskey(1)!=0)
{
if(bioskey(0)==0x11B)
{
printf("\nStopped.\n");
return;
}
}

if(cylinder>1022)
{printf("\nout of hard disk's cylinder range(0-1022)\n");
return;}

if(cmd==2)
{
biosdisk(cmd,hardDisk,head,cylinder,sector,doReadSector,pBuffer);
doFile(2,"ab+",pBuffer,doReadSector,filename,0);
}

else if(cmd==3)
{
doFile(3,"rb",pBuffer,doReadSector,filename,sectorWrite);
biosdisk(cmd,hardDisk,head,cylinder,sector,doReadSector,pBuffer);
}

sectorWrite+= doReadSector;
gotoxy(x,y);
cprintf("%lu%c sectors done.",sectorWrite*100/nSector,'%');

head++;sector=1;

if (head>254) {cylinder++; head=0; sector=1;}
//if (cylinder>1022)
//{printf("\nout of hard disk's cylinder range(0-1022)\n");
//return;}
doReadSector=63;
if(nSector-sectorWrite<63) doReadSector=nSector-sectorWrite;

}
printf("\nDone.");
}

调用示例:
dolba.c
×××××××××××××××××××××××××××
#include ”dolba.h“
#include <stdlib.h>
void main(int argc, char *argv[])
{
unsigned int cmd;
unsigned int hardDisk;
unsigned long startLBASector;
unsigned long sectorToDo;
char *filename,*endptr1,*endptr2;

if(argc!=6)
{
printf("SYNTAX: \nEXE cmd hardDisk startLBASector sectorToDo filename\n");
return;
}

cmd=atoi(argv[1]);
hardDisk=atoi(argv[2]);
//reservedSector=atol(argv[3]);
// sectorPerFAT=atol(argv[4]);
startLBASector=strtoul(argv[3],NULL,10);
sectorToDo=strtoul(argv[4],NULL,10);

filename=argv[5];

//printf("%s,%lu,%c\n%s,%lu,%c\n",argv[3],startLBASector,*endptr1,argv[4],sectorToDo,*endptr2);
/* getFATinfo(0x80,&reservedSector,&sectorPerFAT); */
doLBA(cmd,hardDisk,startLBASector,sectorToDo,filename);
}


运行:
dolba 2 128 100 200 file //从硬盘1 的100扇区处读200扇区到文件
dolba 3 128 100 200 file //把文件写到硬盘1 的100扇区处200扇区

[此贴子已经被作者于2006-6-30 2:08:08编辑过]


有缘相识!我中文系的 3月拿下C/C++/VC 5天写游戏 2月写游戏系统 有空去http://mykool.go2.
2006-06-29 21:52
神vLinux飘飘
Rank: 13Rank: 13Rank: 13Rank: 13
来 自:浙江杭州
等 级:贵宾
威 望:91
帖 子:6140
专家分:217
注 册:2004-7-17
收藏
得分:0 
不错,收藏了,不过正确性还没经过检验,等考试完后就检查。

淘宝杜琨
2006-06-29 21:54
grub2linux
Rank: 1
等 级:新手上路
帖 子:335
专家分:0
注 册:2004-12-25
收藏
得分:0 
代码已更新。。

有缘相识!我中文系的 3月拿下C/C++/VC 5天写游戏 2月写游戏系统 有空去http://mykool.go2.
2006-06-30 02:13
grub2linux
Rank: 1
等 级:新手上路
帖 子:335
专家分:0
注 册:2004-12-25
收藏
得分:0 
上面只能读写8.4G之内,
很希望有谁写过用C语言调用扩展13中断,读写大硬盘,把代码贴出来学习一下就好啦!

到现在还没解决!即等。。。

有缘相识!我中文系的 3月拿下C/C++/VC 5天写游戏 2月写游戏系统 有空去http://mykool.go2.
2006-06-30 17:25
grub2linux
Rank: 1
等 级:新手上路
帖 子:335
专家分:0
注 册:2004-12-25
收藏
得分:0 

用C语言调用扩展13中断,读写大硬盘已解决拉!
主要代码如下:(测试正确)

#include <dos.h>
#include <stdio.h>
void main(){
unsigned char buf[51200];
FILE *f;
union REGS in,out;
struct DiskAddressPacket
{
unsigned char PacketSize; /* 数据包尺寸(16字节) */
unsigned char Reserved; /* ==0 */
unsigned int BlockCount; /* 要传输的数据块个数(以扇区为单位) */
unsigned long BufferAddr;/* 传输缓冲地址(segment:offset) */
unsigned long BlockNum;/* 磁盘起始绝对块地址 */
/*unsigned long ab; */
}dap={16,0,100,0,16434495};
dap.BufferAddr=(unsigned long)buf;

in.h.ah = 0x42;
in.h.dl = 0x80;
in.x.si = &dap;
/*磁盘地址数据包(Disk Address Packet) */

int86(0x13,&in,&out);

f=fopen("int13ext.dat","wb+");
fwrite(buf,512,100,f);
fclose(f);
}

[此贴子已经被作者于2006-6-30 20:23:05编辑过]


有缘相识!我中文系的 3月拿下C/C++/VC 5天写游戏 2月写游戏系统 有空去http://mykool.go2.
2006-06-30 19:40
grub2linux
Rank: 1
等 级:新手上路
帖 子:335
专家分:0
注 册:2004-12-25
收藏
得分:0 
还发现个小奇怪:
在测试我的读写小硬盘的程序中,照理只能读写1023(3FF,1111111111)个柱面(0-1022)
但是,却能读写1024个柱面!

百思不得其解!
谁知道的说一下。。。


有缘相识!我中文系的 3月拿下C/C++/VC 5天写游戏 2月写游戏系统 有空去http://mykool.go2.
2006-06-30 19:53
lxs5216
Rank: 1
等 级:新手上路
帖 子:144
专家分:0
注 册:2006-2-3
收藏
得分:0 
以下是引用grub2linux在2006-6-30 19:40:33的发言:

用C语言调用扩展13中断,读写大硬盘已解决拉!
主要代码如下:(测试正确)

#include <dos.h>
#include <stdio.h>
void main(){
unsigned char buf[51200];
FILE *f;
union REGS in,out; //REGS什么意思,好象没有遇到过呀!
struct DiskAddressPacket
{
unsigned char PacketSize; /* 数据包尺寸(16字节) */
unsigned char Reserved; /* ==0 */
unsigned int BlockCount; /* 要传输的数据块个数(以扇区为单位) */
unsigned long BufferAddr;/* 传输缓冲地址(segment:offset) */
unsigned long BlockNum;/* 磁盘起始绝对块地址 */
/*unsigned long ab; */
}dap={16,0,100,0,16434495};
dap.BufferAddr=(unsigned long)buf;

in.h.ah = 0x42;
in.h.dl = 0x80;
in.x.si = &dap;
/*磁盘地址数据包(Disk Address Packet) */

int86(0x13,&in,&out); //int86是自定义函数吗?

f=fopen("int13ext.dat","wb+");
fwrite(buf,512,100,f);
fclose(f);
}


看完程序了,没有摸着头脑!

2006-07-19 08:52
快速回复:[分享]读取硬盘绝对扇区的函数(纯DOS)
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.019417 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved