home *** CD-ROM | disk | FTP | other *** search
/ PC World 2002 February / PCWorld_2002-02_cd.bin / Software / Vyzkuste / ranish / SOURCES.ZIP / S_FAT16.C < prev    next >
C/C++ Source or Header  |  1998-09-12  |  22KB  |  689 lines

  1. #include "part.h"
  2.  
  3.  
  4. struct boot_ms_dos
  5.     {
  6.      unsigned char  jmp[3];    /* Must be 0xEB, 0x3C, 0x90        */
  7.      unsigned char  sys_id[8];    /* Probably:   "MSDOS5.0"        */
  8.      unsigned short sect_size;    /* Sector size in bytes (512)        */
  9.      unsigned char  clust_size;    /* Sectors per cluster (1,2,4,...,128)    */
  10.      unsigned short res_sects;    /* Reserved sectors at the beginning    */
  11.      unsigned char  num_fats;    /* Number of FAT copies (1 or 2)    */
  12.      unsigned short root_entr;    /* Root directory entries        */
  13.      unsigned short total_sect;    /* Total sectors (if less 64k)        */
  14.      unsigned char  media_desc;    /* Media descriptor byte (F8h for HD)    */
  15.      unsigned short fat_size;    /* Sectors per fat            */
  16.      unsigned short num_sects;    /* Sectors per track            */
  17.      unsigned short num_sides;    /* Sides                */
  18.      unsigned long  hid_sects;    /* Special hidden sectors        */
  19.      unsigned long  big_total;    /* Big total number of sectors      */
  20.      unsigned short drive_num;    /* Drive number                */
  21.      unsigned char  ext_signat;    /* Extended Boot Record signature (29h)    */
  22.      unsigned long  serial_num;    /* Volume serial number            */
  23.      unsigned char  label[11];    /* Volume label                */
  24.      unsigned char  fs_id[8];    /* File system id            */
  25.      unsigned char  xcode[448];    /* Loader executable code        */
  26.      unsigned short magic_num;    /* Magic number (Must be 0xAA55)     */
  27.     };
  28.  
  29. #define BBT_SIZE 12000
  30.  
  31. #define F_NORM  0
  32. #define F_QUICK 1
  33. #define F_DESTR 2
  34.  
  35. #define ROOT_ENTR    (512)
  36. #define ROOT_SIZE    (ROOT_ENTR/16)
  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 part_long *p, char **argv)
  46. {
  47.  char *data_pool;
  48.  struct boot_ms_dos *b;
  49.  unsigned short int *fat;
  50.  int i, j, k, wr_sect, ret_code, fat_size, sys_type, next_bad;
  51.  unsigned long l, num_clust, u_num_sect, x_num_sect, base_sect, base_clust, *bbt;
  52.  
  53.  unsigned int num_bad=0;
  54.  unsigned int clust_size=4;
  55.  unsigned int form_type=F_NORM;
  56.  
  57.  if( (data_pool=malloc(SECT_SIZE+6144+BBT_SIZE*sizeof(long)))==0 )
  58.    {
  59.     show_error(ERROR_MALLOC);
  60.     return FAILED;
  61.    }
  62.  
  63.  b   = (struct boot_ms_dos*)(data_pool);
  64.  fat = (unsigned short*)(data_pool+SECT_SIZE);
  65.  bbt = (unsigned long*)(data_pool+SECT_SIZE+6144);
  66.  
  67.  
  68.  memmove(b,FAT_BOOT,SECT_SIZE);
  69.  memmove(b->sys_id,"MSDOS5.0",8);
  70.  b->sect_size=SECT_SIZE;
  71.  b->res_sects=1;
  72.  b->num_fats=2;
  73.  b->root_entr=ROOT_ENTR;
  74.  b->media_desc=0xF8;
  75.  b->ext_signat=0x29;
  76.  memmove(b->label,"NO NAME    ",11);
  77.  b->magic_num=MBR_MAGIC_NUM;
  78.  
  79.  u_num_sect=p->num_sect;
  80.  x_num_sect=p->num_sect;
  81.  
  82.  while(*argv!=0)
  83.     {
  84.      if( strcmpi(*argv,"/destructive")==0 ) form_type=F_DESTR;
  85.      else if(  strcmpi(*argv,"/quick")==0 ) form_type=F_QUICK;
  86.      else if( strncmpi(*argv,"/c:", 3)==0 )
  87.        {
  88.         k=atoi((*argv)+3);
  89.         for( i=k/2, j=0 ; i!=0 && j<7 ; j++, i/=2 );
  90.         clust_size=1<<j;
  91.         if( clust_size!=k )
  92.           {
  93.            progress("^Invalid cluster size.");
  94.            goto failed;
  95.           }
  96.        }
  97.      else if( strncmpi(*argv,"/x:", 3)==0 )
  98.        {
  99.         if( strcmpi(*argv,"/x:disk")==0 )
  100.           l=dinfo.total_sects;
  101.         else
  102.           l=atol((*argv)+3);
  103.         if( l>x_num_sect ) x_num_sect=l;
  104.        }
  105.      else if( strncmpi(*argv,"/l:", 3)==0 )
  106.        {
  107.         strncpy(tmp,(*argv)+3,11);
  108.         tmp[11]=0;
  109.         for( i=0 ; tmp[i]!=0 && i<11 ; i++ ) b->label[i]=tmp[i];
  110.         for( ; i<11 ; i++ ) b->label[i]=' ';
  111.        }
  112.      else
  113.        {
  114.         progress("^Unknown option:");
  115.         progress(*argv);
  116.         goto failed;
  117.        }
  118.      argv++;
  119.     }
  120.  
  121.  if( p->os_id==0x0400 || p->os_id==0x0600 ||            /* FAT16 */
  122.      p->os_id==0x1400 || p->os_id==0x1600 )
  123.    {
  124.     l=1+512+ROOT_SIZE+64L*MAX_CLUST16;
  125.     if( l<u_num_sect ) u_num_sect=l;
  126.     if( l<x_num_sect ) x_num_sect=l;
  127.     
  128.     while( clust_size<64 )
  129.        { 
  130.         if(1+512+ROOT_SIZE+(unsigned long)clust_size*MAX_CLUST16 > x_num_sect)
  131.           break;
  132.         clust_size*=2;
  133.        }
  134.  
  135.     fat_size =  (x_num_sect-ROOT_SIZE-1+2*clust_size)/(clust_size*256+2)+1;
  136.     num_clust = (x_num_sect-ROOT_SIZE-1-2*fat_size)/(clust_size);
  137.  
  138.     memmove(b->fs_id,"FAT16   ",8);
  139.  
  140.     sys_type=16;
  141.    }
  142.  
  143.  if( p->os_id==0x0100 || p->os_id==0x1100 || num_clust<MAX_CLUST12 )/* FAT12 */
  144.    {
  145.     l=1+512+ROOT_SIZE+64L*MAX_CLUST12;
  146.     if( l<u_num_sect ) u_num_sect=l;
  147.     if( l<x_num_sect ) x_num_sect=l;
  148.  
  149.     while( clust_size<64 )
  150.        { 
  151.         if( 1+24+ROOT_SIZE+(unsigned long)clust_size*MAX_CLUST12 > x_num_sect )
  152.           break;
  153.         clust_size*=2;
  154.        }
  155.  
  156.     fat_size =  (x_num_sect-ROOT_SIZE-1+2*clust_size)/((long)clust_size*512*2/3+2)+1;
  157.     num_clust = (x_num_sect-ROOT_SIZE-1-2*fat_size)/(clust_size);
  158.     
  159.     memmove(b->fs_id,"FAT12   ",8);
  160.  
  161.     sys_type=12;
  162.    }
  163.  
  164.  if( fat_size<0 || 1+2*fat_size+ROOT_SIZE+clust_size > p->num_sect )
  165.    {
  166.     progress("^Partition is too small.");
  167.     goto failed;
  168.    }
  169.  
  170.  b->fat_size=fat_size;
  171.  b->clust_size=clust_size;
  172.  
  173.  b->drive_num=dinfo.disk;
  174.  b->num_sects=dinfo.num_sects;
  175.  b->num_sides=dinfo.num_heads;
  176.  
  177.  b->hid_sects=p->rel_sect;
  178.  b->total_sect = (u_num_sect<65536L) ? u_num_sect : 0;
  179.  b->big_total  = (u_num_sect<65536L) ? 0 : u_num_sect;
  180.  
  181.  b->serial_num=((p->rel_sect<<16)+(p->num_sect*((long)b%451)) )+
  182.                ((dinfo.total_sects%12345L)^(dinfo.total_sects*67891L))+
  183.                ((dinfo.disk*123L)^(dinfo.num_heads%7))+clock();
  184.  
  185.  flush_caches();
  186.  
  187.       if( form_type==F_QUICK ) ret_code=0;
  188.  else if( form_type==F_DESTR )
  189.    ret_code=generic_format(p,BBT_SIZE,bbt);
  190.  else
  191.    ret_code=generic_verify(p,BBT_SIZE,bbt);
  192.  
  193.  if( ret_code<0 )      /* format failed or canceled */
  194.    {
  195.     free(data_pool);
  196.     return ret_code;
  197.    }
  198.  
  199.  num_bad=ret_code;
  200.  
  201.  disk_lock(dinfo.disk);
  202.  
  203.  progress("^Initializing file system ...");
  204.  
  205.  if( num_bad!=0 && bbt[0] < 1+2*fat_size+ROOT_SIZE )
  206.    {
  207.     progress("Beginning of the partition is unusable. Try to move it forward.");
  208.     goto failed;
  209.    }
  210.  
  211.  progress("~Writing boot sector ...");
  212.  
  213.  if( disk_write_rel(p,0,b,1)==-1 )    /*  Writing boot sector  */
  214.    {
  215.     progress("Error writing boot sector.");
  216.     goto failed;
  217.    }
  218.  
  219.  progress("~Writing FAT tables ...");
  220.  
  221.  wr_sect = 1;
  222.  
  223.  if( sys_type==16 )
  224.    {
  225.     for( k=0 ; k<2 ; k++ )         /* Writing two copies of FAT16 */
  226.       {
  227.        next_bad = 0;
  228.        base_sect = 1 + 2*fat_size + ROOT_SIZE;
  229.  
  230.        for( i=0 ; i<fat_size ; i++ )
  231.           {
  232.            memset(fat,0,512);
  233.            if( i==0 )
  234.              {
  235.               fat[0]=0xFFF8;
  236.               fat[1]=0xFFFF;
  237.               while(next_bad!=num_bad && bbt[next_bad]<base_sect+clust_size*254)
  238.                 fat[ (bbt[next_bad++]-base_sect)/clust_size+2 ]=0xFFF7;
  239.               base_sect+=clust_size*254;
  240.              }
  241.            else
  242.              {
  243.               while(next_bad!=num_bad && bbt[next_bad]<base_sect+clust_size*256)
  244.                 fat[ (bbt[next_bad++]-base_sect)/clust_size ]=0xFFF7;
  245.               base_sect+=clust_size*256;
  246.              }
  247.  
  248.            if( disk_write_rel(p,wr_sect++,fat,1)==-1 )
  249.              {
  250.               progress("Error writing FAT.");
  251.               goto failed;
  252.              }
  253.           }
  254.       }
  255.    }/* fat16 */
  256.  else                     /* Writing two copies of FAT12 */
  257.    {
  258.     struct fat12
  259.         {
  260.          unsigned c0:12;
  261.          unsigned c1:12;
  262.         } *fat12 = (struct fat12*)fat;
  263.     
  264.     memset(fat,0,6144);
  265.  
  266.     fat12[0].c0=0xFF8;
  267.     fat12[0].c1=0xFFF;
  268.  
  269.     next_bad = 0;
  270.     base_sect = 1 + 2*fat_size + ROOT_SIZE;
  271.  
  272.     while( next_bad!=num_bad )
  273.        {
  274.         j=(bbt[next_bad++]-base_sect)/clust_size+2;
  275.         
  276.         if( j%2==0 ) fat12[j/2].c0=0xFF7;
  277.                 else fat12[j/2].c1=0xFF7;
  278.        }
  279.  
  280.     for( k=0 ; k<2 ; k++ )
  281.       for( i=0 ; i<fat_size ; i++ )
  282.        if( disk_write_rel(p,wr_sect++,fat+i*256,1)==-1 )
  283.          {
  284.           progress("Error writing FAT.");
  285.           goto failed;
  286.          }
  287.    }/* fat12 */
  288.  
  289.  memset(fat,0,512);
  290.  
  291.  progress("~Writing root directory ...");
  292.  
  293.  for( i=0 ; i<ROOT_SIZE ; i++ )
  294.   if( disk_write_rel(p,wr_sect++,fat,1)==-1 )
  295.     {
  296.      progress("Error writing root directory.");
  297.      goto failed;
  298.     }
  299.  
  300.  
  301.  disk_unlock(dinfo.disk);
  302.  free(data_pool);
  303.  return OK;
  304.  
  305. failed:
  306.  
  307.  disk_unlock(dinfo.disk);
  308.  free(data_pool);
  309.  return FAILED;
  310. }/* format_fat */
  311.  
  312.  
  313. int format_embr(struct part_long *p, char **argv)
  314. {
  315.  struct mbr *mbr=(struct mbr *)&tmp;
  316.  
  317.  flush_caches();
  318.  
  319.  disk_lock(dinfo.disk);
  320.  
  321.  progress("^Initializing Extended DOS partition ...");
  322.  
  323.  progress("~Writing Extended Master Boot Record ...");
  324.  
  325.  memset(mbr,0,SECT_SIZE);
  326.  memmove(mbr->x.std.code, EMP_IPL, EMP_SIZE );
  327.  strncpy(mbr->x.std.code + EMP_SIZE, MESG_EXT_NONBOOT,
  328.                           sizeof(mbr->x.std.code)-EMP_SIZE);
  329.  mbr->magic_num=MBR_MAGIC_NUM;
  330.  
  331.  if( disk_write_rel(p,0,mbr,1)==-1 )
  332.    {
  333.     progress("Error Writing Extended Master Boot Record.");
  334.     disk_unlock(dinfo.disk);
  335.     return FAILED;
  336.    }
  337.  
  338.  argv++; /* so compiler will not show warning */
  339.  
  340.  disk_unlock(dinfo.disk);
  341.  return OK;
  342. }/* format_embr */
  343.  
  344.  
  345.  
  346. int print_fat(struct part_long *p )
  347. {
  348.  int i;
  349.  struct boot_ms_dos *b=(struct boot_ms_dos*)tmp;
  350.  char tmp1[20], tmp2[20];
  351.  
  352.  if( disk_read_rel(p,0,b,1)==-1 )
  353.    {
  354.     fprintf(stderr,"Error reading boot sector.\n");
  355.     return FAILED;
  356.    }
  357.  
  358.  printf("\n              DOS Boot Sector Data              Expected Value\n\n");
  359.  printf("                        System id:  %-.8s\n", b->sys_id );
  360.  printf("                      Sector size:  %-3d         512\n", b->sect_size );
  361.  printf("              Sectors per cluster:  %d\n", b->clust_size );
  362.  printf("Reserved sectors at the beginning:  %d\n", b->res_sects );
  363.  printf("             Number of FAT copies:  %d\n", b->num_fats );
  364.  printf("           Root directory entries:  %d\n", b->root_entr );
  365.  printf("            Total sectors on disk:  %-5u       %u\n", b->total_sect, (b->total_sect==0 || p->num_sect>65535L)?0:p->num_sect );
  366.  printf("            Media descriptor byte:  %02Xh         F8h\n", b->media_desc );
  367.  printf("                  Sectors per FAT:  %d\n", b->fat_size );
  368.  printf("                 Sectors per side:  %-2d          %d\n", b->num_sects, dinfo.num_sects );
  369.  printf("                  Number of sides:  %-3d         %d\n", b->num_sides, dinfo.num_heads );
  370.  printf("Hidden sectors prior to partition:  %-10s  %-10s\n", sprintf_long(tmp1,b->hid_sects), sprintf_long(tmp2,p->rel_sect) );
  371.  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" );
  372.  printf("                     Drive number:  %-3d         %d\n", b->drive_num, dinfo.disk );
  373.  printf("   Extended boot record signature:  %02Xh\n", b->ext_signat );
  374.  printf("             Volume serial number:  %08lX\n", b->serial_num );
  375.  printf("                     Volume label:  %-.11s\n", b->label );
  376.  printf("                 File system type:  %-.8s    %s\n", b->fs_id, (b->clust_size==0)?("?"):(p->num_sect/b->clust_size<4096?"FAT12":"FAT16") );
  377.  printf("         Boot sector magic number:  0%04Xh      0AA55h\n", b->magic_num );
  378.  return 0;
  379. }/* print_fat */
  380.  
  381.  
  382. #define StX  5
  383. #define StY  5
  384. #define StW  66
  385. #define StH  14
  386.  
  387. #define StX2 (StX+30)
  388. #define StX3 (StX+69)
  389.  
  390. #define TEXT_COLOR (BrCyan+BakBlue)
  391. #define DATA_COLOR (BrWhite+BakBlue)
  392. #define EDIT_COLOR (BrWhite+BakBlack)
  393.  
  394. int setup_fat(struct part_long *p)
  395. {
  396.  struct event ev;
  397.  int i, v, syst, act, pos, fatsz;
  398.  char *tmp, *tmp1, *tmp2;
  399.  unsigned long n, l, lc, max_clust, min_clust, min_num_sect, max_num_sect;
  400.  struct boot_ms_dos *b, *b_orig, *fat_boot_code=(struct boot_ms_dos*)FAT_BOOT;
  401.  
  402.  if( (tmp=malloc(3*SECT_SIZE))==0 )
  403.    {
  404.     show_error(ERROR_MALLOC);
  405.     return FAILED;
  406.    }
  407.  
  408.  tmp1=tmp+100;
  409. /* tmp2=tmp+120; */
  410.  b=(struct boot_ms_dos*)(tmp+SECT_SIZE);
  411.  b_orig=b+1;
  412.  
  413.  if( disk_read_rel(p,0,b,1)==-1 )
  414.    {
  415.     show_error("Error reading boot sector");
  416.     free(tmp);
  417.     return FAILED;
  418.    }
  419.  
  420.  memmove(b_orig,b,SECT_SIZE);
  421.  
  422.  clear_window(TEXT_COLOR,2,5,78,19);
  423.  write_string( HINT_COLOR, 45, 24,"         ESC");
  424.  write_string( MENU_COLOR, 57, 24," - Return to MBR view");
  425.  
  426.  write_string( HINT_COLOR, 64, 13,"F5");
  427.  write_string( MENU_COLOR, 66, 13," - SetExpVal");
  428.  write_string( HINT_COLOR, 64, 14,"F6");
  429.  write_string( MENU_COLOR, 66, 14," - FixBoot2G");
  430.  
  431.  syst=0;
  432.  if( strncmp(b->fs_id,"FAT12",5)==0 ) syst=12;
  433.  if( strncmp(b->fs_id,"FAT16",5)==0 ) syst=16;
  434.  
  435.  max_clust =  (syst==0)?(0):( (long)SECT_SIZE*8*b->fat_size/syst - 2 );
  436.  
  437.  write_string( TEXT_COLOR, StX, StY+ 1,"                  System id:");
  438.  write_string( TEXT_COLOR, StX, StY+ 2,"           File system type:                             Media desc:");
  439.  write_string( TEXT_COLOR, StX, StY+ 3,"        Sectors per cluster:                            Sector size:");
  440.  write_string( TEXT_COLOR, StX, StY+ 4,"            Sectors per FAT:                             FAT copies:");
  441.  write_string( TEXT_COLOR, StX, StY+ 5,"     Root directory entries:                               Ext sign:");
  442.  write_string( TEXT_COLOR, StX, StY+ 6,"       Volume serial number:                                  Magic:");
  443.  write_string( TEXT_COLOR, StX, StY+ 7,"               Volume label:               Expected Value");
  444.  write_string( TEXT_COLOR, StX, StY+ 8,"               Drive number:");
  445.  write_string( TEXT_COLOR, StX, StY+ 9,"            Number of sides:");
  446.  write_string( TEXT_COLOR, StX, StY+10,"           Sectors per side:");
  447.  write_string( TEXT_COLOR, StX, StY+11," Sectors prior to partition:               123456789");
  448.  write_string( TEXT_COLOR, StX, StY+12,"    Total number of sectors:               12345");
  449.  write_string( TEXT_COLOR, StX, StY+13,"Big total number of sectors:               123456789");
  450.  write_string( TEXT_COLOR, StX, StY+15,"     Minimum partition size:");
  451.  write_string( TEXT_COLOR, StX, StY+16,"     Current partition size:");
  452.  write_string( TEXT_COLOR, StX, StY+17,"     Maximum partition size:");
  453.  
  454.  sprintf(tmp,"%-.8s", b->sys_id );
  455.  write_string( DATA_COLOR, StX2, StY+1, tmp );
  456.  
  457.  sprintf(tmp,"%-.8s", b->fs_id );
  458.  write_string( DATA_COLOR, StX2, StY+2, tmp );
  459.  
  460.  sprintf(tmp,"%Xh", b->media_desc );
  461.  write_string( DATA_COLOR, StX3, StY+2, tmp );
  462.  
  463.  sprintf(tmp,"%-3u %s bytes/cluster", b->clust_size, sprintf_long(tmp1,(unsigned long)b->clust_size*SECT_SIZE) );
  464.  write_string( DATA_COLOR, StX2, StY+3, tmp );
  465.  
  466.  sprintf(tmp,"%d", b->sect_size );
  467.  write_string( DATA_COLOR, StX3, StY+3, tmp );
  468.  
  469.  sprintf(tmp,"%-3d %s max clusters", b->fat_size, sprintf_long(tmp1,max_clust) );
  470.  write_string( DATA_COLOR, StX2, StY+4, tmp );
  471.  
  472.  sprintf(tmp,"%d", b->num_fats );
  473.  write_string( DATA_COLOR, StX3, StY+4, tmp );
  474.  
  475.  sprintf(tmp,"%d", b->root_entr );
  476.  write_string( DATA_COLOR, StX2, StY+5, tmp );
  477.  
  478.  sprintf(tmp,"%Xh", b->ext_signat );
  479.  write_string( DATA_COLOR, StX3, StY+5, tmp );
  480.  
  481.  sprintf(tmp,"%08lX", b->serial_num );
  482.  write_string( DATA_COLOR, StX2, StY+6, tmp );
  483.  
  484.  
  485.  sprintf(tmp," %u", dinfo.disk );
  486.  write_string( DATA_COLOR, StX2+12, StY+ 8, tmp );
  487.  
  488.  sprintf(tmp," %u", dinfo.num_heads );
  489.  write_string( DATA_COLOR, StX2+12, StY+ 9, tmp );
  490.  
  491.  sprintf(tmp," %u", dinfo.num_sects );
  492.  write_string( DATA_COLOR, StX2+12, StY+10, tmp );
  493.  
  494.  sprintf(tmp," %-9lu", p->rel_sect );
  495.  write_string( DATA_COLOR, StX2+12, StY+11, tmp );
  496.  
  497.  sprintf(tmp," %-5u", (p->num_sect>65535L)?0:p->num_sect );
  498.  write_string( DATA_COLOR, StX2+12, StY+12, tmp );
  499.  
  500.  sprintf(tmp," %-9lu",(p->num_sect>65535L)?p->num_sect:0 );
  501.  write_string( DATA_COLOR, StX2+12, StY+13, tmp );
  502.  
  503.  
  504.  write_string( HINT_COLOR, StX2, StY+16, "Reading FAT... " );
  505.  move_cursor( StX2+14, StY+16 );
  506.  
  507.  fatsz=min(256,b->fat_size);
  508.  l=lc=0;
  509.  for( n=b->res_sects ; n<b->res_sects+fatsz ; n++ )
  510.   if( disk_read_rel(p,n,tmp,1)==-1 )
  511.     {
  512.      show_error("Error reading FAT table");
  513.      break;
  514.     }
  515.   else
  516.    for( i=0 ; i<SECT_SIZE ; i++, l++ )
  517.     if( tmp[i]!=0 ) lc=l;
  518.  
  519.  min_clust = (syst==0)?(0):( lc*8/syst + (lc*8%syst==0?0:1) - 2);
  520.  
  521.  n = b->res_sects + b->num_fats*b->fat_size + b->root_entr*32/SECT_SIZE;
  522.  
  523.  min_num_sect =  n+min_clust*b->clust_size;
  524.  max_num_sect =  n+max_clust*b->clust_size;
  525.  
  526.  sprintf(tmp,"%ld sectors = %s kbytes", min_num_sect, sprintf_long(tmp1,(min_num_sect)/2) );
  527.  write_string( DATA_COLOR, StX2, StY+15, tmp );
  528.  
  529.  sprintf(tmp,"%ld sectors = %s kbytes", max_num_sect, sprintf_long(tmp1,(max_num_sect)/2) );
  530.  write_string( DATA_COLOR, StX2, StY+17, tmp );
  531.  
  532.      n = b->total_sect!=0 ? b->total_sect : b->big_total;
  533.      sprintf(tmp,"%ld sectors = %s kbytes", n, sprintf_long(tmp1,n/2) );
  534.      write_string( DATA_COLOR, StX2, StY+16, tmp );
  535.  
  536.  pos=0;
  537.  act=0;
  538.  
  539.  while(1)
  540.     {
  541.      for( i=0 ; i<11 ; i++ ) tmp[i]=(b->label[i]==0)?' ':b->label[i];
  542.      tmp[i]=0;
  543.      write_string( DATA_COLOR, StX2, StY+ 7, tmp );
  544.      sprintf(tmp,"%-5d",b->drive_num);
  545.      write_string( (b->drive_num==dinfo.disk)?DATA_COLOR:INVAL_COLOR, StX2, StY+ 8, tmp );
  546.      sprintf(tmp,"%-5d",b->num_sides);
  547.      write_string( (b->num_sides==dinfo.num_heads)?DATA_COLOR:INVAL_COLOR, StX2, StY+ 9, tmp );
  548.      sprintf(tmp,"%-5d",b->num_sects);
  549.      write_string( (b->num_sects==dinfo.num_sects)?DATA_COLOR:INVAL_COLOR, StX2, StY+10, tmp );
  550.      sprintf(tmp,"%-9lu",b->hid_sects);
  551.      write_string( (b->hid_sects==p->rel_sect)?DATA_COLOR:INVAL_COLOR, StX2, StY+11, tmp );
  552.      sprintf(tmp,"%-6u",b->total_sect);
  553.      write_string( (b->total_sect==0||b->total_sect==p->num_sect)?DATA_COLOR:INVAL_COLOR, StX2, StY+12, tmp );
  554.      sprintf(tmp,"%-9lu",b->big_total);
  555.      write_string( (b->big_total==0||b->big_total==p->num_sect)?DATA_COLOR:INVAL_COLOR, StX2, StY+13, tmp );
  556.      sprintf(tmp,"%04X", b->magic_num );
  557.      write_string( (b->magic_num==MBR_MAGIC_NUM)?DATA_COLOR:INVAL_COLOR, StX3, StY+6, tmp );
  558.  
  559.      p->changed = ( memcmp(b, b_orig, SECT_SIZE)==0 ) ? 0 : 1;
  560.      if( p->changed==0 ) write_string(         HINT_COLOR, 15, 24,"F2");
  561.      if( p->changed==1 ) write_string( Blink + HINT_COLOR, 15, 24,"F2");
  562.  
  563.      if( act==0 )
  564.        {
  565.         memmove(tmp,b->label,11);
  566.         tmp[11]=0;
  567.         for( i=10 ; i>=0 && tmp[i]==' ' ; i-- ) tmp[i]=0;
  568.         memmove(tmp1,tmp,12);
  569.         edit_str_field(&ev,0,EDIT_COLOR, StX2, StY+7, 12, tmp, &pos );
  570.         if( memcmp(tmp,tmp1,12)!=0 )
  571.           {
  572.            for( i=0 ; tmp[i]!=0 && i<11 ; i++ ) b->label[i]=tmp[i];
  573.            for( ; i<11 ; i++ ) b->label[i]=' ';
  574.           }
  575.        }
  576.  
  577.      if( act==1 )
  578.        {
  579.         n=b->drive_num;
  580.         edit_int_field(&ev,0,EDIT_COLOR, StX2, StY+ 8, -5, &n, 255L );
  581.         b->drive_num=n;
  582.        }
  583.  
  584.      if( act==2 )
  585.        {
  586.         n=b->num_sides;
  587.         edit_int_field(&ev,0,EDIT_COLOR, StX2, StY+ 9, -5, &n, 255L );
  588.         b->num_sides=n;
  589.        }
  590.  
  591.      if( act==3 )
  592.        {
  593.         n=b->num_sects;
  594.         edit_int_field(&ev,0,EDIT_COLOR, StX2, StY+10, -5, &n, 63L );
  595.         b->num_sects=n;
  596.        }
  597.  
  598.      if( act==4 )
  599.         edit_int_field(&ev,0,EDIT_COLOR, StX2, StY+11, -9,
  600.                                                 &b->hid_sects, 999999999L);
  601.      if( act==5 )
  602.        {
  603.         n=b->total_sect;
  604.         edit_int_field(&ev,0,EDIT_COLOR, StX2, StY+12, -6, &n, 65535L );
  605.         b->total_sect=n;
  606.        }
  607.  
  608.      if( act==6 )
  609.         edit_int_field(&ev,0,EDIT_COLOR, StX2, StY+13, -9,
  610.                                                 &b->big_total, 999999999L);
  611. /*   get_event(&ev,EV_KEY); */
  612.  
  613.      n = b->total_sect!=0 ? b->total_sect : b->big_total;
  614.      sprintf(tmp,"%ld sectors = %s kbytes", n, sprintf_long(tmp1,n/2) );
  615.      clear_window(DATA_COLOR, StX2, StY+16, 78-StX2, 1 );
  616.      write_string( (n>=min_num_sect && n<=max_num_sect)?DATA_COLOR:INVAL_COLOR, StX2, StY+16, tmp );
  617.  
  618.      p->changed = ( memcmp(b, b_orig, SECT_SIZE)==0 ) ? 0 : 1;
  619.      if( p->changed==0 ) write_string(         HINT_COLOR, 15, 24,"F2");
  620.      if( p->changed==1 ) write_string( Blink + HINT_COLOR, 15, 24,"F2");
  621.  
  622.      if( ev.key==27 )                 /* ESC */
  623.        {
  624.         if( p->changed ) continue;
  625.         break;
  626.        }
  627.      if( ev.key==13 || ev.key==9 )        /* Enter or Tab */
  628.        {
  629.         act=(act+1)%7;
  630.        }
  631.      else if( ev.scan==0x3B00 )                /* F1 - Help */
  632.        {
  633.         sprintf(tmp,"#setup_fat");
  634.         html_view(tmp);
  635.        }
  636.      else if( ev.scan==0x50E0 || ev.scan==0x5000 )    /* down */
  637.        {
  638.         if( act<6 ) act++;
  639.        }
  640.      else if( ev.scan==0x48E0 || ev.scan==0x4800 )    /* up */
  641.        {
  642.         if( act>0 ) act--;
  643.        }
  644.      else if( ev.scan==0x3C00  )                   /* F2 - Save */
  645.        {
  646.         if( p->inh_invalid || p->inh_changed )
  647.           { show_error(ERROR_INH_INVAL); continue; }
  648.  
  649.         flush_caches();
  650.  
  651.         disk_lock(dinfo.disk);
  652.         
  653.         if( disk_write_rel(p,0,b,1)==-1 )
  654.           {
  655.            show_error("Error saving boot sector");
  656.           }
  657.         else
  658.           {
  659.            memmove(b_orig, b, SECT_SIZE);
  660.           }
  661.  
  662.         disk_unlock(dinfo.disk);
  663.        }
  664.      else if( ev.scan==0x3D00  )                   /* F3 - Undo */
  665.        {
  666.         memmove( b, b_orig, SECT_SIZE );
  667.        }
  668.      else if( ev.scan==0x3F00  )            /* F5 - Set */
  669.        {
  670.         b->drive_num=dinfo.disk;
  671.         b->num_sides=dinfo.num_heads;
  672.         b->num_sects=dinfo.num_sects;
  673.         b->hid_sects=p->rel_sect;
  674.         b->total_sect=(p->num_sect<65536L)?p->num_sect:0;
  675.         b->big_total =(p->num_sect<65536L)?0:p->num_sect;
  676.         b->magic_num=MBR_MAGIC_NUM;
  677.        }
  678.      else if( ev.scan==0x4000  )            /* F6 - Code */
  679.        {
  680.         memmove(b->xcode, fat_boot_code->xcode, sizeof(b->xcode) );
  681.        }
  682.  
  683.     }/* while(1) */
  684.  
  685.  free(tmp);
  686.  return OK;
  687. }/* setup_fat */
  688.  
  689.