Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Partition zu phys. LW? (https://www.delphipraxis.net/196724-partition-zu-phys-lw.html)

Mattze 12. Jun 2018 19:40

Partition zu phys. LW?
 
Hi,

ich hab' da mal 'ne Frage - die ich schon sehr lange habe:
Kennt jemand eine (möglichst direkte) Variante, zu welchem physischen Laufwerk eine Partition gehört?

Indirekit habe ich das (alle phys. LW und alle Partitionen auf diesen auslesen und vergleichen), aber möglichst direkt und nicht als Admin?

Gruß
Mattze

KodeZwerg 12. Jun 2018 19:56

AW: Partition zu phys. LW?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Delphi-Quellcode:
program test;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  ActiveX,
  ComObj,
  Variants;

procedure Main;
const
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator    : OLEVariant;
  FWMIService      : OLEVariant;
  wmiDiskDrives    : OLEVariant;
  wmiDiskPartitions : OLEVariant;
  wmiLogicalDisks  : OLEVariant;
  wmiDiskDrive     : OLEVariant;
  wmiDiskPartition : OLEVariant;
  wmiLogicalDisk   : OLEVariant;
  oEnum            : IEnumvariant;
  oEnum2            : IEnumvariant;
  oEnum3            : IEnumvariant;
  iValue           : LongWord;
  DeviceID         : string;
begin;
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService  := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
  //Get the physical disk drive
  wmiDiskDrives := FWMIService.ExecQuery('SELECT Caption, DeviceID FROM Win32_DiskDrive','WQL',wbemFlagForwardOnly);
  oEnum        := IUnknown(wmiDiskDrives._NewEnum) as IEnumVariant;
  while oEnum.Next(1, wmiDiskDrive, iValue) = 0 do
  begin
     //Use the disk drive device id to find associated partition
     DeviceID:=StringReplace(String(wmiDiskDrive.DeviceID),'\','\\',[rfReplaceAll]);
     wmiDiskPartitions := FWMIService.ExecQuery('ASSOCIATORS OF {Win32_DiskDrive.DeviceID="'+DeviceID+'"} WHERE AssocClass = Win32_DiskDriveToDiskPartition','WQL',wbemFlagForwardOnly);
     oEnum2          := IUnknown(wmiDiskPartitions._NewEnum) as IEnumVariant;
     while oEnum2.Next(1, wmiDiskPartition, iValue) = 0 do
     begin
        wmiLogicalDisks := FWMIService.ExecQuery('ASSOCIATORS OF {Win32_DiskPartition.DeviceID="'+String(wmiDiskPartition.DeviceID)+'"} WHERE AssocClass = Win32_LogicalDiskToPartition','WQL',wbemFlagForwardOnly);
        oEnum3          := IUnknown(wmiLogicalDisks._NewEnum) as IEnumVariant;
        while oEnum3.Next(1, wmiLogicalDisk, iValue) = 0 do
        begin
          Writeln(Format('Drive letter associated with disk drive %s %s Partition %s is %s',[String(wmiDiskDrive.Caption),String(wmiDiskDrive.DeviceID),String(wmiDiskPartition.DeviceID),String(wmiLogicalDisk.DeviceID)]));
          wmiLogicalDisk:=Unassigned;
        end;
       wmiDiskPartition:=Unassigned;
     end;
    wmiDiskDrive:=Unassigned;
    Writeln;
  end;
end;

begin
 try
    CoInitialize(nil);
    try
      Main;
    finally
      CoUninitialize;
    end;
 except
    on E:EOleException do
        Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode]));
    on E:Exception do
        Writeln(E.Classname, ':', E.Message);
 end;
 Writeln('Press Enter to exit');
 Readln;
end.
Das macht exakt was Du möchtest.

Im Anhang Binary plus Source.


Ps: Ob man Admin-Rechte braucht oder nicht teste bitte selber, da enthalte ich mich.

Mattze 12. Jun 2018 20:11

AW: Partition zu phys. LW?
 
Hi,

vielen Dank für die schnelle Amtwort. Auf WMI hätte ich auch selber kommen müssen, aber manchmal sieht ma eben den Wald vor lauter Bäumen nicht.

Das ist eine der "indirekten" Varianten.

Fragestellung:

Ich habe Partition J:. Auf welchem phys. Laufwerk ist die?

Die indirekte Variante: Man sucht alle physischen Laufwerke und deren Partitionen zusammen und vergleicht, wo Partition J: ist. Dann hat man das Ergebnis.
Ich gehe aber davon aus, dass das eigentlich sehr oft (vom IO-System) gebraucht wird und es daher eine schnellere direkte Variante gibt.

Gibt es sowas?

Gruß
Mattze

KodeZwerg 12. Jun 2018 20:22

AW: Partition zu phys. LW?
 
Ich Verstehe die Frage nicht ganz.
Der Source da oben gibt Dir alle Verbauten PHYSICALDRIVEs plus jeweils die zugehörigen Partitions-Nummer + Driveletter (#0 #1 #2 usw <-> C: D: E: usw)
Reicht das nicht aus um das zu basteln was Du möchtest?

Mattze 12. Jun 2018 20:35

AW: Partition zu phys. LW?
 
Hi,

natürlich reicht das auch.
Ich habe nur die umgekehrte Fragestellung.
Wie Du selber schreibst:
Zuerst (!) kriegst Du die physischen LWs, dann die Partitionsnummer und dann den Driveletter.

Ich möchte es genau anderschrum:
Ich habe den Driveletter und möchte von dem ausgehend (!) das physische LW kriegen.
(Und nicht über Deinen Weg mit Vergleich des Driveletters!)

Gruß
Mattze

PS: Dein WMI-Weg klappt übrigens ohne ADMIN-Rechte.

KodeZwerg 12. Jun 2018 20:54

AW: Partition zu phys. LW?
 
Ok ich verstehe, ich tüftel mal was... bis gleich :=)

Basilikum 12. Jun 2018 22:07

AW: Partition zu phys. LW?
 
hier würde sich IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS anbieten (eine Partition kann auch auf mehreren physischen Disk liegen)

KodeZwerg 12. Jun 2018 23:24

AW: Partition zu phys. LW?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Basilikum (Beitrag 1404676)
hier würde sich IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS anbieten

Stimmt!

Im Anhang ist ein komplett Lauffähiges mini-Programm was nur eine Sache macht,
es listet auf Knopfdruck alle DriveLetters auf mit den dazu gehörigen Infos.

Laufwerk Letter Typ Schreibstatus ges.Größe freieGröße Seriennummer Label

Was Dich Interessieren wird ist
Delphi-Quellcode:
function GetPhysicalDiskNumber(Drive: Char): Integer;
das.
Diese Funktion macht folgendes, übergebe Ihr ein Letter und Du erhälst die Laufwerksnummer.
Das war es doch was Du wolltest, richtig?

Binary plus Source im Anhang.

Ps: Alles Winapi und nicht WMI.
Pps: Da hier nicht über Volumes gegangen wird bleiben versteckte Partitionen weiterhin versteckt.

Achso, und wenn CD/DVD Laufwerke connected sind, die bekommen als Laufwerk die Nummer 255.

Mattze 13. Jun 2018 06:09

AW: Partition zu phys. LW?
 
Guten Morgen!

Wunderbar! Genau das war es. Indirekt habe ich das hinbekommen, aber es hat mich immer gestört, dass es da nichts direktes geben soll.
Und das schon eine ziemliche Weile!

Vielen Dank!

Gruß
Mattze

KodeZwerg 13. Jun 2018 07:43

AW: Partition zu phys. LW?
 
Ja gern geschehen, wenn Du Dir den Source anschaust, es ist nicht gerade einfach so etwas simples wie das was Du wolltest umzusetzen. Freut mich wenn es passt. Viel Erfolg mit Deinem Projekt!

Ps: Immer noch meinerseits nicht bestätigt Deine Bitte von wegen ohne Admin, das teste bitte selbst.

markus5766h 14. Jun 2018 19:40

AW: Partition zu phys. LW?
 
Liste der Anhänge anzeigen (Anzahl: 2)
... Admin-Rechte bei mir notwendig ...
aber warum wird mein USb-Stick (K - 32GU2) zur Floppy ? (siehe Anhang)

KodeZwerg 14. Jun 2018 19:48

AW: Partition zu phys. LW?
 
Delphi-Quellcode:
  FUNCTION GetDriveTypeString(CONST DriveType: TDriveType): STRING;
  BEGIN
    CASE DriveType OF
      dtFloppy : RESULT := 'Floppy';
      dtFixed : RESULT := 'Fixed';
      dtNetwork: RESULT := 'Network';
      dtCDROM : RESULT := 'CDROM';
      dtRAM   : RESULT := 'RAM';
      ELSE       RESULT := 'Unknown'
    END
  END;
Das TDriveType muss noch mit der WinApi Ersetzt werden, mein Fehler!! Danke. Auch für testen wegen Admin-Rechte!

Frage: Hast Du die .exe per Source per IDE aufgerufen oder einfach im Explorer mein Kompilat? Weil Eigentlich CD/DVD/BD-Laufwerke eine 255 haben sollten (Wert -1).

markus5766h 14. Jun 2018 19:52

AW: Partition zu phys. LW?
 
hab' das Kompilat benutzt.

KodeZwerg 14. Jun 2018 20:03

AW: Partition zu phys. LW?
 
Danke für diese Information, dann sinds zwei Baustellen, ich werde es fixen.

EWeiss 14. Jun 2018 20:13

AW: Partition zu phys. LW?
 
Zitat:

Zitat von KodeZwerg (Beitrag 1404869)
Danke für diese Information, dann sinds zwei Baustellen, ich werde es fixen.

Zudem solltest du mal deine Rückgabe werte prüfen Integer <> Cardinal
Da ist einiges im argen.

gruss

KodeZwerg 14. Jun 2018 20:21

AW: Partition zu phys. LW?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Fixed.
Delphi-Quellcode:
function GetDriveTypeString(DriveByte: Byte): String;
begin
  case GetDriveType(PChar(Chr(DriveByte + Ord('A')) + ':\')) of
    DRIVE_UNKNOWN: Result := 'Unknown';
    DRIVE_NO_ROOT_DIR: Result := 'not Mounted';
    DRIVE_REMOVABLE: Result := 'Removable';
    DRIVE_FIXED: Result := 'Fixed';
    DRIVE_REMOTE: Result := 'Network';
    DRIVE_CDROM: Result := 'CDROM';
    DRIVE_RAMDISK: Result := 'RAM';
  else
    Result := 'Other';
  end;
end;
Du kannst Byte mit Cardinal austauschen, es sollte aber nicht nötig sein. (Byte 1 - 6 sind gültige Ziele, alles andere ist noch nicht in Delphi 2009 vorhanden und MSDN gibt auch 6 als höchsten Zähler an, beim Api Aufruf nutze ich ein Cardinal und als Laufwerk sollte 26 die Höchste Zahl sein wenn ich mich nicht Irre?)

Bitte testen, Danke!

EWeiss 14. Jun 2018 20:26

AW: Partition zu phys. LW?
 
Zitat:

beim Api Aufruf nutze ich ein Cardinal)
Und was bringt das wenn du am ende doch einen Integer zurück gibst seltsam, aber gut mach wie du willst.
Korrekt ist das nicht.

gruss

KodeZwerg 14. Jun 2018 20:32

AW: Partition zu phys. LW?
 
Von welcher Zeile im Code redest Du? Poste bitte was alles falsch sein soll, ich kann das gerade nicht zuordnen, vielen Dank für mühe!

EWeiss 14. Jun 2018 21:09

AW: Partition zu phys. LW?
 
Zitat:

Zitat von KodeZwerg (Beitrag 1404875)
Von welcher Zeile im Code redest Du? Poste bitte was alles falsch sein soll, ich kann das gerade nicht zuordnen, vielen Dank für mühe!

Delphi-Quellcode:
function GetPhysicalDiskNumber(Drive: Char): Integer; // Integer

  function GetLD(Drive: Char): Cardinal; // Result Cardinal
    var
      Buffer : String;
    begin
      Buffer := Format('\\.\%s:',[Drive]);
      Result := CreateFile(PChar(Buffer), GENERIC_READ,
                           FILE_SHARE_READ or FILE_SHARE_WRITE,
                           nil, OPEN_EXISTING, 0, 0); // Result Cardinal
      Win32Check(Result <> INVALID_HANDLE_VALUE); // Result Cardinal
    end;
//...
      DiskExtents := AllocMem(Max_Path);
      try
        DeviceIOControl(LD,IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,nil,0,DiskExtents,Max_Path,BytesReturned,nil);
        If DiskExtents^.NumberOfDiskExtents > 0 Then
        begin
          DiskExtent := DiskExtents^.Extents[0];
          Result := DiskExtent.DiskNumber; // Result Cardinal und du gibst Integer zurück!
        end;
      finally
        FreeMem(DiskExtents);
      end;
gruss

KodeZwerg 14. Jun 2018 21:23

AW: Partition zu phys. LW?
 
ahhhh ok, habs jetzt gerafft!
Code:
function GetPhysicalDiskNumber(Drive: Char): Cardinal;
So ist es nu aber fixed, oder?


und PS: Vielen lieben Dank fürs draufschauen und vor allem bemerken, da das Record ja passte, flüchtigkeitsfehler tut mir leid!

EWeiss 14. Jun 2018 21:29

AW: Partition zu phys. LW?
 
Zitat:

Zitat von KodeZwerg (Beitrag 1404880)
ahhhh ok, habs jetzt gerafft!
Code:
function GetPhysicalDiskNumber(Drive: Char): Cardinal;
So ist es nu aber fixed, oder?

yep :)

gruss

KodeZwerg 14. Jun 2018 21:50

AW: Partition zu phys. LW?
 
Soll das so sein?
GetDriveType function
Zitat:

DRIVE_REMOVABLE - The drive has removable media; for example, a floppy drive, thumb drive, or flash card reader.
DRIVE_FIXED - The drive has fixed media; for example, a hard disk drive or flash drive.
Zum trennen von intern und extern muss ich da glaube ich mehr Infos einbeziehen damit aus einem Usb-Stick/Drive ein Removable wird. Mist.

Oder ist es fachlich korrekt ein Usb-Stick/Drive als Fixed zu bezeichnen?

Zitat:

Zitat von KodeZwerg (Beitrag 1404880)
und PS: Vielen lieben Dank fürs draufschauen und vor allem bemerken, da das Record ja passte, flüchtigkeitsfehler tut mir leid!

Falls es nicht mehr ankam weil ich im Edit verweilte ^_^

p80286 14. Jun 2018 22:07

AW: Partition zu phys. LW?
 
Zitat:

Zitat von KodeZwerg (Beitrag 1404882)
Zum trennen von intern und extern muss ich da glaube ich mehr Infos einbeziehen damit aus einem Usb-Stick/Drive ein Removable wird.

Unter W7 ist ein USB-Stick
Code:
DRIVE_REMOVABLE
.
U.U. hilft Dir
Code:
IOCTL_STORAGE_GET_HOTPLUG_INFO
weiter.

Gruß
K-H

KodeZwerg 14. Jun 2018 23:09

AW: Partition zu phys. LW?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von p80286 (Beitrag 1404886)
U.U. hilft Dir
Code:
IOCTL_STORAGE_GET_HOTPLUG_INFO
weiter.

100pro :thumb: (IOCTL_STORAGE_QUERY_PROPERTY)

Ich habe es unelegant so gelöst, es wird nach wie vor Winapi GetDriveType verwendet für "Grund-Info" und einen "@Bustyp" rangehangen.
Super Tipp von Dir, 1A!

(insgeheim hoffe ich das ich a) keine neuen Fehler drinnen habe und b) es Final ist)

Binary plus Source im Anhang.

Ps: Habe auch die Darstellung Optimiert, das sah auf dem Bild da oben recht wild aus. Tut mir leid!

*mini update/hotfix nachgeschoben

Pps: Ich habe Usb-Sticks die auch als Fixed von GetDriveType kommen. Wie dem auch sei, nun sollte man definitiv Wissen an was welches Device angebunden ist.

*STORAGE_BUS_TYPE ist nun up-to-date

*IDE Start-Bug behoben, ich hatte da noch ein Integer<>Cardinal Fehler:oops::oops::oops:
*Icon-Resource fixed, anstelle 700kb Icon-Resource nun eine 2kb:oops::oops:

KodeZwerg 15. Jun 2018 10:35

AW: Partition zu phys. LW?
 
Neue Version oben drinn, tut mir leid, da habe ich geschlafen, war spät:twisted:

edit
Mir ist eben erst aufgefallen, das wenn keine Cd (o.ä.) eingelegt ist, da stimmt die Anzeige nicht, passt Euch das bei Bedarf noch an, sorry bei mir liegt meist ein medium drinnen.

markus5766h 18. Jun 2018 22:11

AW: Partition zu phys. LW?
 
Liste der Anhänge anzeigen (Anzahl: 1)
getestet (unter W10 - 64Bit)
konnte keine Unstimmigkeiten feststellen

KodeZwerg 18. Jun 2018 23:16

AW: Partition zu phys. LW?
 
Danke für Feedback und schönes Beispiel wie vielseitig Dinge angebunden sein können:thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:02 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz