CHECK.CPP
上传用户:datang2001
上传日期:2007-02-01
资源大小:53269k
文件大小:11k
源码类别:

操作系统开发

开发平台:

C/C++

  1. /*
  2. FIPS - the First nondestructive Interactive Partition Splitting program
  3. Module check.cpp
  4. RCS - Header:
  5. $Header: c:/daten/fips/source/main/RCS/check.cpp 1.4 1995/01/19 00:20:41 schaefer Exp schaefer $
  6. Copyright (C) 1993 Arno Schaefer
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. Report problems and direct all questions to:
  19. schaefer@rbg.informatik.th-darmstadt.de
  20. */
  21. #include <stdlib.h>
  22. #include "hdstruct.h"
  23. #include "global.h"
  24. #include "fipsspec.h"
  25. #include "input.h"
  26. /* ----------------------------------------------------------------------- */
  27. /* Consistency check of root sector / partition table                      */
  28. /* ----------------------------------------------------------------------- */
  29. void fips_partition_table::correct_physical (const drive_geometry &geometry)
  30. {
  31. for (int i = 0; i < 4; i++)
  32. {
  33. if (partition_info[i].system)
  34. {
  35. physical_sector_no start
  36. (
  37. partition_info[i].start_sector_abs,
  38. geometry
  39. );
  40. partition_info[i].start_cylinder = start.cylinder;
  41. partition_info[i].start_head = start.head;
  42. partition_info[i].start_sector = start.sector;
  43. // recalculate 'physical' start sector
  44. physical_sector_no end
  45. (
  46. partition_info[i].start_sector_abs
  47. + partition_info[i].no_of_sectors_abs
  48. - 1,
  49. geometry
  50. );
  51. partition_info[i].end_cylinder = end.cylinder;
  52. partition_info[i].end_head = end.head;
  53. partition_info[i].end_sector = end.sector;
  54. // recalculate 'physical' end sector
  55. }
  56. }
  57. }
  58. void fips_harddrive::check (boolean final_check)
  59. {
  60. int i,j,k;
  61. boolean bootable = false;
  62. boolean do_correct = false;
  63. byte *root_sector = harddrive::root_sector->data;
  64. partition_info *parts = partition_table().partition_info;
  65. int order[4] = {-1,-1,-1,-1};
  66. printx ("nChecking root sector ... ");
  67. if ((root_sector[510] != 0x55) || (root_sector[511] != 0xaa))
  68. error ("Invalid root sector signature: %02X %02X", root_sector[510], root_sector[511]);
  69. for (i = 0; i < 4; i++)
  70. {
  71. if (parts[i].bootable == 0x80)
  72. {
  73. if (bootable)
  74. {
  75. warning (false, "More than one active partition");
  76. printx ("Continue (y/n)? ");
  77. if (ask_yes_no () == 'n') exit (-1);
  78. }
  79. else bootable = true;
  80. }
  81. else if (parts[i].bootable != 0)
  82. {
  83. warning (false, "Invalid active flag: partition %u: %02Xh",i+1,parts[i].bootable);
  84. // must be 0 or 80h
  85. printx ("Do you want to set the flag to zero (y/n)? ");
  86. if (ask_yes_no () == 'y') parts[i].bootable = 0;
  87. }
  88. if (parts[i].system)
  89. {
  90. if ((parts[i].start_sector == 0) || (parts[i].start_sector > geometry.sectors))
  91. {
  92. if (final_check)
  93. error ("Calculation error: Invalid start sector partition %u: %u", i + 1, parts[i].start_sector);
  94. infomsg ("Partition table inconsistency");
  95. do_correct = true;
  96. }
  97. if ((parts[i].end_sector == 0) || (parts[i].end_sector > geometry.sectors))
  98. {
  99. if (final_check)
  100. error ("Calculation error: Invalid end sector partition %u: %u", i + 1, parts[i].end_sector);
  101. if (!do_correct)
  102. {
  103. infomsg ("Partition table inconsistency");
  104. do_correct = true;
  105. }
  106. }
  107. if
  108. (
  109. (parts[i].start_head > (geometry.heads - 1)) ||
  110. (parts[i].end_head > (geometry.heads - 1)) ||
  111. (parts[i].start_sector_abs !=
  112. (parts[i].start_cylinder * geometry.heads * geometry.sectors +
  113. parts[i].start_head * geometry.sectors + parts[i].start_sector - 1)) ||
  114. // physical start sector does not match logical start sector
  115. ((parts[i].start_sector_abs + parts[i].no_of_sectors_abs - 1) !=
  116. (parts[i].end_cylinder * geometry.heads * geometry.sectors +
  117. parts[i].end_head * geometry.sectors + parts[i].end_sector - 1))
  118. // physical end sector does not match logical end sector
  119. )
  120. {
  121. if (final_check)
  122. error ("Calculation error: Inconsistent table entry for partition %u", i + 1);
  123. if (!do_correct)
  124. {
  125. infomsg ("Partition table inconsistency");
  126. do_correct = true;
  127. }
  128. }
  129. for (j = 0; j < 4; j++)       // insert partition in ordered table
  130. {
  131. if (order[j] == -1)
  132. {
  133. order[j] = i;
  134. break;
  135. }
  136. else if (parts[i].start_sector_abs < parts[order[j]].start_sector_abs)
  137. {
  138. for (k=3;k>j;k--) order[k] = order[k-1];
  139. order[j] = i;
  140. break;
  141. }
  142. }
  143. }
  144. else            // system = 0
  145. {
  146. for (j = 0; j < 16; j++)
  147. {
  148. if (root_sector[0x1be + 16 * i + j] != 0)
  149. {
  150. warning (false, "Invalid partition entry: partition %u", i+1);
  151. printx ("Do you want to delete this entry (y/n)? ");
  152. if (ask_yes_no () == 'y')
  153. {
  154. parts[i].bootable = 0;
  155. parts[i].start_head = 0;
  156. parts[i].start_cylinder = 0;
  157. parts[i].start_sector = 0;
  158. parts[i].end_head = 0;
  159. parts[i].end_cylinder = 0;
  160. parts[i].end_sector = 0;
  161. parts[i].start_sector_abs = 0;
  162. parts[i].no_of_sectors_abs = 0;
  163. }
  164. break;
  165. }
  166. }
  167. }
  168. }
  169. if (do_correct)
  170. {
  171. pr_partition_table.correct_physical (geometry);
  172. printx ("nPartition table adapted to the current drive geometry:nn");
  173. pr_partition_table.print();
  174. }
  175. if (!bootable && number == 0x80) warning (true, "No active partition");
  176. for (i = 0; i < 4; i++)
  177. {
  178. if ((k = order[i]) != -1)         // valid partition
  179. {
  180. if ((parts[k].end_sector != geometry.sectors) || (parts[k].end_head != (geometry.heads - 1)))
  181. warning (true, "Partition does not end on cylinder boundary: partition %u", k + 1);
  182. if (i != 0) if ((parts[k].start_sector != 1) || (parts[k].start_head != 0))
  183. warning (true, "Partition does not begin on cylinder boundary: partition %u", k + 1);
  184. if (i < 3) if ((j = order[i + 1]) != -1)       // following valid partition
  185. {
  186. if ((parts[k].start_sector_abs + parts[k].no_of_sectors_abs) > parts[j].start_sector_abs)
  187. error ("Overlapping partitions: %u and %u", k + 1, j + 1);
  188. if ((parts[k].start_sector_abs + parts[k].no_of_sectors_abs) < parts[j].start_sector_abs)
  189. warning (true, "Free space between partitions: %u and %u", k + 1, j + 1);
  190. }
  191. }
  192. }
  193. printx ("OKn");
  194. }
  195. void fips_partition::check (void)
  196. {
  197. printx ("Checking boot sector ... ");
  198. byte *boot_sector = partition::boot_sector->data;
  199. if (boot_sector[0] == 0xeb)
  200. {
  201. if (boot_sector[2] != 0x90)
  202. error ("Invalid jump instruction in boot sector: %02X %02X %02X", boot_sector[0], boot_sector[1], boot_sector[2]);
  203. }
  204. else if (boot_sector[0] != 0xe9)
  205. error ("Invalid jump instruction in boot sector: %02X %02X %02X", boot_sector[0], boot_sector[1], boot_sector[2]);
  206. if ((boot_sector[510] != 0x55) || (boot_sector[511] != 0xaa))
  207. error ("Invalid boot sector: %02X %02X", boot_sector[510], boot_sector[511]);
  208. if (bpb().bytes_per_sector != 512)
  209. error ("Can't handle number of bytes per sector: %u",bpb().bytes_per_sector);
  210. switch (bpb().sectors_per_cluster)
  211. {
  212. case 1:case 2:case 4:case 8:case 16:case 32:case 64:case 128: break;
  213. default:
  214. error ("Number of sectors per cluster must be a power of 2: actually it is %u",bpb().sectors_per_cluster);
  215. }
  216. if (bpb().reserved_sectors != 1)
  217. {
  218. warning (false, "Number of reserved sectors should be 1: actually it is %u",bpb().reserved_sectors);
  219. if (ask_correction () == 'y') bpb().reserved_sectors = 1;
  220. }
  221. if (bpb().no_of_fats != 2)
  222. error ("Partition must have 2 FATs: actually it has %u",bpb().no_of_fats);
  223. if (bpb().no_of_rootdir_entries % 16)
  224. {
  225. warning (false, "Number of root directory entries must be multiple of 16: actually it is %u",bpb().no_of_rootdir_entries);
  226. printx ("Do you want to set the number to the next multiple of 16 (y/n)? ");
  227. if (ask_yes_no () == 'y')
  228. bpb().no_of_rootdir_entries += (16 - bpb().no_of_rootdir_entries % 16);
  229. }
  230. if (bpb().no_of_rootdir_entries == 0)
  231. error ("Number of root directory entries must not be zero");
  232. if (bpb().media_descriptor != 0xf8)
  233. {
  234. warning (false, "Wrong media descriptor byte in boot sector: %02X",bpb().media_descriptor);
  235. if (ask_correction () == 'y') bpb().media_descriptor = 0xf8;
  236. }
  237. if (bpb().sectors_per_fat > 256)
  238. {
  239. warning (false, "FAT too large: %u sectors",bpb().sectors_per_fat);
  240. printx ("Continue (y/n)? ");
  241. if (ask_yes_no () == 'n') exit (-1);
  242. }
  243. if (bpb().sectors_per_fat < (info().no_of_clusters + 1) / 256 + 1)
  244. {
  245. warning (false, "FAT too small: %u sectors (should be %u)",bpb().sectors_per_fat, (unsigned int) ((info().no_of_clusters + 1) / 256 + 1));
  246. printx ("Continue (y/n)? ");
  247. if (ask_yes_no () == 'n') exit (-1);
  248. }
  249. if (bpb().sectors_per_track != drive->geometry.sectors)
  250. {
  251. warning (false, "Sectors per track incorrect: %u instead of %u",bpb().sectors_per_track,(int) drive->geometry.sectors);
  252. if (ask_correction () == 'y') bpb().sectors_per_track = drive->geometry.sectors;
  253. }
  254. if (bpb().drive_heads != drive->geometry.heads)
  255. {
  256. warning (false, "Number of drive heads incorrect: %u instead of %u",bpb().drive_heads,(int) drive->geometry.heads);
  257. if (ask_correction () == 'y') bpb().drive_heads = drive->geometry.heads;
  258. }
  259. if (bpb().hidden_sectors != partition_info->start_sector_abs)
  260. error ("Number of hidden sectors incorrect: %lu instead of %lu",bpb().hidden_sectors,partition_info->start_sector_abs);
  261. if (info().no_of_clusters <= 4084)
  262. error ("12-bit FAT not supported: number of clusters is %u",(int) info().no_of_clusters);
  263. if (bpb().no_of_sectors)
  264. {
  265. if (partition_info->no_of_sectors_abs > 0xffff)
  266. error ("Number of sectors (short) must be zero");
  267. if (bpb().no_of_sectors != partition_info->no_of_sectors_abs)
  268. error ("Number of sectors (short) does not match partition info:n%u instead of %lu",bpb().no_of_sectors,partition_info->no_of_sectors_abs);
  269. if (partition_info->system != 4)
  270. {
  271. warning (true, "Wrong system indicator byte: %u instead of 4",partition_info->system);
  272. if (ask_correction () == 'y') partition_info->system = 4;
  273. }
  274. }
  275. else
  276. {
  277. if (bpb().no_of_sectors_long != partition_info->no_of_sectors_abs)
  278. error ("Number of sectors (long) does not match partition info:n%lu instead of %lu",bpb().no_of_sectors_long,partition_info->no_of_sectors_abs);
  279. if (bpb().signature != 0x29)
  280. {
  281. warning (false, "Wrong signature: %02Xh",bpb().signature);
  282. if (ask_correction () == 'y') bpb().signature = 0x29;
  283. }
  284. if (partition_info->system != 6)
  285. {
  286. warning (true, "Wrong system indicator byte: %u instead of 6",partition_info->system);
  287. if (ask_correction () == 'y') partition_info->system = 6;
  288. }
  289. }
  290. printx ("OKn");
  291. }