Ermitteln, welche Partition auf welcher Platte ist

Dalai

Grand Admiral Special
Mitglied seit
14.06.2004
Beiträge
7.420
Renomée
262
Standort
Meiningen, Thüringen
Hallo Leute,

ich möchte auf irgendeine Weise herausbekommen, welche Partition (LW C:, D:, E: usw) auf welcher physikalischen Platte liegt. Genauer gesagt geht's mir darum, zu ermitteln, ob eine gegebene Partition (z.B. LW X) auf derselben physikalischen Platte liegt wie die Systempartition bzw. LW C:. Gibt's da passende Windows-API-Funktionen, die mir dabei weiterhelfen können? Programmiersprache ist mir erstmal egal. Umwege über Seriennummern der Partitionen gehen auch, wenn es nur irgendwie möglich ist.

Ich hab schon mit BGinfo geschaut, ob mir WMI weiterhelfen kann, aber bisher hab ich nichts Passendes gefunden.

Ich weiß nur, dass es irgendwie gehen muss, denn HD Tune macht das ja auch: im oberen Bereich sind die phys. Platten gelistet und weiter unten dann die dazugehörigen Partitionen.

MfG Dalai
 
Hallo Leute,

ich möchte auf irgendeine Weise herausbekommen, welche Partition (LW C:, D:, E: usw) auf welcher physikalischen Platte liegt. Genauer gesagt geht's mir darum, zu ermitteln, ob eine gegebene Partition (z.B. LW X) auf derselben physikalischen Platte liegt wie die Systempartition bzw. LW C:. Gibt's da passende Windows-API-Funktionen, die mir dabei weiterhelfen können? Programmiersprache ist mir erstmal egal. Umwege über Seriennummern der Partitionen gehen auch, wenn es nur irgendwie möglich ist.

Ich hab schon mit BGinfo geschaut, ob mir WMI weiterhelfen kann, aber bisher hab ich nichts Passendes gefunden.

Ich weiß nur, dass es irgendwie gehen muss, denn HD Tune macht das ja auch: im oberen Bereich sind die phys. Platten gelistet und weiter unten dann die dazugehörigen Partitionen.

MfG Dalai

Zeigt die Datenträgerverwaltung so etwas nicht an?
 
Also es gibt da Möglichkeiten. Ist leider schon zu lange her, als dass ich mich noch an Details erinnern könnte, aber mit DeviceIoControl und den Disk Management Control Codes sollte es irgendwie gehen. Zum Ausführen sind vermutlich mind. lokale Admin-Rechte notwendig.
 
Mmh, das IOCTL_DISK_GET_DRIVE_LAYOUT_EX sieht schonmal nicht schlecht aus. Nur soll das laut MS erst ab XP funktionieren, ich brauch es aber auch für Win2k... OK, das IOCTL_DISK_GET_DRIVE_LAYOUT soll ab Win2k tun.

Damit hätte ich dann schonmal Infos über die Partitionierung. Wie komme ich dann in Richtung Laufwerksbuchstaben?

Ich hab noch was anderes gefunden: FindFirstVolume. In Zusammenarbeit mit FindFirstVolumeMountPoint könnte das zum Ziel führen.

BoMbY schrieb:
Zum Ausführen sind vermutlich mind. lokale Admin-Rechte notwendig.
Das ist kein Problem, weil für die Operation sowieso schon Admin-Rechte vorhanden sind.

MfG Dalai
 
Ja, das IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS scheint noch besser geeignet zu sein. Ich hab das jetzt mal in Delphi und AutoIt implementiert, wobei ich es in letzterem eher brauche. Kann da mal jemand drüberschauen, ob da (grobe) Fehler drin sind?

Code:
#include <array.au3>
#include <WINAPI.au3>

global const $DRIVES[26] = ['C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', _
                            'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']

global const $IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS = 0x00560000
global const $ERROR_INVALID_HANDLE = 0xFFFFFFFF
Dim $bytes, $msg = ""

for $i=0 to UBound($DRIVES)-1
    if StringUpper(DriveGetType($DRIVES[$i] & ":\")) == "FIXED" then
        $handle = _APIFileOpen(StringFormat("\\\\.\\%s:", $DRIVES[$i]))
    
        if ($handle <> 0) AND ($handle <> $ERROR_INVALID_HANDLE) then
            $s = DllStructCreate("byte[100]")
            if $s <> 0 then
                $ret = Dllcall("kernel32.dll", "int", "DeviceIoControl", _
                               "hwnd", $handle, _
                               "int", $IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, _
                               "ptr", 0, _
                               "int", 0, _
                               "ptr", DllStructGetPtr($s), _
                               "int", DllStructGetSize($s), _
                               "int*", $bytes, _
                               "ptr",0)
                ;~ _ArrayDisplay($ret)
                if @error == 0 then
                    $Res = BinaryMid(DllStructGetData($s, 1), 1, $ret[7])
                    $Res = Number(BinaryMid($Res, 9, 1))
    
                    $msg &= StringFormat("%s: %s\n", $DRIVES[$i], $Res)
                EndIf
            EndIf
            _APIFileClose($handle)
        EndIf
    EndIf
Next

MsgBox(0, "", $msg)

Exit

; _APIFileOpen( <FileName> )
;
; Returns a "REAL" file handle for reading and writing.
; The return value comes directly from "CreateFile" api.
Func _APIFileOpen( $szFile )
    Return _WinAPI_CreateFile($szFile, $OPEN_EXISTING, $GENERIC_READ OR $GENERIC_WRITE, $FILE_SHARE_READ + $FILE_SHARE_Write);,$FILE_ATTRIBUTE_NORMAL)
EndFunc


; _APIFileClose( <FileHandle> )
;
; The return value comes directly from "CloseHandle" api.
Func _APIFileClose( $hFile )
    Return _WinAPI_CloseHandle($hFile)
EndFunc
Ich finde vor allem den Zugriff auf das neunte Byte nicht so prickelnd, weil es evtl. nicht zuverlässig ist. Nur sind die für diese Funktion genutzten Datenstrukturen so kompliziert, dass man sich einen Knoten ins Hirn macht, wenn man das im AutoIt versucht nachzubilden. Wenn jemand eine bessere Idee hat, dann her damit ;).

Korrekte Ausgabe meines Servers, der 2 Platten hat:
Code:
C: 0
D: 0
E: 0
N: 1

MfG Dalai
 
Zurück
Oben Unten