home *** CD-ROM | disk | FTP | other *** search
/ PC World 2002 February / PCWorld_2002-02_cd.bin / Software / Vyzkuste / ranish / SOURCES.ZIP / PART_AUX.C < prev    next >
C/C++ Source or Header  |  1998-07-23  |  19KB  |  707 lines

  1. #include "part.h"
  2.  
  3.  
  4. void part_to_disk_addr(struct part_long *p,  unsigned long rel_sect,
  5.                        struct disk_addr *daddr)
  6. {
  7.  unsigned long abs_sect;
  8.  
  9.  abs_sect = QUICK_BASE(p) + rel_sect;
  10.  
  11.  daddr->disk = dinfo.disk;
  12.  daddr->cyl  = CYL(abs_sect);
  13.  daddr->head = HEAD(abs_sect);
  14.  daddr->sect = SECT(abs_sect);
  15. }/* part_to_disk_addr */
  16.  
  17.  
  18. int disk_read_rel(struct part_long *p, unsigned long rel_sect, void *buf, int num_sect)
  19. {
  20.  struct disk_addr daddr;
  21.  
  22.  part_to_disk_addr(p,rel_sect,&daddr);
  23.  
  24.  return disk_read( &daddr, buf, num_sect ); 
  25. }/* disk_read_rel */
  26.  
  27.  
  28. int disk_write_rel(struct part_long *p, unsigned long rel_sect, void *buf, int num_sect)
  29. {
  30.  struct disk_addr daddr;
  31.  
  32.  part_to_disk_addr(p,rel_sect,&daddr);
  33.  
  34.  return disk_write( &daddr, buf, num_sect ); 
  35. }/* disk_write_rel */
  36.  
  37.  
  38. void pack_part_tab(struct part_long *part, struct part_rec *part_rec, int n)
  39. {
  40.  int i;
  41.  
  42.  for( i=0 ; i<n ; i++ )
  43.     {
  44.      if( part[i].active==0 )
  45.        {
  46.         if( part_rec[i].boot_flag!=0 ) part_rec[i].boot_flag=0;
  47.        }
  48.      else
  49.        {
  50.         if( part_rec[i].boot_flag==0 ) part_rec[i].boot_flag=0x80;
  51.        }
  52.  
  53.      part_rec[i].start_cylL = part[i].start_cyl & 0xFF;
  54.      part_rec[i].start_cylH = part[i].start_cyl >> 8;
  55.      part_rec[i].start_head = part[i].start_head;
  56.      part_rec[i].start_sect = part[i].start_sect;
  57.  
  58.      part_rec[i].end_cylL   = part[i].end_cyl & 0xFF;
  59.      part_rec[i].end_cylH   = part[i].end_cyl >> 8;
  60.      part_rec[i].end_head   = part[i].end_head;
  61.      part_rec[i].end_sect   = part[i].end_sect;
  62.  
  63.      part_rec[i].rel_sect   = part[i].rel_sect;
  64.      part_rec[i].num_sect   = part[i].num_sect;
  65.  
  66.      part_rec[i].os_id  =  part[i].os_id >> 8;
  67.     }
  68. }/* pack_part_tab */
  69.  
  70.  
  71. void unpack_part_tab(struct part_rec *part_rec, struct part_long *part, int n,
  72.                                                 struct part_long *container )
  73. {
  74.  int i;
  75.  
  76.  for( i=0 ; i<n ; i++ )
  77.     {
  78.      part[i].active = (part_rec[i].boot_flag==0)?0:1;
  79.  
  80.      part[i].start_cyl  = part_rec[i].start_cylL+(part_rec[i].start_cylH<<8);
  81.      part[i].start_head = part_rec[i].start_head;
  82.      part[i].start_sect = part_rec[i].start_sect;
  83.  
  84.      part[i].end_cyl    = part_rec[i].end_cylL+(part_rec[i].end_cylH<<8);
  85.      part[i].end_head   = part_rec[i].end_head;
  86.      part[i].end_sect   = part_rec[i].end_sect;
  87.  
  88.      part[i].rel_sect   = part_rec[i].rel_sect;
  89.      part[i].num_sect   = part_rec[i].num_sect;
  90.  
  91.      part[i].os_id  =  part_rec[i].os_id << 8;
  92.  
  93.      if( i>0 && (part[i-1].os_id==0x8100 ||  /* Linix */
  94.                  part[i-1].os_id==0x8300)  /* Linix ext2fs */
  95.              && (part[i].os_id>>8)==0x82 /* Linix swap */ )
  96.        {
  97.         part[i].os_id=0x8201; /* Linux Swap */
  98.        }
  99.  
  100.      determine_os_num( &part[i] );
  101.  
  102.      part[i].level = container->level+1;
  103.  
  104.      if( part[i].level>2 && part[i].os_id==OS_EXT )
  105.         part[i].container = container->container;
  106.      else
  107.         part[i].container = container;
  108.  
  109.      part[i].container_base = QUICK_BASE(part[i].container);
  110.     }
  111. }/* unpack_part_tab */
  112.  
  113.  
  114. void pack_adv_part_tab(struct part_long *part, struct adv_part_rec *part_rec, int n)
  115. {
  116.  int i;
  117.  
  118.  for( i=0 ; i<n ; i++ )
  119.     {
  120.      part_rec[i].os_id   =  part[i].os_id;
  121.      part_rec[i].tag     =  part[i].active;
  122.      part_rec[i].orig_row =  part[i].orig_row;
  123.  
  124.      part_rec[i].rel_sect = part[i].rel_sect;
  125.      part_rec[i].num_sect = part[i].num_sect;
  126.     }
  127.  
  128. }/* pack_adv_part_tab */
  129.  
  130.  
  131.  
  132.  
  133. void unpack_adv_part_tab(struct adv_part_rec *part_rec, struct part_long *part,
  134.                                                  int n, struct part_long *container )
  135. {
  136.  int i, mode = MODE_LBA;
  137.  
  138.  for( i=0 ; i<n ; i++ )
  139.     {
  140.      part[i].os_id    =   part_rec[i].os_id;
  141.      part[i].active   =   part_rec[i].tag;
  142.      part[i].orig_row  =  part_rec[i].orig_row;
  143.  
  144.      part[i].rel_sect   = part_rec[i].rel_sect;
  145.      part[i].num_sect   = part_rec[i].num_sect;
  146.  
  147.  
  148.      part[i].level = container->level+1;
  149.      part[i].container = container;
  150.      part[i].container_base = QUICK_BASE(container);
  151.  
  152.      recalculate_part(&part[i],mode);
  153.  
  154.      determine_os_num( &part[i] );
  155.     }
  156.   
  157. }/* unpack_adv_part_tab */
  158.  
  159.  
  160. void determine_os_num(struct part_long *p)
  161. {
  162.  int i=0;
  163.  
  164.  while( os_desc[i].os_id!=p->os_id && os_desc[i].os_id!=OS_UNKN ) i++;
  165.  
  166.  if( p->os_id==0xFF00 )
  167.    {
  168.     while( os_desc[i].os_id!=OS_HIDDEN ) i++;
  169.    }
  170.  
  171.  p->os_num=i;
  172. }/* determine_os_num */
  173.  
  174.  
  175. void recalculate_part(struct part_long *p, int mode)
  176. {
  177.  unsigned long rel_sect, end_sect;
  178.  
  179.  if( mode==MODE_CHS )
  180.    { 
  181.     p->rel_sect=0;
  182.     p->num_sect=0;
  183.  
  184.     if( p->start_sect!=0 )
  185.       {
  186.        rel_sect = ABS_REL_SECT(p);
  187.        p->rel_sect = rel_sect - p->container_base;
  188.  
  189.        if( p->end_sect!=0 )
  190.           {
  191.            end_sect = ABS_END_SECT(p);
  192.            if( end_sect >= rel_sect ) p->num_sect = end_sect - rel_sect + 1;
  193.           }
  194.       }
  195.    }
  196.  else /* mode==MODE_LBA */
  197.    {
  198.     p->start_cyl=0;    p->end_cyl=0;
  199.     p->start_head=0;    p->end_head=0;
  200.     p->start_sect=0;    p->end_sect=0;
  201.  
  202.     if( p->rel_sect!=0 || p->num_sect!=0 )
  203.       {
  204.        rel_sect = p->container_base + p->rel_sect;
  205.        end_sect = p->container_base + p->rel_sect + p->num_sect - 1 ;
  206.  
  207.        p->start_cyl  = CYL(rel_sect);
  208.        p->start_head = HEAD(rel_sect);
  209.        p->start_sect = SECT(rel_sect);
  210.  
  211.        if( p->num_sect!=0 )
  212.          {
  213.           p->end_cyl  = CYL(end_sect);
  214.           p->end_head = HEAD(end_sect);
  215.           p->end_sect = SECT(end_sect);
  216.          }
  217.       }
  218.    }/* LBA */
  219.  
  220. }/* recalculate_part */
  221.  
  222.  
  223. int validate_table(struct part_long *part, int n, struct part_long *container2)
  224. {
  225.  int i, j;
  226.  struct part_long *p, *q;
  227.  struct part_long *container;
  228.  unsigned long rel_sect, end_sect, num_sect;
  229.  
  230.  for( p=part, i=0 ; i<n ; i++, p++ )
  231.     {
  232.      p->empty=1;
  233.  
  234.           if( p->start_cyl!=0  ) p->empty=0;
  235.      else if( p->start_head!=0 ) p->empty=0;
  236.      else if( p->start_sect!=0 ) p->empty=0;
  237.  
  238.      else if( p->end_cyl!=0  ) p->empty=0;
  239.      else if( p->end_head!=0 ) p->empty=0;
  240.      else if( p->end_sect!=0 ) p->empty=0;
  241.  
  242.      else if( p->rel_sect!=0 ) p->empty=0;
  243.      else if( p->num_sect!=0 ) p->empty=0;
  244.     }
  245.  
  246.  
  247.  for(  p=part, i=0 ; i<n ; i++, p++ )
  248.     {
  249.      if( p->empty ) continue;
  250.      
  251.      p->valid=1;
  252.      p->mbr_err=0;
  253.      p->range_err=0;
  254.      p->overlap_err=0;
  255.      p->inconsist_err=0;
  256.      p->boot_record_err=0;
  257.  
  258.      container = p->container;
  259.      
  260.      rel_sect = ABS_REL_SECT(p);
  261.  
  262.      end_sect = ABS_END_SECT(p);
  263.      
  264.      num_sect = end_sect - rel_sect + 1;
  265.  
  266.      if( rel_sect != p->rel_sect+p->container_base ) p->inconsist_err=1;
  267.      if( num_sect != p->num_sect                   ) p->inconsist_err=1;
  268.  
  269.      if( mode==MODE_CHS )
  270.        {
  271.              if( p->end_cyl <  p->start_cyl ) p->range_err=1;
  272.         else if( p->end_cyl == p->start_cyl && p->end_head <  p->start_head  ) p->range_err=1;
  273.         else if( p->end_cyl == p->start_cyl && p->end_head == p->start_head && p->end_sect < p->start_sect ) p->range_err=1;
  274.  
  275.              if( p->end_cyl >  container->end_cyl ) p->range_err=1;
  276.         else if( p->end_cyl == container->end_cyl && p->end_head >  container->end_head ) p->range_err=1;
  277.         else if( p->end_cyl == container->end_cyl && p->end_head == container->end_head && p->end_sect > container->end_sect ) p->range_err=1;
  278.  
  279.              if( p->start_cyl <  container->start_cyl ) p->range_err=1;
  280.         else if( p->start_cyl == container->start_cyl && p->start_head <  container->start_head ) p->range_err=1;
  281.         else if( p->start_cyl == container->start_cyl && p->start_head == container->start_head && p->start_sect < container->start_sect ) p->range_err=1;
  282.         
  283.         if( p->start_cyl >= dinfo.num_cyls ) p->range_err=1;
  284.         if( p->end_cyl   >= dinfo.num_cyls ) p->range_err=1;
  285.         
  286.         if( p->start_head >= dinfo.num_heads ) p->range_err=1;
  287.         if( p->end_head   >= dinfo.num_heads ) p->range_err=1;
  288.  
  289.         if( p->start_sect >  dinfo.num_sects ) p->range_err=1;
  290.         if( p->end_sect   >  dinfo.num_sects ) p->range_err=1;
  291.  
  292.         if( p->start_sect == 0 ) p->range_err=1;
  293.         if( p->end_sect   == 0 ) p->range_err=1;
  294.  
  295.         if( p->start_cyl  == container->start_cyl &&
  296.             p->start_head == container->start_head &&
  297.             p->start_sect == container->start_sect ) p->mbr_err=1;
  298.        }
  299.      else /* mode==MODE_LBA */
  300.        {
  301.         if( p->rel_sect == 0 ) p->mbr_err=1;
  302.         if( p->rel_sect >= container->num_sect ) p->range_err=1;
  303.         if( p->num_sect - 1 > container->num_sect ) p->range_err=1;
  304.         if( p->rel_sect + p->num_sect - 1 >= container->num_sect ) p->range_err=1;
  305.  
  306.         rel_sect=p->rel_sect + p->container_base;
  307.         end_sect=rel_sect + p->num_sect - 1 ;
  308.        }
  309.  
  310.      for( q=part, j=0 ; j<n ; j++, q++ )
  311.         {
  312.          unsigned long q_rel_sect, q_end_sect;
  313.          
  314.          if( i==j || q->empty ) continue;
  315.          
  316.          q_rel_sect = (mode==MODE_CHS) ? ABS_REL_SECT(q) : (q->rel_sect + q->container_base);
  317.          q_end_sect = (mode==MODE_CHS) ? ABS_END_SECT(q) : (q_rel_sect + q->num_sect - 1);
  318.          
  319.          if( rel_sect >= q_rel_sect && rel_sect <= q_end_sect ) p->overlap_err=1;
  320.          if( q_rel_sect >= rel_sect && q_rel_sect <= end_sect ) p->overlap_err=1;
  321.         }/* q */
  322.      
  323.      if( p->mbr_err || p->range_err || p->overlap_err || p->inconsist_err ) p->valid=0;
  324.     }/* p */
  325.  
  326.  for( i=0 ; i<n ; i++ )
  327.   if( container2->level>1 && part[i].os_id==OS_EXT &&
  328.       part[i].start_cyl < container2->end_cyl+1 )
  329.      {
  330.       part[i].range_err=1;
  331.       part[i].valid=0;
  332.      }
  333.  
  334.  for( i=0 ; i<n ; i++ )
  335.   if( part[i].empty==0 && part[i].valid==0 )
  336.      return 0;
  337.  
  338.  return 1;
  339. }/* validate_table */
  340.  
  341.  
  342.  
  343. int write_int(int attr, int x, int y, int w, unsigned long xx)
  344. {
  345.  char tmp[30];
  346.  
  347.  sprintf(tmp,"%*ld",w,xx);
  348.  write_string(attr,x,y,tmp);
  349.  
  350.  return 0;
  351. }/* write_int */
  352.  
  353.  
  354. char *sprintf_long(char *tmp, unsigned long num)
  355. {
  356.  int i=13;    /* 1,111,111,111 */
  357.  tmp[i--]=0;    /* 0 234 678 012 */
  358.  
  359.  while( num!=0 )
  360.     {
  361.      if( i==9 || i==5 || i==1 ) tmp[i--]=',';
  362.      tmp[i--]=num%10+'0';
  363.      num/=10;
  364.     }
  365.  
  366.  return tmp+i+1;
  367. }/* sprintf_long */
  368.  
  369.  
  370. char *sprintf_systype(char *tmp, int i)
  371. {
  372.  sprintf(tmp," 0x%02X   %-23s     %s     %s      %s ",
  373.                os_desc[i].os_id>>8, os_desc[i].name,
  374.               (os_desc[i].setup!=0)?"Yes":" - ",
  375.               (os_desc[i].format!=0)?"Yes":" - ",
  376.               (os_desc[i].print!=0)?"Yes":" - " );
  377.  return tmp;
  378. }/* sprintf_systype */
  379.  
  380.  
  381. char *sprintf_os_name(char *tmp, struct part_long *p)
  382. {
  383.  if( os_desc[p->os_num].os_id != OS_UNKN )
  384.     sprintf(tmp,"%-23s",os_desc[p->os_num].name );
  385.  else
  386.     sprintf(tmp,NAME_OS_UNKN, p->os_id>>8 );
  387.  
  388.  return tmp;
  389. }/* sprintf_os_name */
  390.  
  391.  
  392.  
  393. char *sprintf_partrec(char *tmp, struct part_long *p, int num, int view)
  394. {
  395.  char tmp1[30], tmp2[30];
  396.  
  397.  if( mode==MODE_CHS )
  398.    {
  399.     sprintf(tmp,"%2d  %-4s  %s %4ld %4ld %4ld  %4ld %4ld %4ld %10s ",
  400.          num,
  401.          p->active ? (view==VIEW_ADV ? "Menu":" Yes") : " No",
  402.          sprintf_os_name(tmp1,p),
  403.          p->start_cyl,
  404.          p->start_head,
  405.          p->start_sect,
  406.          p->end_cyl,
  407.          p->end_head,
  408.          p->end_sect,
  409.          sprintf_long(tmp2,QUICK_SIZE(p)/2) );
  410.    }
  411.  else /* MODE_LBA */
  412.    {
  413.     sprintf(tmp,"%2d  %-4s  %s%9lu %10lu %10lu %10s ",
  414.          num,
  415.          p->active ? (view==VIEW_ADV ? "Menu":" Yes") : " No",
  416.          sprintf_os_name(tmp1,p),
  417.          p->rel_sect,
  418.          p->num_sect,
  419.          (p->num_sect==0)?(0):(p->rel_sect+p->num_sect-1),
  420.          sprintf_long(tmp2,p->num_sect/2) );
  421.    }
  422.  
  423.  return tmp;         
  424. }/* sprintf_part */
  425.  
  426.  
  427. void usage(void)
  428. {
  429.  printf(HELP_CMD_LINE);
  430.  exit(1);
  431. }
  432.  
  433. void cmd_error(char *msg)
  434. {
  435.  if( !quiet ) fprintf(stderr,"\nError: %s\n",msg);
  436.  exit(1);
  437. }
  438.  
  439.  
  440.  
  441. int prepare_adv_mbr_for_save( struct part_long *part, struct mbr *mbr,
  442.                               struct adv *adv )
  443. {
  444.  int i, j;
  445.  struct part_long h;
  446.  
  447.  for( i=0 ; i<MAX_PART_ROWS ; i++ )
  448.   if( part[i].os_id==OS_ADV ) break;
  449.  
  450.  if( i==MAX_PART_ROWS || part[i].num_sect<ADV_NUM_SECTS )
  451.    return 0;
  452.  
  453.  memmove( mbr->x.adv.code, ADV_IPL, sizeof(mbr->x.adv.code) );
  454.  mbr->x.adv.rel_sect=part[i].rel_sect;
  455.  mbr->x.adv.reserved=0;
  456.  mbr->x.adv.act_menu=0;
  457.  mbr->x.adv.boptions=0;
  458.  mbr->x.adv.adv_mbr_magic=ADV_MBR_MAGIC;
  459.  
  460.  memset(mbr->part_rec,0,sizeof(mbr->part_rec));
  461.  h.active=1;
  462.  h.rel_sect=1;
  463.  h.num_sect=dinfo.total_sects-1;
  464.  h.container_base=0;
  465.  h.container=part[i].container;
  466.  h.os_id=OS_HIDDEN;
  467.  recalculate_part(&h,MODE_LBA);
  468.  pack_part_tab(&h,mbr->part_rec,1);
  469.  
  470.  if( adv->options&ADV_OPT_IGN_UNUSED )
  471.    {
  472.     for( i=0 ; i<MAX_PART_ROWS ; i++ )
  473.      if( adv->part[i].os_id==0 ) 
  474.        {
  475.         for( j=i ; j<MAX_PART_ROWS-1 ; j++ )
  476.           adv->part[j]=adv->part[j+1];
  477.         memset( &adv->part[j], 0, sizeof(struct adv_part_rec) );
  478.        }
  479.    }
  480.  
  481.  strcpy( mbr->x.adv_old.signature, ADV_DATA_SIGNATURE );
  482.          mbr->x.adv_old.version=ADV_DATA_VERSION;
  483.  
  484.  strcpy( adv->signature, ADV_DATA_SIGNATURE );
  485.          adv->version=ADV_DATA_VERSION;
  486.  
  487.  if( strncmp(adv->adv_title,MANAGER_TITLE,sizeof(adv->adv_title)-8)==0 )
  488.      strncpy(adv->adv_title,MANAGER_TITLE,sizeof(adv->adv_title));
  489.  
  490.  return 1;
  491. }/* prepare_adv_mbr_for_save */
  492.  
  493.  
  494.  
  495.  
  496.  
  497. int save_to_file(char *filename, void *buf, int len)
  498. {
  499.  FILE *f;
  500.  
  501.  if( (f=fopen(filename,"wb"))==0 ) return -1;
  502.  
  503.  if( fwrite(buf,1,len,f)!=len ) return -1;
  504.  
  505.  fclose(f);
  506.  return 0;
  507. }/* save_to_file */
  508.  
  509.  
  510.  
  511. int load_from_file(char *filename, void *buf, int len)
  512. {
  513.  FILE *f;
  514.  
  515.  if( (f=fopen(filename,"rb"))==0 ) return -1;
  516.  
  517.  if( fread(buf,1,len,f)!=len ) return -1;
  518.  
  519.  fclose(f);
  520.  return 0;
  521. }/* load_from_file */
  522.  
  523.  
  524. void get_base_dir(char *path)
  525. {
  526.  int i;
  527.  char *p, *q;
  528.  
  529.  p=path+strlen(path)-1;
  530.  
  531.  while( p!=path && *p!='\\' && *p!='/' ) p--;
  532.  
  533.  if( *p=='\\' || *p=='/' )
  534.    strncpy(base_dir,path,p-path+1);
  535.  else base_dir[0]=0;
  536.  
  537. }/* get_base_dir */
  538.  
  539.  
  540. void parse_arg(char *str, char **argv, int argv_size)
  541. {
  542.  int i=0;
  543.  char *p=str;
  544.  
  545.  while(1)
  546.     {
  547.      while( *p==' ' || *p=='\t' ) p++;
  548.      if( *p==0 ) break;
  549.      if( i>=argv_size-1 ) break;
  550.      argv[i++]=p;
  551.      while( *p!=' ' && *p!='\t' && *p!=0 ) p++;
  552.      if( *p==0 ) break;
  553.      *p=0;
  554.      p++;
  555.     }
  556.  
  557.  argv[i]=0;
  558. }/* parse_arg */
  559.  
  560.  
  561. void print_part_details(struct part_long *part, int num_rows)
  562. {
  563.  int i;
  564. /*
  565.    HardDisk 1   1236 MB  [ 1023 cyl x 255 heads x 63 sects = 11,111,111 sects ] 
  566.  
  567. Valid            Starting       Ending    Starting  Numb of   Ending  Partition
  568.  |   # HD  FS  Cyl Head Sct  Cyl Head Sct   sector  sectors   sector  Size [KB]
  569. OK   1 80  FF 1023  255  63 1023  255  63 12345678 12345678 12345678  1,111,111
  570.  X   2  0  FF 1023  255  63 1023  255  63 12345678 12345678 12345678  1,111,111
  571.      3  0  00    0    0   0    0    0   0        0        0
  572.      4  0  00    0    0   0    0    0   0        0        0
  573. */
  574.  printf("Valid            Starting       Ending    Starting  Numb of   Ending  Partition\n"
  575.         " |   # %3s FS  Cyl Head Sct  Cyl Head Sct   sector  sectors   sector  Size [KB]\n\n",
  576.          num_rows==4?"HD ":"Row" );
  577.  
  578.  for( i=0 ; i<num_rows ; i++ )
  579.     {
  580.      if( part[i].empty ) continue;
  581.  
  582.      printf("%s %2d %2X  %02X %4lu  %3lu  %2lu %4lu  %3lu  %2lu %8lu %8lu %8lu %10s\n",
  583.           (part[i].valid)?"OK ":" X ", i+1,
  584.            num_rows==4 ? 0x80 : part[i].orig_row,
  585.            part[i].os_id>>8,
  586.            part[i].start_cyl, part[i].start_head, part[i].start_sect,
  587.            part[i].end_cyl,   part[i].end_head,   part[i].end_sect,
  588.            part[i].rel_sect,  part[i].num_sect,
  589.           (part[i].num_sect==0)?(0):(part[i].rel_sect+part[i].num_sect-1),
  590.            sprintf_long(tmp,part[i].num_sect/2) );
  591.     }
  592.  
  593.  printf("\n");
  594.  
  595.  for( i=0 ; i<num_rows ; i++ )
  596.   if( !part[i].empty && !part[i].valid )
  597.     {
  598.      printf("Errors in record %d:",i+1);
  599.      if( part[i].mbr_err ) printf("  mbr");
  600.      if( part[i].range_err ) printf("  range");
  601.      if( part[i].overlap_err ) printf("  overlapped");
  602.      if( part[i].inconsist_err ) printf("  inconsistent");
  603.      if( part[i].boot_record_err ) printf("  boot_record_invalid");
  604.      printf("\n");
  605.     }
  606.  
  607. }/* print_part_details */
  608.  
  609.  
  610.  
  611. int print_embr(struct part_long *p)
  612. {
  613.  int i, n;
  614.  struct mbr *mbr = (struct mbr*)buf;
  615.  struct part_long *part = malloc(4*sizeof(struct part_long));
  616.  
  617.  if( part==0 ) cmd_error(ERROR_MALLOC);
  618.  
  619.  if( disk_read_rel(p,0,mbr,1)==-1 )
  620.    {
  621.     fprintf(stderr,"Warning: %s\n\n",ERROR_READ_MBR);
  622.     return 0;
  623.    }
  624.  
  625.  printf("EMBR Level %2d      Magic number: 0x%04X\n\n",p->level,mbr->magic_num);
  626.  
  627.  if( p->level>30 ) cmd_error("This is too deep.");
  628.  
  629.  unpack_part_tab( mbr->part_rec, part, 4, p );
  630.  
  631.  validate_table(part,4,p);
  632.  
  633.  printf("Valid%s\n |   %s\n\n", HEADER_CHS2, HEADER_CHS3 );
  634.  
  635.  for( i=0 ; i<4 ; i++ )
  636.     {
  637.      sprintf_partrec(tmp, &part[i], i+1, VIEW_EMBR );  tmp[75]=0;
  638.      printf("%s %s\n", part[i].empty?"   ":(part[i].valid?"OK ":" X "),tmp);
  639.     }
  640.  
  641.  printf("\n");
  642.  
  643.  print_part_details(part,4);
  644.  
  645.  for( i=0 ; i<4 ; i++ )
  646.   if(!part[i].empty && part[i].valid && part[i].os_id!=0
  647.                                      && part[i].os_id!=OS_ADV )
  648.     {
  649.      printf("\n\n-------------------------------------------------------------------------------\n\n"
  650.             "%s  [  %luM = %s sectors  at  CHS=(%lu,%lu,%lu)  ]\n\n",
  651.              sprintf_os_name(tmp,&part[i]),
  652.              part[i].num_sect/2048, sprintf_long(tmp2,part[i].num_sect),
  653.              part[i].start_cyl, part[i].start_head, part[i].start_sect );
  654.      if( os_desc[part[i].os_num].print!=0 )
  655.          os_desc[part[i].os_num].print(&part[i]);
  656.      else print_unknown(&part[i]);
  657.     }
  658.  
  659.  free(part);
  660.  return 0;
  661. }/* print_embr */
  662.  
  663.  
  664.  
  665.  
  666. void convert_adv_data(struct adv *adv)
  667. {
  668.  struct adv_v2
  669.     {
  670.      unsigned char signature[15];        /* AdvBootManager\0 */
  671.      unsigned char version;            /* Data structure version */
  672.      unsigned long rel_sect;
  673.      unsigned char act_menu;
  674.      unsigned char reserved[9];
  675.      unsigned char def_menu;
  676.      unsigned char timeout;
  677.      unsigned char options;
  678.      unsigned char options2;
  679.      unsigned long password;            /* code to validate password */
  680.      unsigned char reserved2[10];
  681.      unsigned char adv_title[32];
  682.      struct adv_menu_rec menu[MAX_MENU_ROWS];    /* 1280 */
  683.      struct adv_part_rec part[MAX_PART_ROWS];    /*  512 */
  684.     }*adv_v2=(struct adv_v2*)adv;
  685.  
  686.  adv->version  = ADV_DATA_VERSION;
  687.  adv->def_menu = adv_v2->def_menu;
  688.  adv->timeout  = adv_v2->timeout;
  689.  adv->options  = adv_v2->options;
  690.  adv->options2 = adv_v2->options2;
  691.  adv->password = 0;
  692.  memset(adv->reserved2,0,sizeof(adv->reserved2));
  693.  
  694.  if( interactive )
  695.    {
  696.     show_error("Advanced MBR had an old version. It was converted to the new one.");
  697. /*
  698.     show_error("If you don't want to save it press Ctrl-F10 for unconditional exit.");
  699. */
  700.    }
  701.  else
  702.    {
  703.     printf("Advanced MBR had an old version. It was converted to the new one.\n");
  704.    }
  705. }/* convert_adv_data */
  706.  
  707.