home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 8 / IOPROG_8.ISO / install / fips / source / fipsspec.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-25  |  7.7 KB  |  286 lines

  1. /*
  2.  
  3.     FIPS - the First nondestructive Interactive Partition Splitting program
  4.  
  5.  
  6.  
  7.     Module fipsspec.cpp
  8.  
  9.  
  10.  
  11.     RCS - Header:
  12.  
  13.     $Header: c:/daten/fips/source/main/RCS/fipsspec.cpp 1.4 1995/01/19 00:00:53 schaefer Exp schaefer $
  14.  
  15.  
  16.  
  17.     Copyright (C) 1993 Arno Schaefer
  18.  
  19.  
  20.  
  21.     This program is free software; you can redistribute it and/or modify
  22.  
  23.     it under the terms of the GNU General Public License as published by
  24.  
  25.     the Free Software Foundation; either version 2 of the License, or
  26.  
  27.     (at your option) any later version.
  28.  
  29.  
  30.  
  31.     This program is distributed in the hope that it will be useful,
  32.  
  33.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  34.  
  35.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  36.  
  37.     GNU General Public License for more details.
  38.  
  39.  
  40.  
  41.     You should have received a copy of the GNU General Public License
  42.  
  43.     along with this program; if not, write to the Free Software
  44.  
  45.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  46.  
  47.  
  48.  
  49.  
  50.  
  51.     Report problems and direct all questions to:
  52.  
  53.  
  54.  
  55.     schaefer@rbg.informatik.th-darmstadt.de
  56.  
  57. */
  58.  
  59.  
  60.  
  61. #include <dos.h>
  62.  
  63.  
  64.  
  65. #include "fipsspec.h"
  66.  
  67. #include "global.h"
  68.  
  69. #include "input.h"
  70.  
  71.  
  72.  
  73. #define FIRST_CHECK false
  74.  
  75. #define FINAL_CHECK true
  76.  
  77.  
  78.  
  79. #define DISK_INT 0x13
  80.  
  81.  
  82.  
  83. #define RESET_DISK 0
  84.  
  85. #define GET_DRIVE_PARAMS 8
  86.  
  87.  
  88.  
  89. void fips_bpb::print (void)
  90.  
  91. {
  92.  
  93.     printx ("Bytes per sector: %u\n",bytes_per_sector);
  94.  
  95.     printx ("Sectors per cluster: %u\n",sectors_per_cluster);
  96.  
  97.     printx ("Reserved sectors: %u\n",reserved_sectors);
  98.  
  99.     printx ("Number of FATs: %u\n",no_of_fats);
  100.  
  101.     printx ("Number of rootdirectory entries: %u\n",no_of_rootdir_entries);
  102.  
  103.     printx ("Number of sectors (short): %u\n",no_of_sectors);
  104.  
  105.     printx ("Media descriptor byte: %02Xh\n",media_descriptor);
  106.  
  107.     printx ("Sectors per FAT: %u\n",sectors_per_fat);
  108.  
  109.     printx ("Sectors per track: %u\n",sectors_per_track);
  110.  
  111.     printx ("Drive heads: %u\n",drive_heads);
  112.  
  113.     printx ("Hidden sectors: %lu\n",hidden_sectors);
  114.  
  115.     printx ("Number of sectors (long): %lu\n",no_of_sectors_long);
  116.  
  117.     printx ("Physical drive number: %02Xh\n",phys_drive_no);
  118.  
  119.     printx ("Signature: %02Xh\n\n",signature);
  120.  
  121. }
  122.  
  123.  
  124.  
  125. void fips_partition_table::print (void)
  126.  
  127. {
  128.  
  129.     printx ("     |        |     Start      |      |      End       | Start  |Number of|\n");
  130.  
  131.     printx ("Part.|bootable|Head Cyl. Sector|System|Head Cyl. Sector| Sector |Sectors  |  MB\n");
  132.  
  133.     printx ("-----+--------+----------------+------+----------------+--------+---------+----\n");
  134.  
  135.     for (int i=0;i<4;i++)
  136.  
  137.     {
  138.  
  139.         printx ("%u    |    %s |%4u %4u   %4u|   %02Xh|%4u %4u   %4u|%8lu| %8lu|%4lu\n",i+1,
  140.  
  141.         partition_info[i].bootable ? "yes" : " no",
  142.  
  143.         partition_info[i].start_head,partition_info[i].start_cylinder,partition_info[i].start_sector,
  144.  
  145.         partition_info[i].system,partition_info[i].end_head,partition_info[i].end_cylinder,partition_info[i].end_sector,
  146.  
  147.         partition_info[i].start_sector_abs,partition_info[i].no_of_sectors_abs,partition_info[i].no_of_sectors_abs / 2048);
  148.  
  149.     }
  150.  
  151. }
  152.  
  153.  
  154.  
  155. void fips_harddrive::get_geometry (void)
  156.  
  157. {
  158.  
  159.     union REGS regs;
  160.  
  161.  
  162.  
  163.     regs.h.ah = GET_DRIVE_PARAMS;
  164.  
  165.     regs.h.dl = number;
  166.  
  167.     int86 (DISK_INT,®s,®s);
  168.  
  169.     if (global.debug_mode)
  170.  
  171.     {
  172.  
  173.         fprintf (global.debugfile,"\nRegisters after call to int 13h 08h (drive %02Xh):\n\n",number);
  174.  
  175.         fprintf (global.debugfile,"   00       sc/cl    hd\n");
  176.  
  177.         fprintf (global.debugfile,"al ah bl bh cl ch dl dh   si    di    cflgs flags\n");
  178.  
  179.         hexwrite ((byte *) ®s,16,global.debugfile);
  180.  
  181.     }
  182.  
  183.     if ((errorcode = regs.h.ah) != 0) return;
  184.  
  185.     geometry.heads = (dword) regs.h.dh + 1;
  186.  
  187.     geometry.sectors = (dword) regs.h.cl & 0x3f;
  188.  
  189.     geometry.cylinders = ((dword) regs.h.ch | (((dword) regs.h.cl << 2) & 0x300)) + 1;
  190.  
  191.  
  192.  
  193.     if (global.debug_mode)
  194.  
  195.     {
  196.  
  197.         fprintf (global.debugfile, "\nGeometry reported by BIOS:\n");
  198.  
  199.         fprintf
  200.  
  201.         (
  202.  
  203.             global.debugfile,
  204.  
  205.             "%ld cylinders, %ld heads, %ld sectors\n",
  206.  
  207.             geometry.cylinders,
  208.  
  209.             geometry.heads,
  210.  
  211.             geometry.sectors
  212.  
  213.         );
  214.  
  215.     }
  216.  
  217. }
  218.  
  219.  
  220.  
  221. void fips_harddrive::reset (void)
  222.  
  223. {
  224.  
  225.     union REGS regs;
  226.  
  227.  
  228.  
  229.     regs.h.ah = RESET_DISK;
  230.  
  231.     regs.h.dl = number;
  232.  
  233.     int86 (DISK_INT,®s,®s);
  234.  
  235.     if (global.debug_mode)
  236.  
  237.     {
  238.  
  239.         fprintf (global.debugfile,"\nRegisters after call to int 13h 00h (drive %02Xh):\n\n",number);
  240.  
  241.         fprintf (global.debugfile,"al ah bl bh cl ch dl dh   si    di    cflgs flags\n");
  242.  
  243.         hexwrite ((byte *) ®s,16,global.debugfile);
  244.  
  245.     }
  246.  
  247.     errorcode = regs.h.ah;
  248.  
  249. }
  250.  
  251.  
  252.  
  253. void fips_logdrive_info::put_debug_info (void)
  254.  
  255. {
  256.  
  257.     fprintf (global.debugfile,"Calculated Partition Characteristica:\n\n");
  258.  
  259.     fprintf (global.debugfile,"Start of FAT 1: %lu\n",start_fat1);
  260.  
  261.     fprintf (global.debugfile,"Start of FAT 2: %lu\n",start_fat2);
  262.  
  263.     fprintf (global.debugfile,"Start of Rootdirectory: %lu\n",start_rootdir);
  264.  
  265.     fprintf (global.debugfile,"Start of Data: %lu\n",start_data);
  266.  
  267.     fprintf (global.debugfile,"Number of Clusters: %lu\n",no_of_clusters);
  268.  
  269. }
  270.  
  271.  
  272.  
  273. dword fips_partition::min_cylinder (fat16 fat, drive_geometry geometry)
  274.  
  275. {
  276.  
  277.     dword new_part_min_sector =
  278.  
  279.         info().start_data
  280.  
  281.         + (dword) 4085
  282.  
  283.         * bpb().sectors_per_cluster;
  284.  
  285.  
  286.  
  287.     dword new_part_min_cylinder =
  288.  
  289.         (
  290.  
  291.             new_part_min_sector
  292.  
  293.             + partition_info->start_sector_abs
  294.  
  295.             - 1
  296.  
  297.         )
  298.  
  299.         / (geometry.heads * geometry.sectors)
  300.  
  301.         + 1;
  302.  
  303.  
  304.  
  305.     if (new_part_min_cylinder > partition_info->end_cylinder)
  306.  
  307.         error ("Partition too small - can't split");
  308.  
  309.  
  310.  
  311.     dword min_free_cluster = fat.min_free_cluster ();
  312.  
  313.     dword min_free_sector =
  314.  
  315.         info().start_data
  316.  
  317.         + (min_free_cluster - 2)
  318.  
  319.         * (dword) bpb().sectors_per_cluster;
  320.  
  321.  
  322.  
  323.     dword min_free_cylinder =
  324.  
  325.         (
  326.  
  327.             min_free_sector
  328.  
  329.             + partition_info->start_sector_abs
  330.  
  331.             - 1
  332.  
  333.         )
  334.  
  335.         / (geometry.heads * geometry.sectors)
  336.  
  337.         + 1;
  338.  
  339.  
  340.  
  341.     if (min_free_cylinder > partition_info->end_cylinder)
  342.  
  343.         error ("Last cylinder is not free");
  344.  
  345.  
  346.  
  347.     if (new_part_min_cylinder < min_free_cylinder)
  348.  
  349.         new_part_min_cylinder = min_free_cylinder;
  350.  
  351.  
  352.  
  353.     return (new_part_min_cylinder);
  354.  
  355. }
  356.  
  357.  
  358.  
  359.  
  360.  
  361. boolean fips_partition::split (fips_harddrive hd)
  362.  
  363. {
  364.  
  365.     if (read_boot_sector ())
  366.  
  367.         error ("Error reading boot sector");
  368.  
  369.  
  370.  
  371.     if (global.debug_mode)
  372.  
  373.     {
  374.  
  375.         fprintf
  376.  
  377.         (
  378.  
  379.             global.debugfile,
  380.  
  381.             "\nBoot sector drive %02Xh, partition %u:\n\n",
  382.  
  383.             hd.number,
  384.  
  385.             number + 1
  386.  
  387.         );
  388.  
  389.  
  390.  
  391.         hexwrite
  392.  
  393.         (
  394.  
  395.             boot_sector->data,
  396.  
  397.             512,
  398.  
  399.             global.debugfile
  400.  
  401.         );
  402.  
  403.     }
  404.  
  405.  
  406.  
  407.     get_bpb ();
  408.  
  409.  
  410.  
  411.     printx ("\nBoot sector:\n\n");
  412.  
  413.     print_bpb ();
  414.  
  415.  
  416.  
  417.     get_info ();
  418.  
  419.     if (global.debug_mode)
  420.  
  421.         write_info_debugfile ();
  422.  
  423.  
  424.  
  425.     check ();
  426.  
  427.  
  428.  
  429.     fat16 fat1 (this,1);
  430.  
  431.     fat16 fat2 (this,2);
  432.  
  433.  
  434.  
  435.     fat1.check_against (&fat2);
  436.  
  437.  
  438.  
  439.     dword new_part_min_cylinder =
  440.  
  441.         min_cylinder (fat2, hd.geometry);
  442.  
  443.  
  444.  
  445.     if (ask_if_save()) save_root_and_boot(&hd,this);
  446.  
  447.  
  448.  
  449.     dword new_start_cylinder =
  450.  
  451.         ask_for_new_start_cylinder
  452.  
  453.         (
  454.  
  455.             partition_info->start_cylinder,
  456.  
  457.             new_part_min_cylinder,
  458.  
  459.             partition_info->end_cylinder,
  460.  
  461.             hd.geometry.heads * hd.geometry.sectors
  462.  
  463.         );
  464.  
  465.  
  466.  
  467.     fat2.check_empty
  468.  
  469.     (
  470.  
  471.         new_start_cylinder
  472.  
  473.             * hd.geometry.heads
  474.  
  475.             * hd.geometry.sectors
  476.  
  477.         - partition_info->start_sector_abs
  478.  
  479.     );
  480.  
  481.  
  482.  
  483.     hd.calculate_new_root (new_start_cylinder, this);
  484.  
  485.  
  486.  
  487.     hd.put_partition_table();
  488.  
  489.     hd.get_partition_table();
  490.  
  491.  
  492.  
  493.     printx ("\nNew partition table:\n\n");
  494.  
  495.     hd.print_partition_table ();
  496.  
  497.  
  498.  
  499.     hd.check (FINAL_CHECK);
  500.  
  501.  
  502.  
  503.     if (ask_if_continue () == false)
  504.  
  505.     {
  506.  
  507.         return (false);
  508.  
  509.     }
  510.  
  511.  
  512.  
  513.     calculate_new_boot ();
  514.  
  515.  
  516.  
  517.     put_bpb ();
  518.  
  519.     get_bpb ();
  520.  
  521.  
  522.  
  523.     printx ("\nNew boot sector:\n\n");
  524.  
  525.     print_bpb ();
  526.  
  527.  
  528.  
  529.     get_info ();
  530.  
  531.     if (global.debug_mode)
  532.  
  533.         write_info_debugfile ();
  534.  
  535.  
  536.  
  537.     check();
  538.  
  539.  
  540.  
  541.     if (!global.test_mode)
  542.  
  543.     {
  544.  
  545.         ask_for_write_permission ();
  546.  
  547.  
  548.  
  549.         if (hd.write_root_sector ())
  550.  
  551.             error ("Error writing root sector");
  552.  
  553.  
  554.  
  555.         if (write_boot_sector ())
  556.  
  557.             error ("Error writing boot sector");
  558.  
  559.  
  560.  
  561.         printx ("Repartitioning complete\n");
  562.  
  563.     }
  564.  
  565.  
  566.  
  567.     return (true);
  568.  
  569. }
  570.  
  571.