home *** CD-ROM | disk | FTP | other *** search
/ PC Open 19 / pcopen19.iso / Zipped / PART231.ZIP / SOURCES.ZIP / S_FAT16.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-12  |  9.9 KB  |  331 lines

  1. #include "part.h"
  2.  
  3. struct boot_ms_dos
  4.     {
  5.      unsigned char  jmp[3];    /* Must be 0xEB, 0x3C, 0x90        */
  6.      unsigned char  sys_id[8];    /* Probably:   "MSDOS5.0"        */
  7.      unsigned short sect_size;    /* Sector size in bytes (512)        */
  8.      unsigned char  clust_size;    /* Sectors per cluster (1,2,4,...,128)    */
  9.      unsigned short res_sects;    /* Reserved sectors at the beginning    */
  10.      unsigned char  num_fats;    /* Number of FAT copies (1 or 2)    */
  11.      unsigned short root_entr;    /* Root directory entries        */
  12.      unsigned short total_sect;    /* Total sectors (if less 64k)        */
  13.      unsigned char  media_desc;    /* Media descriptor byte (F8h for HD)    */
  14.      unsigned short fat_size;    /* Sectors per fat            */
  15.      unsigned short num_sects;    /* Sectors per track            */
  16.      unsigned short num_sides;    /* Sides                */
  17.      unsigned long  hid_sects;    /* Special hidden sectors        */
  18.      unsigned long  big_total;    /* Big total number of sectors      */
  19.      unsigned short drive_num;    /* Drive number                */
  20.      unsigned char  ext_signat;    /* Extended Boot Record signature (29h)    */
  21.      unsigned long  serial_num;    /* Volume serial number            */
  22.      unsigned char  label[11];    /* Volume label                */
  23.      unsigned char  fs_id[8];    /* File system id            */
  24.      unsigned char  xcode[448];    /* Loader executable code        */
  25.      unsigned short magic;    /* Magic number (Must be 0xAA55)     */
  26.     };
  27.  
  28. #define BBT_SIZE 16000
  29.  
  30. extern struct boot_ms_dos BOOT_FAT12, BOOT_FAT16;
  31.  
  32. #define F_NORM  0
  33. #define F_QUICK 1
  34. #define F_DESTR 2
  35.  
  36. #define ROOT_SIZE    (512/16)  /* 512 entries in root directory 16/sector */
  37. #define MAX_CLUST12  (4084)    /* Maximum number of clusters in FAT12 system */
  38. #define MAX_CLUST16  (65524)   /* Maximum number of clusters in FAT16 system */
  39.  
  40. /*   0x01, "DOS FAT-12"            */
  41. /*   0x04, "DOS FAT-16 (<=32Mb)"    */
  42. /*   0x06, "BIGDOS FAT-16 (>=32Mb)"    */
  43.  
  44.  
  45. int format_fat(struct disk_info *dinfo, struct part_long *p, char **argv, int (*progress)(char*) )
  46. {
  47.  char tmp[60];
  48.  struct boot_ms_dos b;
  49.  unsigned short int *fat;
  50.  unsigned long num_clust, base_sect, base_clust, *bbt;
  51.  int i, j, k, wr_sect, ret_code, fat_size, sys_type, next_bad;
  52.  
  53.  unsigned int num_bad=0;
  54.  unsigned int clust_size=4;
  55.  unsigned int form_type=F_NORM;
  56.  
  57. #if 0
  58.  if( p->rel_sect==1008 ) /* I don't want to format my own disk by chance :) */
  59.    {
  60.     progress("Are you crazy!!! This is your own hard disk!!!");
  61.     return FORMAT_FAILED;
  62.    }
  63. #endif
  64.  
  65.  if( p->os_id!=0x06 && p->num_sect>65535L )
  66.    {
  67.     progress("  Please choose BIGDOS file system for partitions greater than 32M. ");
  68.     return FORMAT_FAILED;
  69.    }
  70.  
  71.  if( p->num_sect<3+ROOT_SIZE+64 )
  72.    {
  73.     progress("  Common!  Partition is so small it isn't even funny. ");
  74.     return FORMAT_FAILED;
  75.    }
  76.  
  77.  while(*argv!=0)
  78.     {
  79.      if( strcmpi(*argv,"/destructive")==0 ) form_type=F_DESTR;
  80.      else if(  strcmpi(*argv,"/quick")==0 ) form_type=F_QUICK;
  81.      else if( strncmpi(*argv,"/c:", 3)==0 )
  82.        {
  83.         k=atoi((*argv)+3);
  84.         for( i=k/2, j=0 ; i!=0 && j<7 ; j++, i/=2 );
  85.         clust_size=1<<j;
  86.         if( clust_size!=k )
  87.           {
  88.            progress("^Invalid cluster size.");
  89.            return FORMAT_FAILED;
  90.           }
  91.        }
  92.      else
  93.        {
  94.         progress("^Unknown option:");
  95.         progress(*argv);
  96.         return FORMAT_FAILED;
  97.        }
  98.      argv++;
  99.     }
  100.  
  101.  if( p->os_id==0x04 || p->os_id==0x06 )            /* FAT16 */
  102.    {
  103.     while( clust_size<128 )
  104.        { 
  105.         if( 1+512+ROOT_SIZE+(unsigned long)clust_size*MAX_CLUST16 > p->num_sect)
  106.           break;
  107.         clust_size*=2;
  108.        }
  109.  
  110.     fat_size =  (p->num_sect-ROOT_SIZE-1+2*clust_size)/(clust_size*256+2)+1;
  111.     num_clust = (p->num_sect-ROOT_SIZE-1-2*fat_size)/(clust_size);
  112.  
  113.     memmove(&b,&BOOT_FAT16,512);
  114.  
  115.     sys_type=16;
  116.    }
  117.  
  118.  if( p->os_id==0x01 || num_clust<MAX_CLUST12 )         /* FAT12 */
  119.    {
  120.     while( clust_size<128 )
  121.        { 
  122.         if( 1+24+ROOT_SIZE+(unsigned long)clust_size*MAX_CLUST12 > p->num_sect )
  123.           break;
  124.         clust_size*=2;
  125.        }
  126.  
  127.     fat_size =  (p->num_sect-ROOT_SIZE-1+2*clust_size)/((long)clust_size*512*2/3+2)+1;
  128.     num_clust = (p->num_sect-ROOT_SIZE-1-2*fat_size)/(clust_size);
  129.     
  130.     memmove(&b,&BOOT_FAT12,512);
  131.  
  132.     sys_type=12;
  133.    }
  134.  
  135.  b.fat_size=fat_size;
  136.  b.clust_size=clust_size;
  137.  
  138.  b.drive_num=dinfo->disk;
  139.  b.num_sects=dinfo->num_sects;
  140.  b.num_sides=dinfo->num_heads;
  141.  
  142.  b.hid_sects=p->rel_sect;
  143.  b.big_total=p->num_sect;
  144.  
  145.  if( p->num_sect<65536L )        /* Not nessessary, really */
  146.    {
  147.     b.big_total=0;
  148.     b.total_sect=p->num_sect;
  149.    }
  150.  
  151.  
  152.  if( (bbt=malloc(BBT_SIZE*sizeof(long)))==0 ) 
  153.    {
  154.     progress(ERROR_MALLOC);
  155.     return FORMAT_FAILED;
  156.    }
  157.  
  158.  if( (fat=malloc(6144))==0  )  /* (fat=malloc(256*sizeof(short)))==0 */
  159.    {
  160.     progress(ERROR_MALLOC);
  161.     free(bbt);
  162.     return FORMAT_FAILED;
  163.    }
  164.       if( form_type==F_QUICK ) ret_code=0;
  165.  else if( form_type==F_DESTR )
  166.    ret_code=generic_format(dinfo,p,BBT_SIZE,bbt,progress);
  167.  else
  168.    ret_code=generic_verify(dinfo,p,BBT_SIZE,bbt,progress);
  169.  
  170.  if( ret_code<0 )      /* format failed or canceled */
  171.    {
  172.     free(bbt);
  173.     free(fat);
  174.     return ret_code;
  175.    }
  176.  
  177.  num_bad=ret_code;
  178.  
  179.  disk_lock(dinfo->disk);
  180.  progress("^Initializing file system ...");
  181.  
  182.  if( num_bad!=0 && bbt[0] < 1+2*fat_size+ROOT_SIZE )
  183.    {
  184.     progress("Beginning of the partition is unusable. Try to move it up.");
  185.     goto FAILED;
  186.    }
  187.  
  188.  
  189.  progress("Writing boot sector ...");
  190.  
  191.  if( disk_write_rel(dinfo,p,0,&b,1)==-1 )    /*  Writing boot sector  */
  192.    {
  193.     progress("Error writing boot sector.");
  194.     goto FAILED;
  195.    }
  196.  
  197.  sleep(1);
  198.  progress("Writing FAT tables ...");
  199.  
  200.  wr_sect = 1;
  201.  
  202.  if( sys_type==16 )
  203.    {
  204.     for( k=0 ; k<2 ; k++ )         /* Writing two copies of FAT16 */
  205.       {
  206.        next_bad = 0;
  207.        base_sect = 1 + 2*fat_size + ROOT_SIZE;
  208.  
  209.        for( i=0 ; i<fat_size ; i++ )
  210.           {
  211.            memset(fat,0,512);
  212.            if( i==0 )
  213.              {
  214.               fat[0]=0xFFF8;
  215.               fat[1]=0xFFFF;
  216.               while(next_bad!=num_bad && bbt[next_bad]<base_sect+clust_size*254)
  217.                 fat[ (bbt[next_bad++]-base_sect)/clust_size+2 ]=0xFFF7;
  218.               base_sect+=clust_size*254;
  219.              }
  220.            else
  221.              {
  222.               while(next_bad!=num_bad && bbt[next_bad]<base_sect+clust_size*256)
  223.                 fat[ (bbt[next_bad++]-base_sect)/clust_size ]=0xFFF7;
  224.               base_sect+=clust_size*256;
  225.              }
  226.  
  227.            if( disk_write_rel(dinfo,p,wr_sect++,fat,1)==-1 )
  228.              {
  229.               progress("Error writing FAT.");
  230.               goto FAILED;
  231.              }
  232.           }
  233.       }
  234.    }/* fat16 */
  235.  else                     /* Writing two copies of FAT12 */
  236.    {
  237.     struct fat12
  238.         {
  239.          unsigned c0:12;
  240.          unsigned c1:12;
  241.         } *fat12 = (struct fat12*)fat;
  242.     
  243.     memset(fat,0,6144);
  244.  
  245.     fat12[0].c0=0xFF8;
  246.     fat12[0].c1=0xFFF;
  247.  
  248.     next_bad = 0;
  249.     base_sect = 1 + 2*fat_size + ROOT_SIZE;
  250.  
  251.     while( next_bad!=num_bad )
  252.        {
  253.         j=(bbt[next_bad++]-base_sect)/clust_size+2;
  254.         
  255.         if( j%2==0 ) fat12[j/2].c0=0xFF7;
  256.                 else fat12[j/2].c1=0xFF7;
  257.        }
  258.  
  259.     for( k=0 ; k<2 ; k++ )
  260.       for( i=0 ; i<fat_size ; i++ )
  261.        if( disk_write_rel(dinfo,p,wr_sect++,fat+i*256,1)==-1 )
  262.          {
  263.           progress("Error writing FAT.");
  264.           goto FAILED;
  265.          }
  266.    }/* fat12 */
  267.  
  268.  memset(fat,0,512);
  269.  
  270.  sleep(1);
  271.  progress("Writing root directory ...");
  272.  
  273.  for( i=0 ; i<ROOT_SIZE ; i++ )
  274.   if( disk_write_rel(dinfo,p,wr_sect++,fat,1)==-1 )
  275.     {
  276.      progress("Error writing root directory.");
  277.      goto FAILED;
  278.     }
  279.  
  280.  sleep(1);
  281.  
  282.  disk_unlock(dinfo->disk);
  283.  free(bbt);
  284.  free(fat);
  285.  return FORMAT_OK;
  286.  
  287. FAILED:
  288.  
  289.  disk_unlock(dinfo->disk);
  290.  free(bbt);
  291.  free(fat);
  292.  return FORMAT_FAILED;
  293. }/* format_fat */
  294.  
  295.  
  296. int print_fat(struct disk_info *dinfo, struct part_long *p )
  297. {
  298.  int i;
  299.  struct boot_ms_dos b;
  300.  char tmp1[20], tmp2[20];
  301.  
  302.  if( disk_read_rel(dinfo,p,0,&b,1)==-1 )
  303.    {
  304.     fprintf(stderr,"Error reading boot sector.\n");
  305.     return -1;
  306.    }
  307.  
  308.  printf("\n              DOS Boot Sector Data              Expected Value\n\n");
  309.  printf("                        System id:  %-.8s\n", b.sys_id );
  310.  printf("                      Sector size:  %-3d         512\n", b.sect_size );
  311.  printf("              Sectors per cluster:  %d\n", b.clust_size );
  312.  printf("Reserved sectors at the beginning:  %d\n", b.res_sects );
  313.  printf("             Number of FAT copies:  %d\n", b.num_fats );
  314.  printf("           Root directory entries:  %d\n", b.root_entr );
  315.  printf("            Total sectors on disk:  %-5u       %u\n", b.total_sect, (b.total_sect==0 || p->num_sect>65535L)?0:p->num_sect );
  316.  printf("            Media descriptor byte:  %02Xh         F8h\n", b.media_desc );
  317.  printf("                  Sectors per FAT:  %d\n", b.fat_size );
  318.  printf("                Sectors per track:  %-2d          %d\n", b.num_sects, dinfo->num_sects );
  319.  printf("                  Number of sides:  %-3d         %d\n", b.num_sides, dinfo->num_heads );
  320.  printf("Hidden sectors prior to partition:  %-10s  %-10s\n", sprintf_long(tmp1,b.hid_sects), sprintf_long(tmp2,p->rel_sect) );
  321.  printf("      Big total number of sectors:  %-10s  %-10s\n", b.big_total==0?"0":sprintf_long(tmp1,b.big_total), (b.total_sect==0 || p->num_sect>65535L)?sprintf_long(tmp2,p->num_sect):"0" );
  322.  printf("                     Drive number:  %-3d         %d\n", b.drive_num, dinfo->disk );
  323.  printf("   Extended boot record signature:  %02Xh\n", b.ext_signat );
  324.  printf("             Volume serial number:  %08lX\n", b.serial_num );
  325.  printf("                     Volume label:  %-.11s\n", b.label );
  326.  printf("                 File system type:  %-.8s    %s\n", b.fs_id, (b.clust_size==0)?("?"):(p->num_sect/b.clust_size<4096?"FAT12":"FAT16") );
  327.  printf("         Boot sector magic number:  0%04Xh      0AA55h\n", b.magic );
  328.  return 0;
  329. }/* print_fat */
  330.  
  331.