📄 hdtool.c
字号:
/*
HDTOOL.C --- Hard disk tools Ver 1.1
(C) M.L.Y 2000.8, 2001.6
*/
#include "HDTOOL.H"
USGC rwv_buf[63*0x0200];
char help_msg[] =
"HDTOOL --- Hard disk tools Ver 1.1\n"
"(C) M.L.Y 2000.8, 2001.6\n\n"
"Usage: HDTOOL func disk_no other_parms...\n"
" 1.Read test total disk:\n"
" HDTOOL 1 disk_no\n"
" 2.Clone (copy sector by sector: 80->81, 81->80, etc):\n"
" HDTOOL 2 src_disk_no dest_disk_no [LBA_begin [LBA_end]]\n"
" 3.Format a track:\n"
" HDTOOL 3 disk_no cyl_no head_no\n"
" 4.Display a sector:\n"
" HDTOOL 4 disk_no cyl_no head_no sector_no\n"
" 5.Backup a sector to file:\n"
" HDTOOL 5 disk_no cyl_no head_no sector_no filename\n"
" 6.Restore a sector from file:\n"
" HDTOOL 6 disk_no cyl_no head_no sector_no filename\n"
" 7.Backup a track to file:\n"
" HDTOOL 7 disk_no cyl_no head_no filename\n"
" 8.Restore a track from file:\n"
" HDTOOL 8 disk_no cyl_no head_no filename\n"
"where: disk_no: 0=A,1=B,80-83=hard disk no 1-4\n";
int main(int argc,char **argv)
{
int writeflag=2;
int func, drv = 0, drv2 = 0, head = -1, sec = 0;
long cyl = -1;
char filename[256];
int rc = 0, i, n;
USGI cyl_num[4], head_num[4], sec_num[4], drvnum;
int ext_ver[4];
USGI phy_cyl[4], phy_head[4], phy_sec[4];
USGL LBA_sec_numL[4], LBA_sec_numH[4], MB;
USGL sabn = 0; /* starting absolute block number */
USGL LBA_begin = 0L, LBA_end = 0L;
char *endptr;
/* if (argc<4)
{
printf("Usage:%s R/W A/B FileName Flag\n",argv[0]);
return -1;
}
*/
if(argc == 1)
{
printf(help_msg);
printf("\nPress any key to continue ...\n");
getch();
for(i = 0; i < 4; i++)
{
printf("Get hard disk %d parm: ", i+1);
rc = get_drv_parm(0x80+i,
&cyl_num[i], &head_num[i], &sec_num[i], &drvnum,
&phy_cyl[i], &phy_head[i], &phy_sec[i],
&ext_ver[i], &LBA_sec_numL[i], &LBA_sec_numH[i]);
if(rc < 0)
printf("Error!\n");
else
{
printf("Cyl=%d, head=%d, sec=%d, drv num=%d\n",
cyl_num[i], head_num[i], sec_num[i], drvnum);
if(ext_ver[i] > 0)
{
MB = LBA_sec_numL[i] / 2 / 1024;
printf("(Ext: Cyl=%d, head=%d, sec=%d, LBA sectors: ",
phy_cyl[i], phy_head[i], phy_sec[i]);
if(LBA_sec_numH[i] > 0)
printf("Too big.");
else
printf("%lu (%lu MB)", LBA_sec_numL[i], MB);
printf(")\n");
}
}
}
return 0;
}
if(argc < 3) rc = -1;
else
{
func = atoi(argv[1]);
if (func<0)
{
writeflag=3;
func=func*(-1);
}
else writeflag=2;
if(func < 1 || func > 8) rc = -1;
else drv = atoi(argv[2]);
if(argc >= 4)
{
if(func == 2) drv2 = atoi(argv[3]);
else cyl = atoi(argv[3]);
}
if(argc >= 5)
{
if(func == 2) LBA_begin = strtoul(argv[4], &endptr, 0);
else head = atoi(argv[4]);
}
if(argc >= 6)
{
if(func >= 7 && func <= 8) strcpy(filename, argv[5]);
else if(func == 2) LBA_end = strtoul(argv[5], &endptr, 0);
else sec = atoi(argv[5]);
}
if(func >= 5 && func <= 6 && argc >= 7) strcpy(filename, argv[6]);
if((func == 2 && argc < 3) || (func == 3 && argc < 4) ||
(func == 4 && argc < 5) || (func >= 5 && func <= 6 && argc < 7) ||
(func >= 7 && func <= 8 && argc < 6))
rc = -1;
}
if(rc >= 0)
{
if(!((drv >= 0 && drv <= 1) || (drv >= 80 && drv <= 83))) rc = -1;
if(func == 2 && !(drv >= 80 && drv2 >= 80 && drv2 != drv)) rc = -1;
if(func >= 3 && func <= 8 && (cyl < 0 || head < 0)) rc = -1;
if((func >= 4 && func <= 6) && sec <= 0) rc = -1;
}
if(rc < 0)
{
printf(help_msg);
return 0;
}
if(drv >= 80) drv = drv - 80 + 0x80;
if(drv2 >= 80) drv2 = drv2 - 80 + 0x80;
rc = get_drv_parm(drv, &cyl_num[0], &head_num[0], &sec_num[0], &drvnum,
&phy_cyl[0], &phy_head[0], &phy_sec[0],
&ext_ver[0], &LBA_sec_numL[0], &LBA_sec_numH[0]);
if(func == 2 && drvnum < 2)
{
printf("Error: you have only %d hard disk!\n", drvnum);
return -1;
}
if(rc < 0)
{
printf("Get drive parm. error!\n");
return -1;
}
if(ext_ver[0] > 0)
{
cyl_num[0] = phy_cyl[0];
head_num[0] = phy_head[0];
sec_num[0] = phy_sec[0];
if(LBA_sec_numH[0] > 0)
{
printf("Hard disk too big.\n");
return -2;
}
}
if(func == 2)
{
rc = get_drv_parm(drv2, &cyl_num[1], &head_num[1], &sec_num[1], &drvnum,
&phy_cyl[1], &phy_head[1], &phy_sec[1],
&ext_ver[1], &LBA_sec_numL[1], &LBA_sec_numH[1]);
if(rc < 0)
{
printf("Get drive parm. error!\n");
return -1;
}
if(ext_ver[1] > 0)
{
cyl_num[1] = phy_cyl[1];
head_num[1] = phy_head[1];
sec_num[1] = phy_sec[1];
if(LBA_sec_numH[1] > 0)
{
printf("Hard disk too big.\n");
return -2;
}
}
}
if(func == 1)
/*
read_test_disk(drv, cyl_num[0], head_num[0], sec_num[0],
ext_ver[0], LBA_sec_numL[0]);
*/
if (writeflag==3)
{
WriteFloppyFromFile(drv, cyl_num[0], head_num[0], sec_num[0],
ext_ver[0], LBA_sec_numL[0],argv[3]);
}
else
ReadFloppyToFile(drv, cyl_num[0], head_num[0], sec_num[0],
ext_ver[0], LBA_sec_numL[0],argv[3]);
if(func == 2)
{
if((cyl_num[0] < cyl_num[1] &&
head_num[0] < head_num[1] &&
sec_num[0] < sec_num[1]) ||
(cyl_num[0] >= cyl_num[1] &&
head_num[0] >= head_num[1] &&
sec_num[0] >= sec_num[1]))
{
if(LBA_end == 0) LBA_end = min(LBA_sec_numL[0], LBA_sec_numL[1]);
printf("Clone hard disk: 0x%02X -> 0x%02X (LBA from %lu to %lu),"
" are you sure(Y/N)? ", drv, drv2, LBA_begin, LBA_end);
gets(filename);
if(filename[0] != 'y' && filename[0] != 'Y') return 0;
hd_clone(drv, cyl_num[0], head_num[0], sec_num[0],
ext_ver[0], LBA_sec_numL[0],
drv2, cyl_num[1], head_num[1], sec_num[1],
ext_ver[1], LBA_sec_numL[1],
LBA_begin, LBA_end);
}
else
{
printf("Error: 2 disks parm. do not match!\n");
return -1;
}
}
if(func == 3)
{
rc = format_cyl(drv, cyl, head, sec_num[0], ext_ver[0]);
if(rc < 0)
{
printf("Error!\n");
return -1;
}
printf("Ok!\n");
}
if(func == 4)
{
if(ext_ver[0] > 0)
{
sabn = cyl;
sabn = (sabn * head_num[0] + head) * sec_num[0] + sec - 1;
}
rc = rwv_disk_sect(2, drv, cyl, head, sec, 1, rwv_buf, ext_ver[0], sabn);
if(rc == 0)
disp_hex(rwv_buf, 0x0200);
else
printf("Error!\n");
}
if(func == 5 || func == 7)
{
n = 1;
if(func == 7)
{
sec = 1;
n = sec_num[0];
}
if(ext_ver[0] > 0)
{
sabn = cyl;
sabn = (sabn * head_num[0] + head) * sec_num[0] + sec - 1;
}
rc = rwv_disk_sect(2, drv, cyl, head, sec, n, rwv_buf, ext_ver[0], sabn);
if(rc < 0)
{
printf("Reading disk error!\n");
return -1;
}
else
rc = wrt_buf2file(filename, rwv_buf, n*0x0200);
}
if(func == 6 || func == 8)
{
n = 1;
if(func == 8)
{
sec = 1;
n = sec_num[0];
}
rc = read_file2buf(filename, rwv_buf, n*0x0200);
if(rc >= 0)
{
if(ext_ver[0] > 0)
{
sabn = cyl;
sabn = (sabn * head_num[0] + head) * sec_num[0] + sec - 1;
}
rc = rwv_disk_sect(3, drv, cyl, head, sec, n, rwv_buf, ext_ver[0], sabn);
if(rc < 0)
{
printf("Reading disk error!\n");
return -1;
}
}
}
return 0;
}
/* ------------------------------------------------------------------------- */
int int13_ext_chk(USGC drv_no, int *ext_ver)
{
union REGS inregs, outregs;
struct SREGS segregs;
inregs.h.ah = 0x41;
inregs.x.bx = 0x55AA;
inregs.h.dl = drv_no;
int86x(0x13, &inregs, &outregs, &segregs);
if(outregs.x.cflag) return -1;
if(outregs.x.bx != 0xAA55) return -1;
*ext_ver = outregs.h.ah;
return 0;
}
/* ------------------------------------------------------------------------- */
int get_drv_parm(USGC drv_no, USGI *cyl, USGI *head, USGI *sec, USGI *drvnum,
USGI *phy_cyl, USGI *phy_head, USGI *phy_sec,
int *ext_ver, USGL *LBA_sec_numL, USGL *LBA_sec_numH)
{
union REGS inregs, outregs;
struct SREGS segregs;
USGC para_buf[0x42];
*ext_ver = 0;
*phy_cyl = 0;
*phy_head = 0;
*phy_sec = 0;
*LBA_sec_numL = 0;
*LBA_sec_numH = 0;
inregs.h.ah = 0x08;
inregs.h.dl = drv_no;
int86x(0x13, &inregs, &outregs, &segregs);
if(outregs.x.cflag) return -1;
*cyl = (outregs.h.cl >> 6 << 8 | outregs.h.ch) + 1;
*sec = outregs.h.cl & 0x3F;
*head = outregs.h.dh + 1;
*drvnum = outregs.h.dl;
if(int13_ext_chk(drv_no, ext_ver) < 0)
{
*ext_ver = 0;
return 0;
}
memset(para_buf, 0x00, sizeof(para_buf));
if(*ext_ver == 0x01)
*(int *)para_buf = 0x001A;
else if(*ext_ver == 0x20 || *ext_ver == 0x21)
*(int *)para_buf = 0x001E;
else /* *ext_ver == 30h */
*(int *)para_buf = 0x0042;
inregs.x.si = FP_OFF(para_buf);
segregs.ds = FP_SEG(para_buf);
inregs.h.dl = drv_no;
inregs.h.ah = 0x48;
int86x(0x13, &inregs, &outregs, &segregs);
if(outregs.x.cflag)
{
*ext_ver = 0;
return 0;
}
*phy_cyl = *(USGL *)(para_buf+0x04);
*phy_head = *(USGL *)(para_buf+0x08);
*phy_sec = *(USGL *)(para_buf+0x0C);
*LBA_sec_numL = *(USGL *)(para_buf+0x10);
*LBA_sec_numH = *(USGL *)(para_buf+0x14);
return 0;
}
/* ------------------------------------------------------------------------- */
int rwv_disk_sect(USGC rwv, USGC drv_no, USGI cyl, USGC head, USGC sec,
USGC sec_num, USGC *buf, int ext_ver, USGL sabn)
{
union REGS inregs, outregs;
struct SREGS segregs;
int i, rc;
USGC pkt_buf[0x18];
printf("\nrwv=%d drv_no=%d cyl=%d head=%d sec=%d sec_num=%d ext_ver=%d",
rwv,drv_no,cyl,head,sec,sec_num,ext_ver);
for(i = 0; i < 3; i++)
{
rc = 0;
if(ext_ver == 0)
{
inregs.h.ah = rwv; /* 2 -- read, 3 -- write, 4 -- verify */
inregs.h.al = sec_num;
inregs.h.dh = head;
inregs.h.dl = drv_no;
inregs.h.ch = cyl & 0xFF;
inregs.h.cl = cyl >> 8 << 6 | sec;
inregs.x.bx = FP_OFF(buf);
segregs.es = FP_SEG(buf);
int86x(0x13, &inregs, &outregs, &segregs);
printf("\n-----[%02X]-----\n",buf[10]);
if(!outregs.x.cflag) break;
}
else
{
memset(pkt_buf, 0x00, sizeof(pkt_buf));
*(int *)pkt_buf = 0x0018;
*(int *)(pkt_buf+0x02) = sec_num;
*(USGI *)(pkt_buf+0x04) = FP_OFF(buf);
*(USGI *)(pkt_buf+0x06) = FP_SEG(buf);
*(USGL *)(pkt_buf+0x08) = sabn;
inregs.h.dl = drv_no;
inregs.x.si = FP_OFF(pkt_buf);
segregs.ds = FP_SEG(pkt_buf);
inregs.h.ah = rwv + 0x40; /* 42h -- read, 43h -- write, 44h -- verify */
inregs.h.al = 0;
int86x(0x13, &inregs, &outregs, &segregs);
if(!outregs.x.cflag) break;
}
rc = -1;
inregs.h.ah = 0;
inregs.h.dl = drv_no;
int86x(0x13, &inregs, &outregs, &segregs);
}
return rc;
}
/* ------------------------------------------------------------------------- */
int format_cyl(USGC drv_no, USGI cyl, USGC head, USGC sec_num, int ext_ver)
{
union REGS inregs, outregs;
struct SREGS segregs;
int i, rc;
USGC format_buf[63*4];
if(ext_ver > 0) return -2; /* Not support now */
if(drv_no < 0x80) /* floppy disk */
{
for(i = 0; i < sec_num; i++)
{
format_buf[i*4+0] = cyl;
format_buf[i*4+1] = head;
format_buf[i*4+2] = i+1;
format_buf[i*4+3] = 0x02; /* sector size (02h=512) */
}
}
else /* fixed disk (hard disk) */
{
for(i = 0; i < sec_num; i++)
{
format_buf[i*2+0] = 0x00; /* F = 00h for good sector, 80h for bad */
format_buf[i*2+1] = i+1; /* N = sector number */
}
}
for(i = 0; i < 3; i++)
{
rc = 0;
inregs.h.ah = 0x07; /* 5 -- format a cylinder */
if(drv_no < 0x80) /* floppy disk */
inregs.h.al = sec_num;
else /* fixed disk (hard disk) */
inregs.h.al = 0x00; /* interleave value (XT-type controllers only) */
inregs.h.dh = head;
inregs.h.dl = drv_no;
inregs.h.ch = cyl & 0xFF;
inregs.h.cl = cyl >> 8 << 6 | sec_num;
inregs.x.bx = FP_OFF(format_buf);
segregs.es = FP_SEG(format_buf);
int86x(0x13, &inregs, &outregs, &segregs);
if(!outregs.x.cflag) break;
rc = -1;
inregs.h.ah = 0;
inregs.h.dl = drv_no;
int86x(0x13, &inregs, &outregs, &segregs);
}
return rc;
}
/* ------------------------------------------------------------------------- */
int ReadFloppyToFile(USGC drv, USGI cyl_num, USGI head_num, USGI sec_num,
int ext_ver, USGL LBA_sec_num,char * FileName)
{
int i, j, k, rc = 0, rc1,l;
USGL n;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -