home *** CD-ROM | disk | FTP | other *** search
/ James Briskly's Game Magazine 2 / JBGM002S.ZIP / SOURCE / FIPSSPEC.CPP < prev    next >
C/C++ Source or Header  |  1995-08-22  |  8KB  |  286 lines

  1. /*
  2.     FIPS - the First nondestructive Interactive Partition Splitting program
  3.  
  4.     Module fipsspec.cpp
  5.  
  6.     RCS - Header:
  7.     $Header: c:/daten/fips/source/main/RCS/fipsspec.cpp 1.4 1995/01/19 00:00:53 schaefer Exp schaefer $
  8.  
  9.     Copyright (C) 1993 Arno Schaefer
  10.  
  11.     This program is free software; you can redistribute it and/or modify
  12.     it under the terms of the GNU General Public License as published by
  13.     the Free Software Foundation; either version 2 of the License, or
  14.     (at your option) any later version.
  15.  
  16.     This program is distributed in the hope that it will be useful,
  17.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.     GNU General Public License for more details.
  20.  
  21.     You should have received a copy of the GNU General Public License
  22.     along with this program; if not, write to the Free Software
  23.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  
  25.  
  26.     Report problems and direct all questions to:
  27.  
  28.     schaefer@rbg.informatik.th-darmstadt.de
  29. */
  30.  
  31. #include <dos.h>
  32.  
  33. #include "fipsspec.h"
  34. #include "global.h"
  35. #include "input.h"
  36.  
  37. #define FIRST_CHECK false
  38. #define FINAL_CHECK true
  39.  
  40. #define DISK_INT 0x13
  41.  
  42. #define RESET_DISK 0
  43. #define GET_DRIVE_PARAMS 8
  44.  
  45. void fips_bpb::print (void)
  46. {
  47.     printx ("Bytes per sector: %u\n",bytes_per_sector);
  48.     printx ("Sectors per cluster: %u\n",sectors_per_cluster);
  49.     printx ("Reserved sectors: %u\n",reserved_sectors);
  50.     printx ("Number of FATs: %u\n",no_of_fats);
  51.     printx ("Number of rootdirectory entries: %u\n",no_of_rootdir_entries);
  52.     printx ("Number of sectors (short): %u\n",no_of_sectors);
  53.     printx ("Media descriptor byte: %02Xh\n",media_descriptor);
  54.     printx ("Sectors per FAT: %u\n",sectors_per_fat);
  55.     printx ("Sectors per track: %u\n",sectors_per_track);
  56.     printx ("Drive heads: %u\n",drive_heads);
  57.     printx ("Hidden sectors: %lu\n",hidden_sectors);
  58.     printx ("Number of sectors (long): %lu\n",no_of_sectors_long);
  59.     printx ("Physical drive number: %02Xh\n",phys_drive_no);
  60.     printx ("Signature: %02Xh\n\n",signature);
  61. }
  62.  
  63. void fips_partition_table::print (void)
  64. {
  65.     printx ("     |        |     Start      |      |      End       | Start  |Number of|\n");
  66.     printx ("Part.|bootable|Head Cyl. Sector|System|Head Cyl. Sector| Sector |Sectors  |  MB\n");
  67.     printx ("-----+--------+----------------+------+----------------+--------+---------+----\n");
  68.     for (int i=0;i<4;i++)
  69.     {
  70.         printx ("%u    |    %s |%4u %4u   %4u|   %02Xh|%4u %4u   %4u|%8lu| %8lu|%4lu\n",i+1,
  71.         partition_info[i].bootable ? "yes" : " no",
  72.         partition_info[i].start_head,partition_info[i].start_cylinder,partition_info[i].start_sector,
  73.         partition_info[i].system,partition_info[i].end_head,partition_info[i].end_cylinder,partition_info[i].end_sector,
  74.         partition_info[i].start_sector_abs,partition_info[i].no_of_sectors_abs,partition_info[i].no_of_sectors_abs / 2048);
  75.     }
  76. }
  77.  
  78. void fips_harddrive::get_geometry (void)
  79. {
  80.     union REGS regs;
  81.  
  82.     regs.h.ah = GET_DRIVE_PARAMS;
  83.     regs.h.dl = number;
  84.     int86 (DISK_INT,®s,®s);
  85.     if (global.debug_mode)
  86.     {
  87.         fprintf (global.debugfile,"\nRegisters after call to int 13h 08h (drive %02Xh):\n\n",number);
  88.         fprintf (global.debugfile,"   00       sc/cl    hd\n");
  89.         fprintf (global.debugfile,"al ah bl bh cl ch dl dh   si    di    cflgs flags\n");
  90.         hexwrite ((byte *) ®s,16,global.debugfile);
  91.     }
  92.     if ((errorcode = regs.h.ah) != 0) return;
  93.     geometry.heads = (dword) regs.h.dh + 1;
  94.     geometry.sectors = (dword) regs.h.cl & 0x3f;
  95.     geometry.cylinders = ((dword) regs.h.ch | (((dword) regs.h.cl << 2) & 0x300)) + 1;
  96.  
  97.     if (global.debug_mode)
  98.     {
  99.         fprintf (global.debugfile, "\nGeometry reported by BIOS:\n");
  100.         fprintf
  101.         (
  102.             global.debugfile,
  103.             "%ld cylinders, %ld heads, %ld sectors\n",
  104.             geometry.cylinders,
  105.             geometry.heads,
  106.             geometry.sectors
  107.         );
  108.     }
  109. }
  110.  
  111. void fips_harddrive::reset (void)
  112. {
  113.     union REGS regs;
  114.  
  115.     regs.h.ah = RESET_DISK;
  116.     regs.h.dl = number;
  117.     int86 (DISK_INT,®s,®s);
  118.     if (global.debug_mode)
  119.     {
  120.         fprintf (global.debugfile,"\nRegisters after call to int 13h 00h (drive %02Xh):\n\n",number);
  121.         fprintf (global.debugfile,"al ah bl bh cl ch dl dh   si    di    cflgs flags\n");
  122.         hexwrite ((byte *) ®s,16,global.debugfile);
  123.     }
  124.     errorcode = regs.h.ah;
  125. }
  126.  
  127. void fips_logdrive_info::put_debug_info (void)
  128. {
  129.     fprintf (global.debugfile,"Calculated Partition Characteristica:\n\n");
  130.     fprintf (global.debugfile,"Start of FAT 1: %lu\n",start_fat1);
  131.     fprintf (global.debugfile,"Start of FAT 2: %lu\n",start_fat2);
  132.     fprintf (global.debugfile,"Start of Rootdirectory: %lu\n",start_rootdir);
  133.     fprintf (global.debugfile,"Start of Data: %lu\n",start_data);
  134.     fprintf (global.debugfile,"Number of Clusters: %lu\n",no_of_clusters);
  135. }
  136.  
  137. dword fips_partition::min_cylinder (fat16 fat, drive_geometry geometry)
  138. {
  139.     dword new_part_min_sector =
  140.         info().start_data
  141.         + (dword) 4085
  142.         * bpb().sectors_per_cluster;
  143.  
  144.     dword new_part_min_cylinder =
  145.         (
  146.             new_part_min_sector
  147.             + partition_info->start_sector_abs
  148.             - 1
  149.         )
  150.         / (geometry.heads * geometry.sectors)
  151.         + 1;
  152.  
  153.     if (new_part_min_cylinder > partition_info->end_cylinder)
  154.         error ("Partition too small - can't split");
  155.  
  156.     dword min_free_cluster = fat.min_free_cluster ();
  157.     dword min_free_sector =
  158.         info().start_data
  159.         + (min_free_cluster - 2)
  160.         * (dword) bpb().sectors_per_cluster;
  161.  
  162.     dword min_free_cylinder =
  163.         (
  164.             min_free_sector
  165.             + partition_info->start_sector_abs
  166.             - 1
  167.         )
  168.         / (geometry.heads * geometry.sectors)
  169.         + 1;
  170.  
  171.     if (min_free_cylinder > partition_info->end_cylinder)
  172.         error ("Last cylinder is not free");
  173.  
  174.     if (new_part_min_cylinder < min_free_cylinder)
  175.         new_part_min_cylinder = min_free_cylinder;
  176.  
  177.     return (new_part_min_cylinder);
  178. }
  179.  
  180.  
  181. boolean fips_partition::split (fips_harddrive hd)
  182. {
  183.     if (read_boot_sector ())
  184.         error ("Error reading boot sector");
  185.  
  186.     if (global.debug_mode)
  187.     {
  188.         fprintf
  189.         (
  190.             global.debugfile,
  191.             "\nBoot sector drive %02Xh, partition %u:\n\n",
  192.             hd.number,
  193.             number + 1
  194.         );
  195.  
  196.         hexwrite
  197.         (
  198.             boot_sector->data,
  199.             512,
  200.             global.debugfile
  201.         );
  202.     }
  203.  
  204.     get_bpb ();
  205.  
  206.     printx ("\nBoot sector:\n\n");
  207.     print_bpb ();
  208.  
  209.     get_info ();
  210.     if (global.debug_mode)
  211.         write_info_debugfile ();
  212.  
  213.     check ();
  214.  
  215.     fat16 fat1 (this,1);
  216.     fat16 fat2 (this,2);
  217.  
  218.     fat1.check_against (&fat2);
  219.  
  220.     dword new_part_min_cylinder =
  221.         min_cylinder (fat2, hd.geometry);
  222.  
  223.     if (ask_if_save()) save_root_and_boot(&hd,this);
  224.  
  225.     dword new_start_cylinder =
  226.         ask_for_new_start_cylinder
  227.         (
  228.             partition_info->start_cylinder,
  229.             new_part_min_cylinder,
  230.             partition_info->end_cylinder,
  231.             hd.geometry.heads * hd.geometry.sectors
  232.         );
  233.  
  234.     fat2.check_empty
  235.     (
  236.         new_start_cylinder
  237.             * hd.geometry.heads
  238.             * hd.geometry.sectors
  239.         - partition_info->start_sector_abs
  240.     );
  241.  
  242.     hd.calculate_new_root (new_start_cylinder, this);
  243.  
  244.     hd.put_partition_table();
  245.     hd.get_partition_table();
  246.  
  247.     printx ("\nNew partition table:\n\n");
  248.     hd.print_partition_table ();
  249.  
  250.     hd.check (FINAL_CHECK);
  251.  
  252.     if (ask_if_continue () == false)
  253.     {
  254.         return (false);
  255.     }
  256.  
  257.     calculate_new_boot ();
  258.  
  259.     put_bpb ();
  260.     get_bpb ();
  261.  
  262.     printx ("\nNew boot sector:\n\n");
  263.     print_bpb ();
  264.  
  265.     get_info ();
  266.     if (global.debug_mode)
  267.         write_info_debugfile ();
  268.  
  269.     check();
  270.  
  271.     if (!global.test_mode)
  272.     {
  273.         ask_for_write_permission ();
  274.  
  275.         if (hd.write_root_sector ())
  276.             error ("Error writing root sector");
  277.  
  278.         if (write_boot_sector ())
  279.             error ("Error writing boot sector");
  280.  
  281.         printx ("Repartitioning complete\n");
  282.     }
  283.  
  284.     return (true);
  285. }
  286.