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