home *** CD-ROM | disk | FTP | other *** search
/ PC World 2002 February / PCWorld_2002-02_cd.bin / Software / Vyzkuste / ranish / SOURCES.ZIP / PART_GEN.C < prev    next >
C/C++ Source or Header  |  1998-06-01  |  8KB  |  333 lines

  1. #include "part.h"
  2.  
  3.  
  4. /* 
  5.  
  6. bbt - Bad Blocks Table - will have numbers of bad sectors found 
  7. bbt_size - size of the table, if  0 halt on first bad sector,
  8.                               if -1 return number of bad sectors.
  9. generic_verify and
  10. generic_format will return number of bad sectors found, or 
  11.                CANCEL, if user pressed ESC, or
  12.                FAILED, if there was unrecoverable error ot bbt is too small   
  13.  
  14. genric_clean
  15.  
  16. */
  17.  
  18.  
  19. int generic_verify(struct part_long *p, int bbt_size, unsigned long *bbt)
  20. {
  21.  char tmp[90];
  22.  struct disk_addr daddr;
  23.  unsigned long base_sect=0; 
  24.  int s_sect, e_sect;
  25.  int i, j, cyl, head, sect, num_sect, x, num_bad=0, hd=dinfo.disk;
  26.  
  27.  disk_lock(hd);
  28.  
  29.  progress(MESG_VERIFYING);
  30.  
  31.  for( cyl=p->start_cyl ; cyl<=p->end_cyl ; cyl++ )
  32.     {
  33.      for( head=((cyl==p->start_cyl)?p->start_head:0) ;
  34.           head<((cyl==p->end_cyl)?p->end_head+1:dinfo.num_heads) ; head++ )
  35.         {
  36.          daddr.disk=hd;
  37.          daddr.cyl=cyl;
  38.          daddr.head=head;
  39.  
  40.          s_sect = (cyl==p->start_cyl && head==p->start_head) ? p->start_sect : 1;
  41.          e_sect = (cyl==p->end_cyl   && head==p->end_head  ) ? p->end_sect : dinfo.num_sects;
  42.  
  43.          daddr.sect=s_sect;
  44.          num_sect=e_sect-s_sect+1;
  45.  
  46.          if( disk_verify(&daddr,num_sect)==-1 )
  47.            {
  48.             for( sect=s_sect ; sect<=e_sect ; sect++ )
  49.                {
  50.                 daddr.sect=sect;
  51.                 if( disk_verify(&daddr,1)==-1 )
  52.                   {
  53.                    if( bbt_size!=-1 )
  54.                      {
  55.                       if( num_bad==bbt_size ) 
  56.                         {
  57.                          disk_unlock(hd);
  58.                          return FAILED;
  59.                         }
  60.                       bbt[num_bad]=base_sect+sect;
  61.                      }
  62.                    num_bad++;
  63.                   }
  64.                }
  65.            }
  66.  
  67.          base_sect+=num_sect;
  68.  
  69.          x=base_sect*100/p->num_sect;
  70.  
  71.          sprintf(tmp,"%% %3d%%  Cylinder: %3d",x,cyl);
  72.          if( progress(tmp)==CANCEL )
  73.            {
  74.             disk_unlock(hd);
  75.             return CANCEL;
  76.            }
  77.         }/* head */
  78.     }/* cyl */
  79.  
  80.  disk_unlock(hd);
  81.  return num_bad;
  82. }/* generic_verify */
  83.  
  84.  
  85. /*
  86.    Some BIOSes have problems with mapping logical cylinders into physical
  87. on the large hard disks. If you use destructive format on such systems it
  88. may cause corruption of the several sectors at the beginning of the next
  89. partition. To avoid it generic_format will not format first and last side
  90. of the partition, but will verify it and clear with zeros.
  91.  
  92. */
  93.  
  94. int generic_format(struct part_long *p, int bbt_size, unsigned long *bbt)
  95. {
  96.  char tmp[90];
  97.  struct disk_addr daddr;
  98.  unsigned long base_sect=0; 
  99.  static unsigned char ftab[512];
  100.  int i, j, cyl, head, sect, num_sect, x, num_bad=0, hd=dinfo.disk;
  101.  
  102.  progress(MESG_FORMATTING);
  103.  
  104.  if( p->start_sect!=1 || p->end_sect!=dinfo.num_sects )
  105.    {
  106.     progress(ERROR_FORMAT_FRACTION);
  107.     return FAILED;
  108.    }
  109.  
  110.  if( detected_os==SYS_WIN95 )
  111.    {
  112.     progress(ERROR_FORMAT_WIN95);
  113.     return FAILED;
  114.    }
  115.  
  116.  disk_lock(hd);
  117.  
  118.  num_sect=dinfo.num_sects;
  119.  
  120.  /* -----> now we handle special case for the first side */
  121.  
  122.   daddr.disk=hd;
  123.   daddr.cyl=p->start_cyl;
  124.   daddr.head=p->start_head;
  125.   daddr.sect=0;
  126.   
  127.   memset(ftab,0,512);
  128.   
  129.   for( sect=0 ; sect<num_sect ; sect++ )
  130.      {
  131.       daddr.sect=sect+1;
  132.       if( disk_verify(&daddr,1)==-1 )
  133.         {
  134.          if( bbt_size!=-1 )
  135.            {
  136.             if( num_bad==bbt_size ) 
  137.               {
  138.                disk_unlock(hd);
  139.                return FAILED;
  140.               }
  141.             bbt[num_bad]=base_sect;
  142.            }
  143.          num_bad++;
  144.         }
  145.       base_sect++;
  146.      }/* sect */
  147.  
  148.   for( sect=0 ; sect<num_sect ; sect++ )
  149.      {
  150.       daddr.sect=sect+1;
  151.       disk_write(&daddr,ftab,1);
  152.      }/* sect */
  153.  
  154.  /* -----> end special case */
  155.  
  156.  for( cyl=p->start_cyl ; cyl<=p->end_cyl ; cyl++ )
  157.     {
  158.      for( head=((cyl==p->start_cyl)?p->start_head+1:0) ;
  159.           head<((cyl==p->end_cyl)?p->end_head:dinfo.num_heads) ; head++ )
  160.         {
  161.          daddr.disk=hd;
  162.          daddr.cyl=cyl;
  163.          daddr.head=head;
  164.          daddr.sect=0;
  165.  
  166.          for( sect=0 ; sect<num_sect ; sect++ )
  167.             {
  168.              ftab[sect*2+1]=sect+1;
  169.             }
  170.  
  171.          if( disk_format(&daddr,ftab)==-1 )
  172.            {
  173.             progress(ERROR_FORMAT_GEN);
  174.             disk_unlock(hd);
  175.             return FAILED;
  176.            }
  177.  
  178.          for( sect=0 ; sect<num_sect ; sect++ )
  179.           if( ftab[sect*2]!=0 )        /* is it a bad sector? */ 
  180.             {
  181.              if( bbt_size!=-1 )
  182.                {
  183.                 if( num_bad==bbt_size ) 
  184.                   {
  185.                    disk_unlock(hd);
  186.                    return FAILED;
  187.                   }
  188.                 bbt[num_bad]=base_sect+sect;
  189.                }
  190.              num_bad++;
  191.             }
  192.  
  193.          base_sect+=num_sect;
  194.  
  195.          x=base_sect*100/p->num_sect;
  196.  
  197.          sprintf(tmp,"%% %3d%%  Cylinder: %3d",x,cyl);
  198.          if( progress(tmp)==CANCEL )
  199.            {
  200.             disk_unlock(hd);
  201.             return CANCEL;
  202.            }
  203.         }/* head */
  204.     }/* cyl */
  205.  
  206.  /* -----> now we handle special case for the last side */
  207.  
  208.   daddr.disk=hd;
  209.   daddr.cyl=p->end_cyl;
  210.   daddr.head=p->end_head;
  211.   
  212.   memset(ftab,0,512);
  213.   
  214.   for( sect=0 ; sect<num_sect ; sect++ )
  215.      {
  216.       daddr.sect=sect+1;
  217.       if( disk_verify(&daddr,1)==-1 )
  218.         {
  219.          if( bbt_size!=-1 )
  220.            {
  221.             if( num_bad==bbt_size ) 
  222.               {
  223.                disk_unlock(hd);
  224.                return FAILED;
  225.               }
  226.             bbt[num_bad]=base_sect+sect;
  227.            }
  228.          num_bad++;
  229.         }
  230.      }/* sect */
  231.  
  232.   for( sect=0 ; sect<num_sect ; sect++ )
  233.      {
  234.       daddr.sect=sect+1;
  235.       disk_write(&daddr,ftab,1);
  236.      }/* sect */
  237.  
  238.  sprintf(tmp,"%% 100%%  Cylinder: %3d",p->end_cyl);
  239.  progress(tmp);
  240.  
  241.  /* -----> end special case */
  242.  
  243.  disk_unlock(hd);
  244.  return num_bad;
  245. }/* generic_format */
  246.  
  247.  
  248. int format_unused(struct part_long *p, char **argv)
  249. {
  250.  int x;
  251.  
  252.  if( argv==0 || *argv==0 || strcmpi(*argv,"/clean")!=0 &&
  253.                             strcmpi(*argv,"/destructive")!=0 )
  254.    {
  255.     progress("^I will not do that.");
  256.     progress("To enforce operation use option \"/clean\" or \"/destructive\" ");
  257.     return FAILED;
  258.    }
  259.  
  260.  flush_caches();
  261.  
  262.  if( strcmpi(*argv,"/clean")==0 )
  263.    {
  264.     x=generic_clean(p);
  265.    }
  266.  else /* /destructive */
  267.    {
  268.     x=generic_format(p,-1,0);
  269.    }
  270.  
  271.  if( x<0 ) return x;
  272.  
  273.  return OK;
  274. }/* format_unused */
  275.  
  276.  
  277.  
  278.  
  279. int generic_clean(struct part_long *p)
  280. {
  281.  char *z, tmp[90];
  282.  struct disk_addr daddr;
  283.  unsigned long total_done=0;
  284.  int i, j, cyl, head, sect, s_sect, e_sect, num_sect, x, hd=dinfo.disk;
  285.  
  286.  if( (z=(char*)malloc(63*SECT_SIZE))==0 )
  287.    {
  288.     show_error(ERROR_MALLOC);
  289.     return FAILED;
  290.    }
  291.  
  292.  memset(z,0,63*SECT_SIZE);
  293.  
  294.  progress(MESG_CLEANING);
  295.  
  296.  disk_lock(hd);
  297.  
  298.  for( cyl=p->start_cyl ; cyl<=p->end_cyl ; cyl++ )
  299.     {
  300.      for( head=((cyl==p->start_cyl)?p->start_head:0) ;
  301.           head<((cyl==p->end_cyl)?p->end_head+1:dinfo.num_heads) ; head++ )
  302.         {
  303.          daddr.disk=hd;
  304.          daddr.cyl=cyl;
  305.          daddr.head=head;
  306.  
  307.          s_sect = (cyl==p->start_cyl && head==p->start_head) ? p->start_sect : 1;
  308.          e_sect = (cyl==p->end_cyl   && head==p->end_head  ) ? p->end_sect : dinfo.num_sects;
  309.  
  310.          daddr.sect=s_sect;
  311.          num_sect=e_sect-s_sect+1;
  312.  
  313.          disk_write(&daddr,z,num_sect);
  314.  
  315.          total_done+=num_sect;
  316.  
  317.          x=total_done*100/p->num_sect;
  318.  
  319.          sprintf(tmp,"%% %3d%%  Cylinder: %3d",x,cyl);
  320.          if( progress(tmp)==CANCEL )
  321.            {
  322.             disk_unlock(hd);
  323.             free(z);
  324.             return CANCEL;
  325.            }
  326.         }/* head */
  327.     }/* cyl */
  328.  
  329.  disk_unlock(hd);
  330.  free(z);
  331.  return OK;
  332. }/* generic_clean */
  333.