NT4/private/ntos/dd/ntft/cmd/drvparms/drvparms.c
2020-09-30 17:12:29 +02:00

278 lines
8.8 KiB
C

#include <stdio.h>
#include <windows.h>
#include <winioctl.h>
#include <malloc.h>
//
// Boot record disk partition table entry structure format.
//
typedef struct _PARTITION_DESCRIPTOR {
UCHAR ActiveFlag; // Bootable or not
UCHAR StartingTrack; // Not used
UCHAR StartingCylinderLsb; // Not used
UCHAR StartingCylinderMsb; // Not used
UCHAR PartitionType; // 12 bit FAT, 16 bit FAT etc.
UCHAR EndingTrack; // Not used
UCHAR EndingCylinderLsb; // Not used
UCHAR EndingCylinderMsb; // Not used
UCHAR StartingSectorLsb0; // Hidden sectors
UCHAR StartingSectorLsb1;
UCHAR StartingSectorMsb0;
UCHAR StartingSectorMsb1;
UCHAR PartitionLengthLsb0; // Sectors in this partition
UCHAR PartitionLengthLsb1;
UCHAR PartitionLengthMsb0;
UCHAR PartitionLengthMsb1;
} PARTITION_DESCRIPTOR, *PPARTITION_DESCRIPTOR;
//
// Number of partition table entries
//
#define NUM_PARTITION_TABLE_ENTRIES 4
//
// Partition table record and boot signature offsets in 16-bit words.
//
#define PARTITION_TABLE_OFFSET (0x1be / 2)
#define BOOT_SIGNATURE_OFFSET ((0x200 / 2) - 1)
//
// Boot record signature value.
//
#define BOOT_RECORD_SIGNATURE (0xaa55)
VOID
DisplayXbr(
PUCHAR Buffer
)
{
PPARTITION_DESCRIPTOR mbr;
ULONG sectorStart;
ULONG sectorLength;
ULONG index;
mbr = (PPARTITION_DESCRIPTOR) (Buffer + 0x1be);
printf("\n");
printf(" Starting Ending Sector\n");
printf(" Track Cylinder Track Cylinder Type Start Length\n");
for (index = 0; index < NUM_PARTITION_TABLE_ENTRIES; index++) {
sectorStart = ((ULONG) mbr->StartingSectorMsb1 << 24) |
((ULONG) mbr->StartingSectorMsb0 << 16) |
((ULONG) mbr->StartingSectorLsb1 << 8) |
((ULONG) mbr->StartingSectorLsb0);
sectorLength = ((ULONG) mbr->PartitionLengthMsb1 << 24) |
((ULONG) mbr->PartitionLengthMsb0 << 16) |
((ULONG) mbr->PartitionLengthLsb1 << 8) |
((ULONG) mbr->PartitionLengthLsb0);
printf("%c %4x %4x %4x %4x %2x %8x %8x\n",
(mbr->ActiveFlag & 0x80) ? '*' : ' ',
mbr->StartingTrack,
((SHORT) mbr->StartingCylinderMsb << 8) | mbr->StartingCylinderLsb,
mbr->EndingTrack,
((SHORT) mbr->EndingCylinderMsb << 8) | mbr->EndingCylinderLsb,
mbr->PartitionType,
sectorStart,
sectorLength);
mbr++;
}
}
//
// main line
//
int _CRTAPI1
main(int argc, char *argv[])
{
PDRIVE_LAYOUT_INFORMATION driveLayout;
PPARTITION_INFORMATION partitionInformation;
PPARTITION_DESCRIPTOR mbr;
PUCHAR buffer;
PUCHAR alignedBuffer;
DWORD numBytes;
HANDLE hFile;
DISK_GEOMETRY diskGeometry;
ULONG trackSize;
ULONG cylinderSize;
ULONG index;
ULONG bytesRead;
ULONG sectorStart;
ULONG tmpStart;
ULONG sectorLength;
LONGLONG diskSize;
LONGLONG diskSizeMB;
if (argc < 2) {
printf("usage: %s <drive>\n");
return 0;
}
hFile = CreateFile(argv[1],
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if (hFile == INVALID_HANDLE_VALUE) {
printf("BLOCKED: CreatFile() Failed %s [Error %d]\n",
argv[1],
GetLastError());
return FALSE;
}
if (!DeviceIoControl(hFile,
IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL,
0,
&diskGeometry,
sizeof(diskGeometry),
&numBytes,
NULL)) {
printf("Unable to get drive geometry [Error %d].\n",
GetLastError());
CloseHandle(hFile);
return FALSE;
}
printf("Cylinders TracksPerCylinder SectorsPerTrack BytesPerSector MediaType\n");
printf("%9d %17d %15d %14d 0x%7x\n",
diskGeometry.Cylinders.LowPart,
diskGeometry.TracksPerCylinder,
diskGeometry.SectorsPerTrack,
diskGeometry.BytesPerSector,
diskGeometry.MediaType);
trackSize = diskGeometry.BytesPerSector * diskGeometry.SectorsPerTrack;
cylinderSize = trackSize * diskGeometry.TracksPerCylinder;
diskSize = cylinderSize * diskGeometry.Cylinders.QuadPart;
diskSizeMB = diskSize / (1024 * 1024);
printf("TrackSize = %d, CylinderSize = %d, DiskSize = 0x%x%x (%dMB)\n\n",
trackSize,
cylinderSize,
(ULONG) (diskSize >> 32),
(ULONG) diskSize,
(ULONG) diskSizeMB);
numBytes = sizeof(DRIVE_LAYOUT_INFORMATION) + (500 * sizeof(PARTITION_INFORMATION));
driveLayout = malloc(numBytes);
if (!driveLayout) {
printf("Unable to allocate memory\n");
CloseHandle(hFile);
return FALSE;
}
if (!DeviceIoControl(hFile,
IOCTL_DISK_GET_DRIVE_LAYOUT,
NULL,
0,
driveLayout,
numBytes,
&numBytes,
NULL)) {
printf("Unable to get drive layout [Error %d].\n",
GetLastError());
free(driveLayout);
CloseHandle(hFile);
return FALSE;
}
printf("PartitionCount = %d, Signature = 0x%8x\n",
driveLayout->PartitionCount,
driveLayout->Signature);
printf(" StartingOffset PartitionLength HiddenSectors PartitionNumber\n");
for (index = 0; index < driveLayout->PartitionCount; index++) {
partitionInformation = &driveLayout->PartitionEntry[index];
printf("%c%8x:%8x %8x:%8x 0x%11x %15d %s\n",
(partitionInformation->BootIndicator ? '*' : ' '),
partitionInformation->StartingOffset.HighPart,
partitionInformation->StartingOffset.LowPart,
partitionInformation->PartitionLength.HighPart,
partitionInformation->PartitionLength.LowPart,
partitionInformation->HiddenSectors,
partitionInformation->PartitionNumber,
partitionInformation->RecognizedPartition ? "Recognized" : "");
}
free(driveLayout);
//
// Do this from the MBR
//
buffer = malloc(4096);
alignedBuffer = (buffer + 1023);
alignedBuffer = (PUCHAR)((ULONG)alignedBuffer & 0xfffffc00);
ReadFile(hFile,
alignedBuffer,
1024,
&bytesRead,
NULL);
if (bytesRead == 1024) {
ULONG offset = 0;
printf("MBR:\n");
DisplayXbr(alignedBuffer);
//
// Now process any extended partitions
//
mbr = (PPARTITION_DESCRIPTOR) (alignedBuffer + 0x1be);
while (1) {
for (index = 0; index < 4; index++) {
if (mbr->PartitionType == 5) {
//
// Seek to EBR and read it.
//
sectorStart = ((ULONG) mbr->StartingSectorMsb1 << 24) |
((ULONG) mbr->StartingSectorMsb0 << 16) |
((ULONG) mbr->StartingSectorLsb1 << 8) |
((ULONG) mbr->StartingSectorLsb0);
tmpStart = ((ULONG) mbr->StartingSectorMsb1 << 24) +
((ULONG) mbr->StartingSectorMsb0 << 16) +
((ULONG) mbr->StartingSectorLsb1 << 8) +
((ULONG) mbr->StartingSectorLsb0);
offset += (sectorStart * 512);
SetFilePointer(hFile,
(ULONG) offset,
NULL,
FILE_BEGIN);
ReadFile(hFile,
alignedBuffer,
1024,
&bytesRead,
NULL);
if (bytesRead == 1024) {
printf("Ebr (0x%x, 0x%x, 0x%x):\n",
offset,
sectorStart,
tmpStart);
DisplayXbr(alignedBuffer);
}
break;
}
mbr++;
}
if (index == 4) {
break;
}
}
}
free(buffer);
CloseHandle(hFile);
return TRUE;
}