AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Direktes lesen auf dem physischen Datenträger
Thema durchsuchen
Ansicht
Themen-Optionen

Direktes lesen auf dem physischen Datenträger

Ein Thema von Delphi-Delphin · begonnen am 10. Jun 2018 · letzter Beitrag vom 20. Jun 2018
Antwort Antwort
Seite 1 von 3  1 23      
Delphi-Delphin

Registriert seit: 23. Feb 2010
10 Beiträge
 
FreePascal / Lazarus
 
#1

Direktes lesen auf dem physischen Datenträger

  Alt 10. Jun 2018, 17:06
Wie kann man direkt auf dem physischen Datenträger lesen? Ich würde gerne auf den MBR/GPT und die Bootblöcke der einzelnen Partitionen zugreifen.

Verwendet wird Lazarus.
Künstliche Intelligenz ist gar nichts - verglichen mit natürlicher Dummheit
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.685 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Direktes lesen auf dem physischen Datenträger

  Alt 10. Jun 2018, 17:26
MSDN-Library durchsuchenCreateFile mit "\\.\PhysicalDrive0" (Admin Rechte!)
Das öffnet Festplatte 0 bei Dir (also die erste)
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Delphi-Delphin

Registriert seit: 23. Feb 2010
10 Beiträge
 
FreePascal / Lazarus
 
#3

AW: Direktes lesen auf dem physischen Datenträger

  Alt 11. Jun 2018, 16:41
Danke.

Gibt es denn eine Funktion, die mir die erkannten physischen Datenträger auflisten kann?
Künstliche Intelligenz ist gar nichts - verglichen mit natürlicher Dummheit
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.685 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Direktes lesen auf dem physischen Datenträger

  Alt 11. Jun 2018, 17:14
Hmmm.... das erste war noch einfach für mich zu beantworten da es Winapi war.
Hier mische ich Delphi mit Winapi, keine Ahnung in wie fern das kompatibel zu Lazarus ist.
Folgender Code ermittelt alle Laufwerke mit Ihren Namen, da findest Du schon die passende Stelle wo Du Dich reinklinken kannst, wenn nicht, frage
Delphi-Quellcode:
function GetVolumeLabel(DriveChar: Char): string;
var
  NotUsed: DWORD;
  VolumeFlags: DWORD;
  VolumeInfo: array[0..MAX_PATH] of Char;
  VolumeSerialNumber: DWORD;
  Buf: array [0..MAX_PATH] of Char;
begin
    GetVolumeInformation(PChar(DriveChar + ':\'),
    Buf, SizeOf(VolumeInfo), @VolumeSerialNumber, NotUsed,
    VolumeFlags, nil, 0);
 
    SetString(Result, Buf, StrLen(Buf)); { Set return result }
    Result:=AnsiUpperCase(Result)
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  Drive : Char;
  DriveLetter : String;
begin
  For Drive := 'ATo 'ZDo
    begin
    DriveLetter := Drive + ':\';
    If GetDriveType(PChar(DriveLetter)) = DRIVE_FIXED Then
      begin
      Memo1.Lines.Add(Drive + ': ' + GetVolumeLabel(Drive));
    end;
  end;
end;
oder enumeriere die Laufwerke auf diese Winapi/Delphi Weise wie hier beschrieben.
Zitat:
The simplest way is actually to use GetDiskFreeSpaceEx from the sysutils.pas file.
There are 2 parts to this example. the 1st is the important part using GetDiskFreeSpaceEX.
Delphi-Quellcode:
function DriveSpace(DriveLetter : String; var FreeSpace, UsedSpace, TotalSpace : int64) : Boolean;
begin
  Result := SysUtils.GetDiskFreeSpaceEx(Pchar(DriveLetter), UsedSpace, TotalSpace, @FreeSpace);

  if UsedSpace > 0 then
    UsedSpace := TotalSpace - FreeSpace;

  if not Result then
  begin
    UsedSpace := 0;
    TotalSpace := 0;
    FreeSpace := 0;
  end;
end;
If you are going to request drives that you already know the drive letter for such as C: then that is all you need.
Usage would be something like:
Delphi-Quellcode:
var
  FS,
  US,
  TS : Int64
begin
  DriveSpace('C:', FS, US, TS);
  //Do something with the 3 variables.
end;
Having said that if you want to find the drives as well you could use something like this:
Delphi-Quellcode:
procedure ListDrivesOfType(DriveType : Integer; var Drives : TStringList);
var
  DriveMap,
  dMask : DWORD;
  dRoot : String;
  I : Integer;
begin
  dRoot := 'A:\'; //' // work around highlighting
  DriveMap := GetLogicalDrives;
  dMask := 1;

  for I := 0 to 32 do
  begin
    if (dMask and DriveMap) <> 0 then
      if GetDriveType(PChar(dRoot)) = DriveType then
      begin
        Drives.Add(dRoot[1] + ':');
      end;

    dMask := dMask shl 1;
    Inc(dRoot[1]);
  end;
end;
Note the DriveType integer, should be one of the following:
Delphi-Quellcode:
DRIVE_UNKNOWN = 0;
DRIVE_NO_ROOT_DIR = 1;
DRIVE_REMOVABLE = 2;
DRIVE_FIXED = 3;
DRIVE_REMOTE = 4;
DRIVE_CDROM = 5;
DRIVE_RAMDISK = 6;
(I have taken these straight out of windows.pas)
Now finally to answer your question (and this is very rough) the following would add information into a memo (called memo1) for all FIXED HARD DRIVES:
Delphi-Quellcode:
Procedure TAform.SomeNameICantThinkOfNow;
const
  BytesPerMB = 1048576;
var
  MyDrives : TStringlist;
  I : Integer;
  FreeSpace,
  UsedSpace,
  TotalSpace : int64;
begin
  MyDrives := TStringlist.Create;
  ListDrivesOfType(DRIVE_FIXED, MyDrives);

  Memo1.Lines.Clear;

  for I := 0 to MyDrives.Count - 1 do
  begin
    FreeSpace := 0;
    UsedSpace := 0;
    TotalSpace := 0;

    if DriveSpace(MyDrives.Strings[I], FreeSpace, UsedSpace, TotalSpace) then
    begin
      FreeSpace := FreeSpace div BytesPerMB;
      UsedSpace := UsedSpace div BytesPerMB;
      TotalSpace := TotalSpace div BytesPerMB;

      Memo1.Lines.Add('Drive: ' + MyDrives.Strings[I] + ' = Free Space :' + IntToStr(FreeSpace) +
                      ' Used Space: ' + IntToStr(UsedSpace) + ' Total Space: ' + IntToStr(TotalSpace));
    end;
  end;
end;
I did say it would be nasty! I have just run this up in the IDE and it works, I have done as MB but really you should convert to Double and choose your formatting if doing as MB to be more precise as the example I have create above will of course just round up.
Hope this is of some small assistance.
Gruß vom KodeZwerg

Geändert von KodeZwerg (11. Jun 2018 um 17:22 Uhr)
  Mit Zitat antworten Zitat
jus

Registriert seit: 22. Jan 2005
343 Beiträge
 
Delphi 2007 Professional
 
#5

AW: Direktes lesen auf dem physischen Datenträger

  Alt 12. Jun 2018, 08:49
Oder du machst die Abfrage über WMI. Oft bekommt man hier schneller mehr Infos, als sich mit irgendwelche APIs herumzuschlagen.

lg,
jus
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.685 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Direktes lesen auf dem physischen Datenträger

  Alt 12. Jun 2018, 09:22
*entfernt*
und er schrieb
Gibt es denn eine Funktion, die mir die erkannten physischen Datenträger auflisten kann?
Was das WMI Beispiel voll und ganz abgedeckt hatte.

An TE, im Anhang ist ein Binary von dem WMI Beispiel, schau es Dir an, wenn es das ist was Du brauchst das findest Du als Source hier in DP.
Angehängte Dateien
Dateityp: 7z GetWMI_DiskDriveInfo.7z (40,4 KB, 19x aufgerufen)
Gruß vom KodeZwerg

Geändert von KodeZwerg (12. Jun 2018 um 09:33 Uhr)
  Mit Zitat antworten Zitat
Daniel
(Co-Admin)

Registriert seit: 30. Mai 2002
Ort: Hamburg
13.919 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: Direktes lesen auf dem physischen Datenträger

  Alt 12. Jun 2018, 09:24
Er schreibt, dass er auf den MBR zugreifen möchte. Wie hilft ihm da dieses WMI-Beispiel?
Daniel R. Wolf
mit Grüßen aus Hamburg
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.685 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Direktes lesen auf dem physischen Datenträger

  Alt 12. Jun 2018, 10:41
dass er auf den MBR zugreifen möchte
Delphi-Quellcode:
type
  TMBR = Array of Byte;

Function GetMBR (const DiskNumber: Byte; const MBRSize: Cardinal; out MBR: TMBR): Boolean;
var
  nBytesRead ,
  fHandle : Cardinal;
begin
  fHandle := CreateFile(
    PChar('\\.\PHYSICALDRIVE'+IntToStr(DiskNumber)),
    GENERIC_READ, FILE_SHARE_WRITE,
    nil,
    OPEN_EXISTING,
    0, 0);
  if fHandle = INVALID_HANDLE_VALUE then
  begin
    Result := False;
    ShowMessage('CreateFile - Fehler: Invalid Handle' +#13#10#13#10+
                'Hinweis: liegen Admin-Rechte vor?');
    exit;
  end;
  SetLength(MBR, MBRSize);
  Result := ReadFile(fHandle, MBR[0], MBRSize, nBytesRead, nil);
  if nBytesRead-1 <> High(MBR) then Result := False;
  if not Result then
  begin
    ShowMessage('ReadFile - Fehler' +#13#10#13#10+
                'Es sollten '+IntToStr(High(MBR))+ ' bytes gelesen werden' +#13#10+
                'aber nur '+ IntToStr(nBytesRead-1) +' bytes waren lesbar!');
  end;
  CloseHandle(fHandle);
end;
So könnte ein möglicher Aufruf aussehen:
Delphi-Quellcode:
procedure x;
var
  MyMBR: TMBR;
begin
  if GetMBR(0, 512, MyMBR) then // <<-- 512 als MBR Größe ist nicht immer korrekt, also vorher diesen Wert ermitteln, das dient nur als Beispiel
  begin
   // mach was mit MyMBR
  end;
end;
So könnte ein möglicher Ansatz für MBR sein.
Gruß vom KodeZwerg

Geändert von KodeZwerg (12. Jun 2018 um 11:11 Uhr) Grund: Code optimiert
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.685 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Direktes lesen auf dem physischen Datenträger

  Alt 12. Jun 2018, 17:15
Ich bin gerade den Code nochmal durchgegangen, es kann sehr gut möglich sein das ich  if nBytesRead-1 <> High(MBR) then Result := False; das falsch habe und es  if nBytesRead <> High(MBR)+1 then Result := False; lauten müsste, beim weiteren nBytesRead das -1 dann weglassen aber beim High(MBR) ein +1 ranbaumeln.
Gruß vom KodeZwerg

Geändert von KodeZwerg (12. Jun 2018 um 19:04 Uhr)
  Mit Zitat antworten Zitat
Delphi-Delphin

Registriert seit: 23. Feb 2010
10 Beiträge
 
FreePascal / Lazarus
 
#10

AW: Direktes lesen auf dem physischen Datenträger

  Alt 18. Jun 2018, 12:26
Vielen Dank, für deine großartige Hilfe.

Deine Exe liefert sogar noch viel mehr Informationen, als ich brauche.

Mit dem Code lässt sich also sehr gut was anfangen. Der verlinkte Code ließ sich auch fehlerfrei im Lazarus kompilieren.

Edit: Hab auch noch einen Fehler im Code gefunden.
Bei Writeln(Format('Size %d',[VarToInt(FWbemObject.Size)]));// Uint64 kommt es zu einem Überlauf, da die Funktion selbst nur einen 32 Bit Integer verwendet.

Angepasst:
Delphi-Quellcode:
//-----------------------------------------------------------------------------------------------------
// This code was generated by the Wmi Delphi Code Creator http://theroadtodelphi.wordpress.com
// Version: 1.8.3.0
// LIABILITY DISCLAIMER
// THIS GENERATED CODE IS DISTRIBUTED "AS IS". NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED.
// YOU USE IT AT YOUR OWN RISK. THE AUTHOR NOT WILL BE LIABLE FOR DATA LOSS,
// DAMAGES AND LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING OR MISUSING THIS CODE.
//----------------------------------------------------------------------------------------------------
program GetWMI_DiskDriveInfo;

{$APPTYPE CONSOLE}

uses
 // SysUtils, ActiveX, ComObj, Variants;
  SysUtils,
  ActiveX,
  ComObj,
  Variants;

function VarToInt(const AVariant: Variant): integer;
begin Result := StrToIntDef(Trim(VarToStr(AVariant)), 0); end;

function VarToQWord(const AVariant: Variant): QWord;
begin Result := StrToQWordDef(Trim(VarToStr(AVariant)), 0); end;

// Die Klasse "Win32_DiskDrive" stellt ein physikalisches Laufwerk eines Computer dar,
// auf dem das Win32-Betriebssystem ausgeführt wird. Jede Schnittstelle zu einem physikalischen
// Win32-Laufwerk ist ein Mitglied dieser Klasse. Die Funktionen des Laufwerks in diesem
// Objekt entsprechen den logischen Laufwerkmerkmalen. Ein Objekt, das auf einem anderen logischen Gerät basiert,
// ist kein Mitglied dieser Klasse.
// Beispiel: IDE-Festplatte.

procedure GetWin32_DiskDriveInfo;
const
  WbemUser ='';
  WbemPassword ='';
  WbemComputer ='localhost';
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator : OLEVariant;
  FWMIService : OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject : OLEVariant;
  oEnum : IEnumvariant;
  iValue : LongWord;
  i: integer;
begin
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
  FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_DiskDrive','WQL',wbemFlagForwardOnly);
  oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
  i:=0;
  while oEnum.Next(1, FWbemObject, iValue) = 0 do
  begin
    Writeln(Format('*** DISK %d ***',[i]));
    Writeln(Format('Availability %d',[VarToInt(FWbemObject.Availability)]));// Uint16
    Writeln(Format('BytesPerSector %d',[VarToInt(FWbemObject.BytesPerSector)]));// Uint32
// Writeln(Format('Capabilities %d',[VarToInt(FWbemObject.Capabilities)]));// Array of Uint16
// Writeln(Format('CapabilityDescriptions %s',[VarToStr(FWbemObject.CapabilityDescriptions)]));// Array of VarToStr
    Writeln(Format('Caption %s',[VarToStr(FWbemObject.Caption)]));// VarToStr
    Writeln(Format('CompressionMethod %s',[VarToStr(FWbemObject.CompressionMethod)]));// String
    Writeln(Format('ConfigManagerErrorCode %d',[VarToInt(FWbemObject.ConfigManagerErrorCode)]));// Uint32
    Writeln(Format('ConfigManagerUserConfig %s',[VarToStr(FWbemObject.ConfigManagerUserConfig)]));// Boolean
    Writeln(Format('CreationClassName %s',[VarToStr(FWbemObject.CreationClassName)]));// String
    Writeln(Format('DefaultBlockSize %d',[VarToInt(FWbemObject.DefaultBlockSize)]));// Uint64
    Writeln(Format('Description %s',[VarToStr(FWbemObject.Description)]));// String
    Writeln(Format('DeviceID %s',[VarToStr(FWbemObject.DeviceID)]));// String
    Writeln(Format('ErrorCleared %s',[VarToStr(FWbemObject.ErrorCleared)]));// Boolean
    Writeln(Format('ErrorDescription %s',[VarToStr(FWbemObject.ErrorDescription)]));// String
    Writeln(Format('ErrorMethodology %s',[VarToStr(FWbemObject.ErrorMethodology)]));// String
    Writeln(Format('FirmwareRevision %s',[VarToStr(FWbemObject.FirmwareRevision)]));// String
    Writeln(Format('Index %d',[VarToInt(FWbemObject.Index)]));// Uint32
    Writeln(Format('InstallDate %s',[VarToStr(FWbemObject.InstallDate)]));// Datetime
    Writeln(Format('InterfaceType %s',[VarToStr(FWbemObject.InterfaceType)]));// String
    Writeln(Format('LastErrorCode %d',[VarToInt(FWbemObject.LastErrorCode)]));// Uint32
    Writeln(Format('Manufacturer %s',[VarToStr(FWbemObject.Manufacturer)]));// String
    Writeln(Format('MaxBlockSize %d',[VarToInt(FWbemObject.MaxBlockSize)]));// Uint64
    Writeln(Format('MaxMediaSize %d',[VarToInt(FWbemObject.MaxMediaSize)]));// Uint64
    Writeln(Format('MediaLoaded %s',[VarToStr(FWbemObject.MediaLoaded)]));// Boolean
    Writeln(Format('MediaType %s',[VarToStr(FWbemObject.MediaType)]));// String
    Writeln(Format('MinBlockSize %d',[VarToInt(FWbemObject.MinBlockSize)]));// Uint64
    Writeln(Format('Model %s',[VarToStr(FWbemObject.Model)]));// String
    Writeln(Format('Name %s',[VarToStr(FWbemObject.Name)]));// String
    Writeln(Format('NeedsCleaning %s',[VarToStr(FWbemObject.NeedsCleaning)]));// Boolean
    Writeln(Format('NumberOfMediaSupported %d',[VarToInt(FWbemObject.NumberOfMediaSupported)]));// Uint32
    Writeln(Format('Partitions %d',[VarToInt(FWbemObject.Partitions)]));// Uint32
    Writeln(Format('PNPDeviceID %s',[VarToStr(FWbemObject.PNPDeviceID)]));// String
    Writeln(Format('PowerManagementCapabilities %d',[VarToInt(FWbemObject.PowerManagementCapabilities)]));// Array of Uint16
    Writeln(Format('PowerManagementSupported %s',[VarToStr(FWbemObject.PowerManagementSupported)]));// Boolean
    Writeln(Format('SCSIBus %d',[VarToInt(FWbemObject.SCSIBus)]));// Uint32
    Writeln(Format('SCSILogicalUnit %d',[VarToInt(FWbemObject.SCSILogicalUnit)]));// Uint16
    Writeln(Format('SCSIPort %d',[VarToInt(FWbemObject.SCSIPort)]));// Uint16
    Writeln(Format('SCSITargetId %d',[VarToInt(FWbemObject.SCSITargetId)]));// Uint16
    Writeln(Format('SectorsPerTrack %d',[VarToInt(FWbemObject.SectorsPerTrack)]));// Uint32
    Writeln(Format('SerialNumber %s',[TRIM(VarToStr(FWbemObject.SerialNumber))]));// String
    Writeln(Format('Signature %d',[VarToInt(FWbemObject.Signature)]));// Uint32
    Writeln(Format('Size %d Byte = %f GB',[VarToQWord(FWbemObject.Size),VarToQWord(FWbemObject.Size)/(1000000000)]));// Uint64
    Writeln(Format('Status %s',[VarToStr(FWbemObject.Status)]));// String
    Writeln(Format('StatusInfo %d',[VarToInt(FWbemObject.StatusInfo)]));// Uint16
    Writeln(Format('SystemCreationClassName %s',[VarToStr(FWbemObject.SystemCreationClassName)]));// String
    Writeln(Format('SystemName %s',[VarToStr(FWbemObject.SystemName)]));// String
    Writeln(Format('TotalCylinders %d',[VarToInt(FWbemObject.TotalCylinders)]));// Uint64
    Writeln(Format('TotalHeads %d',[VarToInt(FWbemObject.TotalHeads)]));// Uint32
    Writeln(Format('TotalSectors %d',[VarToInt(FWbemObject.TotalSectors)]));// Uint64
    Writeln(Format('TotalTracks %d',[VarToInt(FWbemObject.TotalTracks)]));// Uint64
    Writeln(Format('TracksPerCylinder %d',[VarToInt(FWbemObject.TracksPerCylinder)]));// Uint32

    Writeln('----------------------------------------------------------------------------');
    FWbemObject:=Unassigned;

    inc(i);
  end;
end;


begin
 try
    CoInitialize(nil);
    try
      GetWin32_DiskDriveInfo;
    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.
Künstliche Intelligenz ist gar nichts - verglichen mit natürlicher Dummheit

Geändert von Delphi-Delphin (18. Jun 2018 um 13:09 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:41 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