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

📄 sys.c

📁 GNU FreeDOS兼容MS DOS很好的东东.
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************                                    sys.c                                    DOS-C                            sys utility for DOS-C                             Copyright (c) 1991                             Pasquale J. Villani                             All Rights Reserved This file is part of DOS-C. DOS-C is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. DOS-C is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with DOS-C; see the file COPYING.  If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.***************************************************************/#define DEBUG/* #define DDEBUG */#define SYS_VERSION "v3.2"#include <stdlib.h>#include <dos.h>#include <ctype.h>#include <fcntl.h>#include <sys/stat.h>#ifdef __TURBOC__#include <mem.h>#else#include <memory.h>#endif#include <string.h>#ifdef __TURBOC__#include <dir.h>#endif#define SYS_MAXPATH   260#include "portab.h"#include "algnbyte.h"#include "device.h"#include "dcb.h"#include "xstructs.h"#include "date.h"#include "../hdr/time.h"#include "fat.h"/* These definitions deliberately put here instead of * #including <stdio.h> to make executable MUCH smaller * using [s]printf from prf.c! */extern int VA_CDECL printf(const char * fmt, ...);extern int VA_CDECL sprintf(char * buff, const char * fmt, ...);#include "fat12com.h"#include "fat16com.h"#ifdef WITHFAT32#include "fat32chs.h"#include "fat32lba.h"#endif#ifndef __WATCOMC__#include <io.h>#elselong filelength(int __handle);#pragma aux filelength = \      "mov ax, 0x4202" \      "xor cx, cx" \      "xor dx, dx" \      "int 0x21" \      "push ax" \      "push dx" \      "mov ax, 0x4200" \      "xor cx, cx" \      "xor dx, dx" \      "int 0x21" \      "pop dx" \      "pop ax" \      parm [bx] \      modify [cx] \      value [dx ax];extern int unlink(const char *pathname);/* some non-conforming functions to make the executable smaller */int open(const char *pathname, int flags, ...){  int handle;  int result = (flags & O_CREAT ?                _dos_creat(pathname, _A_NORMAL, &handle) :                _dos_open(pathname, flags & (O_RDONLY | O_WRONLY | O_RDWR),                          &handle));  return (result == 0 ? handle : -1);}int read(int fd, void *buf, unsigned count){  unsigned bytes;  int result = _dos_read(fd, buf, count, &bytes);  return (result == 0 ? bytes : -1);}int write(int fd, const void *buf, unsigned count){  unsigned bytes;  int result = _dos_write(fd, buf, count, &bytes);  return (result == 0 ? bytes : -1);}#define close _dos_closeint stat(const char *file_name, struct stat *buf){  struct find_t find_tbuf;  UNREFERENCED_PARAMETER(buf);  return _dos_findfirst(file_name, _A_NORMAL | _A_HIDDEN | _A_SYSTEM, &find_tbuf);}/* WATCOM's getenv is case-insensitive which wastes a lot of space   for our purposes. So here's a simple case-sensitive one */char *getenv(const char *name){  char **envp, *ep;  const char *np;  char ec, nc;  for (envp = environ; (ep = *envp) != NULL; envp++) {    np = name;    do {      ec = *ep++;      nc = *np++;      if (nc == 0) {        if (ec == '=')          return ep;        break;      }    } while (ec == nc);  }  return NULL;}#endifBYTE pgm[] = "SYS";void put_boot(int, char *, char *, int, int);BOOL check_space(COUNT, ULONG);BOOL copy(COUNT drive, BYTE * srcPath, BYTE * rootPath, BYTE * file);#define SEC_SIZE        512#define COPY_SIZE	0x7e00struct bootsectortype {  UBYTE bsJump[3];  char OemName[8];  UWORD bsBytesPerSec;  UBYTE bsSecPerClust;  UWORD bsResSectors;  UBYTE bsFATs;  UWORD bsRootDirEnts;  UWORD bsSectors;  UBYTE bsMedia;  UWORD bsFATsecs;  UWORD bsSecPerTrack;  UWORD bsHeads;  ULONG bsHiddenSecs;  ULONG bsHugeSectors;  UBYTE bsDriveNumber;  UBYTE bsReserved1;  UBYTE bsBootSignature;  ULONG bsVolumeID;  char bsVolumeLabel[11];  char bsFileSysType[8];};struct bootsectortype32 {  UBYTE bsJump[3];  char OemName[8];  UWORD bsBytesPerSec;  UBYTE bsSecPerClust;  UWORD bsResSectors;  UBYTE bsFATs;  UWORD bsRootDirEnts;  UWORD bsSectors;  UBYTE bsMedia;  UWORD bsFATsecs;  UWORD bsSecPerTrack;  UWORD bsHeads;  ULONG bsHiddenSecs;  ULONG bsHugeSectors;  ULONG bsBigFatSize;  UBYTE bsFlags;  UBYTE bsMajorVersion;  UWORD bsMinorVersion;  ULONG bsRootCluster;  UWORD bsFSInfoSector;  UWORD bsBackupBoot;  ULONG bsReserved2[3];  UBYTE bsDriveNumber;  UBYTE bsReserved3;  UBYTE bsExtendedSignature;  ULONG bsSerialNumber;  char bsVolumeLabel[11];  char bsFileSystemID[8];};/* * globals needed by put_boot & check_space */enum {FAT12 = 12, FAT16 = 16, FAT32 = 32} fs;  /* file system type *//* static */ struct xfreespace x; /* we make this static to be 0 by default -                                     this avoids FAT misdetections */#define SBOFFSET        11#define SBSIZE          (sizeof(struct bootsectortype) - SBOFFSET)#define SBSIZE32        (sizeof(struct bootsectortype32) - SBOFFSET)/* essentially - verify alignment on byte boundaries at compile time  */struct VerifyBootSectorSize {  char failure1[sizeof(struct bootsectortype) == 62 ? 1 : -1];  char failure2[sizeof(struct bootsectortype) == 62 ? 1 : 0];/* (Watcom has a nice warning for this, by the way) */};int FDKrnConfigMain(int argc, char **argv);int main(int argc, char **argv){  COUNT drive;                  /* destination drive */  COUNT drivearg = 0;           /* drive argument position */  COUNT srcarg = 0;             /* source argument position */  BYTE *bsFile = NULL;          /* user specified destination boot sector */  unsigned srcDrive;            /* source drive */  BYTE srcPath[SYS_MAXPATH];    /* user specified source drive and/or path */  BYTE rootPath[4];             /* alternate source path to try if not '\0' */  WORD slen;  int argno = 0;  int bootonly = 0;  int both = 0;  char *kernel_name = "KERNEL.SYS";  int load_segment = 0x60;  printf("FreeDOS System Installer " SYS_VERSION ", " __DATE__ "\n\n");  if (argc > 1 && memicmp(argv[1], "CONFIG", 6) == 0)  {    exit(FDKrnConfigMain(argc, argv));  }  for(argno = 1; argno < argc; argno++)  {    char *argp = argv[argno];    if (argp[1] == ':' && argp[2] == '\0' && drivearg <= srcarg)      drivearg = argno;    if (srcarg == 0)    {      srcarg = argno;    }    else if (argp[0] == '/' && toupper(argp[1]) == 'K' && argno + 1 < argc)    {      argno++;      kernel_name = argv[argno];    }    else if (argp[0] == '/' && toupper(argp[1]) == 'L' && argno + 1 < argc)    {      argno++;      load_segment = (int)strtol(argv[argno], NULL, 16);    }    else if (memicmp(argp, "BOOTONLY", 8) == 0 && !bootonly)    {      bootonly = 1;    }    else if (memicmp(argp, "BOTH", 4) == 0 && !both)    {      both = 1;    }    else if (drivearg != argno)    {      if (bsFile == NULL)      {        bsFile = argp;      }      else      {        drivearg = 0;        break;      }    }  }  if (drivearg == 0)  {    printf(      "Usage: %s [source] drive: [bootsect [BOTH]] [BOOTONLY] [/K name] [/L segm]\n"      "  source   = A:,B:,C:\\KERNEL\\BIN\\,etc., or current directory if not given\n"      "  drive    = A,B,etc.\n"      "  bootsect = name of 512-byte boot sector file image for drive:\n"      "             to write to *instead* of real boot sector\n"      "  BOTH     : write to *both* the real boot sector and the image file\n"      "  BOOTONLY : do *not* copy kernel / shell, only update boot sector or image\n"      "  /K name  : name of kernel to use instead of KERNEL.SYS\n"      "  /L segm  : hex load segment to use instead of 60\n"      "%s CONFIG /help\n", pgm, pgm);    exit(1);  }  drive = toupper(argv[drivearg][0]) - 'A';  if (drive < 0 || drive >= 26)  {    printf("%s: drive %c must be A:..Z:\n", pgm,           *argv[(argc == 3 ? 2 : 1)]);    exit(1);  }  srcPath[0] = '\0';  if (drivearg > srcarg && srcarg)  {    strncpy(srcPath, argv[srcarg], SYS_MAXPATH - 12);    /* leave room for COMMAND.COM\0 */    srcPath[SYS_MAXPATH - 13] = '\0';    /* make sure srcPath + "file" is a valid path */    slen = strlen(srcPath);    if ((srcPath[slen - 1] != ':') &&        ((srcPath[slen - 1] != '\\') || (srcPath[slen - 1] != '/')))    {      srcPath[slen] = '\\';      slen++;      srcPath[slen] = '\0';    }  }  /* Get source drive */  if ((strlen(srcPath) > 1) && (srcPath[1] == ':'))     /* src specifies drive */    srcDrive = toupper(*srcPath) - 'A';  else                          /* src doesn't specify drive, so assume current drive */  {#ifdef __TURBOC__    srcDrive = (unsigned) getdisk();#else    _dos_getdrive(&srcDrive);    srcDrive--;#endif  }  /* Don't try root if src==dst drive or source path given */  if ((drive == srcDrive)      || (*srcPath          && ((srcPath[1] != ':') || ((srcPath[1] == ':') && srcPath[2]))))    *rootPath = '\0';  else    sprintf(rootPath, "%c:\\", 'A' + srcDrive);  printf("Processing boot sector...\n");  put_boot(drive, bsFile, kernel_name, load_segment, both);  if (!bootonly)  {    printf("\nCopying %s...\n", kernel_name);    if (!copy(drive, srcPath, rootPath, kernel_name))    {      printf("\n%s: cannot copy \"%s\"\n", pgm, kernel_name);      exit(1);    } /* copy kernel */    printf("\nCopying COMMAND.COM...\n");    if (!copy(drive, srcPath, rootPath, "COMMAND.COM"))    {      char *comspec = getenv("COMSPEC");      if (comspec != NULL)      {        printf("%s: Trying \"%s\"\n", pgm, comspec);        if (!copy(drive, comspec, NULL, "COMMAND.COM"))          comspec = NULL;      }      if (comspec == NULL)      {        printf("\n%s: cannot copy \"COMMAND.COM\"\n", pgm);        exit(1);      }    } /* copy shell */  }  printf("\nSystem transferred.\n");  return 0;}#ifdef DDEBUGVOID dump_sector(unsigned char far * sec){  COUNT x, y;  char c;  for (x = 0; x < 32; x++)  {    printf("%03X  ", x * 16);    for (y = 0; y < 16; y++)    {      printf("%02X ", sec[x * 16 + y]);    }    for (y = 0; y < 16; y++)    {      c = sec[x * 16 + y];      if (isprint(c))        printf("%c", c);      else        printf(".");    }    printf("\n");  }  printf("\n");}#endif#ifdef __WATCOMC__int absread(int DosDrive, int nsects, int foo, void *diskReadPacket);#pragma aux absread =  \      "push bp"           \      "int 0x25"          \      "sbb ax, ax"        \      "popf"              \      "pop bp"            \      parm [ax] [cx] [dx] [bx] \      modify [si di] \      value [ax];int abswrite(int DosDrive, int nsects, int foo, void *diskReadPacket);#pragma aux abswrite =  \      "push bp"           \      "int 0x26"          \      "sbb ax, ax"        \      "popf"              \      "pop bp"            \      parm [ax] [cx] [dx] [bx] \      modify [si di] \      value [ax];int fat32readwrite(int DosDrive, void *diskReadPacket, unsigned intno);#pragma aux fat32readwrite =  \      "mov ax, 0x7305"    \      "mov cx, 0xffff"    \      "int 0x21"          \      "sbb ax, ax"        \      parm [dx] [bx] [si] \      modify [cx dx si]   \      value [ax];void reset_drive(int DosDrive);#pragma aux reset_drive = \      "push ds" \      "inc dx" \      "mov ah, 0xd" \       "int 0x21" \      "mov ah,0x32" \      "int 0x21" \      "pop ds" \      parm [dx] \      modify [ax bx];void truename(char far *dest, const char *src);#pragma aux truename = \      "mov ah,0x60"	  \      "int 0x21"          \      parm [es di] [si];int generic_block_ioctl(unsigned char drive, unsigned cx, unsigned char *par);#pragma aux generic_block_ioctl = \      "mov ax, 0x440d" \      "int 0x21" \      "sbb ax, ax" \      value [ax] \      parm [bl] [cx] [dx];#else#ifndef __TURBOC__int2526readwrite(int DosDrive, void *diskReadPacket, unsigned intno){  union REGS regs;  regs.h.al = (BYTE) DosDrive;  regs.x.bx = (short)diskReadPacket;  regs.x.cx = 0xffff;  int86(intno, &regs, &regs);  return regs.x.cflag;}#define absread(DosDrive, foo, cx, diskReadPacket) \int2526readwrite(DosDrive, diskReadPacket, 0x25)#define abswrite(DosDrive, foo, cx, diskReadPacket) \int2526readwrite(DosDrive, diskReadPacket, 0x26)#endiffat32readwrite(int DosDrive, void *diskReadPacket, unsigned intno)

⌨️ 快捷键说明

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