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

📄 dsk.c

📁 GNU FreeDOS兼容MS DOS很好的东东.
💻 C
📖 第 1 页 / 共 3 页
字号:
STATIC WORD getbpb(ddt * pddt){  ULONG count;  bpb *pbpbarray = &pddt->ddt_bpb;  unsigned secs_per_cyl;  WORD ret;  /* pddt->ddt_descflags |= DF_NOACCESS;    * disabled for now - problems with FORMAT ?? */  /* set drive to not accessible and changed */  if (diskchange(pddt) != M_NOT_CHANGED)    pddt->ddt_descflags |= DF_DISKCHANGE;  ret = RWzero(pddt, LBA_READ);  if (ret != 0)    return (dskerr(ret));  pbpbarray->bpb_nbyte = getword(&DiskTransferBuffer[BT_BPB]);  if (DiskTransferBuffer[0x1fe] != 0x55      || DiskTransferBuffer[0x1ff] != 0xaa || pbpbarray->bpb_nbyte != 512)  {    /* copy default bpb to be sure that there is no bogus data */    memcpy(pbpbarray, &pddt->ddt_defbpb, sizeof(bpb));    return S_DONE;  }  pddt->ddt_descflags &= ~DF_NOACCESS;  /* set drive to accessible *//*TE ~ 200 bytes*/  memcpy(pbpbarray, &DiskTransferBuffer[BT_BPB], sizeof(bpb));  /*?? */  /*  2b is fat16 volume label. if memcmp, then offset 0x36.     if (fstrncmp((BYTE *) & DiskTransferBuffer[0x36], "FAT16",5) == 0  ||     fstrncmp((BYTE *) & DiskTransferBuffer[0x36], "FAT12",5) == 0) {     TE: I'm not sure, what the _real_ decision point is, however MSDN     'A_BF_BPB_SectorsPerFAT     The number of sectors per FAT.     Note: This member will always be zero in a FAT32 BPB.     Use the values from A_BF_BPB_BigSectorsPerFat...  */  {    struct FS_info *fs = (struct FS_info *)&DiskTransferBuffer[0x27];#ifdef WITHFAT32    if (pbpbarray->bpb_nfsect == 0)    {      /* FAT32 boot sector */      fs = (struct FS_info *)&DiskTransferBuffer[0x43];    }#endif    pddt->ddt_serialno = getlong(&fs->serialno);    memcpy(pddt->ddt_volume, fs->volume, sizeof fs->volume);    memcpy(pddt->ddt_fstype, fs->fstype, sizeof fs->fstype);  }#ifdef DSK_DEBUG  printf("BPB_NBYTE     = %04x\n", pbpbarray->bpb_nbyte);  printf("BPB_NSECTOR   = %02x\n", pbpbarray->bpb_nsector);  printf("BPB_NRESERVED = %04x\n", pbpbarray->bpb_nreserved);  printf("BPB_NFAT      = %02x\n", pbpbarray->bpb_nfat);  printf("BPB_NDIRENT   = %04x\n", pbpbarray->bpb_ndirent);  printf("BPB_NSIZE     = %04x\n", pbpbarray->bpb_nsize);  printf("BPB_MDESC     = %02x\n", pbpbarray->bpb_mdesc);  printf("BPB_NFSECT    = %04x\n", pbpbarray->bpb_nfsect);#endif  count =      pbpbarray->bpb_nsize == 0 ?      pbpbarray->bpb_huge : pbpbarray->bpb_nsize;  secs_per_cyl = pbpbarray->bpb_nheads * pbpbarray->bpb_nsecs;  if (secs_per_cyl == 0)  {    tmark(pddt);    return failure(E_FAILURE);  }  /* this field is problematic for partitions > 65535 cylinders,     in general > 512 GiB. However: we are not using it ourselves. */  pddt->ddt_ncyl = (UWORD)((count + (secs_per_cyl - 1)) / secs_per_cyl);  tmark(pddt);#ifdef DSK_DEBUG  printf("BPB_NSECS     = %04x\n", pbpbarray->bpb_nsecs);  printf("BPB_NHEADS    = %04x\n", pbpbarray->bpb_nheads);  printf("BPB_HIDDEN    = %08lx\n", pbpbarray->bpb_hidden);  printf("BPB_HUGE      = %08lx\n", pbpbarray->bpb_huge);#endif  return 0;}STATIC WORD bldbpb(rqptr rp, ddt * pddt){  WORD result;  if ((result = getbpb(pddt)) != 0)    return result;  rp->r_bpptr = &pddt->ddt_bpb;  return S_DONE;}STATIC WORD IoctlQueblk(rqptr rp, ddt * pddt){  UNREFERENCED_PARAMETER(pddt);#ifdef WITHFAT32  if (rp->r_cat == 8 || rp->r_cat == 0x48)#else  if (rp->r_cat == 8)#endif  {    switch (rp->r_fun)    {    case 0x46:    case 0x47:    case 0x60:    case 0x66:    case 0x67:      return S_DONE;    }  }  return failure(E_CMD);}STATIC COUNT Genblockio(ddt * pddt, UWORD mode, WORD head, WORD track,                 WORD sector, WORD count, VOID FAR * buffer){  UWORD transferred;  /* apparently sector is ZERO, not ONE based !!! */  return LBA_Transfer(pddt, mode, buffer,                      ((ULONG) track * pddt->ddt_bpb.bpb_nheads + head) *                      (ULONG) pddt->ddt_bpb.bpb_nsecs +                      pddt->ddt_offset + sector, count, &transferred);}STATIC WORD Genblkdev(rqptr rp, ddt * pddt){  int ret;  unsigned descflags = pddt->ddt_descflags;#ifdef WITHFAT32  int extended = 0;  if (rp->r_cat == 0x48)    extended = 1;  else#endif  if (rp->r_cat != 8)    return failure(E_CMD);  switch (rp->r_fun)  {    case 0x40:                 /* set device parameters */      {        struct gblkio FAR *gblp = rp->r_io;        bpb *pbpb;        pddt->ddt_type = gblp->gbio_devtype;        pddt->ddt_descflags = (descflags & ~3) | (gblp->gbio_devattrib & 3)            | (DF_DPCHANGED | DF_REFORMAT);        pddt->ddt_ncyl = gblp->gbio_ncyl;        /* use default dpb or current bpb? */        pbpb =            (gblp->gbio_spcfunbit & 0x01) ==            0 ? &pddt->ddt_defbpb : &pddt->ddt_bpb;#ifdef WITHFAT32        fmemcpy(pbpb, &gblp->gbio_bpb,                extended ? sizeof(gblp->gbio_bpb) : BPB_SIZEOF);#else        fmemcpy(pbpb, &gblp->gbio_bpb, sizeof(gblp->gbio_bpb));#endif        /*pbpb->bpb_nsector = gblp->gbio_nsecs; */        break;      }    case 0x41:                 /* write track */      {        struct gblkrw FAR *rw = rp->r_rw;        ret = Genblockio(pddt, LBA_WRITE, rw->gbrw_head, rw->gbrw_cyl,                         rw->gbrw_sector, rw->gbrw_nsecs, rw->gbrw_buffer);        if (ret != 0)          return dskerr(ret);      }      break;    case 0x42:                 /* format/verify track */      {        struct gblkfv FAR *fv = rp->r_fv;        COUNT tracks;        struct thst {          UBYTE track, head, sector, type;        } *addrfield, afentry;        pddt->ddt_descflags &= ~DF_DPCHANGED;        if (hd(descflags))        {          /* XXX no low-level formatting for hard disks implemented */          fv->gbfv_spcfunbit = 1;       /* "not supported by bios" */          return S_DONE;        }        if (descflags & DF_DPCHANGED)        {          /* first try newer setmediatype function */          ret = fl_setmediatype(pddt->ddt_driveno, pddt->ddt_ncyl,                                pddt->ddt_bpb.bpb_nsecs);          if (ret == 0xc)          {            /* specified tracks, sectors/track not allowed for drive */            fv->gbfv_spcfunbit = 2;            return dskerr(ret);          }          else if (ret == 0x80)          {            fv->gbfv_spcfunbit = 3;     /* no disk in drive */            return dskerr(ret);          }          else if (ret != 0)            /* otherwise, setdisktype */          {            unsigned char type;            unsigned tracks, secs;            if ((fv->gbfv_spcfunbit & 1) &&                (ret =                 fl_read(pddt->ddt_driveno, 0, 0, 1, 1,                         DiskTransferBuffer)) != 0)            {              fv->gbfv_spcfunbit = 3;   /* no disk in drive */              return dskerr(ret);            }            /* type 1: 320/360K disk in 360K drive */            /* type 2: 320/360K disk in 1.2M drive */            tracks = pddt->ddt_ncyl;            secs = pddt->ddt_bpb.bpb_nsecs;            type = pddt->ddt_type + 1;            if (!(tracks == 40 && (secs == 9 || secs == 8) && type < 3))            {              /* type 3: 1.2M disk in 1.2M drive */              /* type 4: 720kb disk in 1.44M or 720kb drive */              type++;              if (type == 9) /* 1.44M drive */                type = 4;              if (!(tracks == 80 && ((secs == 15 && type == 3) ||                                     (secs == 9 && type == 4))))              {                /* specified tracks, sectors/track not allowed for drive */                fv->gbfv_spcfunbit = 2;                return dskerr(0xc);              }            }            fl_setdisktype(pddt->ddt_driveno, type);          }        }        if (fv->gbfv_spcfunbit & 1)          return S_DONE;        afentry.type = 2;       /* 512 byte sectors */        afentry.track = fv->gbfv_cyl;        afentry.head = fv->gbfv_head;        for (tracks = fv->gbfv_spcfunbit & 2 ? fv->gbfv_ntracks : 1;             tracks > 0; tracks--)        {          addrfield = (struct thst *)DiskTransferBuffer;          if (afentry.track > pddt->ddt_ncyl)            return failure(E_FAILURE);          for (afentry.sector = 1;               afentry.sector <= pddt->ddt_bpb.bpb_nsecs; afentry.sector++)            memcpy(addrfield++, &afentry, sizeof(afentry));          ret =              Genblockio(pddt, LBA_FORMAT, afentry.head, afentry.track, 0,                         pddt->ddt_bpb.bpb_nsecs, DiskTransferBuffer);          if (ret != 0)            return dskerr(ret);        }        afentry.head++;        if (afentry.head >= pddt->ddt_bpb.bpb_nheads)        {          afentry.head = 0;          afentry.track++;        }      }      /* fall through to verify */    case 0x62:                 /* verify track */      {        struct gblkfv FAR *fv = rp->r_fv;        ret = Genblockio(pddt, LBA_VERIFY, fv->gbfv_head, fv->gbfv_cyl, 0,                         (fv->gbfv_spcfunbit ?                          fv->gbfv_ntracks * pddt->ddt_defbpb.bpb_nsecs :                          pddt->ddt_defbpb.bpb_nsecs), DiskTransferBuffer);        if (ret != 0)          return dskerr(ret);        fv->gbfv_spcfunbit = 0; /* success */      }      break;    case 0x46:                 /* set volume serial number */      {        struct Gioc_media FAR *gioc = rp->r_gioc;        struct FS_info *fs;        ret = getbpb(pddt);        if (ret != 0)          return (ret);        fs = (struct FS_info *)&DiskTransferBuffer            [(pddt->ddt_bpb.bpb_nfsect != 0 ? 0x27 : 0x43)];        fs->serialno = gioc->ioc_serialno;        pddt->ddt_serialno = fs->serialno;        ret = RWzero(pddt, LBA_WRITE);        if (ret != 0)          return (dskerr(ret));      }      break;    case 0x47:                 /* set access flag */      {        struct Access_info FAR *ai = rp->r_ai;        pddt->ddt_descflags = (descflags & ~DF_NOACCESS) |          (ai->AI_Flag ? 0 : DF_NOACCESS);      }      break;    case 0x60:                 /* get device parameters */      {        struct gblkio FAR *gblp = rp->r_io;        bpb *pbpb;        gblp->gbio_devtype = pddt->ddt_type;        gblp->gbio_devattrib = descflags & 3;        /* 360 kb disk in 1.2 MB drive */        gblp->gbio_media = (pddt->ddt_type == 1) && (pddt->ddt_ncyl == 40);        gblp->gbio_ncyl = pddt->ddt_ncyl;        /* use default dpb or current bpb? */        pbpb =            (gblp->gbio_spcfunbit & 0x01) ==            0 ? &pddt->ddt_defbpb : &pddt->ddt_bpb;#ifdef WITHFAT32        fmemcpy(&gblp->gbio_bpb, pbpb,                extended ? sizeof(gblp->gbio_bpb) : BPB_SIZEOF);#else        fmemcpy(&gblp->gbio_bpb, pbpb, sizeof(gblp->gbio_bpb));#endif        /*gblp->gbio_nsecs = pbpb->bpb_nsector; */        break;      }    case 0x61:                 /* read track */      {        struct gblkrw FAR *rw = rp->r_rw;        ret = Genblockio(pddt, LBA_READ, rw->gbrw_head, rw->gbrw_cyl,                         rw->gbrw_sector, rw->gbrw_nsecs, rw->gbrw_buffer);        if (ret != 0)          return dskerr(ret);      }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -