home *** CD-ROM | disk | FTP | other *** search
/ PC World 1999 August / PCWorld_1999-08_cd.bin / dosutils / fips20 / source / fat.cpp < prev    next >
C/C++ Source or Header  |  1997-12-20  |  7KB  |  262 lines

  1. /*
  2.     FIPS - the First nondestructive Interactive Partition Splitting program
  3.  
  4.     Module fat.cpp
  5.  
  6.     RCS - Header:
  7.     $Header: c:/daten/fips/source/main/RCS/fat.cpp 1.4 1995/01/19 00:00:51 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 <stdlib.h>
  32.  
  33. #include "logdr_st.h"
  34. #include "global.h"
  35. #include "fat.h"
  36. #include "input.h"
  37.  
  38.  
  39. fat::fat (class logical_drive *logical_drive,int number)
  40. {
  41.     fat::logical_drive = logical_drive;
  42.     fat::number = number;
  43.     buffer = new sector;
  44.     start_sector = (number == 1) ? logical_drive->info().start_fat1 : logical_drive->info().start_fat2;
  45.     sector_in_buffer = -1;
  46. }
  47.  
  48.  
  49. dword fat16::next_cluster (dword cluster_number)
  50. {
  51.     dword sector = cluster_number / 256;
  52.     int offset = (cluster_number % 256) * 2;
  53.  
  54.     if (sector != sector_in_buffer)
  55.     {
  56.         read_sector (sector);
  57.     }
  58.  
  59.     return ((dword) buffer->data[offset] | ((dword) buffer->data[offset + 1] << 8));
  60. }
  61.  
  62. void fat::read_sector (dword sector)
  63. {
  64.     if (logical_drive->read_sector (sector + start_sector,buffer))
  65.         if (number == 1)
  66.             error ("Error reading FAT 1");
  67.         else
  68.             error ("Error reading FAT 2");
  69.  
  70.     sector_in_buffer = sector;
  71. }
  72.  
  73.  
  74. void fat16::check_against (class fat16 *fat2)
  75. {
  76.     printx ("Checking FAT ... ");
  77.  
  78.     for (int i=0;i<logical_drive->bpb().sectors_per_fat;i++)
  79.     {
  80.         read_sector (i);
  81.         fat2->read_sector (i);
  82.  
  83.         for (int j=0;j<512;j++) if (buffer->data[j] != fat2->buffer->data[j])
  84.             error ("FAT copies differ: FAT 1 -> %02Xh, FAT 2 -> %02Xh in sector %u, byte %u",buffer->data[j],fat2->buffer->data[j],i,j);
  85.  
  86.         if (i == 0)
  87.         {
  88.             if (buffer->data[0] != 0xf8)
  89.             {
  90.                 warning (false, "Wrong media descriptor byte in FAT: %02Xh",buffer->data[0]);
  91.  
  92.                 printx ("Continue (y/n)? ");
  93.                 if (ask_yes_no () == 'n') exit (-1);
  94.             }
  95.  
  96.             if ((buffer->data[1] != 0xff) || (buffer->data[2] != 0xff) || (buffer->data[3] != 0xff))
  97.                 warning (true, "Wrong FAT entries 1 & 2: %02X %02X %02X %02X",buffer->data[0],buffer->data[1],buffer->data[2],buffer->data[3]);
  98.         }
  99.     }
  100.     printx ("OK\n");
  101. }
  102.  
  103.  
  104. void fat16::check_empty (dword new_start_sector)
  105. {
  106.     dword first_cluster = (new_start_sector - logical_drive->info().start_data) / logical_drive->bpb().sectors_per_cluster + 2;
  107.  
  108.     dword last_cluster = logical_drive->info().no_of_clusters + 1;
  109.  
  110.     if (last_cluster > ((dword) 256 * logical_drive->bpb().sectors_per_fat - 1)) last_cluster = (dword) 256 * logical_drive->bpb().sectors_per_fat - 1;
  111.  
  112.     printx ("First Cluster: %lu\nLast Cluster: %lu\n\n",first_cluster,last_cluster);
  113.     printx ("Testing if empty ... ");
  114.  
  115.     for (dword i=first_cluster;i <= last_cluster;i++)
  116.     {
  117.         dword fat_entry = next_cluster (i);
  118.  
  119.         if (fat_entry != 0) if (fat_entry != 0xfff7)
  120.         {
  121.             if (fat_entry == 0xffff)
  122.             {
  123.                 error ("New partition not empty: cluster %lu ( FAT entry: <EOF> )",i);
  124.             }
  125.             else
  126.             {
  127.                 error ("New partition not empty: cluster %lu ( FAT entry: %lu )",i,fat_entry);
  128.             }
  129.         }
  130.     }
  131.  
  132.     printx ("OK\n");
  133. }
  134.  
  135.  
  136. dword fat16::min_free_cluster (void)
  137. {
  138.     dword first_cluster = 2;
  139.  
  140.     dword last_cluster = logical_drive->info().no_of_clusters + 1;
  141.  
  142.     if (last_cluster > ((dword) 256 * logical_drive->bpb().sectors_per_fat - 1)) last_cluster = (dword) 256 * logical_drive->bpb().sectors_per_fat - 1;
  143.  
  144.     printx ("Searching for free space ... ");
  145.  
  146.     dword i;
  147.  
  148.     for (i=last_cluster;i >= first_cluster;i--)
  149.     {
  150.         dword fat_entry = next_cluster (i);
  151.  
  152.         if (fat_entry != 0) if (fat_entry != 0xfff7)
  153.         {
  154.             i++;
  155.             break;
  156.         }
  157.     }
  158.     printx ("OK\n\n");
  159.     return (i);
  160. }
  161.  
  162.  
  163. dword fat32::next_cluster (dword cluster_number)
  164. {
  165.     dword sector = cluster_number / 128;
  166.     int offset = (cluster_number % 128) * 4;
  167.  
  168.     if (sector != sector_in_buffer)
  169.     {
  170.         read_sector (sector);
  171.     }
  172.  
  173.     return ((dword) buffer->data[offset]) | ((dword) buffer->data[offset + 1] << 8) |
  174.          ((dword) buffer->data[offset + 2] << 16) | ((dword) buffer->data[offset + 3] << 24);
  175. }
  176.  
  177. void fat32::check_against (class fat32 *fat2)
  178. {
  179.     printx ("Checking FAT ... ");
  180.  
  181.     for (int i=0;i<logical_drive->bpb().sectors_per_fat;i++)
  182.     {
  183.         read_sector (i);
  184.         fat2->read_sector (i);
  185.  
  186.         for (int j=0;j<512;j++) if (buffer->data[j] != fat2->buffer->data[j])
  187.             error ("FAT copies differ: FAT 1 -> %02Xh, FAT 2 -> %02Xh in sector %u, byte %u",buffer->data[j],fat2->buffer->data[j],i,j);
  188.  
  189.         if (i == 0)
  190.         {
  191.             if (buffer->data[0] != 0xf8)
  192.             {
  193.                 warning (false, "Wrong media descriptor byte in FAT: %02Xh",buffer->data[0]);
  194.  
  195.                 printx ("Continue (y/n)? ");
  196.                 if (ask_yes_no () == 'n') exit (-1);
  197.             }
  198.         }
  199.     }
  200.     printx ("OK\n");
  201. }
  202.  
  203.  
  204. void fat32::check_empty (dword new_start_sector)
  205. {
  206.     dword first_cluster = (new_start_sector - logical_drive->info().start_data) / logical_drive->bpb().sectors_per_cluster + 2;
  207.  
  208.     dword last_cluster = logical_drive->info().no_of_clusters + 1;
  209.  
  210.     if (last_cluster > ((dword) 128 * logical_drive->bpb().sectors_per_fat - 1)) last_cluster = (dword) 128 * logical_drive->bpb().sectors_per_fat - 1;
  211.  
  212.     printx ("First Cluster: %lu\nLast Cluster: %lu\n\n",first_cluster,last_cluster);
  213.     printx ("Testing if empty ... ");
  214.  
  215.     for (dword i=first_cluster;i <= last_cluster;i++)
  216.     {
  217.         dword fat_entry = next_cluster (i);
  218.  
  219.         if (fat_entry != 0) if (fat_entry != 0xffffff7L)
  220.         {
  221.             if (fat_entry == 0xfffffffL || fat_entry == 0xffffffffL)
  222.             {
  223.                 error ("New partition not empty: cluster %lu ( FAT entry: <EOF> )",i);
  224.             }
  225.             else
  226.             {
  227.                 error ("New partition not empty: cluster %lu ( FAT entry: %lu )",i,fat_entry);
  228.             }
  229.         }
  230.     }
  231.  
  232.     printx ("OK\n");
  233. }
  234.  
  235.  
  236. dword fat32::min_free_cluster (void)
  237. {
  238.     dword first_cluster = 2;
  239.  
  240.     dword last_cluster = logical_drive->info().no_of_clusters + 1;
  241.  
  242.     if (last_cluster > ((dword) 128 * logical_drive->bpb().sectors_per_fat - 1)) last_cluster = (dword) 128 * logical_drive->bpb().sectors_per_fat - 1;
  243.  
  244.     printx ("Searching for free space ... ");
  245.  
  246.     dword i;
  247.  
  248.     for (i=last_cluster;i >= first_cluster;i--)
  249.     {
  250.         dword fat_entry = next_cluster (i);
  251.  
  252.         if (fat_entry != 0) if (fat_entry != 0xffffff7L)
  253.         {
  254.             i++;
  255.             break;
  256.         }
  257.     }
  258.     printx ("OK\n\n");
  259.     return (i);
  260. }
  261.  
  262.