844fe8f83d8597b9f79c9f09074eca14442ca80b
[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 <string.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10
11 //#define DUMP_DATA
12 #define DUMP_SIZE_INFO
13
14
15 #ifdef DUMP_DATA
16 void HexDump(char *buffer, ULONG size)
17 {
18 ULONG offset = 0;
19 unsigned char *ptr;
20
21 while (offset < (size & ~15))
22 {
23 ptr = (unsigned char*)((ULONG)buffer + offset);
24 printf("%08lx %02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx-%02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx\n",
25 offset,
26 ptr[0],
27 ptr[1],
28 ptr[2],
29 ptr[3],
30 ptr[4],
31 ptr[5],
32 ptr[6],
33 ptr[7],
34 ptr[8],
35 ptr[9],
36 ptr[10],
37 ptr[11],
38 ptr[12],
39 ptr[13],
40 ptr[14],
41 ptr[15]);
42 offset += 16;
43 }
44
45 ptr = (unsigned char*)((ULONG)buffer + offset);
46 printf("%08lx ", offset);
47 while (offset < size)
48 {
49 printf(" %02hx", *ptr);
50 offset++;
51 ptr++;
52 }
53
54 printf("\n\n\n");
55 }
56 #endif
57
58
59 void Usage(void)
60 {
61 puts("Usage: partinfo <drive number>");
62 }
63
64
65 int main (int argc, char *argv[])
66 {
67 HANDLE hDisk;
68 DWORD dwRead;
69 DWORD i;
70 char *Buffer;
71 DRIVE_LAYOUT_INFORMATION *LayoutBuffer;
72 DISK_GEOMETRY DiskGeometry;
73 ULONG ulDrive;
74 CHAR DriveName[40];
75 SYSTEM_DEVICE_INFORMATION DeviceInfo;
76 NTSTATUS Status;
77
78 if (argc != 2)
79 {
80 Usage();
81 return(0);
82 }
83
84 ulDrive = strtoul(argv[1], NULL, 10);
85 if (errno != 0)
86 {
87 printf("Error: Malformed drive number\n");
88 return(0);
89 }
90
91 /* Check drive number */
92 Status = NtQuerySystemInformation(SystemDeviceInformation,
93 &DeviceInfo,
94 sizeof(SYSTEM_DEVICE_INFORMATION),
95 &i);
96 if (!NT_SUCCESS(Status))
97 {
98 printf("NtQuerySystemInformation() failed (Status %lx)\n", Status);
99 return(0);
100 }
101
102 if (DeviceInfo.NumberOfDisks == 0)
103 {
104 printf("No disk drive installed!\n");
105 return(0);
106 }
107
108 if (ulDrive >= DeviceInfo.NumberOfDisks)
109 {
110 printf("Invalid disk drive number! Valid drive numbers [0-%lu]\n",
111 DeviceInfo.NumberOfDisks-1);
112 return(0);
113 }
114
115 /* Build full drive name */
116 sprintf(DriveName, "\\\\.\\PHYSICALDRIVE%lu", ulDrive);
117
118 /* Open drive */
119 hDisk = CreateFile(DriveName,
120 GENERIC_READ,
121 FILE_SHARE_READ | FILE_SHARE_WRITE,
122 NULL,
123 OPEN_EXISTING,
124 0,
125 NULL);
126 if (hDisk == INVALID_HANDLE_VALUE)
127 {
128 printf("Invalid disk handle!");
129 return 0;
130 }
131
132 /* Get drive geometry */
133 if (!DeviceIoControl(hDisk,
134 IOCTL_DISK_GET_DRIVE_GEOMETRY,
135 NULL,
136 0,
137 &DiskGeometry,
138 sizeof(DISK_GEOMETRY),
139 &dwRead,
140 NULL))
141 {
142 CloseHandle(hDisk);
143 printf("DeviceIoControl failed! Error: %lu\n",
144 GetLastError());
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: %x\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: %lu\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 %lu Signature %lx\n",
195 LayoutBuffer->PartitionCount,
196 LayoutBuffer->Signature);
197
198 for (i = 0; i < LayoutBuffer->PartitionCount; i++)
199 {
200 printf(" %ld: nr: %ld 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 }