113{
121 union
122 {
125 } DiskGeometry;
127 union
128 {
131 } PartInfo;
134 union
135 {
137 PDRIVE_LAYOUT_INFORMATION_EX InfoEx;
138 } LayoutBuffer;
141
143 {
145 return 0;
146 }
147
150 {
151 printf(
"Error: Malformed drive number\n");
152 return 0;
153 }
154
155
156
157
163 {
164 printf(
"NtQuerySystemInformation() failed (Status 0x%lx)\n",
Status);
165 return 0;
166 }
168 {
169 printf(
"No disk drive installed!\n");
170 return 0;
171 }
172
174 {
175 printf(
"Invalid disk drive number! Valid drive numbers: [0-%lu]\n",
177 return 0;
178 }
179
180
181 swprintf(DriveName,
L"\\\\.\\PHYSICALDRIVE%lu", ulDrive);
182
183
189 0,
192 {
193 printf(
"Could not open drive!");
194 return 0;
195 }
196
197 printf(
"Drive number: %lu\n\n", ulDrive);
198
199
200
201
202
210 0,
211 &DiskGeometry.Info,
212 sizeof(DiskGeometry.Info));
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
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",
232 }
233
234
235
236
237
246 0,
247 &DiskGeometry.InfoEx,
248 sizeof(DiskGeometry.InfoEx));
250 {
251 printf(
"NtDeviceIoControlFile(IOCTL_DISK_GET_DRIVE_GEOMETRY_EX) failed! (Status 0x%lx)\n",
Status);
252 }
253 else
254 {
255
256
257 pDiskGeometry = &DiskGeometry.InfoEx.Geometry;
258
259#ifdef DUMP_DATA
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",
271 DiskGeometry.InfoEx.DiskSize.QuadPart);
272
273 printf(
"SizeOfDetectInfo: %lu DetectionType: %u (%s)\n",
274 DiskGeometry.InfoEx.Detection.SizeOfDetectInfo,
275 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,
311
313 {
314 printf(
" Signature: 0x%08lx Checksum 0x%08lx\n",
315 DiskGeometry.InfoEx.Partition.Mbr.Signature,
316 DiskGeometry.InfoEx.Partition.Mbr.CheckSum);
317 }
319 {
322 }
323 else
324 {
325
327 }
328 }
329
330
331
332
333
342 0,
343 &PartInfo.Info,
344 sizeof(PartInfo.Info));
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
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",
365 }
366
375 0,
376 &PartInfo.InfoEx,
377 sizeof(PartInfo.InfoEx));
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
388#endif
389 printf(
"IOCTL_DISK_GET_PARTITION_INFO_EX\n");
390
392 {
393 printf(
"nr: %ld [%s] boot: %1x type: 0x%x (%s) start: 0x%016I64x count: 0x%016I64x hidden: 0x%lx\n",
402#if (NTDDI_VERSION >= NTDDI_WINBLUE)
405#endif
406 }
408 {
412 " attrs: 0x%016I64x\n"
413 " name : '%.*S'\n"
414 " start: 0x%016I64x count: 0x%016I64x\n",
424 }
425 }
426
427
428
429
430
432
433
438 if (!LayoutBuffer.Info)
439 {
441 goto Quit;
442 }
443
444
445
446
447
448
449 for (;;)
450 {
458 0,
459 LayoutBuffer.Info,
462 {
463
464
465#if 1
467#else
469#endif
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
490
492 {
493 RtlFreeHeap(RtlGetProcessHeap(), 0, LayoutBuffer.Info);
494 goto Quit;
495 }
496 else
497 {
498
499 break;
500 }
501 }
502
503
509 {
511 RtlFreeHeap(RtlGetProcessHeap(), 0, LayoutBuffer.Info);
512 goto Quit;
513 }
514 LayoutBuffer.Info =
ptr;
515 }
516
518 {
519#ifdef DUMP_DATA
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",
540 }
541 }
542 RtlFreeHeap(RtlGetProcessHeap(), 0, LayoutBuffer.Info);
543
544
545
546
547
549
550
555 if (!LayoutBuffer.InfoEx)
556 {
558 goto Quit;
559 }
560
561
562
563
564
565
566 for (;;)
567 {
575 0,
576 LayoutBuffer.InfoEx,
579 {
580
581
582#if 1
584#else
586#endif
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
608 {
609 RtlFreeHeap(RtlGetProcessHeap(), 0, LayoutBuffer.InfoEx);
610 goto Quit;
611 }
612 else
613 {
614
615 break;
616 }
617 }
618
619
625 {
627 RtlFreeHeap(RtlGetProcessHeap(), 0, LayoutBuffer.InfoEx);
628 goto Quit;
629 }
630 LayoutBuffer.InfoEx =
ptr;
631 }
632
634 {
635#ifdef DUMP_DATA
637#endif
638 printf(
"IOCTL_DISK_GET_DRIVE_LAYOUT_EX\n"
639 "PartitionStyle: %lu [%s]\n",
640 LayoutBuffer.InfoEx->PartitionStyle,
642
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
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",
669#if (NTDDI_VERSION >= NTDDI_WINBLUE)
672#endif
673 }
674 }
676 {
677 printf(
"Partitions: %lu MaxPartitionCount: %lu\n"
679 "StartingUsableOffset: 0x%016I64x UsableLength: 0x%016I64x\n",
680 LayoutBuffer.InfoEx->PartitionCount,
681 LayoutBuffer.InfoEx->Gpt.MaxPartitionCount,
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"
693 " attrs: 0x%016I64x\n"
694 " name : '%.*S'\n"
695 " start: 0x%016I64x count: 0x%016I64x\n",
706 }
707 }
708 }
709 RtlFreeHeap(RtlGetProcessHeap(), 0, LayoutBuffer.InfoEx);
710
711Quit:
713 return 0;
714}
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
void HexDump(PUCHAR buffer, ULONG size)
#define NT_SUCCESS(StatCode)
#define INVALID_HANDLE_VALUE
#define IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
#define IOCTL_DISK_GET_PARTITION_INFO_EX
#define IOCTL_DISK_GET_DRIVE_LAYOUT_EX
@ SystemDeviceInformation
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
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T)
#define DRIVE_LAYOUT_INFO_SIZE(n)
#define ROUND_UP_NUM(num, up)
#define GUID_ELEMENTS(Guid)
#define DETECT_TYPE_NAME(DetectType)
#define DRIVE_LAYOUT_INFOEX_SIZE(n)
#define PARTITION_STYLE_NAME(PartStyle)
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)
#define HEAP_REALLOC_IN_PLACE_ONLY
#define IOCTL_DISK_GET_DRIVE_LAYOUT
#define IOCTL_DISK_GET_PARTITION_INFO
#define STATUS_BUFFER_TOO_SMALL
NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)
#define STATUS_INVALID_DEVICE_REQUEST
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize