[PARTINFO][ARP]
[reactos.git] / rosapps / applications / sysutils / utils / partinfo / partinfo.c
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 }