windows-nt/Source/XPSP1/NT/base/ntsetup/mpk/diskstat/diskstat.c
2020-09-26 16:20:57 +08:00

415 lines
11 KiB
C

#include <mytypes.h>
#include <partio.h>
#include <diskio.h>
#include <misclib.h>
#include <partimag.h>
#include <msgfile.h>
#include <stdio.h>
#include <malloc.h>
#include <memory.h>
#include <dos.h>
#include <stdlib.h>
char *textDiskCount;
char *textDiskN;
char *textInt13Unit;
char *textSectorsPerTrack;
char *textHeads;
char *textCylinders;
char *textExtInt13;
char *textNoExtInt13;
char *textPartitionsOnDisk;
char *textSystemId;
char *textStartSector;
char *textSectorCount;
char *textNoPartitionsOnDisk;
char *textCantAllocBuffer;
char *textIsNotMasterDisk;
char *textIsMasterDisk;
char *textCantAccessDisk;
char *textPartImageCount;
char *textImageN;
char *textImageCorrupt;
char *textImageName;
char *textOriginalTotalSectors;
char *textMBParens;
char *textDone;
char *textUsage;
char *textChecksum;
char *textChecksumFail;
char *textBytesProcessed;
char *textValidateFile;
char *textChecksumOk;
char *textRelocBitmap;
char *textRelocBoot;
MESSAGE_STRING TextMessages[] = { { &textDiskCount, 1 },
{ &textDiskN, 2 },
{ &textInt13Unit, 3 },
{ &textSectorsPerTrack, 4 },
{ &textHeads, 5 },
{ &textCylinders, 6 },
{ &textExtInt13, 7 },
{ &textNoExtInt13, 8 },
{ &textPartitionsOnDisk, 9 },
{ &textSystemId, 10 },
{ &textStartSector, 11 },
{ &textSectorCount, 12 },
{ &textNoPartitionsOnDisk, 13 },
{ &textCantAllocBuffer, 14 },
{ &textIsNotMasterDisk, 15 },
{ &textIsMasterDisk, 16 },
{ &textCantAccessDisk, 17 },
{ &textPartImageCount, 18 },
{ &textImageN, 19 },
{ &textImageCorrupt, 20 },
{ &textImageName, 21 },
{ &textOriginalTotalSectors,22 },
{ &textMBParens, 24 },
{ &textDone, 25 },
{ &textUsage, 26 },
{ &textChecksum, 27 },
{ &textChecksumFail, 28 },
{ &textBytesProcessed, 29 },
{ &textValidateFile, 30 },
{ &textChecksumOk, 31 },
{ &textRelocBitmap, 32 },
{ &textRelocBoot, 33 }
};
UINT PartCount;
BYTE SaveBuffer[512];
CMD_LINE_ARGS CmdLineArgs;
VOID
DumpDisk(
IN UINT DiskId
);
VOID
DumpPartitionsOnDisk(
IN UINT DiskId
);
VOID
DumpMasterDiskInfo(
IN UINT DiskId
);
BOOL
TestImage(
IN HDISK DiskHandle,
IN ULONG StartSector
);
int
main(
IN int argc,
IN char *argv[]
)
{
UINT DiskCount,i;
if(!GetTextForProgram(argv[0],TextMessages,sizeof(TextMessages)/sizeof(TextMessages[0]))) {
fprintf(stderr,"Unable to find messages for program\n");
return(FAILURE);
}
if(!ParseArgs(argc,argv,TRUE,"XT",&CmdLineArgs)) {
fprintf(stderr,textUsage);
fprintf(stderr,"\n");
return(FAILURE);
}
PartCount = InitializePartitionList();
DiskCount = InitializeDiskList();
printf(textDiskCount,DiskCount);
printf("\n");
for(i=0; i<DiskCount; i++) {
DumpDisk(i);
}
return(SUCCESS);
}
VOID
DumpDisk(
IN UINT DiskId
)
{
BYTE Int13Unit;
BYTE SectorsPerTrack;
USHORT Heads;
USHORT Cylinders;
ULONG ExtendedSectorCount;
printf("\n");
printf(textDiskN,DiskId);
printf("\n\n");
GetDiskInfoById(
DiskId,
0,
&Int13Unit,
&SectorsPerTrack,
&Heads,
&Cylinders,
&ExtendedSectorCount
);
printf(" %s ",textInt13Unit);
printf("%x\n",Int13Unit);
printf(" %s ",textSectorsPerTrack);
printf("%u\n",SectorsPerTrack);
printf(" %s ",textHeads);
printf("%u\n",Heads);
printf(" %s ",textCylinders);
printf("%u\n",Cylinders);
if(ExtendedSectorCount) {
printf(" %s ",textExtInt13);
printf("0x%lx\n",ExtendedSectorCount);
} else {
printf(" %s\n",textNoExtInt13);
}
DumpPartitionsOnDisk(DiskId);
DumpMasterDiskInfo(DiskId);
printf("\n%s\n",textDone);
}
VOID
DumpPartitionsOnDisk(
IN UINT DiskId
)
{
UINT i;
UINT id;
BYTE SysId;
ULONG StartSector;
ULONG SectorCount;
unsigned count;
count = 0;
printf("\n");
for(i=0; i<PartCount; i++) {
GetPartitionInfoById(
i,
0,
&id,
&SysId,
&StartSector,
&SectorCount
);
if(id == DiskId) {
if(!count++) {
printf(" %s\n",textPartitionsOnDisk);
}
printf("\n %s ",textSystemId);
printf("%u\n",SysId);
printf(" %s ",textStartSector);
printf("0x%lx\n",StartSector);
printf(" %s ",textSectorCount);
printf("0x%lx ",SectorCount);
printf(textMBParens,SectorCount/2048);
printf("\n");
}
}
if(!count) {
printf(" %s\n",textNoPartitionsOnDisk);
}
}
VOID
DumpMasterDiskInfo(
IN UINT DiskId
)
{
FPVOID Buffer,OriginalBuffer;
HDISK hDisk;
FPMASTER_DISK MasterDisk;
FPPARTITION_IMAGE Image;
UINT i;
printf("\n");
if(!AllocTrackBuffer(1,&Buffer,&OriginalBuffer)) {
printf(" %s\n",textCantAllocBuffer);
return;
}
if(IsMasterDisk(DiskId,Buffer)) {
printf(" %s ",textIsMasterDisk);
if(hDisk = OpenDisk(DiskId)) {
if(ReadDisk(hDisk,1,1,Buffer)) {
memcpy(SaveBuffer,Buffer,512);
MasterDisk = (FPMASTER_DISK)SaveBuffer;
printf("\n (%u %s)\n", MasterDisk->ImageCount, textPartImageCount);
Image = Buffer;
for(i=0; i<MasterDisk->ImageCount; i++) {
printf("\n ");
printf(textImageN,i+1);
printf("\n\n");
if(ReadDisk(hDisk,MasterDisk->ImageStartSector[i],1,Buffer)) {
if((Image->Signature == PARTITION_IMAGE_SIGNATURE)
&& (Image->Size == sizeof(PARTITION_IMAGE))) {
printf(" %s %u\n",textSystemId,Image->SystemId);
printf(" %s 0x%lx ",textOriginalTotalSectors,Image->TotalSectorCount);
printf(textMBParens,Image->TotalSectorCount/2048);
printf("\n");
if( Image->Flags & PARTIMAGE_RELOCATE_BITMAP ) {
printf(" %s 0x%lx\n",textRelocBitmap,Image->BitmapRelocationStart);
}
if( Image->Flags & PARTIMAGE_RELOCATE_BOOT ) {
printf(" %s 0x%lx\n",textRelocBoot,Image->BootRelocationStart);
}
printf("\n");
if(CmdLineArgs.Test) {
TestImage(hDisk,MasterDisk->ImageStartSector[i]);
}
} else {
printf(" %s\n",textImageCorrupt);
}
} else {
printf(" %s\n",textCantAccessDisk);
}
}
} else {
printf("\n %s\n",textCantAccessDisk);
}
} else {
printf("\n %s\n",textCantAccessDisk);
}
} else {
printf(" %s\n",textIsNotMasterDisk);
}
free(OriginalBuffer);
}
BOOL
TestImage(
IN HDISK DiskHandle,
IN ULONG StartSector
)
{
FPVOID Buffer,OriginalBuffer;
ULONG CurrentSector;
ULONG ImageCRC;
ULONG CalcCRC;
ULONG BytesCRC;
ULONG SectorsRemaining;
ULONG TotalSectors;
ULONG BitmapSize;
BYTE Count;
// need to allocate aligned buffer
if(!AllocTrackBuffer(63,&Buffer,&OriginalBuffer)) {
printf(" %s\n",textCantAllocBuffer);
return FALSE;
}
CalcCRC = CRC32_INITIAL_VALUE;
BytesCRC = 0;
// read inital sector to get info
CurrentSector = StartSector;
if( ReadDisk( DiskHandle, CurrentSector, 1, Buffer ) ) {
ImageCRC = ((PPARTITION_IMAGE)Buffer)->CRC;
// determine the image bitmap size
BitmapSize = ((PPARTITION_IMAGE)Buffer)->LastUsedCluster;
BitmapSize = (BitmapSize % (8*512)) ? BitmapSize/(8*512)+1 : BitmapSize/(8*512);
// calculate how many sectors remain in the image
SectorsRemaining = ((PPARTITION_IMAGE)Buffer)->NonClusterSectors // fs structs
+ ((PPARTITION_IMAGE)Buffer)->SectorsPerCluster
* ((PPARTITION_IMAGE)Buffer)->UsedClusterCount // data area
+ BitmapSize; // image cluster bitmap
// zero out these fields in the header so we can recalculate the original CRC
((PPARTITION_IMAGE)Buffer)->CRC = 0;
((PPARTITION_IMAGE)Buffer)->BitmapRelocationStart = 0;
((PPARTITION_IMAGE)Buffer)->BootRelocationStart = 0;
((PPARTITION_IMAGE)Buffer)->Flags = 0;
TotalSectors = SectorsRemaining;
} else {
printf("\n %s\n",textCantAccessDisk);
return FALSE;
}
CurrentSector++;
// update the computed CRC
CalcCRC = CRC32Compute( Buffer, 512, CalcCRC);
BytesCRC += 512;
// loop reading the entire file, updating the CRC
while (SectorsRemaining) {
Count = (BYTE) ((SectorsRemaining > 63L) ? 63L : SectorsRemaining);
if( ReadDisk( DiskHandle, CurrentSector, Count , Buffer ) ) {
CalcCRC = CRC32Compute( Buffer, Count*512, CalcCRC);
BytesCRC += Count*512;
} else {
printf("\n %s\n",textCantAccessDisk);
return FALSE;
}
SectorsRemaining -= Count;
CurrentSector += Count;
// print progress
printf("\r %s (%u%%)", textValidateFile,100*(TotalSectors-SectorsRemaining)/TotalSectors);
}
// compare with stored CRC
printf("\r %s = 0x%08lx\n", textChecksum, CalcCRC );
printf("\r %s = 0x%08lx\n", textBytesProcessed,BytesCRC );
if( CalcCRC != ImageCRC ) {
printf("\n%s 0x%08lx\n",textChecksumFail,ImageCRC);
return FALSE;
} else {
printf("\r %s\n", textChecksumOk);
}
free(OriginalBuffer);
return TRUE;
}