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

📄 sys.c

📁 GNU FreeDOS兼容MS DOS很好的东东.
💻 C
📖 第 1 页 / 共 2 页
字号:
{  union REGS regs;  regs.x.ax = 0x7305;  regs.h.dl = DosDrive;  regs.x.bx = (short)diskReadPacket;  regs.x.cx = 0xffff;  regs.x.si = intno;  intdos(&regs, &regs);    return regs.x.cflag;} /* fat32readwrite */void reset_drive(int DosDrive){  union REGS regs;  regs.h.ah = 0xd;  intdos(&regs, &regs);  regs.h.ah = 0x32;  regs.h.dl = DosDrive + 1;  intdos(&regs, &regs);} /* reset_drive */int generic_block_ioctl(unsigned char drive, unsigned cx, unsigned char *par){  union REGS regs;  regs.x.ax = 0x440d;  regs.x.cx = cx;  regs.x.dx = (unsigned)par;  regs.h.bl = drive + 1;  intdos(&regs, &regs);  return regs.x.cflag;} /* generic_block_ioctl */void truename(char *dest, const char *src){  union REGS regs;  struct SREGS sregs;  regs.h.ah = 0x60;  sregs.es = FP_SEG(dest);  regs.x.di = FP_OFF(dest);  sregs.ds = FP_SEG(src);  regs.x.si = FP_OFF(src);  intdosx(&regs, &regs, &sregs);} /* truename */#endifint MyAbsReadWrite(int DosDrive, int count, ULONG sector, void *buffer,                   int write){  struct {    unsigned long sectorNumber;    unsigned short count;    void far *address;  } diskReadPacket;  diskReadPacket.sectorNumber = sector;  diskReadPacket.count = count;  diskReadPacket.address = buffer;  if ((!write && absread(DosDrive, -1, -1, &diskReadPacket) == -1)      || (write && abswrite(DosDrive, -1, -1, &diskReadPacket) == -1))  {#ifdef WITHFAT32    return fat32readwrite(DosDrive + 1, &diskReadPacket, write);#else    return 0xff;#endif  }  return 0;} /* MyAbsReadWrite */#ifdef __WATCOMC__unsigned getextdrivespace(void far *drivename, void *buf, unsigned buf_size);#pragma aux getextdrivespace =  \      "mov ax, 0x7303"    \      "stc"		  \      "int 0x21"          \      "sbb ax, ax"        \      parm [es dx] [di] [cx] \      value [ax];#else /* !defined __WATCOMC__ */unsigned getextdrivespace(void *drivename, void *buf, unsigned buf_size){  union REGS regs;  struct SREGS sregs;  regs.x.ax = 0x7303;         /* get extended drive free space */  sregs.es = FP_SEG(buf);  regs.x.di = FP_OFF(buf);  sregs.ds = FP_SEG(drivename);  regs.x.dx = FP_OFF(drivename);  regs.x.cx = buf_size;  intdosx(&regs, &regs, &sregs);  return regs.x.ax == 0x7300 || regs.x.cflag;} /* getextdrivespace */#endif /* defined __WATCOMC__ */#ifdef __WATCOMC__/* * If BIOS has got LBA extensions, after the Int 13h call BX will be 0xAA55. * If extended disk access functions are supported, bit 0 of CX will be set. */BOOL haveLBA(void);     /* return TRUE if we have LBA BIOS, FALSE otherwise */#pragma aux haveLBA =  \      "mov ax, 0x4100"  /* IBM/MS Int 13h Extensions - installation check */ \      "mov bx, 0x55AA" \      "mov dl, 0x80"   \      "int 0x13"       \      "xor ax, ax"     \      "cmp bx, 0xAA55" \      "jne quit"       \      "and cx, 1"      \      "xchg cx, ax"    \"quit:"                \      modify [bx cx]   \      value [ax];#elseBOOL haveLBA(void){  union REGS r;  r.x.ax = 0x4100;  r.x.bx = 0x55AA;  r.h.dl = 0x80;  int86(0x13, &r, &r);  return r.x.bx == 0xAA55 && r.x.cx & 1;}#endifvoid correct_bpb(struct bootsectortype *default_bpb,                 struct bootsectortype *oldboot){  /* don't touch partitions (floppies most likely) that don't have hidden     sectors */  if (default_bpb->bsHiddenSecs == 0)    return;#ifdef DEBUG  printf("Old boot sector values: sectors/track: %u, heads: %u, hidden: %lu\n",         oldboot->bsSecPerTrack, oldboot->bsHeads, oldboot->bsHiddenSecs);  printf("Default and new boot sector values: sectors/track: %u, heads: %u, "         "hidden: %lu\n", default_bpb->bsSecPerTrack, default_bpb->bsHeads,         default_bpb->bsHiddenSecs);#endif  oldboot->bsSecPerTrack = default_bpb->bsSecPerTrack;  oldboot->bsHeads = default_bpb->bsHeads;  oldboot->bsHiddenSecs = default_bpb->bsHiddenSecs;}void put_boot(int drive, char *bsFile, char *kernel_name, int load_seg, int both){#ifdef WITHFAT32  struct bootsectortype32 *bs32;#endif  struct bootsectortype *bs;  static unsigned char oldboot[SEC_SIZE], newboot[SEC_SIZE];  static unsigned char default_bpb[0x5c];#ifdef DEBUG  printf("Reading old bootsector from drive %c:\n", drive + 'A');#endif  /* lock drive */  generic_block_ioctl((unsigned char)drive + 1, 0x84a, NULL);  reset_drive(drive);  /* suggestion: allow reading from a boot sector or image file here */  if (MyAbsReadWrite(drive, 1, 0, oldboot, 0) != 0)  {    printf("can't read old boot sector for drive %c:\n", drive + 'A');    exit(1);  }#ifdef DDEBUG  printf("Old Boot Sector:\n");  dump_sector(oldboot);#endif  bs = (struct bootsectortype *)&oldboot;  if (bs->bsBytesPerSec != SEC_SIZE)  {    printf("Sector size is not 512 but %d bytes - not currently supported!\n",      bs->bsBytesPerSec);    exit(1); /* Japan?! */  }  {   /* see "FAT: General Overview of On-Disk Format" v1.02, 5.V.1999    * (http://www.nondot.org/sabre/os/files/FileSystems/FatFormat.pdf)    */    ULONG fatSize, totalSectors, dataSectors, clusters;    UCOUNT rootDirSectors;    bs32 = (struct bootsectortype32 *)&oldboot;    rootDirSectors = (bs->bsRootDirEnts * DIRENT_SIZE  /* 32 */                 + bs32->bsBytesPerSec - 1) / bs32->bsBytesPerSec;    fatSize      = bs32->bsFATsecs ? bs32->bsFATsecs : bs32->bsBigFatSize;    totalSectors = bs32->bsSectors ? bs32->bsSectors : bs32->bsHugeSectors;    dataSectors = totalSectors      - bs32->bsResSectors - (bs32->bsFATs * fatSize) - rootDirSectors;    clusters = dataSectors / bs32->bsSecPerClust;     if (clusters < FAT_MAGIC)        /* < 4085 */      fs = FAT12;    else if (clusters < FAT_MAGIC16) /* < 65525 */      fs = FAT16;    else      fs = FAT32;  }  /* bit 0 set if function to use current BPB, clear if Device           BIOS Parameter Block field contains new default BPB     bit 1 set if function to use track layout fields only           must be clear if CL=60h     bit 2 set if all sectors in track same size (should be set) (RBIL) */  default_bpb[0] = 4;  if (fs == FAT32)  {    printf("FAT type: FAT32\n");    /* get default bpb (but not for floppies) */    if (drive >= 2 &&        generic_block_ioctl((unsigned char)drive + 1, 0x4860, default_bpb) == 0)      correct_bpb((struct bootsectortype *)(default_bpb + 7 - 11), bs);#ifdef WITHFAT32                /* copy one of the FAT32 boot sectors */    memcpy(newboot, haveLBA() ? fat32lba : fat32chs, SEC_SIZE);#else    printf("SYS hasn't been compiled with FAT32 support.\n"           "Consider using -DWITHFAT32 option.\n");    exit(1);#endif  }  else  { /* copy the FAT12/16 CHS+LBA boot sector */    printf("FAT type: FAT1%c\n", fs + '0' - 10);    if (drive >= 2 &&        generic_block_ioctl((unsigned char)drive + 1, 0x860, default_bpb) == 0)      correct_bpb((struct bootsectortype *)(default_bpb + 7 - 11), bs);    memcpy(newboot, fs == FAT16 ? fat16com : fat12com, SEC_SIZE);  }  /* Copy disk parameter from old sector to new sector */#ifdef WITHFAT32  if (fs == FAT32)    memcpy(&newboot[SBOFFSET], &oldboot[SBOFFSET], SBSIZE32);  else#endif    memcpy(&newboot[SBOFFSET], &oldboot[SBOFFSET], SBSIZE);  bs = (struct bootsectortype *)&newboot;  memcpy(bs->OemName, "FreeDOS ", 8);#ifdef WITHFAT32  if (fs == FAT32)  {    bs32 = (struct bootsectortype32 *)&newboot;    /* put 0 for A: or B: (force booting from A:), otherwise use DL */    bs32->bsDriveNumber = drive < 2 ? 0 : 0xff;    /* the location of the "0060" segment portion of the far pointer       in the boot sector is just before cont: in boot*.asm.       This happens to be offset 0x78 (=0x3c * 2) for FAT32 and       offset 0x5c (=0x2e * 2) for FAT16 */    /* i.e. BE CAREFUL WHEN YOU CHANGE THE BOOT SECTORS !!! */    ((int *)newboot)[0x3C] = load_seg;#ifdef DEBUG    printf(" FAT starts at sector %lx + %x\n",           bs32->bsHiddenSecs, bs32->bsResSectors);#endif  }  else#endif  {    /* put 0 for A: or B: (force booting from A:), otherwise use DL */    bs->bsDriveNumber = drive < 2 ? 0 : 0xff;    ((int *)newboot)[0x2E] = load_seg;  }#ifdef DEBUG /* add an option to display this on user request? */  printf("Root dir entries = %u\n", bs->bsRootDirEnts);  printf("FAT starts at sector (%lu + %u)\n",         bs->bsHiddenSecs, bs->bsResSectors);  printf("Root directory starts at sector (PREVIOUS + %u * %u)\n",         bs->bsFATsecs, bs->bsFATs);#endif  {    int i = 0;    memset(&newboot[0x1f1], ' ', 11);    while (kernel_name[i] && kernel_name[i] != '.')    {      if (i < 8)        newboot[0x1f1+i] = toupper(kernel_name[i]);      i++;    }    if (kernel_name[i] == '.')    {      /* copy extension */      int j = 0;      i++;      while (kernel_name[i+j] && j < 3)      {        newboot[0x1f9+j] = toupper(kernel_name[i+j]);        j++;      }    }  }#ifdef DEBUG  /* there's a zero past the kernel name in all boot sectors */  printf("Boot sector kernel name set to %s\n", &newboot[0x1f1]);  printf("Boot sector load segment set to %Xh\n", load_seg);#endif#ifdef DDEBUG  printf("\nNew Boot Sector:\n");  dump_sector(newboot);#endif  if ((bsFile == NULL) || both)  {#ifdef DEBUG    printf("writing new bootsector to drive %c:\n", drive + 'A');#endif    /* write newboot to a drive */    if (MyAbsReadWrite(drive, 1, 0, newboot, 1) != 0)    {      printf("Can't write new boot sector to drive %c:\n", drive + 'A');      exit(1);    }  } /* if write boot sector */  if (bsFile != NULL)  {    int fd;#ifdef DEBUG    printf("writing new bootsector to file %s\n", bsFile);#endif    /* write newboot to bsFile */    if ((fd = /* suggestion: do not trunc - allows to write to images */         open(bsFile, O_RDWR | O_TRUNC | O_CREAT | O_BINARY,              S_IREAD | S_IWRITE)) < 0)    {      printf(" %s: can't create\"%s\"\nDOS errnum %d", pgm, bsFile, errno);      exit(1);    }    if (write(fd, newboot, SEC_SIZE) != SEC_SIZE)    {      printf("Can't write %u bytes to %s\n", SEC_SIZE, bsFile);      close(fd);      unlink(bsFile);      exit(1);    }    close(fd);  } /* if write boot sector file */  reset_drive(drive);  /* unlock_drive */  generic_block_ioctl((unsigned char)drive + 1, 0x86a, NULL);} /* put_boot *//* * Returns TRUE if `drive` has at least `bytes` free space, FALSE otherwise. * put_sector() must have been already called to determine file system type. */BOOL check_space(COUNT drive, ULONG bytes){#ifdef WITHFAT32  if (fs == FAT32)  {    char *drivename = "A:\\";    drivename[0] = 'A' + drive;    getextdrivespace(drivename, &x, sizeof(x));    return x.xfs_freeclusters > (bytes / (x.xfs_clussize * x.xfs_secsize));  }  else#endif  {#ifdef __TURBOC__    struct dfree df;    getdfree(drive + 1, &df);    return (ULONG)df.df_avail * df.df_sclus * df.df_bsec >= bytes;#else    struct _diskfree_t df;    _dos_getdiskfree(drive + 1, &df);    return (ULONG)df.avail_clusters * df.sectors_per_cluster      * df.bytes_per_sector >= bytes;#endif  }} /* check_space */BYTE copybuffer[COPY_SIZE];BOOL copy(COUNT drive, BYTE * srcPath, BYTE * rootPath, BYTE * file){  static BYTE dest[SYS_MAXPATH], source[SYS_MAXPATH];  unsigned ret;  int fdin, fdout;  ULONG copied = 0;  struct stat fstatbuf;  strcpy(source, srcPath);  if (rootPath != NULL) /* trick for comspec */    strcat(source, file);  if (stat(source, &fstatbuf))  {    printf("%s: \"%s\" not found\n", pgm, source);    if ((rootPath != NULL) && (*rootPath) /* && (errno == ENOENT) */ )    {      sprintf(source, "%s%s", rootPath, file);      printf("%s: Trying \"%s\"\n", pgm, source);      if (stat(source, &fstatbuf))      {        printf("%s: \"%s\" not found\n", pgm, source);        return FALSE;      }    }    else      return FALSE;  }  truename(dest, source);  strcpy(source, dest);  sprintf(dest, "%c:\\%s", 'A' + drive, file);  if (stricmp(source, dest) == 0)  {    printf("%s: source and destination are identical: skipping \"%s\"\n",           pgm, source);    return TRUE;  }  if ((fdin = open(source, O_RDONLY | O_BINARY)) < 0)  {    printf("%s: failed to open \"%s\"\n", pgm, source);    return FALSE;  }  if (!check_space(drive, filelength(fdin)))  {    printf("%s: Not enough space to transfer %s\n", pgm, file);    close(fdin);    exit(1);  }  if ((fdout =       open(dest, O_RDWR | O_TRUNC | O_CREAT | O_BINARY,            S_IREAD | S_IWRITE)) < 0)  {    printf(" %s: can't create\"%s\"\nDOS errnum %d", pgm, dest, errno);    close(fdin);    return FALSE;  }  while ((ret = read(fdin, copybuffer, COPY_SIZE)) > 0)  {    if (write(fdout, copybuffer, ret) != ret)    {      printf("Can't write %u bytes to %s\n", ret, dest);      close(fdout);      unlink(dest);      break;    }    copied += ret;  }  {#if defined __WATCOMC__ || defined _MSC_VER /* || defined __BORLANDC__ */    unsigned short date, time;	      _dos_getftime(fdin, &date, &time);    _dos_setftime(fdout, date, time);#elif defined __TURBOC__    struct ftime ftime;    getftime(fdin, &ftime);    setftime(fdout, &ftime);#endif  }  close(fdin);  close(fdout);#ifdef __SOME_OTHER_COMPILER__  {#include <utime.h>    struct utimbuf utimb;    utimb.actime =              /* access time */        utimb.modtime = fstatbuf.st_mtime;      /* modification time */    utime(dest, &utimb);  };#endif  printf("%lu Bytes transferred", copied);  return TRUE;} /* copy */

⌨️ 快捷键说明

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