⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hdtool.c

📁 读取软盘内容按照HD-COPY的格式写入文件
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
   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 + -