1 /* 2 * partinfo - partition info program 3 */ 4 5 #define WIN32_NO_STATUS 6 #include <windows.h> 7 #include <stdlib.h> 8 #include <ntndk.h> 9 #include <stdio.h> 10 11 //#define DUMP_DATA 12 #define DUMP_SIZE_INFO 13 14 #ifdef DUMP_DATA 15 void HexDump(char *buffer, ULONG size) 16 { 17 ULONG offset = 0; 18 unsigned char *ptr; 19 20 while (offset < (size & ~15)) 21 { 22 ptr = (unsigned char*)((ULONG)buffer + offset); 23 printf("%08lx %02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx-%02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx\n", 24 offset, 25 ptr[0], 26 ptr[1], 27 ptr[2], 28 ptr[3], 29 ptr[4], 30 ptr[5], 31 ptr[6], 32 ptr[7], 33 ptr[8], 34 ptr[9], 35 ptr[10], 36 ptr[11], 37 ptr[12], 38 ptr[13], 39 ptr[14], 40 ptr[15]); 41 offset += 16; 42 } 43 44 ptr = (unsigned char*)((ULONG)buffer + offset); 45 printf("%08lx ", offset); 46 while (offset < size) 47 { 48 printf(" %02hx", *ptr); 49 offset++; 50 ptr++; 51 } 52 53 printf("\n\n\n"); 54 } 55 #endif 56 57 58 void Usage(void) 59 { 60 puts("Usage: partinfo <drive number>"); 61 } 62 63 64 int main (int argc, char *argv[]) 65 { 66 HANDLE hDisk; 67 DWORD dwRead; 68 DWORD i; 69 char *Buffer; 70 DRIVE_LAYOUT_INFORMATION *LayoutBuffer; 71 DISK_GEOMETRY DiskGeometry; 72 ULONG ulDrive; 73 CHAR DriveName[40]; 74 SYSTEM_DEVICE_INFORMATION DeviceInfo; 75 NTSTATUS Status; 76 77 if (argc != 2) 78 { 79 Usage(); 80 return(0); 81 } 82 83 ulDrive = strtoul(argv[1], NULL, 10); 84 if (errno != 0) 85 { 86 printf("Error: Malformed drive number\n"); 87 return(0); 88 } 89 90 /* Check drive number */ 91 Status = NtQuerySystemInformation(SystemDeviceInformation, 92 &DeviceInfo, 93 sizeof(SYSTEM_DEVICE_INFORMATION), 94 &i); 95 if (!NT_SUCCESS(Status)) 96 { 97 printf("NtQuerySystemInformation() failed (Status %lx)\n", Status); 98 return(0); 99 } 100 101 if (DeviceInfo.NumberOfDisks == 0) 102 { 103 printf("No disk drive installed!\n"); 104 return(0); 105 } 106 107 if (ulDrive >= DeviceInfo.NumberOfDisks) 108 { 109 printf("Invalid disk drive number! Valid drive numbers [0-%lu]\n", 110 DeviceInfo.NumberOfDisks-1); 111 return(0); 112 } 113 114 /* Build full drive name */ 115 sprintf(DriveName, "\\\\.\\PHYSICALDRIVE%lu", ulDrive); 116 117 /* Open drive */ 118 hDisk = CreateFileA(DriveName, 119 GENERIC_READ, 120 FILE_SHARE_READ | FILE_SHARE_WRITE, 121 NULL, 122 OPEN_EXISTING, 123 0, 124 NULL); 125 if (hDisk == INVALID_HANDLE_VALUE) 126 { 127 printf("Invalid disk handle!"); 128 return 0; 129 } 130 131 /* Get drive geometry */ 132 if (!DeviceIoControl(hDisk, 133 IOCTL_DISK_GET_DRIVE_GEOMETRY, 134 NULL, 135 0, 136 &DiskGeometry, 137 sizeof(DISK_GEOMETRY), 138 &dwRead, 139 NULL)) 140 { 141 CloseHandle(hDisk); 142 printf("DeviceIoControl failed! Error: %lu\n", 143 GetLastError()); 144 return 0; 145 } 146 147 #ifdef DUMP_DATA 148 HexDump((char*)&DiskGeometry, dwRead); 149 #endif 150 printf("Drive number: %lu\n", ulDrive); 151 printf("Cylinders: %I64u\nMediaType: %x\nTracksPerCylinder: %lu\n" 152 "SectorsPerTrack: %lu\nBytesPerSector: %lu\n\n", 153 DiskGeometry.Cylinders.QuadPart, 154 DiskGeometry.MediaType, 155 DiskGeometry.TracksPerCylinder, 156 DiskGeometry.SectorsPerTrack, 157 DiskGeometry.BytesPerSector); 158 159 160 Buffer = (char*)malloc(8192); 161 if (Buffer == NULL) 162 { 163 CloseHandle(hDisk); 164 printf("Out of memory!"); 165 return 0; 166 } 167 memset(Buffer, 0, 8192); 168 169 if (!DeviceIoControl(hDisk, 170 IOCTL_DISK_GET_DRIVE_LAYOUT, 171 NULL, 172 0, 173 Buffer, 174 8192, 175 &dwRead, 176 NULL)) 177 { 178 CloseHandle(hDisk); 179 printf("DeviceIoControl(IOCTL_DISK_GET_DRIVE_LAYOUT) failed! Error: %lu\n", 180 GetLastError()); 181 free(Buffer); 182 return 0; 183 } 184 185 CloseHandle(hDisk); 186 187 #ifdef DUMP_DATA 188 HexDump(Buffer, dwRead); 189 #endif 190 191 LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)Buffer; 192 193 printf("Partitions %lu Signature %lx\n", 194 LayoutBuffer->PartitionCount, 195 LayoutBuffer->Signature); 196 197 for (i = 0; i < LayoutBuffer->PartitionCount; i++) 198 { 199 printf(" %ld: nr: %ld boot: %1x type: %x start: 0x%I64x count: 0x%I64x\n", 200 i, 201 LayoutBuffer->PartitionEntry[i].PartitionNumber, 202 LayoutBuffer->PartitionEntry[i].BootIndicator, 203 LayoutBuffer->PartitionEntry[i].PartitionType, 204 LayoutBuffer->PartitionEntry[i].StartingOffset.QuadPart, 205 LayoutBuffer->PartitionEntry[i].PartitionLength.QuadPart); 206 } 207 208 free(Buffer); 209 210 return 0; 211 } 212