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

📄 mkdosfs.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
  for (x = 1; x <= nr_fats; x++)
#ifdef _WIN32
	  /*
	   * WIN32 appearently has problems writing very large chunks directly
	   * to disk devices. To not produce errors because of resource shortages
	   * split up the write in sector size chunks.
	   */
	  for (blk = 0; blk < fat_length; blk++)
		  writebuf(fat+blk*sector_size, sector_size, "FAT");
#else
    writebuf( fat, fat_length * sector_size, "FAT" );
#endif
  /* Write the root directory directly after the last FAT. This is the root
   * dir area on FAT12/16, and the first cluster on FAT32. */
  writebuf( (char *) root_dir, size_root_dir, "root directory" );

  if (info_sector) free( info_sector );
  free (root_dir);   /* Free up the root directory space from setup_tables */
  free (fat);  /* Free up the fat table space reserved during setup_tables */
}


/* Report the command usage and return a failure error code */

void
usage (void)
{
  fatal_error("\
Usage: mkdosfs [-A] [-c] [-C] [-v] [-I] [-l bad-block-file] [-b backup-boot-sector]\n\
       [-m boot-msg-file] [-n volume-name] [-i volume-id]\n\
       [-s sectors-per-cluster] [-S logical-sector-size] [-f number-of-FATs]\n\
       [-F fat-size] [-r root-dir-entries] [-R reserved-sectors]\n\
       /dev/name [blocks]\n");
}

/*
 * ++roman: On m68k, check if this is an Atari; if yes, turn on Atari variant
 * of MS-DOS filesystem by default.
 */
static void check_atari( void )
{
#ifdef __mc68000__
    FILE *f;
    char line[128], *p;

    if (!(f = fopen( "/proc/hardware", "r" ))) {
	perror( "/proc/hardware" );
	return;
    }

    while( fgets( line, sizeof(line), f ) ) {
	if (strncmp( line, "Model:", 6 ) == 0) {
	    p = line + 6;
	    p += strspn( p, " \t" );
	    if (strncmp( p, "Atari ", 6 ) == 0)
		atari_format = 1;
	    break;
	}
    }
    fclose( f );
#endif
}

/* The "main" entry point into the utility - we pick up the options and attempt to process them in some sort of sensible
   way.  In the event that some/all of the options are invalid we need to tell the user so that something can be done! */

int
main (int argc, char **argv)
{
  int c;
  char *tmp;
  char *listfile = NULL;
  FILE *msgfile;
#ifdef _WIN32
  static char dev_buf[] = "\\\\.\\X:";
#else
  struct stat statbuf;
#endif
  int i = 0, pos, ch;
  int create = 0;
  
  if (argc && *argv) {		/* What's the program name? */
    char *p;
    program_name = *argv;
#ifdef _WIN32
    if ((p = strrchr( program_name, '\\' )))
#else
    if ((p = strrchr( program_name, '/' )))
#endif
	program_name = p+1;
  }

  time(&create_time);
  volume_id = (long)create_time;	/* Default volume ID = creation time */
  check_atari();
  
  printf ("%s " VERSION " (" VERSION_DATE ")\n"
#ifdef _WIN32
	  "Win32 port by Jens-Uwe Mager <jum@anubis.han.de>\n"
#endif
	   , program_name);

  while ((c = getopt (argc, argv, "AcCf:F:Ii:l:m:n:r:R:s:S:v")) != EOF)
    /* Scan the command line for options */
    switch (c)
      {
      case 'A':		/* toggle Atari format */
	atari_format = !atari_format;
	break;

      case 'b':		/* b : location of backup boot sector */
	backup_boot = (int) strtol (optarg, &tmp, 0);
	if (*tmp || backup_boot < 2 || backup_boot > 0xffff)
	  {
	    printf ("Bad location for backup boot sector : %s\n", optarg);
	    usage ();
	  }
	break;
	
      case 'c':		/* c : Check FS as we build it */
	check = TRUE;
	break;

      case 'C':		/* C : Create a new file */
	create = TRUE;
	break;

      case 'f':		/* f : Choose number of FATs */
	nr_fats = (int) strtol (optarg, &tmp, 0);
	if (*tmp || nr_fats < 1 || nr_fats > 4)
	  {
	    printf ("Bad number of FATs : %s\n", optarg);
	    usage ();
	  }
	break;

      case 'F':		/* F : Choose FAT size */
	size_fat = (int) strtol (optarg, &tmp, 0);
	if (*tmp || (size_fat != 12 && size_fat != 16 && size_fat != 32))
	  {
	    printf ("Bad FAT type : %s\n", optarg);
	    usage ();
	  }
	size_fat_by_user = 1;
	break;

      case 'I':
	ignore_full_disk = 1;
	break;

      case 'i':		/* i : specify volume ID */
	volume_id = strtol(optarg, &tmp, 16);
	if ( *tmp )
	  {
	    printf("Volume ID must be a hexadecimal number\n");
	    usage();
	  }
	break;

      case 'l':		/* l : Bad block filename */
	listfile = optarg;
	break;

      case 'm':		/* m : Set boot message */
	if ( strcmp(optarg, "-") )
	  {
	    msgfile = fopen(optarg, "r");
	    if ( !msgfile )
	      perror(optarg);
	  }
	else
	  msgfile = stdin;

	if ( msgfile )
	  {
	    /* The boot code ends at offset 448 and needs a null terminator */
	    i = MESSAGE_OFFSET;
	    pos = 0;		/* We are at beginning of line */
	    do
	      {
		ch = getc(msgfile);
		switch (ch)
		  {
		  case '\r':	/* Ignore CRs */
		  case '\0':	/* and nulls */
		    break;

		  case '\n':	/* LF -> CR+LF if necessary */
		    if ( pos )	/* If not at beginning of line */
		      {
			dummy_boot_code[i++] = '\r';
			pos = 0;
		      }
		    dummy_boot_code[i++] = '\n';
		    break;

		  case '\t':	/* Expand tabs */
		    do
		      {
			dummy_boot_code[i++] = ' ';
			pos++;
		      }
		    while ( pos % 8 && i < BOOTCODE_SIZE-1 );
		    break;

		  case EOF:
		    dummy_boot_code[i++] = '\0'; /* Null terminator */
		    break;

		  default:
		    dummy_boot_code[i++] = ch; /* Store character */
		    pos++;	/* Advance position */
		    break;
		  }
	      }
	    while ( ch != EOF && i < BOOTCODE_SIZE-1 );

	    /* Fill up with zeros */
	    while( i < BOOTCODE_SIZE-1 )
		dummy_boot_code[i++] = '\0';
	    dummy_boot_code[BOOTCODE_SIZE-1] = '\0'; /* Just in case */
	    
	    if ( ch != EOF )
	      printf ("Warning: message too long; truncated\n");
	    
	    if ( msgfile != stdin )
	      fclose(msgfile);
	  }
	break;

      case 'n':		/* n : Volume name */
	sprintf(volume_name, "%-11.11s", optarg);
	break;

      case 'r':		/* r : Root directory entries */
	root_dir_entries = (int) strtol (optarg, &tmp, 0);
	if (*tmp || root_dir_entries < 16 || root_dir_entries > 32768)
	  {
	    printf ("Bad number of root directory entries : %s\n", optarg);
	    usage ();
	  }
	break;

      case 'R':		/* R : number of reserved sectors */
	reserved_sectors = (int) strtol (optarg, &tmp, 0);
	if (*tmp || reserved_sectors < 1 || reserved_sectors > 0xffff)
	  {
	    printf ("Bad number of reserved sectors : %s\n", optarg);
	    usage ();
	  }
	break;
	
      case 's':		/* s : Sectors per cluster */
	sectors_per_cluster = (int) strtol (optarg, &tmp, 0);
	if (*tmp || (sectors_per_cluster != 1 && sectors_per_cluster != 2
		     && sectors_per_cluster != 4 && sectors_per_cluster != 8
		   && sectors_per_cluster != 16 && sectors_per_cluster != 32
		&& sectors_per_cluster != 64 && sectors_per_cluster != 128))
	  {
	    printf ("Bad number of sectors per cluster : %s\n", optarg);
	    usage ();
	  }
	break;

      case 'S':		/* S : Sector size */
	sector_size = (int) strtol (optarg, &tmp, 0);
	if (*tmp || (sector_size != 512 && sector_size != 1024 &&
		     sector_size != 2048 && sector_size != 4096 &&
		     sector_size != 8192 && sector_size != 16384 &&
		     sector_size != 32768))
	  {
	    printf ("Bad logical sector size : %s\n", optarg);
	    usage ();
	  }
	sector_size_set = 1;
	break;

      case 'v':		/* v : Verbose execution */
	++verbose;
	break;
	
      default:
	printf( "Unknown option: %c\n", c );
	usage ();
      }

  if (optind >= argc)
	  usage();
  device_name = argv[optind];	/* Determine the number of blocks in the FS */
#ifdef _WIN32
  if (device_name[1] == ':' && device_name[2] == '\0') {
	  dev_buf[4] = device_name[0];
	  device_name = dev_buf;
	  is_device = 1;
  }
#endif
  if (!create)
    i = count_blocks (device_name); /*  Have a look and see! */
  if (optind == argc - 2)	/*  Either check the user specified number */
    {
      blocks = (int) strtol (argv[optind + 1], &tmp, 0);
      if (!create && blocks != i)
	{
	  fprintf (stderr, "Warning: block count mismatch: ");
	  fprintf (stderr, "found %d but assuming %d.\n",i,blocks);
	}
    }
  else if (optind == argc - 1)	/*  Or use value found */
    {
      if (create)
	die( "Need intended size with -C." );
      blocks = i;
      tmp = "";
    }
  else
    usage ();
  if (*tmp)
    {
      printf ("Bad block count : %s\n", argv[optind + 1]);
      usage ();
    }

  if (check && listfile)	/* Auto and specified bad block handling are mutually */
    die ("-c and -l are incompatible");		/* exclusive of each other! */

  if (!create) {
    check_mount (device_name);	/* Is the device already mounted? */
    dev = open (device_name, O_RDWR|O_SHARED);	/* Is it a suitable device to build the FS on? */
    if (dev < 0)
      die ("unable to open %s");
#ifdef _WIN32
	if (is_device) {
		if (fsctl(dev, FSCTL_LOCK_VOLUME) == -1)
			die("unable to lock %s");
	}
#endif
  }
  else {
      loff_t offset = blocks*BLOCK_SIZE - 1;
      char null = 0;
      /* create the file */
      dev = open( device_name, O_RDWR|O_CREAT|O_TRUNC, 0775 );
      if (dev < 0)
	die("unable to create %s");
      /* seek to the intended end-1, and write one byte. this creates a
       * sparse-as-possible file of appropriate size. */
      if (llseek( dev, offset, SEEK_SET ) != offset)
	die( "seek failed" );
      if (write( dev, &null, 1 ) < 0)
	die( "write failed" );
      if (llseek( dev, 0, SEEK_SET ) != 0)
	die( "seek failed" );
  }
  
#ifdef _WIN32
  if (!is_device)
	  check = 0;
  establish_params();
#else
  if (fstat (dev, &statbuf) < 0)
    die ("unable to stat %s");
  if (!S_ISBLK (statbuf.st_mode)) {
    statbuf.st_rdev = 0;
    check = 0;
  }
  else
    /*
     * Ignore any 'full' fixed disk devices, if -I is not given.
     * On a MO-disk one doesn't need partitions.  The filesytem can go
     * directly to the whole disk.  Under other OSes this is known as
     * the 'superfloppy' format.  As I don't know how to find out if
     * this is a MO disk I introduce a -I (ignore) switch.  -Joey
     */
    if (!ignore_full_disk && (
	(statbuf.st_rdev & 0xff3f) == 0x0300 || /* hda, hdb */
	(statbuf.st_rdev & 0xff0f) == 0x0800 || /* sd */
	(statbuf.st_rdev & 0xff3f) == 0x0d00 || /* xd */
	(statbuf.st_rdev & 0xff3f) == 0x1600 )  /* hdc, hdd */
	)
      die ("Will not try to make filesystem on '%s'");

  establish_params (statbuf.st_rdev,statbuf.st_size);	
                                /* Establish the media parameters */
#endif

  setup_tables ();		/* Establish the file system tables */

  if (check)			/* Determine any bad block locations and mark them */
    check_blocks ();
  else if (listfile)
    get_list_blocks (listfile);

  write_tables ();		/* Write the file system tables away! */

#ifdef _WIN32
	if (is_device) {
		if (fsctl(dev, FSCTL_DISMOUNT_VOLUME) == -1)
			die("unable to dismount %s");
		if (fsctl(dev, FSCTL_UNLOCK_VOLUME) == -1)
			die("unable to unlock %s");
	}
#endif
  exit (0);			/* Terminate with no errors! */
}


/* That's All Folks */
/* Local Variables: */
/* tab-width: 8     */
/* End:             */

⌨️ 快捷键说明

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