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

📄 main.c

📁 可以格式化超过200G硬盘的格式化工具
💻 C
字号:
/*
// Program:  Format
// Version:  0.92
// (0.90b/c/d/e/f - mixed improvements - Eric Auer 2003)
// Written By:  Brian E. Reifsnyder
// Copyright:  2003 under the terms of the GNU GPL, Version 2
// Module Name:  main.c
// Module Description:  Main Module
*/

#define MAIN


#include <dir.h>
#include <stdio.h>
#include <ctype.h>			/* (jh) for isalpha, ... */
#include <string.h> /* strncpy */
#include <dos.h>

#include "format.h"
#include "hdisk.h"

#include "init.h"
#include "userint.h"
#include "createfs.h"
#include "uformat.h"
#include "btstrct.h"
#include "savefs.h"

#include "driveio.h"
#include "floppy.h"

#include "getopt.h"			/* (jh) support for getopt */

char Check_For_Format(void);
void Write_System_Files(void);


void Initialization(void);
void Unconditional_Format(void);
void Record_Bad_Clusters(void);
void Set_Floppy_Media_Type(void);
void Enable_Disk_Access(void);



/* Check to see if the media is formatted.  */
/* Returns TRUE if formatted and FALSE if it is not formatted. */
/* Non-DOS formats count as formats as well! (Eric) */
char Check_For_Format(void)
{
  union REGS regs;

  regs.h.ah = 0x0d;
  intdos(&regs,&regs); /* flush buffers, reset disk system */

  if (param.drive_number < 2) /* floppy? */
    {
    if (Drive_IO(READ, 0L, 1) == 0) /* try DIRECT sector read first */
      {
      /* still have to analyze DPB below */
      /* *** TODO: analyze current format TYPE found in sector *** */
      /* *** (to avoid "quickformat in spite of size change"). *** */
      }
    else
      {
      printf("  Boot sector unreadable, disk not yet formatted\n");
      return FALSE;
      }
    } /* end floppy */

  regs.h.ah = 0x32;
  regs.h.dl = param.drive_number + 1; /* 0 default 1 A: 2 B: ... */
  intdosx(&regs,&regs,&sregs); /* re-read DPB for that drive */
  /* this can cause a critical error if boot sector not readable! */

  if (regs.h.al == 0)
    {
    /* could analyze returned DPB - pointer is DS:BX */
    return TRUE;
    }
  else
    {
    printf("  DPB not available - network drive?\n");
    return FALSE; /* this is a network drive or something */
    }

}


/* Write System Files */
void Write_System_Files(void)
{
  int sys_found = FALSE;
  char sys[9] = {'s','y','s',' ','x',':',13,0,0};

  /* Check for the sys command. */
  if (NULL!=searchpath("sys.com") ) sys_found = TRUE;
  if (NULL!=searchpath("sys.exe") ) sys_found = TRUE;

  if (sys_found==TRUE)
    {
    /* Issue the command to write system files. */
    sys[4]=param.drive_letter[0];
    printf("\nRunning SYS command: %s\n",sys);
    system(sys);
    }
  else
    {
    printf("\n Error:  The SYS command has not been located.\n");
    printf(  "         System files have not be written to the disk.\n");
    }
}


/*
/////////////////////////////////////////////////////////////////////////////
//  MAIN ROUTINE
/////////////////////////////////////////////////////////////////////////////
*/
void main(int argc, char *argv[])
{
  int ch;
  int index;
  int n;
  int found_format_sectors_per_track = 0;
  int found_format_heads = 0;

  int drive_letter_found = FALSE;

  Initialization();


  param.n = FALSE;
  param.t = FALSE;
  param.v = FALSE;
  param.q = FALSE;
  param.u = FALSE;
  param.b = FALSE;
  param.s = FALSE;
  param.f = FALSE;
  param.one = FALSE;
  param.four = FALSE;
  param.eight = FALSE;
  debug_prog = FALSE;


  /* if FORMAT is typed without any options */

  if (argc == 1)
    {
    Display_Help_Screen();
    exit(1);
    }

  /* (jh) check command line */

  while (  (index = getopt (argc, argv, "V:v:QqUuBbSsYy148F:f:T:t:N:n:/")) != EOF)
    {
      switch(index)
	{
	case 'V':
	case 'v':
	  param.v=TRUE;
	  /* avoid overflow of param.volume_label (12 chars) */
	  /* need to skip over first character (':') */

	  strncpy (param.volume_label, optarg+1, 11);
	  param.volume_label[11] = '\0';

	  for (n = 0; param.volume_label[n] != '\0'; n++)
	    {
	      ch = param.volume_label[n];
	      param.volume_label[n] = toupper (ch);
	    }
	  break;
	case 'Q': /* quick - flush metadata only */
	case 'q':
	  param.q =TRUE;
	  break;
	case 'U': /* unconditional - full format */
	case 'u':
	  param.u=TRUE;
	  break;
	case 'B': /* reserve space for system, deprecated */
	case 'b':
	  param.b=TRUE;
	  break;
	case 'S': /* run SYS command */
	case 's':
	  param.s=TRUE;
	  break;
	case 'Y': /* assume yes on questions - undocumented */
	case 'y':
	  param.force_yes=TRUE;
	  break;
	case 'D': /* debug mode, more verbose output */
	case 'd':
	  debug_prog=TRUE;
	  break;
	case '1': /* one side only */
	  param.one=TRUE;
	  break;
	case '4': /* 360k disk in 1.2M drive */
	  param.four=TRUE;
	  break;
	case '8': /* 8 sectors per track */
	  param.eight=TRUE;
	  break;

	case 'F':           /* /F:size */
	case 'f':           /* /F:size */
	  param.f=TRUE;
	  n = atoi (optarg + 1);

	  if ((n == 160) || (n == 180) || (n == 320) || (n == 360) ||
	      (n == 720) || (n == 1200) || (n == 1440) || (n == 2880) ||
              (n == 400) || (n == 800) || (n == 1680) || (n == 3360) ||
              (n == 1494) || (n == 1743) || (n == 3486))
	    {
	    param.size = n;
	    }
	  else
	    {
            printf("Ok: 160, 180, 320, 360, 720, 1200, 1440, 2880.\n");
            printf("???: 400, 800, 1680, 3360,   1494, 1743, 3486.\n");
	    IllegalArg("/F",optarg);
	    }
	  break;

	case 'T': /* tracks (cylinders) */
	case 't': /* tracks (cylinders) */
	  param.t=TRUE;
	  n = atoi (optarg + 1);

	  if ((n == 40) || (n == 80) || (n == 83))
	    {
	    param.cylinders = n;
	    }
	  else
	    {
            printf("Ok: 40, 80. ???: 83.\n");
	    IllegalArg("/T",optarg);
	    }
	  break;

	case 'N': /* sectors per track */
	case 'n': /* sectors per track */
	  param.n=TRUE;
	  n = atoi (optarg + 1);

	  if ((n == 8) || (n == 9) || (n == 15) || (n == 18) || (n == 36) ||
              (n == 10) || (n == 21) || (n == 42))
	    {
	    param.sectors = n;
	    }
	  else
	    {
            printf("Ok: 8, 9, 15, 18, 36. ???: 10, 21, 42.\n");
	    IllegalArg("/N",optarg);
	    }
	  break;

	case '~':
	  param.drive_letter[0] = toupper (optarg[0]);
	  param.drive_number = param.drive_letter[0] - 'A';
	  param.drive_letter[1] = ':';
	  drive_letter_found = TRUE;
	  break;

	default:
	  printf("Unrecognized option: /%c\n", index);
	  Display_Help_Screen();
	  exit(1);
	case '/':			/* Ignore '/' in middle of option */
	  break;
	}       /* switch (index) */
    }         /* for all args (getopt) */


  if ( (argc > optind) && (isalpha (argv[optind][0])) &&
       (argv[optind][1] == ':') && (argv[optind][2] == '\0') &&
       (drive_letter_found == FALSE) )
    {
    param.drive_letter[0] = toupper (argv[optind][0]);
    param.drive_number = param.drive_letter[0] - 'A';
    param.drive_letter[1] = ':';
    }
  else
    if (drive_letter_found == FALSE)
      {
      printf("Required parameter missing -\n");
      exit(1);
      }

  /* (jh) done with parsing command line */

  /* if FORMAT is typed with a drive letter */

  if (debug_prog==TRUE)
    printf("\n[DEBUG]  Drive To Format->  %s \n\n",param.drive_letter);

  /* Set the type of disk */
  if (param.drive_number>1)
    param.drive_type=HARD;
  else
    param.drive_type=FLOPPY;


  /* *** TODO: complain about ANY size determination if type HARD *** */


  /* Ensure that valid switch combinations were entered */
  if ( (param.b==TRUE) && (param.s==TRUE) )
    Display_Invalid_Combination();
    /* cannot reserve space for SYS and actually SYS at the same time */
  if ( (param.v==TRUE) && (param.eight==TRUE) )
    Display_Invalid_Combination();
    /* no label allowed if 160k / 320k */

  if ( ( (param.one==TRUE) || (param.four==TRUE) /* 360k in 1.2M drive */ ) &&
       ( (param.f==TRUE) || (param.t==TRUE) || (param.n==TRUE) ) )
    Display_Invalid_Combination();
    /* cannot combine size/track/sector override with 1-sided / 360k */

  if ( ( (param.t==TRUE) && (param.n!=TRUE) ) || 
       ( (param.n==TRUE) && (param.t!=TRUE) ) ) 
    {
    printf("You can only give /T -and- /N or -neither- of them.\n");
    Display_Invalid_Combination();
    /* you must give BOTH track and sector arguments if giving either */
    }

  if ( (param.f==TRUE) && ( (param.t==TRUE) || (param.n==TRUE) ) )
    Display_Invalid_Combination();
    /* you can only give EITHER size OR track/sector arguments */
  
#if 0
  if ( ( (param.one==TRUE) || (param.four==TRUE) ) && (param.eight==TRUE) )
    Display_Invalid_Combination();
    /* 360k / one-sided are both not 8 sectors per track (360k is 40x2x9) */
#endif

  /* we do allow /8 to reach 160k (with /1) and 320k (with /4) */
  /* it is more the other way round: we do not want 8 sector/track > 320k! */


/* ... */


  if (param.one==TRUE) /* one-sided: 160k and 180k only */
    {
    param.sides = 1;
    param.cylinders = 40;
    /* *** this is actually handled in Set_Floppy_Media_Type mostly *** */
    }

  if (param.four==TRUE) /* 360k in 1200k drive */
    { 
    param.cylinders = 40;
    param.sectors = 9;
    }

  if (param.eight==TRUE) /* DOS 1.0 formats: 160k and 320k only */
    {
    param.sectors = 8;
    }

next_disk:

  /* User interaction. */
  if (param.drive_type==FLOPPY && param.force_yes==FALSE)
   Ask_User_To_Insert_Disk();

  if (param.drive_type==HARD && param.force_yes==FALSE)
   Confirm_Hard_Drive_Formatting();


  if ((param.u==TRUE) && (param.q==FALSE))
    {
    param.existing_format = FALSE; /* do not even check */
    }
  else
    {

    /* Check to see if the media is currently formatted. */
    param.existing_format = Check_For_Format();

    if ((param.existing_format==TRUE) && (param.drive_type==FLOPPY))
      {
      found_format_sectors_per_track = sector_buffer[0x18];
      found_format_heads = sector_buffer[0x1a];
      }
    }
  

  /* Determine and set media parameters */
  if (param.drive_type==FLOPPY)
    {
    Set_Floppy_Media_Type();

    if ((param.existing_format == FALSE) && (param.u==FALSE))
      {
      /* try finding existing format again - after setting media type */
      if (debug_prog==TRUE)
        printf("[DEBUG] Searching for existing format again...\n");

      param.existing_format = Check_For_Format();

      if ((param.existing_format==TRUE) && (param.drive_type==FLOPPY))
        {
	found_format_sectors_per_track = sector_buffer[0x18];
        found_format_heads = sector_buffer[0x1a];
        }
      }

    if (param.existing_format == TRUE)
      {
      if ((drive_specs[param.media_type].sectors_per_cylinder !=
        found_format_sectors_per_track) || (found_format_heads !=
        drive_specs[param.media_type].number_of_heads))
        {
        printf("Will change size by formatting - forcing full format\n");
        printf("Old: %d sectors per track, %d heads. New: %d sect. %d heads\n",
          found_format_sectors_per_track, found_format_heads,
          drive_specs[param.media_type].sectors_per_cylinder,
          drive_specs[param.media_type].number_of_heads);
        param.u = TRUE;
        param.q = FALSE;
        }
      }
     /* if no existing format, we force full format anyway */

    }
  else
    {
    Set_Hard_Drive_Media_Parameters();
    Enable_Disk_Access();
    }
  /* *** Maybe we should have done drive setup earlier, for Check_...? *** */


  if (param.existing_format == FALSE)
    {
    if ( (param.u!=TRUE) || (param.q!=FALSE) )
      {
      printf("Cannot find existing format - forcing full format\n");
      }
    param.u = TRUE;
    param.q = FALSE;
    }


  /* Format Drive */
  if ( (param.u==TRUE) && (param.q==FALSE) )
    {
    /* /U is Unconditional Format */
    printf(" Full Formatting (wiping all data)\n");
    Unconditional_Format();
    Create_File_System();
    }

  if ( (param.u==TRUE) && (param.q==TRUE) )
    {
    /* /Q /U is Quick Unconditional format */
    printf(" QuickFormatting (only flushing metadata)\n");
    Create_File_System();
    }

  if ( (param.u==FALSE) /* && (param.q==TRUE) */ )
    {

    /* this is the default, so if no /U given, it is irrelevant   */
    /* whether /Q is given or not... Should trigger FULL format   */
    /* if existing filesystem has other size or disk needs format */

    /* /Q is Quick Format */
    /* -- is Safe  Format */
/* TEMPORARILY DISABLED FOR FAT32 */
    if ((param.drive_type==HARD) && (param.fat_type!=FAT32))
      {
      printf(" Safe QuickFormatting (trying to save UnFormat data)\n");
      Save_File_System();
      }
    else
      {
      printf(" QuickFormatting (only flushing metadata)\n");
      }
    Create_File_System();
    }

  if (param.drive_type==HARD) Set_DPB_Access_Flag();

  if (bad_sector_map[0]>0)
/* TEMPORARILY DISABLED FOR FAT32 */
     if (param.fat_type!=FAT32)
       Record_Bad_Clusters();

  printf("\nFormat complete.\n");

  if (param.s==TRUE)
    Write_System_Files();

  Display_Drive_Statistics();

  /* *** ASK USER... IF YES, GOTO next_disk ... *** */

  exit(0);
}

⌨️ 快捷键说明

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