+ if (DeviceIoControl(hDisk,
+ IOCTL_DISK_GET_DRIVE_LAYOUT,
+ NULL,
+ 0,
+ LayoutBuffer,
+ BufferSize,
+ &dwRead,
+ NULL))
+ {
+ dwLastError = ERROR_SUCCESS;
+ break;
+ }
+
+ dwLastError = GetLastError();
+ if (dwLastError != ERROR_INSUFFICIENT_BUFFER)
+ {
+ printf("DeviceIoControl(IOCTL_DISK_GET_DRIVE_LAYOUT) failed! Error: %lu\n",
+ dwLastError);
+
+ /* Bail out if any other error than "invalid function" has been emitted.
+ * This happens for example when calling it on GPT disks. */
+ if (dwLastError != ERROR_INVALID_FUNCTION)
+ {
+ free(LayoutBuffer);
+ CloseHandle(hDisk);
+ return 0;
+ }
+ else
+ {
+ /* Just stop getting this information */
+ break;
+ }
+ }
+
+ /* Reallocate the buffer */
+ BufferSize += 4 * sizeof(PARTITION_INFORMATION);
+ ptr = realloc(LayoutBuffer, BufferSize);
+ if (!ptr)
+ {
+ printf("Out of memory!");
+ free(LayoutBuffer);
+ CloseHandle(hDisk);
+ return 0;
+ }
+ LayoutBuffer = ptr;
+ memset(LayoutBuffer, 0, BufferSize);
+ }
+
+ if (dwLastError == ERROR_SUCCESS)
+ {
+#ifdef DUMP_DATA
+ HexDump(LayoutBuffer, dwRead);
+#endif
+
+ printf("IOCTL_DISK_GET_DRIVE_LAYOUT\n"
+ "Partitions: %lu Signature: 0x%08lx\n",
+ LayoutBuffer->PartitionCount,
+ LayoutBuffer->Signature);
+
+ for (i = 0; i < LayoutBuffer->PartitionCount; i++)
+ {
+ printf(" %ld: nr: %ld boot: %1x type: %x start: 0x%016I64x count: 0x%016I64x hidden: 0x%lx\n",
+ i,
+ LayoutBuffer->PartitionEntry[i].PartitionNumber,
+ LayoutBuffer->PartitionEntry[i].BootIndicator,
+ LayoutBuffer->PartitionEntry[i].PartitionType,
+ LayoutBuffer->PartitionEntry[i].StartingOffset.QuadPart,
+ LayoutBuffer->PartitionEntry[i].PartitionLength.QuadPart,
+ LayoutBuffer->PartitionEntry[i].HiddenSectors);
+ }
+