Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

414 lines
11 KiB

  1. #include <mytypes.h>
  2. #include <partio.h>
  3. #include <diskio.h>
  4. #include <misclib.h>
  5. #include <partimag.h>
  6. #include <msgfile.h>
  7. #include <stdio.h>
  8. #include <malloc.h>
  9. #include <memory.h>
  10. #include <dos.h>
  11. #include <stdlib.h>
  12. char *textDiskCount;
  13. char *textDiskN;
  14. char *textInt13Unit;
  15. char *textSectorsPerTrack;
  16. char *textHeads;
  17. char *textCylinders;
  18. char *textExtInt13;
  19. char *textNoExtInt13;
  20. char *textPartitionsOnDisk;
  21. char *textSystemId;
  22. char *textStartSector;
  23. char *textSectorCount;
  24. char *textNoPartitionsOnDisk;
  25. char *textCantAllocBuffer;
  26. char *textIsNotMasterDisk;
  27. char *textIsMasterDisk;
  28. char *textCantAccessDisk;
  29. char *textPartImageCount;
  30. char *textImageN;
  31. char *textImageCorrupt;
  32. char *textImageName;
  33. char *textOriginalTotalSectors;
  34. char *textMBParens;
  35. char *textDone;
  36. char *textUsage;
  37. char *textChecksum;
  38. char *textChecksumFail;
  39. char *textBytesProcessed;
  40. char *textValidateFile;
  41. char *textChecksumOk;
  42. char *textRelocBitmap;
  43. char *textRelocBoot;
  44. MESSAGE_STRING TextMessages[] = { { &textDiskCount, 1 },
  45. { &textDiskN, 2 },
  46. { &textInt13Unit, 3 },
  47. { &textSectorsPerTrack, 4 },
  48. { &textHeads, 5 },
  49. { &textCylinders, 6 },
  50. { &textExtInt13, 7 },
  51. { &textNoExtInt13, 8 },
  52. { &textPartitionsOnDisk, 9 },
  53. { &textSystemId, 10 },
  54. { &textStartSector, 11 },
  55. { &textSectorCount, 12 },
  56. { &textNoPartitionsOnDisk, 13 },
  57. { &textCantAllocBuffer, 14 },
  58. { &textIsNotMasterDisk, 15 },
  59. { &textIsMasterDisk, 16 },
  60. { &textCantAccessDisk, 17 },
  61. { &textPartImageCount, 18 },
  62. { &textImageN, 19 },
  63. { &textImageCorrupt, 20 },
  64. { &textImageName, 21 },
  65. { &textOriginalTotalSectors,22 },
  66. { &textMBParens, 24 },
  67. { &textDone, 25 },
  68. { &textUsage, 26 },
  69. { &textChecksum, 27 },
  70. { &textChecksumFail, 28 },
  71. { &textBytesProcessed, 29 },
  72. { &textValidateFile, 30 },
  73. { &textChecksumOk, 31 },
  74. { &textRelocBitmap, 32 },
  75. { &textRelocBoot, 33 }
  76. };
  77. UINT PartCount;
  78. BYTE SaveBuffer[512];
  79. CMD_LINE_ARGS CmdLineArgs;
  80. VOID
  81. DumpDisk(
  82. IN UINT DiskId
  83. );
  84. VOID
  85. DumpPartitionsOnDisk(
  86. IN UINT DiskId
  87. );
  88. VOID
  89. DumpMasterDiskInfo(
  90. IN UINT DiskId
  91. );
  92. BOOL
  93. TestImage(
  94. IN HDISK DiskHandle,
  95. IN ULONG StartSector
  96. );
  97. int
  98. main(
  99. IN int argc,
  100. IN char *argv[]
  101. )
  102. {
  103. UINT DiskCount,i;
  104. if(!GetTextForProgram(argv[0],TextMessages,sizeof(TextMessages)/sizeof(TextMessages[0]))) {
  105. fprintf(stderr,"Unable to find messages for program\n");
  106. return(FAILURE);
  107. }
  108. if(!ParseArgs(argc,argv,TRUE,"XT",&CmdLineArgs)) {
  109. fprintf(stderr,textUsage);
  110. fprintf(stderr,"\n");
  111. return(FAILURE);
  112. }
  113. PartCount = InitializePartitionList();
  114. DiskCount = InitializeDiskList();
  115. printf(textDiskCount,DiskCount);
  116. printf("\n");
  117. for(i=0; i<DiskCount; i++) {
  118. DumpDisk(i);
  119. }
  120. return(SUCCESS);
  121. }
  122. VOID
  123. DumpDisk(
  124. IN UINT DiskId
  125. )
  126. {
  127. BYTE Int13Unit;
  128. BYTE SectorsPerTrack;
  129. USHORT Heads;
  130. USHORT Cylinders;
  131. ULONG ExtendedSectorCount;
  132. printf("\n");
  133. printf(textDiskN,DiskId);
  134. printf("\n\n");
  135. GetDiskInfoById(
  136. DiskId,
  137. 0,
  138. &Int13Unit,
  139. &SectorsPerTrack,
  140. &Heads,
  141. &Cylinders,
  142. &ExtendedSectorCount
  143. );
  144. printf(" %s ",textInt13Unit);
  145. printf("%x\n",Int13Unit);
  146. printf(" %s ",textSectorsPerTrack);
  147. printf("%u\n",SectorsPerTrack);
  148. printf(" %s ",textHeads);
  149. printf("%u\n",Heads);
  150. printf(" %s ",textCylinders);
  151. printf("%u\n",Cylinders);
  152. if(ExtendedSectorCount) {
  153. printf(" %s ",textExtInt13);
  154. printf("0x%lx\n",ExtendedSectorCount);
  155. } else {
  156. printf(" %s\n",textNoExtInt13);
  157. }
  158. DumpPartitionsOnDisk(DiskId);
  159. DumpMasterDiskInfo(DiskId);
  160. printf("\n%s\n",textDone);
  161. }
  162. VOID
  163. DumpPartitionsOnDisk(
  164. IN UINT DiskId
  165. )
  166. {
  167. UINT i;
  168. UINT id;
  169. BYTE SysId;
  170. ULONG StartSector;
  171. ULONG SectorCount;
  172. unsigned count;
  173. count = 0;
  174. printf("\n");
  175. for(i=0; i<PartCount; i++) {
  176. GetPartitionInfoById(
  177. i,
  178. 0,
  179. &id,
  180. &SysId,
  181. &StartSector,
  182. &SectorCount
  183. );
  184. if(id == DiskId) {
  185. if(!count++) {
  186. printf(" %s\n",textPartitionsOnDisk);
  187. }
  188. printf("\n %s ",textSystemId);
  189. printf("%u\n",SysId);
  190. printf(" %s ",textStartSector);
  191. printf("0x%lx\n",StartSector);
  192. printf(" %s ",textSectorCount);
  193. printf("0x%lx ",SectorCount);
  194. printf(textMBParens,SectorCount/2048);
  195. printf("\n");
  196. }
  197. }
  198. if(!count) {
  199. printf(" %s\n",textNoPartitionsOnDisk);
  200. }
  201. }
  202. VOID
  203. DumpMasterDiskInfo(
  204. IN UINT DiskId
  205. )
  206. {
  207. FPVOID Buffer,OriginalBuffer;
  208. HDISK hDisk;
  209. FPMASTER_DISK MasterDisk;
  210. FPPARTITION_IMAGE Image;
  211. UINT i;
  212. printf("\n");
  213. if(!AllocTrackBuffer(1,&Buffer,&OriginalBuffer)) {
  214. printf(" %s\n",textCantAllocBuffer);
  215. return;
  216. }
  217. if(IsMasterDisk(DiskId,Buffer)) {
  218. printf(" %s ",textIsMasterDisk);
  219. if(hDisk = OpenDisk(DiskId)) {
  220. if(ReadDisk(hDisk,1,1,Buffer)) {
  221. memcpy(SaveBuffer,Buffer,512);
  222. MasterDisk = (FPMASTER_DISK)SaveBuffer;
  223. printf("\n (%u %s)\n", MasterDisk->ImageCount, textPartImageCount);
  224. Image = Buffer;
  225. for(i=0; i<MasterDisk->ImageCount; i++) {
  226. printf("\n ");
  227. printf(textImageN,i+1);
  228. printf("\n\n");
  229. if(ReadDisk(hDisk,MasterDisk->ImageStartSector[i],1,Buffer)) {
  230. if((Image->Signature == PARTITION_IMAGE_SIGNATURE)
  231. && (Image->Size == sizeof(PARTITION_IMAGE))) {
  232. printf(" %s %u\n",textSystemId,Image->SystemId);
  233. printf(" %s 0x%lx ",textOriginalTotalSectors,Image->TotalSectorCount);
  234. printf(textMBParens,Image->TotalSectorCount/2048);
  235. printf("\n");
  236. if( Image->Flags & PARTIMAGE_RELOCATE_BITMAP ) {
  237. printf(" %s 0x%lx\n",textRelocBitmap,Image->BitmapRelocationStart);
  238. }
  239. if( Image->Flags & PARTIMAGE_RELOCATE_BOOT ) {
  240. printf(" %s 0x%lx\n",textRelocBoot,Image->BootRelocationStart);
  241. }
  242. printf("\n");
  243. if(CmdLineArgs.Test) {
  244. TestImage(hDisk,MasterDisk->ImageStartSector[i]);
  245. }
  246. } else {
  247. printf(" %s\n",textImageCorrupt);
  248. }
  249. } else {
  250. printf(" %s\n",textCantAccessDisk);
  251. }
  252. }
  253. } else {
  254. printf("\n %s\n",textCantAccessDisk);
  255. }
  256. } else {
  257. printf("\n %s\n",textCantAccessDisk);
  258. }
  259. } else {
  260. printf(" %s\n",textIsNotMasterDisk);
  261. }
  262. free(OriginalBuffer);
  263. }
  264. BOOL
  265. TestImage(
  266. IN HDISK DiskHandle,
  267. IN ULONG StartSector
  268. )
  269. {
  270. FPVOID Buffer,OriginalBuffer;
  271. ULONG CurrentSector;
  272. ULONG ImageCRC;
  273. ULONG CalcCRC;
  274. ULONG BytesCRC;
  275. ULONG SectorsRemaining;
  276. ULONG TotalSectors;
  277. ULONG BitmapSize;
  278. BYTE Count;
  279. // need to allocate aligned buffer
  280. if(!AllocTrackBuffer(63,&Buffer,&OriginalBuffer)) {
  281. printf(" %s\n",textCantAllocBuffer);
  282. return FALSE;
  283. }
  284. CalcCRC = CRC32_INITIAL_VALUE;
  285. BytesCRC = 0;
  286. // read inital sector to get info
  287. CurrentSector = StartSector;
  288. if( ReadDisk( DiskHandle, CurrentSector, 1, Buffer ) ) {
  289. ImageCRC = ((PPARTITION_IMAGE)Buffer)->CRC;
  290. // determine the image bitmap size
  291. BitmapSize = ((PPARTITION_IMAGE)Buffer)->LastUsedCluster;
  292. BitmapSize = (BitmapSize % (8*512)) ? BitmapSize/(8*512)+1 : BitmapSize/(8*512);
  293. // calculate how many sectors remain in the image
  294. SectorsRemaining = ((PPARTITION_IMAGE)Buffer)->NonClusterSectors // fs structs
  295. + ((PPARTITION_IMAGE)Buffer)->SectorsPerCluster
  296. * ((PPARTITION_IMAGE)Buffer)->UsedClusterCount // data area
  297. + BitmapSize; // image cluster bitmap
  298. // zero out these fields in the header so we can recalculate the original CRC
  299. ((PPARTITION_IMAGE)Buffer)->CRC = 0;
  300. ((PPARTITION_IMAGE)Buffer)->BitmapRelocationStart = 0;
  301. ((PPARTITION_IMAGE)Buffer)->BootRelocationStart = 0;
  302. ((PPARTITION_IMAGE)Buffer)->Flags = 0;
  303. TotalSectors = SectorsRemaining;
  304. } else {
  305. printf("\n %s\n",textCantAccessDisk);
  306. return FALSE;
  307. }
  308. CurrentSector++;
  309. // update the computed CRC
  310. CalcCRC = CRC32Compute( Buffer, 512, CalcCRC);
  311. BytesCRC += 512;
  312. // loop reading the entire file, updating the CRC
  313. while (SectorsRemaining) {
  314. Count = (BYTE) ((SectorsRemaining > 63L) ? 63L : SectorsRemaining);
  315. if( ReadDisk( DiskHandle, CurrentSector, Count , Buffer ) ) {
  316. CalcCRC = CRC32Compute( Buffer, Count*512, CalcCRC);
  317. BytesCRC += Count*512;
  318. } else {
  319. printf("\n %s\n",textCantAccessDisk);
  320. return FALSE;
  321. }
  322. SectorsRemaining -= Count;
  323. CurrentSector += Count;
  324. // print progress
  325. printf("\r %s (%u%%)", textValidateFile,100*(TotalSectors-SectorsRemaining)/TotalSectors);
  326. }
  327. // compare with stored CRC
  328. printf("\r %s = 0x%08lx\n", textChecksum, CalcCRC );
  329. printf("\r %s = 0x%08lx\n", textBytesProcessed,BytesCRC );
  330. if( CalcCRC != ImageCRC ) {
  331. printf("\n%s 0x%08lx\n",textChecksumFail,ImageCRC);
  332. return FALSE;
  333. } else {
  334. printf("\r %s\n", textChecksumOk);
  335. }
  336. free(OriginalBuffer);
  337. return TRUE;
  338. }