ctypes.cast von DRIVE_LAYOUT_INFORMATION_EX
Verfasst: Montag 14. Januar 2013, 09:23
Hallo,
ich versuche mich gerade am Auslesen von Informationen einer Festplatte unter Windows. Hierzu benutze ich die Funktion win32file.DeviceIoControl mit dem ControlCode: IOCTL_DISK_GET_DRIVE_LAYOUT_EX
Als Antwort bekommt man eine Bytestruktur in C. Diese wandle ich mit ctypes.cast( ... ) in meine Struktur um. Laut Microsoft hat die Zielstruktur folgende Gestaltung:
Mein Problem bezieht sich jetzt auf das letzte Element der Struktur: PARTITION_INFORMATION_EX, welche laut Microsoft ein dynamisches Array sein soll. Ähnliche Strukturen mit POINTER für den Umgang mit dynamischen Arrays habe ich ebenfalls schon probiert, aber auch hier ist das Ergebnis das gleiche.
Ich gestalte die Struktur in Python folgendermaßen:
Der Cast sieht wie folgt aus:
Im Test sieht das Ganze wie folgt aus:
Dieser Text läuft auch super durch, ich kann auch auf die Partitionsinformationen wunderbar zugreifen, allerdings ist in diesem Array nur der erste Eintrag korrekt, die weiteren sind alle vollkommen fehlerhaft.
Meine Fragen: Verstehe ich die Struktur von Microsoft falsch bzw. setze ich das ganze dadurch falsch um? Bzw. wie soll der Cast dann korrekterweise sein?
Für Hilfe in jeder Art und Weise bin ich sehr dankbar.
vG ativ
ich versuche mich gerade am Auslesen von Informationen einer Festplatte unter Windows. Hierzu benutze ich die Funktion win32file.DeviceIoControl mit dem ControlCode: IOCTL_DISK_GET_DRIVE_LAYOUT_EX
Als Antwort bekommt man eine Bytestruktur in C. Diese wandle ich mit ctypes.cast( ... ) in meine Struktur um. Laut Microsoft hat die Zielstruktur folgende Gestaltung:
Code: Alles auswählen
typedef struct _DRIVE_LAYOUT_INFORMATION_EX {
DWORD PartitionStyle;
DWORD PartitionCount;
union {
DRIVE_LAYOUT_INFORMATION_MBR Mbr;
DRIVE_LAYOUT_INFORMATION_GPT Gpt;
};
PARTITION_INFORMATION_EX PartitionEntry[1];
} DRIVE_LAYOUT_INFORMATION_EX, *PDRIVE_LAYOUT_INFORMATION_EX;Ich gestalte die Struktur in Python folgendermaßen:
Code: Alles auswählen
class DRIVE_LAYOUT_INFORMATION_EX(ctypes.Structure):
'''
DRIVE_LAYOUT_INFORMATION_EX structure
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364001(v=vs.85).aspx
'''
_anonymous_ = ("DriveLayoutInformation", )
_fields_ = [("PartitionStyle", wintypes.DWORD),
("PartitionCount", wintypes.DWORD),
("DriveLayoutInformation",DriveLayoutInformation),
("PartitionEntry", wintypes.BYTE*8912)]
def getPartitionEntries(self):
byteStructure = self.PartitionEntry
print(byteStructure)
return ctypes.cast(byteStructure, ctypes.POINTER(ctypes.ARRAY(PARTITION_INFORMATION_EX, self.PartitionCount))).contentsCode: Alles auswählen
def getDriveLayout_EX(driveHandle):
if driveHandle == win32file.INVALID_HANDLE_VALUE:
print("Invalid Handle Value!")
return None
answerByteStructure = win32file.DeviceIoControl(driveHandle.getWin32Handle(), winioctlcon.IOCTL_DISK_GET_DRIVE_LAYOUT_EX, None, 8192)
temp = ctypes.cast(answerByteStructure, ctypes.POINTER(DRIVE_LAYOUT_INFORMATION_EX)).contents
return tempCode: Alles auswählen
handle = DriveHandle("0")
try:
driveGeometry = DeviceIOControl.getDriveGeometry_EX(handle)
finally:
handle.destroy()
print("Disk Size: " +str(driveGeometry.DiskSize))
print("BytesPerSector: "+str(driveGeometry.Geometry.BytesPerSector))
print("SectorsPerTrack: "+str(driveGeometry.Geometry.SectorsPerTrack))
print("TracksPerCylinders: "+str(driveGeometry.Geometry.TracksPerCylinder))
print("Cylinders: "+str(driveGeometry.Geometry.Cylinders))
print("MediaType: "+str(hex(driveGeometry.Geometry.MediaType)))
print("CtypesAddressOf: "+str(ctypes.addressof(driveGeometry)))
print("=====DriveLayout=====")
handle = DriveHandle("0")
try:
driveLayout = DeviceIOControl.getDriveLayout_EX(handle)
finally:
handle.destroy()
print("PartitionCount: "+str(driveLayout.PartitionCount))
print("PartitionStyle: "+str(DeviceIOControl.PartitionStyle[driveLayout.PartitionStyle]))
print("-----------------------")
partitionEntries = driveLayout.getPartitionEntries()
print("PartitionEntries: "+str(partitionEntries))
for index in range(driveLayout.PartitionCount):
print("\n index:"+str(index))
print("PartitionStyle: "+str(partitionEntries[index].PartitionStyle))
print("StartingOffset: "+str(partitionEntries[index].StartingOffset))
print("PartitionLength: "+str(partitionEntries[index].PartitionLength))
print("PartitionNumber: "+str(partitionEntries[index].PartitionNumber))
print("RewritePartition: "+str(partitionEntries[index].RewritePartition))Meine Fragen: Verstehe ich die Struktur von Microsoft falsch bzw. setze ich das ganze dadurch falsch um? Bzw. wie soll der Cast dann korrekterweise sein?
Für Hilfe in jeder Art und Weise bin ich sehr dankbar.
vG ativ