ReactOS  0.4.15-dev-2700-g4b4ffa9
partinfo.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Partition Information Tool
3  * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE: Displays disk and partition information for MBR and GPT disks.
5  * COPYRIGHT: Copyright 2001-2002 Eric Kohl
6  * Copyright 2020-2021 Hermes Belusca-Maito
7  */
8 
9 /* INCLUDES *****************************************************************/
10 
11 #include <stdio.h>
12 #include <stdlib.h>
13 
14 #define WIN32_NO_STATUS
15 #include <windows.h>
16 #include <ntndk.h>
17 
18 /* The maximum information a DISK_GEOMETRY_EX dynamic structure can contain */
19 typedef struct _DISK_GEOMETRY_EX_INTERNAL
20 {
23  DISK_PARTITION_INFO Partition;
24  DISK_DETECTION_INFO Detection;
26 
27 #define DRIVE_LAYOUT_INFO_ENTRY_SIZE \
28  RTL_FIELD_SIZE(DRIVE_LAYOUT_INFORMATION, PartitionEntry[0])
29 
30 #define DRIVE_LAYOUT_INFO_SIZE(n) \
31  (FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION, PartitionEntry) + \
32  ((n) * DRIVE_LAYOUT_INFO_ENTRY_SIZE))
33 
34 #define DRIVE_LAYOUT_INFOEX_ENTRY_SIZE \
35  RTL_FIELD_SIZE(DRIVE_LAYOUT_INFORMATION_EX, PartitionEntry[0])
36 
37 #define DRIVE_LAYOUT_INFOEX_SIZE(n) \
38  (FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION_EX, PartitionEntry) + \
39  ((n) * DRIVE_LAYOUT_INFOEX_ENTRY_SIZE))
40 
41 
42 /* Rounding up for number; not the same as ROUND_UP() with power-of-two sizes */
43 #define ROUND_UP_NUM(num, up) ((((num) + (up) - 1) / (up)) * (up))
44 
45 
46 // #define DUMP_DATA
47 
48 
49 /* FORMATTING HELPERS *******************************************************/
50 
51 static PCSTR PartitionStyleNames[] = {"MBR", "GPT", "RAW", "Unknown"};
52 #define PARTITION_STYLE_NAME(PartStyle) \
53  ( ((PartStyle) <= PARTITION_STYLE_RAW) \
54  ? PartitionStyleNames[(PartStyle)] \
55  : PartitionStyleNames[_countof(PartitionStyleNames)-1] )
56 
57 static PCSTR DetectTypeNames[] = { "None", "DetectInt13", "DetectExInt13", "Unknown" };
58 #define DETECT_TYPE_NAME(DetectType) \
59  ( ((DetectType) <= DetectExInt13) \
60  ? DetectTypeNames[(DetectType)] \
61  : DetectTypeNames[_countof(DetectTypeNames)-1] )
62 
63 #define GUID_FORMAT_STR "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"
64 #define GUID_ELEMENTS(Guid) \
65  (Guid)->Data1, (Guid)->Data2, (Guid)->Data3, \
66  (Guid)->Data4[0], (Guid)->Data4[1], (Guid)->Data4[2], (Guid)->Data4[3], \
67  (Guid)->Data4[4], (Guid)->Data4[5], (Guid)->Data4[6], (Guid)->Data4[7]
68 
69 
70 /* FUNCTIONS ****************************************************************/
71 
72 #ifdef DUMP_DATA
73 void HexDump(
74  IN PVOID buffer,
75  IN ULONG size)
76 {
77  ULONG_PTR offset = 0;
78  PUCHAR ptr;
79 
80  while (offset < (size & ~15))
81  {
83  printf("%08lx %02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx-%02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx\n",
84  offset,
85  ptr[0], ptr[1], ptr[2] , ptr[3] , ptr[4] , ptr[5] , ptr[6] , ptr[7],
86  ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15]);
87  offset += 16;
88  }
89 
90  if (offset < size)
91  {
93  printf("%08lx ", offset);
94  while (offset < size)
95  {
96  printf(" %02hx", *ptr);
97  offset++;
98  ptr++;
99  }
100  printf("\n");
101  }
102 
103  printf("\n");
104 }
105 #endif
106 
107 void Usage(void)
108 {
109  puts("Usage: partinfo <drive number>");
110 }
111 
112 int main(int argc, char *argv[])
113 {
115  ULONG ulDrive;
116  HANDLE hDisk;
117  ULONG i;
121  union
122  {
125  } DiskGeometry;
126  PDISK_GEOMETRY pDiskGeometry;
127  union
128  {
131  } PartInfo;
132  PPARTITION_INFORMATION pPartInfo;
133  PPARTITION_INFORMATION_EX pPartInfoEx;
134  union
135  {
137  PDRIVE_LAYOUT_INFORMATION_EX InfoEx;
138  } LayoutBuffer;
139  PVOID ptr;
140  WCHAR DriveName[40];
141 
142  if (argc != 2)
143  {
144  Usage();
145  return 0;
146  }
147 
148  ulDrive = strtoul(argv[1], NULL, 10);
149  if (errno != 0)
150  {
151  printf("Error: Malformed drive number\n");
152  return 0;
153  }
154 
155  /*
156  * Retrieve the number of disks on the system.
157  */
159  &DeviceInfo,
160  sizeof(DeviceInfo),
161  &i);
162  if (!NT_SUCCESS(Status))
163  {
164  printf("NtQuerySystemInformation() failed (Status 0x%lx)\n", Status);
165  return 0;
166  }
167  if (DeviceInfo.NumberOfDisks == 0)
168  {
169  printf("No disk drive installed!\n");
170  return 0;
171  }
172 
173  if (ulDrive >= DeviceInfo.NumberOfDisks)
174  {
175  printf("Invalid disk drive number! Valid drive numbers: [0-%lu]\n",
176  DeviceInfo.NumberOfDisks-1);
177  return 0;
178  }
179 
180  /* Build the full drive name */
181  swprintf(DriveName, L"\\\\.\\PHYSICALDRIVE%lu", ulDrive);
182 
183  /* Open the drive */
184  hDisk = CreateFileW(DriveName,
185  GENERIC_READ,
187  NULL,
189  0,
190  NULL);
191  if (hDisk == INVALID_HANDLE_VALUE)
192  {
193  printf("Could not open drive!");
194  return 0;
195  }
196 
197  printf("Drive number: %lu\n\n", ulDrive);
198 
199 
200  /*
201  * Get the drive geometry.
202  */
204  NULL,
205  NULL,
206  NULL,
207  &Iosb,
209  NULL,
210  0,
211  &DiskGeometry.Info,
212  sizeof(DiskGeometry.Info));
213  if (!NT_SUCCESS(Status))
214  {
215  printf("NtDeviceIoControlFile(IOCTL_DISK_GET_DRIVE_GEOMETRY) failed! (Status 0x%lx)\n", Status);
216  }
217  else
218  {
219  pDiskGeometry = &DiskGeometry.Info;
220 
221 #ifdef DUMP_DATA
222  HexDump(&DiskGeometry.Info, (ULONG)Iosb.Information);
223 #endif
224  printf("IOCTL_DISK_GET_DRIVE_GEOMETRY\n"
225  "Cylinders: %I64u\nMediaType: 0x%x\nTracksPerCylinder: %lu\n"
226  "SectorsPerTrack: %lu\nBytesPerSector: %lu\n",
227  pDiskGeometry->Cylinders.QuadPart,
228  pDiskGeometry->MediaType,
229  pDiskGeometry->TracksPerCylinder,
230  pDiskGeometry->SectorsPerTrack,
231  pDiskGeometry->BytesPerSector);
232  }
233 
234 
235  /*
236  * Get the extended drive geometry.
237  */
238  printf("\n");
240  NULL,
241  NULL,
242  NULL,
243  &Iosb,
245  NULL,
246  0,
247  &DiskGeometry.InfoEx,
248  sizeof(DiskGeometry.InfoEx));
249  if (!NT_SUCCESS(Status))
250  {
251  printf("NtDeviceIoControlFile(IOCTL_DISK_GET_DRIVE_GEOMETRY_EX) failed! (Status 0x%lx)\n", Status);
252  }
253  else
254  {
255  // PDISK_DETECTION_INFO DiskDetectInfo = &DiskGeometry.InfoEx.Detection; // DiskGeometryGetDetect(&DiskGeometry.InfoEx);
256  // PDISK_PARTITION_INFO DiskPartInfo = &DiskGeometry.InfoEx.Partition; // DiskGeometryGetPartition(&DiskGeometry.InfoEx);
257  pDiskGeometry = &DiskGeometry.InfoEx.Geometry;
258 
259 #ifdef DUMP_DATA
260  HexDump(&DiskGeometry.InfoEx, (ULONG)Iosb.Information);
261 #endif
262  printf("IOCTL_DISK_GET_DRIVE_GEOMETRY_EX\n"
263  "Cylinders: %I64u\nMediaType: 0x%x\nTracksPerCylinder: %lu\n"
264  "SectorsPerTrack: %lu\nBytesPerSector: %lu\n"
265  "DiskSize: %I64u\n",
266  pDiskGeometry->Cylinders.QuadPart,
267  pDiskGeometry->MediaType,
268  pDiskGeometry->TracksPerCylinder,
269  pDiskGeometry->SectorsPerTrack,
270  pDiskGeometry->BytesPerSector,
271  DiskGeometry.InfoEx.DiskSize.QuadPart);
272 
273  printf("SizeOfDetectInfo: %lu DetectionType: %u (%s)\n",
274  DiskGeometry.InfoEx.Detection.SizeOfDetectInfo,
275  DiskGeometry.InfoEx.Detection.DetectionType,
276  DETECT_TYPE_NAME(DiskGeometry.InfoEx.Detection.DetectionType));
277  switch (DiskGeometry.InfoEx.Detection.DetectionType)
278  {
279  case DetectInt13:
280  {
281  PDISK_INT13_INFO pInt13 = &DiskGeometry.InfoEx.Detection.Int13;
282  printf(" DriveSelect: %u MaxCylinders: %lu SectorsPerTrack: %u MaxHeads: %u NumberDrives: %u\n",
283  pInt13->DriveSelect, pInt13->MaxCylinders,
284  pInt13->SectorsPerTrack, pInt13->MaxHeads,
285  pInt13->NumberDrives);
286  break;
287  }
288 
289  case DetectExInt13:
290  {
291  PDISK_EX_INT13_INFO pExInt13 = &DiskGeometry.InfoEx.Detection.ExInt13;
292  printf(" ExBufferSize: %u ExFlags: %u\n"
293  " ExCylinders: %lu ExHeads: %lu ExSectorsPerTrack: %lu\n"
294  " ExSectorsPerDrive: %I64u ExSectorSize: %u ExReserved: %u\n",
295  pExInt13->ExBufferSize, pExInt13->ExFlags,
296  pExInt13->ExCylinders, pExInt13->ExHeads,
297  pExInt13->ExSectorsPerTrack, pExInt13->ExSectorsPerDrive,
298  pExInt13->ExSectorSize, pExInt13->ExReserved);
299  break;
300  }
301 
302  case DetectNone:
303  default:
304  break;
305  }
306 
307  printf("SizeOfPartitionInfo: %lu PartitionStyle: %u [%s]\n",
308  DiskGeometry.InfoEx.Partition.SizeOfPartitionInfo,
309  DiskGeometry.InfoEx.Partition.PartitionStyle,
310  PARTITION_STYLE_NAME(DiskGeometry.InfoEx.Partition.PartitionStyle));
311 
312  if (DiskGeometry.InfoEx.Partition.PartitionStyle == PARTITION_STYLE_MBR)
313  {
314  printf(" Signature: 0x%08lx Checksum 0x%08lx\n",
315  DiskGeometry.InfoEx.Partition.Mbr.Signature,
316  DiskGeometry.InfoEx.Partition.Mbr.CheckSum);
317  }
318  else if (DiskGeometry.InfoEx.Partition.PartitionStyle == PARTITION_STYLE_GPT)
319  {
320  printf(" DiskId: {" GUID_FORMAT_STR "}\n",
321  GUID_ELEMENTS(&DiskGeometry.InfoEx.Partition.Gpt.DiskId));
322  }
323  else
324  {
325  /* Unknown */
326  printf("\n");
327  }
328  }
329 
330 
331  /*
332  * Display partition 0 (i.e. the whole disk) information.
333  */
334  printf("\n");
336  NULL,
337  NULL,
338  NULL,
339  &Iosb,
341  NULL,
342  0,
343  &PartInfo.Info,
344  sizeof(PartInfo.Info));
345  if (!NT_SUCCESS(Status))
346  {
347  printf("NtDeviceIoControlFile(IOCTL_DISK_GET_PARTITION_INFO) failed! (Status 0x%lx)\n", Status);
348  }
349  else
350  {
351  pPartInfo = &PartInfo.Info;
352 
353 #ifdef DUMP_DATA
354  HexDump(&PartInfo.Info, (ULONG)Iosb.Information);
355 #endif
356  printf("IOCTL_DISK_GET_PARTITION_INFO\n"
357  "nr: %ld boot: %1x type: 0x%x (%s) start: 0x%016I64x count: 0x%016I64x hidden: 0x%lx\n",
358  pPartInfo->PartitionNumber,
359  pPartInfo->BootIndicator,
360  pPartInfo->PartitionType,
361  pPartInfo->RecognizedPartition ? "Recognized" : "Not recognized",
362  pPartInfo->StartingOffset.QuadPart,
363  pPartInfo->PartitionLength.QuadPart,
364  pPartInfo->HiddenSectors);
365  }
366 
367  printf("\n");
369  NULL,
370  NULL,
371  NULL,
372  &Iosb,
374  NULL,
375  0,
376  &PartInfo.InfoEx,
377  sizeof(PartInfo.InfoEx));
378  if (!NT_SUCCESS(Status))
379  {
380  printf("NtDeviceIoControlFile(IOCTL_DISK_GET_PARTITION_INFO_EX) failed! (Status 0x%lx)\n", Status);
381  }
382  else
383  {
384  pPartInfoEx = &PartInfo.InfoEx;
385 
386 #ifdef DUMP_DATA
387  HexDump(&PartInfo.InfoEx, (ULONG)Iosb.Information);
388 #endif
389  printf("IOCTL_DISK_GET_PARTITION_INFO_EX\n");
390 
391  if (pPartInfoEx->PartitionStyle == PARTITION_STYLE_MBR)
392  {
393  printf("nr: %ld [%s] boot: %1x type: 0x%x (%s) start: 0x%016I64x count: 0x%016I64x hidden: 0x%lx\n",
394  pPartInfoEx->PartitionNumber,
395  PARTITION_STYLE_NAME(pPartInfoEx->PartitionStyle),
396  pPartInfoEx->Mbr.BootIndicator,
397  pPartInfoEx->Mbr.PartitionType,
398  pPartInfoEx->Mbr.RecognizedPartition ? "Recognized" : "Not recognized",
399  pPartInfoEx->StartingOffset.QuadPart,
400  pPartInfoEx->PartitionLength.QuadPart,
401  pPartInfoEx->Mbr.HiddenSectors);
402 #if (NTDDI_VERSION >= NTDDI_WINBLUE)
403  printf(" PartitionId: {" GUID_FORMAT_STR "}\n",
404  GUID_ELEMENTS(&pPartInfoEx->Mbr.PartitionId));
405 #endif
406  }
407  else if (pPartInfoEx->PartitionStyle == PARTITION_STYLE_GPT)
408  {
409  printf("nr: %ld [%s]\n"
410  " type : {" GUID_FORMAT_STR "}\n"
411  " id : {" GUID_FORMAT_STR "}\n"
412  " attrs: 0x%016I64x\n"
413  " name : '%.*S'\n"
414  " start: 0x%016I64x count: 0x%016I64x\n",
415  pPartInfoEx->PartitionNumber,
416  PARTITION_STYLE_NAME(pPartInfoEx->PartitionStyle),
417  GUID_ELEMENTS(&pPartInfoEx->Gpt.PartitionType),
418  GUID_ELEMENTS(&pPartInfoEx->Gpt.PartitionId),
419  pPartInfoEx->Gpt.Attributes,
420  (int)_countof(pPartInfoEx->Gpt.Name),
421  pPartInfoEx->Gpt.Name,
422  pPartInfoEx->StartingOffset.QuadPart,
423  pPartInfoEx->PartitionLength.QuadPart);
424  }
425  }
426 
427 
428  /*
429  * Retrieve the legacy partition layout
430  */
431  printf("\n");
432 
433  /* Allocate a layout buffer with initially 4 partition entries (or 16 for NEC PC-98) */
435  LayoutBuffer.Info = RtlAllocateHeap(RtlGetProcessHeap(),
437  BufferSize);
438  if (!LayoutBuffer.Info)
439  {
440  printf("Out of memory!");
441  goto Quit;
442  }
443 
444  /*
445  * Keep looping while the drive layout buffer is too small.
446  * Iosb.Information or PartitionCount only contain actual info only
447  * once NtDeviceIoControlFile(IOCTL_DISK_GET_DRIVE_LAYOUT) succeeds.
448  */
449  for (;;)
450  {
452  NULL,
453  NULL,
454  NULL,
455  &Iosb,
457  NULL,
458  0,
459  LayoutBuffer.Info,
460  BufferSize);
461  if (NT_SUCCESS(Status))
462  {
463  /* We succeeded; compactify the layout structure but keep the
464  * number of partition entries rounded up to a multiple of 4. */
465 #if 1
466  BufferSize = DRIVE_LAYOUT_INFO_SIZE(ROUND_UP_NUM(LayoutBuffer.Info->PartitionCount, 4));
467 #else
468  BufferSize = (ULONG)Iosb.Information;
469 #endif
470  ptr = RtlReAllocateHeap(RtlGetProcessHeap(),
472  LayoutBuffer.Info, BufferSize);
473  if (!ptr)
474  {
475  printf("Compactification failed; keeping original structure.\n");
476  }
477  else
478  {
479  LayoutBuffer.Info = ptr;
480  }
482  break;
483  }
484 
486  {
487  printf("NtDeviceIoControlFile(IOCTL_DISK_GET_DRIVE_LAYOUT) failed! (Status 0x%lx)\n", Status);
488 
489  /* Bail out if any other error than "invalid function" has been emitted.
490  * This happens for example when calling it on GPT disks. */
492  {
493  RtlFreeHeap(RtlGetProcessHeap(), 0, LayoutBuffer.Info);
494  goto Quit;
495  }
496  else
497  {
498  /* Just stop getting this information */
499  break;
500  }
501  }
502 
503  /* Reallocate the buffer by chunks of 4 entries */
505  ptr = RtlReAllocateHeap(RtlGetProcessHeap(),
507  LayoutBuffer.Info, BufferSize);
508  if (!ptr)
509  {
510  printf("Out of memory!");
511  RtlFreeHeap(RtlGetProcessHeap(), 0, LayoutBuffer.Info);
512  goto Quit;
513  }
514  LayoutBuffer.Info = ptr;
515  }
516 
517  if (Status == STATUS_SUCCESS)
518  {
519 #ifdef DUMP_DATA
520  HexDump(LayoutBuffer.Info, (ULONG)Iosb.Information);
521 #endif
522  printf("IOCTL_DISK_GET_DRIVE_LAYOUT\n"
523  "Partitions: %lu Signature: 0x%08lx\n",
524  LayoutBuffer.Info->PartitionCount,
525  LayoutBuffer.Info->Signature);
526 
527  for (i = 0; i < LayoutBuffer.Info->PartitionCount; i++)
528  {
529  pPartInfo = &LayoutBuffer.Info->PartitionEntry[i];
530 
531  printf(" %ld: nr: %ld boot: %1x type: 0x%x (%s) start: 0x%016I64x count: 0x%016I64x hidden: 0x%lx\n",
532  i,
533  pPartInfo->PartitionNumber,
534  pPartInfo->BootIndicator,
535  pPartInfo->PartitionType,
536  pPartInfo->RecognizedPartition ? "Recognized" : "Not recognized",
537  pPartInfo->StartingOffset.QuadPart,
538  pPartInfo->PartitionLength.QuadPart,
539  pPartInfo->HiddenSectors);
540  }
541  }
542  RtlFreeHeap(RtlGetProcessHeap(), 0, LayoutBuffer.Info);
543 
544 
545  /*
546  * Retrieve the extended partition layout
547  */
548  printf("\n");
549 
550  /* Allocate a layout buffer with initially 4 partition entries (or 16 for NEC PC-98) */
552  LayoutBuffer.InfoEx = RtlAllocateHeap(RtlGetProcessHeap(),
554  BufferSize);
555  if (!LayoutBuffer.InfoEx)
556  {
557  printf("Out of memory!");
558  goto Quit;
559  }
560 
561  /*
562  * Keep looping while the drive layout buffer is too small.
563  * Iosb.Information or PartitionCount only contain actual info only
564  * once NtDeviceIoControlFile(IOCTL_DISK_GET_DRIVE_LAYOUT_EX) succeeds.
565  */
566  for (;;)
567  {
569  NULL,
570  NULL,
571  NULL,
572  &Iosb,
574  NULL,
575  0,
576  LayoutBuffer.InfoEx,
577  BufferSize);
578  if (NT_SUCCESS(Status))
579  {
580  /* We succeeded; compactify the layout structure but keep the
581  * number of partition entries rounded up to a multiple of 4. */
582 #if 1
583  BufferSize = DRIVE_LAYOUT_INFOEX_SIZE(ROUND_UP_NUM(LayoutBuffer.InfoEx->PartitionCount, 4));
584 #else
585  BufferSize = (ULONG)Iosb.Information;
586 #endif
587  ptr = RtlReAllocateHeap(RtlGetProcessHeap(),
589  LayoutBuffer.InfoEx, BufferSize);
590  if (!ptr)
591  {
592  printf("Compactification failed; keeping original structure.\n");
593  }
594  else
595  {
596  LayoutBuffer.InfoEx = ptr;
597  }
599  break;
600  }
601 
603  {
604  printf("NtDeviceIoControlFile(IOCTL_DISK_GET_DRIVE_LAYOUT_EX) failed! (Status 0x%lx)\n", Status);
605 
606  /* Bail out if any other error than "invalid function" has been emitted */
608  {
609  RtlFreeHeap(RtlGetProcessHeap(), 0, LayoutBuffer.InfoEx);
610  goto Quit;
611  }
612  else
613  {
614  /* Just stop getting this information */
615  break;
616  }
617  }
618 
619  /* Reallocate the buffer by chunks of 4 entries */
621  ptr = RtlReAllocateHeap(RtlGetProcessHeap(),
623  LayoutBuffer.InfoEx, BufferSize);
624  if (!ptr)
625  {
626  printf("Out of memory!");
627  RtlFreeHeap(RtlGetProcessHeap(), 0, LayoutBuffer.InfoEx);
628  goto Quit;
629  }
630  LayoutBuffer.InfoEx = ptr;
631  }
632 
633  if (Status == STATUS_SUCCESS)
634  {
635 #ifdef DUMP_DATA
636  HexDump(LayoutBuffer.InfoEx, (ULONG)Iosb.Information);
637 #endif
638  printf("IOCTL_DISK_GET_DRIVE_LAYOUT_EX\n"
639  "PartitionStyle: %lu [%s]\n",
640  LayoutBuffer.InfoEx->PartitionStyle,
641  PARTITION_STYLE_NAME(LayoutBuffer.InfoEx->PartitionStyle));
642 
643  if (LayoutBuffer.InfoEx->PartitionStyle == PARTITION_STYLE_MBR)
644  {
645  printf("Partitions: %lu Signature: 0x%08lx",
646  LayoutBuffer.InfoEx->PartitionCount,
647  LayoutBuffer.InfoEx->Mbr.Signature);
648 #if (NTDDI_VERSION >= NTDDI_WIN10_RS1)
649  printf(" Checksum 0x%08lx\n",
650  LayoutBuffer.InfoEx->Mbr.CheckSum);
651 #else
652  printf("\n");
653 #endif
654 
655  for (i = 0; i < LayoutBuffer.InfoEx->PartitionCount; i++)
656  {
657  pPartInfoEx = &LayoutBuffer.InfoEx->PartitionEntry[i];
658 
659  printf(" %ld: nr: %ld [%s] boot: %1x type: 0x%x (%s) start: 0x%016I64x count: 0x%016I64x hidden: 0x%lx\n",
660  i,
661  pPartInfoEx->PartitionNumber,
662  PARTITION_STYLE_NAME(pPartInfoEx->PartitionStyle),
663  pPartInfoEx->Mbr.BootIndicator,
664  pPartInfoEx->Mbr.PartitionType,
665  pPartInfoEx->Mbr.RecognizedPartition ? "Recognized" : "Not recognized",
666  pPartInfoEx->StartingOffset.QuadPart,
667  pPartInfoEx->PartitionLength.QuadPart,
668  pPartInfoEx->Mbr.HiddenSectors);
669 #if (NTDDI_VERSION >= NTDDI_WINBLUE)
670  printf(" PartitionId: {" GUID_FORMAT_STR "}\n",
671  GUID_ELEMENTS(&pPartInfoEx->Mbr.PartitionId));
672 #endif
673  }
674  }
675  else if (LayoutBuffer.InfoEx->PartitionStyle == PARTITION_STYLE_GPT)
676  {
677  printf("Partitions: %lu MaxPartitionCount: %lu\n"
678  "DiskId: {" GUID_FORMAT_STR "}\n"
679  "StartingUsableOffset: 0x%016I64x UsableLength: 0x%016I64x\n",
680  LayoutBuffer.InfoEx->PartitionCount,
681  LayoutBuffer.InfoEx->Gpt.MaxPartitionCount,
682  GUID_ELEMENTS(&LayoutBuffer.InfoEx->Gpt.DiskId),
683  LayoutBuffer.InfoEx->Gpt.StartingUsableOffset.QuadPart,
684  LayoutBuffer.InfoEx->Gpt.UsableLength.QuadPart);
685 
686  for (i = 0; i < LayoutBuffer.InfoEx->PartitionCount; i++)
687  {
688  pPartInfoEx = &LayoutBuffer.InfoEx->PartitionEntry[i];
689 
690  printf(" %ld: nr: %ld [%s]\n"
691  " type : {" GUID_FORMAT_STR "}\n"
692  " id : {" GUID_FORMAT_STR "}\n"
693  " attrs: 0x%016I64x\n"
694  " name : '%.*S'\n"
695  " start: 0x%016I64x count: 0x%016I64x\n",
696  i,
697  pPartInfoEx->PartitionNumber,
698  PARTITION_STYLE_NAME(pPartInfoEx->PartitionStyle),
699  GUID_ELEMENTS(&pPartInfoEx->Gpt.PartitionType),
700  GUID_ELEMENTS(&pPartInfoEx->Gpt.PartitionId),
701  pPartInfoEx->Gpt.Attributes,
702  (int)_countof(pPartInfoEx->Gpt.Name),
703  pPartInfoEx->Gpt.Name,
704  pPartInfoEx->StartingOffset.QuadPart,
705  pPartInfoEx->PartitionLength.QuadPart);
706  }
707  }
708  }
709  RtlFreeHeap(RtlGetProcessHeap(), 0, LayoutBuffer.InfoEx);
710 
711 Quit:
712  CloseHandle(hDisk);
713  return 0;
714 }
#define IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
Definition: ntddk_ex.h:208
int main(int argc, char *argv[])
Definition: partinfo.c:112
static int argc
Definition: ServiceArgs.c:12
#define IN
Definition: typedefs.h:39
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
Definition: utclib.c:696
NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)
#define CloseHandle
Definition: compat.h:598
LARGE_INTEGER PartitionLength
Definition: ntdddisk.h:414
DISK_GEOMETRY Geometry
Definition: disk.c:3665
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define INVALID_HANDLE_VALUE
Definition: compat.h:590
GLuint buffer
Definition: glext.h:5915
ULONG BytesPerSector
Definition: ntdddisk.h:409
ULONG TracksPerCylinder
Definition: ntdddisk.h:407
NTSYSAPI NTSTATUS NTAPI NtDeviceIoControlFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG DeviceIoControlCode, IN PVOID InBuffer OPTIONAL, IN ULONG InBufferLength, OUT PVOID OutBuffer OPTIONAL, IN ULONG OutBufferLength)
int errno
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define swprintf
Definition: precomp.h:40
#define argv
Definition: mplay32.c:18
PARTITION_INFORMATION_MBR Mbr
Definition: imports.h:226
#define FILE_SHARE_READ
Definition: compat.h:136
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
LARGE_INTEGER DiskSize
Definition: disk.c:3666
struct _DISK_GEOMETRY_EX_INTERNAL DISK_GEOMETRY_EX_INTERNAL
uint32_t ULONG_PTR
Definition: typedefs.h:65
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:683
PARTITION_INFORMATION_GPT Gpt
Definition: imports.h:227
PARTITION_STYLE PartitionStyle
Definition: imports.h:220
#define DETECT_TYPE_NAME(DetectType)
Definition: partinfo.c:58
static PVOID ptr
Definition: dispmode.c:27
#define ROUND_UP_NUM(num, up)
Definition: partinfo.c:43
#define DRIVE_LAYOUT_INFOEX_SIZE(n)
Definition: partinfo.c:37
#define OPEN_EXISTING
Definition: compat.h:634
#define IsNEC_98
Definition: ketypes.h:899
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
Status
Definition: gdiplustypes.h:24
GLsizeiptr size
Definition: glext.h:5919
__wchar_t WCHAR
Definition: xmlstorage.h:180
return Iosb
Definition: create.c:4402
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
LARGE_INTEGER StartingOffset
Definition: ntdddisk.h:413
GLintptr offset
Definition: glext.h:5920
#define _countof(array)
Definition: sndvol32.h:68
LARGE_INTEGER Cylinders
Definition: ntdddisk.h:405
ULONG SectorsPerTrack
Definition: ntdddisk.h:408
void HexDump(PUCHAR buffer, ULONG size)
Definition: cmdcons.c:277
struct _DeviceInfo DeviceInfo
#define GUID_FORMAT_STR
Definition: partinfo.c:63
MEDIA_TYPE MediaType
Definition: ntdddisk.h:406
LARGE_INTEGER PartitionLength
Definition: imports.h:222
#define PARTITION_STYLE_NAME(PartStyle)
Definition: partinfo.c:52
#define DRIVE_LAYOUT_INFO_SIZE(n)
Definition: partinfo.c:30
#define GUID_ELEMENTS(Guid)
Definition: partinfo.c:64
LARGE_INTEGER StartingOffset
Definition: imports.h:221
#define IOCTL_DISK_GET_PARTITION_INFO
Definition: ntdddisk.h:106
static const WCHAR L[]
Definition: oid.c:1250
void Usage(void)
Definition: partinfo.c:107
#define GENERIC_READ
Definition: compat.h:135
static PCSTR PartitionStyleNames[]
Definition: partinfo.c:51
int puts(const char *string)
Definition: crtsupp.c:23
#define DRIVE_LAYOUT_INFO_ENTRY_SIZE
Definition: partinfo.c:27
static PCSTR DetectTypeNames[]
Definition: partinfo.c:57
#define IOCTL_DISK_GET_DRIVE_LAYOUT
Definition: ntdddisk.h:91
#define DRIVE_LAYOUT_INFOEX_ENTRY_SIZE
Definition: partinfo.c:34
#define IOCTL_DISK_GET_DRIVE_LAYOUT_EX
Definition: ntddk_ex.h:207
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define CreateFileW
Definition: compat.h:600
DISK_DETECTION_INFO Detection
Definition: disk.c:3668
DISK_PARTITION_INFO Partition
Definition: disk.c:3667
unsigned int ULONG
Definition: retypes.h:1
struct _DISK_GEOMETRY_EX_INTERNAL * PDISK_GEOMETRY_EX_INTERNAL
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T)
Definition: heap.c:2667
BOOLEAN RecognizedPartition
Definition: ntdddisk.h:419
const char * PCSTR
Definition: typedefs.h:52
#define STATUS_SUCCESS
Definition: shellext.h:65
#define HEAP_REALLOC_IN_PLACE_ONLY
Definition: nt_native.h:1696
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
#define IOCTL_DISK_GET_PARTITION_INFO_EX
Definition: ntddk_ex.h:206
#define BufferSize
Definition: mmc.h:75
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:251
LONGLONG QuadPart
Definition: typedefs.h:114
#define printf
Definition: config.h:203