scroll mode for very long start menus
[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 free(Buffer);
146 return 0;
147 }
148
149 #ifdef DUMP_DATA
150 HexDump((char*)&DiskGeometry, dwRead);
151 #endif
152 printf("Drive number: %lu\n", ulDrive);
153 printf("Cylinders: %I64u\nMediaType: %x\nTracksPerCylinder: %lu\n"
154 "SectorsPerTrack: %lu\nBytesPerSector: %lu\n\n",
155 DiskGeometry.Cylinders.QuadPart,
156 DiskGeometry.MediaType,
157 DiskGeometry.TracksPerCylinder,
158 DiskGeometry.SectorsPerTrack,
159 DiskGeometry.BytesPerSector);
160
161
162 Buffer = (char*)malloc(8192);
163 if (Buffer == NULL)
164 {
165 CloseHandle(hDisk);
166 printf("Out of memory!");
167 return 0;
168 }
169 memset(Buffer, 0, 8192);
170
171 if (!DeviceIoControl(hDisk,
172 IOCTL_DISK_GET_DRIVE_LAYOUT,
173 NULL,
174 0,
175 Buffer,
176 8192,
177 &dwRead,
178 NULL))
179 {
180 CloseHandle(hDisk);
181 printf("DeviceIoControl(IOCTL_DISK_GET_DRIVE_LAYOUT) failed! Error: %lu\n",
182 GetLastError());
183 free(Buffer);
184 return 0;
185 }
186
187 CloseHandle(hDisk);
188
189 #ifdef DUMP_DATA
190 HexDump(Buffer, dwRead);
191 #endif
192
193 LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)Buffer;
194
195 printf("Partitions %lu Signature %lx\n",
196 LayoutBuffer->PartitionCount,
197 LayoutBuffer->Signature);
198
199 for (i = 0; i < LayoutBuffer->PartitionCount; i++)
200 {
201 printf(" %ld: nr: %ld boot: %1x type: %x start: 0x%I64x count: 0x%I64x\n",
202 i,
203 LayoutBuffer->PartitionEntry[i].PartitionNumber,
204 LayoutBuffer->PartitionEntry[i].BootIndicator,
205 LayoutBuffer->PartitionEntry[i].PartitionType,
206 LayoutBuffer->PartitionEntry[i].StartingOffset.QuadPart,
207 LayoutBuffer->PartitionEntry[i].PartitionLength.QuadPart);
208 }
209
210 free(Buffer);
211
212 return 0;
213 }