56dbd482906dd9aeb8e5bc1973c58674276e4b44
[reactos.git] / reactos / apps / utils / partinfo / partinfo.c
1 /*
2 * partinfo - partition info program
3 */
4
5 #include <windows.h>
6 //#include <winioctl.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9
10 //#define DUMP_DATA
11 #define DUMP_SIZE_INFO
12
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", errno);
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 = CreateFile(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: %u\n",
143 GetLastError());
144 free(Buffer);
145 return 0;
146 }
147
148 #ifdef DUMP_DATA
149 HexDump((char*)&DiskGeometry, dwRead);
150 #endif
151 printf("Drive number: %lu\n", ulDrive);
152 printf("Cylinders: %I64u\nMediaType: %lx\nTracksPerCylinder: %lu\n"
153 "SectorsPerTrack: %lu\nBytesPerSector: %lu\n\n",
154 DiskGeometry.Cylinders.QuadPart,
155 DiskGeometry.MediaType,
156 DiskGeometry.TracksPerCylinder,
157 DiskGeometry.SectorsPerTrack,
158 DiskGeometry.BytesPerSector);
159
160
161 Buffer = (char*)malloc(8192);
162 if (Buffer == NULL)
163 {
164 CloseHandle(hDisk);
165 printf("Out of memory!");
166 return 0;
167 }
168 memset(Buffer, 0, 8192);
169
170 if (!DeviceIoControl(hDisk,
171 IOCTL_DISK_GET_DRIVE_LAYOUT,
172 NULL,
173 0,
174 Buffer,
175 8192,
176 &dwRead,
177 NULL))
178 {
179 CloseHandle(hDisk);
180 printf("DeviceIoControl(IOCTL_DISK_GET_DRIVE_LAYOUT) failed! Error: %u\n",
181 GetLastError());
182 free(Buffer);
183 return 0;
184 }
185
186 CloseHandle(hDisk);
187
188 #ifdef DUMP_DATA
189 HexDump(Buffer, dwRead);
190 #endif
191
192 LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)Buffer;
193
194 printf("Partitions %u Signature %x\n",
195 LayoutBuffer->PartitionCount,
196 LayoutBuffer->Signature);
197
198 for (i = 0; i < LayoutBuffer->PartitionCount; i++)
199 {
200 printf(" %d: nr: %d boot: %1x type: %x start: 0x%I64x count: 0x%I64x\n",
201 i,
202 LayoutBuffer->PartitionEntry[i].PartitionNumber,
203 LayoutBuffer->PartitionEntry[i].BootIndicator,
204 LayoutBuffer->PartitionEntry[i].PartitionType,
205 LayoutBuffer->PartitionEntry[i].StartingOffset.QuadPart,
206 LayoutBuffer->PartitionEntry[i].PartitionLength.QuadPart);
207 }
208
209 free(Buffer);
210
211 return 0;
212 }