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