AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Partitionen grafisch anzeigen wie Windows Datenträgerverwaltung
Thema durchsuchen
Ansicht
Themen-Optionen

Partitionen grafisch anzeigen wie Windows Datenträgerverwaltung

Ein Thema von Guido Eisenbeis · begonnen am 10. Apr 2013 · letzter Beitrag vom 28. Apr 2013
 
Alter Mann

Registriert seit: 15. Nov 2003
Ort: Berlin
949 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#10

AW: Partitionen grafisch anzeigen wie Windows Datenträgerverwaltung

  Alt 20. Apr 2013, 07:59
Moin, Moin

Keiner ist Perfekt, daher gibt es Änderungen in den beiden Units.

comHDDInfoGui

Delphi-Quellcode:
procedure TDeviceInfoPanel.ShowDeviceData;

  function ConvertSerialNumber(Input : String) : String;
  var
    I : Integer;
    CC : Char;
  begin
    Result := '';
    I := 1;
    while I < Length(Input) do
    begin
      CC := Char(StrToInt(Format('$%s%s',[Input[I], Input[I+1]])));
      Inc(I, 2);
      if CC <> ' then // change CC <> '' to CC <> ' ' 20.04.2013
        Result := Result + CC;
    end;
  end;

  // added FormatModell 20.04.2013
  function FormatModell(Input : String) : String;
  var
    St : String;
  begin
    St := Copy(Input, POS(' ', Input) + 1, Length(Input));
    St := Copy(St, 1, POS(' ', St));
    Result := St;
  end;

begin
  if (FDeviceInfoRecord <> nil) then
  begin
    with FDeviceInfoRecord^ do
    begin
      FPartitionMapPanel.DriveLayout := @LayoutRecord;
      FPartitionMapPanel.DeviceLength := DeviceLength;
      FPartitionMapPanel.VolumenInfo := @InfoRecord;
    end;

    lbSerialNumberInfo.Caption := ConvertSerialNumber(FDeviceInfoRecord.IdentRecord.SerialNumber);
    lbFirmWareInfo.Caption := FDeviceInfoRecord.IdentRecord.FirmwareRev;
    lbModelNameInfo.Caption := FormatModell(FDeviceInfoRecord.IdentRecord.ModelNumber);
    lbDeviceSizeInfo.Caption := Format('%d %s', [LBASizeToGB(FDeviceInfoRecord.DeviceLength), SizeFormatStr(FDeviceInfoRecord.DeviceLength)]);
    lbInterfaceInfo.Caption := FDeviceInfoRecord.IdentRecord.InterfaceType;

    FPartitionMapPanel.ShowPartitionData;
  end;
end;

procedure TPartitionMapPanel.ShowPartitionData;
var
  I, J, RF : Integer;
begin
  RF := FDeviceLength div (Width - 2);
  for I := 0 to FDriveLayoutRecord.PartitionCount - 1 do
  begin
    J := FPartitionList.Add(TPartitionInfoPanel.Create(Self));
    with TPartitionInfoPanel(FPartitionList[J]) do
    begin
      Left := 2 + Round(FDriveLayoutRecord.PartitionEntry[I].StartingOffset / RF); // change 1 to 2 20.04.2013
      Top := 2;
      Width := Round(FDriveLayoutRecord.PartitionEntry[I].PartitionLength / RF) -1;
      Height := 75;
      Index := J;
      InfoID := I;
      OnCreateEvent := CreatePartitionPanel;
    end;
    TPartitionInfoPanel(FPartitionList[J]).Parent := Self;
  end;
end;

procedure TPartitionInfoPanel.ShowDeviceData;
begin
  FDriveVolume.Caption := Format('%s (%s:\)', [FInfoVolumeRecord.VolumeName, FInfoVolumeRecord.DriveLetter]);
  FFileSystem.Caption := Format('%d %s', [LBASizeToGB(FInfoVolumeRecord.VolumeSize), SizeFormatStr(FInfoVolumeRecord.VolumeSize)]);
  case FInfoVolumeRecord.FileSystemID of
    1 : FColorPanel.Color := clAqua; // FAT
    2 : FColorPanel.Color := clGreen; // FAT32
    3 : FColorPanel.Color := clBlue; // NTFS
    4 : FColorPanel.Color := clFuchsia; // exFAT
    5 : FColorPanel.Color := clBlack; // UNKNOWN
  end;
  FColorPanel.Refresh;
end;
Wer auch den Hersteller haben möchte, passt die Procedure ShowDeviceData so an:
Delphi-Quellcode:
...
    lbManufacturer.Caption := Copy(FDeviceInfoRecord.IdentRecord.ModelNumber, 1, POS(' ', FDeviceInfoRecord.IdentRecord.ModelNumber) -1);
...
Vorausgesetzt, dass Label lbManufacturer existiert.

Die Unit comHelpHDD hat sich geändert:
Delphi-Quellcode:
unit comHelpHDD;

interface

uses
  Windows, Classes, jwaWinIOCTL;

type
  TParatitionInfoRecord = record
    DriveLetter : Char;
    PartitionStyle : Byte;
    PartitionLength : Int64;
    PartitionNumber : DWORD;
    StartingOffset : Int64;
  end;

  PVolumenInfoEntry = ^TVolumenInfoEntry;
  TVolumenInfoEntry = record
    DriveLetter : Char;
    FileSystemID : Byte;
    FileSystem : String;
    VolumeName : String;
    FreeSpace : Int64;
    VolumeSize : Int64;
  end;

  PVolumeInfoRecord = ^TVolumeInfoRecord;
  TVolumeInfoRecord = Array of TVolumenInfoEntry;

  PDriveLayoutRecord = ^TDriveLayoutRecord;
  TDriveLayoutRecord = record
    PartitionStyle : DWORD;
    PartitionCount : DWORD;
    Union : record
      case Integer of
        0: (Mbr: DRIVE_LAYOUT_INFORMATION_MBR);
        1: (Gpt: DRIVE_LAYOUT_INFORMATION_GPT);
      end;
    PartitionEntry : array [0..3] of TParatitionInfoRecord;
  end;

  PDeviceIdentRecord = ^TDeviceIdentRecord;
  TDeviceIdentRecord = record
    SerialNumber : String;
    FirmwareRev : String;
    ModelNumber : String;
    InterfaceType : String;
  end;


  TSizeFormat = (sfMB, sfGB, sfTB);

  PDeviceInfoRecord = ^TDeviceInfoRecord;
  TDeviceInfoRecord = record
    DeviceID : Byte;
    DeviceLength : Int64;
    IdentRecord : TDeviceIdentRecord;
    LayoutRecord : TDriveLayoutRecord;
    InfoRecord : TVolumeInfoRecord;
  end;


function SizeFormatStr(DeviceSize : Int64; GiBs : Boolean = true) : String;
function LBASizeToGB(DeviceSize : Int64; GiBs : Boolean = true) : Integer;
function MeasureDeviceInfoRecord(aDeviceID : Byte) : PDeviceInfoRecord;

implementation

uses
  SysUtils, ActiveX, Variants, WbemScript;

type
  TDriveInfoObject = class(TObject)
  private
    FDriveLetter : Char;
    FDeviceID : Byte;
    FPartitionNumber : DWORD;
  public
    constructor Create(aDrive : Char; aDeviceID: Byte; aPartitionNumber : DWORD);
    property DriveLetter : Char read FDriveLetter;
    property DeviceID : Byte read FDeviceID;
    property PartitionNumber : DWORD read FPartitionNumber;
  end;

{**************************** TDriveInfoObject *******************************}

constructor TDriveInfoObject.Create(aDrive : Char; aDeviceID: Byte; aPartitionNumber : DWORD);
begin
  FDriveLetter := aDrive;
  FDeviceID := aDeviceID;
  FPartitionNumber := aPartitionNumber;
end;

{**************************** Helpers *****************************************}

function LBASizeToGB(DeviceSize : Int64; GiBs : Boolean = true) : Integer;
var
  I, J : Integer;
begin
  if GiBs then J := 1000000000
          else J := 1073741824;
  if DeviceSize = 0 then I := 0
  else
  begin
    I := Round(DeviceSize / J);
    while (I <= 1) do
    begin
      if GiBs then J := J div 1000
              else J := J div 1024;
      I := Round(DeviceSize / J);
    end;
  end;
  Result := I;
end;

function SizeFormatStr(DeviceSize : Int64; GiBs : Boolean = true) : String;
var
  J : Int64;
begin
  if GiBs then J := 1000000000
          else J := 1073741824;
  if DeviceSize < J then Result := 'MB'
  else
  if DeviceSize > J then
  begin
    if GiBs then J := J * 1000
            else J := J * 1024;
    if DeviceSize >= J then Result := 'TB'
                       else Result := 'GB';
  end;
end;

function FindDeviceByDriveLetter(DeviceID : Byte; aDetails : Boolean) : TStringList;
var
  I : Integer;
  hVolume : THandle;
  SDN : STORAGE_DEVICE_NUMBER;
  lpBytesReturned : Cardinal;
begin
  Result := TStringList.Create;
  try
    for I := Ord('C') to Ord('Z') do
    begin
      hVolume := CreateFile(PChar(Format('\\.\%s:', [Char(I)])),
                          GENERIC_READ,
                          FILE_SHARE_READ or FILE_SHARE_WRITE,
                          nil,
                          OPEN_EXISTING, 0, 0);
      if hVolume <> INVALID_HANDLE_VALUE then
      begin
        if DeviceIOControl(hVolume,
                           IOCTL_STORAGE_GET_DEVICE_NUMBER,
                           nil,
                           0,
                           @SDN,
                           SizeOf(SDN),
                           lpBytesReturned,
                           nil) then
        if SDN.DeviceType = FILE_DEVICE_DISK then
          if DeviceID = SDN.DeviceNumber then
            if aDetails then
              Result.AddObject(IntToStr(SDN.PartitionNumber), TDriveInfoObject.Create(Char(I), SDN.DeviceNumber, SDN.PartitionNumber))
            else
              Result.Add(Char(I) + ':\');
      end;
    end;
  except
    Result.Free;
  end;
end;

function DeviceExists(aDeviceName : String) : Boolean;
var
  DeviceHandle : THandle;
  {$IFDEF VER200}
  DeviceName : PWideChar;
  {$ELSE}
  DeviceName : PChar;
  {$ENDIF}
  GLI : GET_LENGTH_INFORMATION;
  lpBytesReturned : Cardinal;
begin
  DeviceName := StrAlloc(MAX_PATH);
  StrPCopy(DeviceName, aDeviceName);
  DeviceHandle := CreateFile(DeviceName, GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
  StrDispose(DeviceName);
  Result := DeviceHandle <> INVALID_HANDLE_VALUE;
  if Result then
  begin
    if DeviceIOControl(DeviceHandle, IOCTL_DISK_GET_LENGTH_INFO, nil, 0, @GLI, SizeOf(GLI), lpBytesReturned, nil) then
      Result := GLI.Length.QuadPart > 0
    else
      Result := false;
    CloseHandle(DeviceHandle);
  end;
end;

function DeviceSize(aDeviceName : String) : UInt64;
var
  DeviceHandle : THandle;
  {$IFDEF VER200}
  DeviceName : PWideChar;
  {$ELSE}
  DeviceName : PChar;
  {$ENDIF}
  GLI : GET_LENGTH_INFORMATION;
  lpBytesReturned : Cardinal;
begin
  Result := 0;
  DeviceName := StrAlloc(MAX_PATH);
  StrPCopy(DeviceName, aDeviceName);
  DeviceHandle := CreateFile(DeviceName, GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
  StrDispose(DeviceName);
  if DeviceHandle <> INVALID_HANDLE_VALUE then
  begin
    if DeviceIOControl(DeviceHandle, IOCTL_DISK_GET_LENGTH_INFO, nil, 0, @GLI, SizeOf(GLI), lpBytesReturned, nil) then
      Result := GLI.Length.QuadPart;
    CloseHandle(DeviceHandle);
  end;
end;

function GetDevicePartitionInfo(aDeviceName : String; var LayoutRecord: TDriveLayoutRecord) : Boolean;
var
  DeviceHandle : THandle;
  {$IFDEF VER200}
  DeviceName : PWideChar;
  {$ELSE}
  DeviceName : PChar;
  {$ENDIF}
  pDLIE : PDRIVE_LAYOUT_INFORMATION_EX;
  dwSize : DWORD;
  lpBytesReturned : Cardinal;
  I : Integer;
begin
  Result := False;
  GetMem(DeviceName, MAX_PATH);
  StrPCopy(DeviceName, aDeviceName);
  DeviceHandle:= CreateFile(DeviceName,
                            GENERIC_READ, // or GENERIC_WRITE,
                            FILE_SHARE_READ or FILE_SHARE_WRITE,
                            nil, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, 0);
  if DeviceHandle <> INVALID_HANDLE_VALUE then
  begin
    try

      dwSize := SizeOf(_DRIVE_LAYOUT_INFORMATION_EX) + SizeOf(_PARTITION_INFORMATION_EX) * 31;
      GetMem(pDLIE, dwSize);
      FillChar(pDLIE^, dwSize, 0);
      Result := DeviceIOControl(DeviceHandle, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, nil, 0,
                         pDLIE, dwSize, lpBytesReturned, nil);
      if Result then
      begin
        LayoutRecord.PartitionStyle := pDLIE^.PartitionStyle;
        LayoutRecord.PartitionCount := 0;
// LayoutRecord.Union := pDLIE^.Union;
        for I := 0 to pDLIE^.PartitionCount - 1 do
          if pDLIE^.PartitionEntry[I].PartitionLength.QuadPart > 0 then
          begin
            LayoutRecord.PartitionEntry[I].PartitionStyle := DWORD(pDLIE^.PartitionEntry[I].PartitionStyle);
            LayoutRecord.PartitionEntry[I].PartitionLength:= pDLIE^.PartitionEntry[I].PartitionLength.QuadPart;
            LayoutRecord.PartitionEntry[I].PartitionNumber:= pDLIE^.PartitionEntry[I].PartitionNumber;
            LayoutRecord.PartitionEntry[I].StartingOffset := pDLIE^.PartitionEntry[I].StartingOffset.QuadPart;
            Inc(LayoutRecord.PartitionCount);
          end;
      end;

      FreeMem(pDLIE);
    finally
      CloseHandle(DeviceHandle);
    end;
  end;
  FreeMem(DeviceName);
end;

function GetWMIDeviceInfo(aID : Byte; aWQLStr : String; var Data) : Boolean;
var
  wmiLocator : ISWbemLocator;
  wmiServices : ISWbemServices;
  wmiObjectSet : ISWbemObjectSet;
  wmiObject : ISWbemObject;
  propSet : ISWbemPropertySet;
  wmiProp : ISWbemProperty;
  propEnum,
  Enum : IEnumVariant;
  ovVar : OleVariant;
  lwValue : LongWord;
  sValue,
  sName : String;
  i : integer;
begin
  CoInitialize(nil);
  wmiLocator := CoSWbemLocator.Create;
  try
    wmiServices := wmiLocator.ConnectServer('.', 'root\CIMV2', '', '','', '', 0, nil);
    try
      if Assigned(wmiServices) then
      begin
        wmiObjectSet := wmiServices.ExecQuery(aWQLStr, 'WQL', wbemFlagReturnWhenComplete, nil);
        if wmiObjectSet.Count > 0 then
        begin
          Enum := (wmiObjectSet._NewEnum) as IEnumVariant;
          if ((Enum <> nil) and (Enum.Next (1, ovVar, lwValue) = S_OK)) then
          begin
            wmiObject := IUnknown(ovVar) as SWBemObject;
            propSet := wmiObject.Properties_;
            propEnum := (propSet._NewEnum) as IEnumVariant;
            while (propEnum.Next (1, ovVar, lwValue) = S_OK) do
            begin
              wmiProp := IUnknown(ovVar) as SWBemProperty;
              sName := AnsiLowercase(wmiProp.Name);

              svalue := #0;
              if VarIsNull(wmiProp.Get_Value) then
                sValue := #0
              else
              begin
                case wmiProp.CIMType of
                    wbemCimtypeSint8,
                    wbemCimtypeUint8,
                    wbemCimtypeSint16,
                    wbemCimtypeUint16,
                    wbemCimtypeSint32,
                    wbemCimtypeUint32,
                    wbemCimtypeSint64 : if VarIsArray(wmiProp.Get_Value) then
                                            begin
                                              for I := 0 to VarArrayHighBound(wmiProp.Get_Value, 1) do
                                              begin
                                                if I > 0 then sValue := sValue + '|' ;
                                                sValue := sValue + IntToStr(wmiProp.Get_Value[I]) ;
                                              end ;
                                            end
                                            else
                                            sValue := IntToStr(wmiProp.Get_Value);
                     wbemCimtypeReal32,
                     wbemCimtypeReal64 : sValue := FloatToStr (wmiProp.Get_Value);
                     wbemCimtypeBoolean : if wmiProp.Get_Value then svalue := 'Trueelse svalue := 'False';
                     wbemCimtypeString,
                     wbemCimtypeUint64 : if VarIsArray(wmiProp.Get_Value) then
                                            begin
                                                for I := 0 to VarArrayHighBound (wmiProp.Get_Value, 1) do
                                                begin
                                                    if I > 0 then svalue := svalue + '|' ;
                                                    sValue := sValue + wmiProp.Get_Value [I] ;
                                                end ;
                                            end
                                            else
                                                sValue := wmiProp.Get_Value;
                     wbemCimtypeDatetime : sValue := wmiProp.Get_Value;
                     wbemCimtypeReference : begin
                                              sValue := wmiProp.Get_Value;
                                            end;
                end;
              end;
              case aID of
               0 : begin
                     if sName = 'serialnumberthen TDeviceIdentRecord(Data).SerialNumber := TrimLeft(TrimRight(sValue));
                     if sName = 'firmwarerevisionthen TDeviceIdentRecord(Data).FirmwareRev := TrimLeft(TrimRight(sValue));
                     if sName = 'modelthen TDeviceIdentRecord(Data).ModelNumber := TrimLeft(TrimRight(sValue));
                     if sName = 'interfacetypethen TDeviceIdentRecord(Data).InterfaceType := TrimLeft(TrimRight(sValue));
                   end;
               1 : begin
                     if sName = 'volumenamethen TVolumenInfoEntry(Data).VolumeName := TrimLeft(TrimRight(sValue));
                     if sName = 'filesystemthen
                     begin
                       TVolumenInfoEntry(Data).FileSystem := TrimLeft(TrimRight(sValue));
                       if TVolumenInfoEntry(Data).FileSystem = 'FATthen TVolumenInfoEntry(Data).FileSystemID := 1
                       else
                       if TVolumenInfoEntry(Data).FileSystem = 'FAT32then TVolumenInfoEntry(Data).FileSystemID := 2
                       else
                       if TVolumenInfoEntry(Data).FileSystem = 'NTFSthen TVolumenInfoEntry(Data).FileSystemID := 3
                       else
                       if TVolumenInfoEntry(Data).FileSystem = 'exFATthen TVolumenInfoEntry(Data).FileSystemID := 4
                       else
                       begin
                        TVolumenInfoEntry(Data).FileSystemID := 4;
                        TVolumenInfoEntry(Data).FileSystem := 'UNKNOWN';
                       end;
                     end;
                     if sName = 'freespace'  then TVolumenInfoEntry(Data).FreeSpace := StrToInt64(TrimLeft(TrimRight(sValue)));
                     if sName = 'size'       then TVolumenInfoEntry(Data).VolumeSize := StrToInt64(TrimLeft(TrimRight(sValue)));
                   end;
              end;
            end;
          end;
        end;
      end;
    finally
    end;
  finally
    wmiLocator := nil;
    CoUninitialize;
    case aID of
      0 : with TDeviceIdentRecord(Data) do Result := (SerialNumber <> '') or (FirmwareRev <> '') or (ModelNumber <> '') or (InterfaceType <> '');
      1 : with TVolumenInfoEntry(Data) do Result := (VolumeName <> '') or (FileSystem <> '');
    end;
  end;
end;

function MeasureDeviceInfoRecord(aDeviceID : Byte) : PDeviceInfoRecord;
var
  DN : String;
  DL : TStringList;
  WqlStr: String;
  Data : TDeviceIdentRecord;
  DLR : TDriveLayoutRecord;
  VIR : TVolumeInfoRecord;
  I, J : Integer;
begin
  DN := Format('\\.\PHYSICALDRIVE%d', [aDeviceID]);
  Result := New(PDeviceInfoRecord);
  with Result^ do
  begin
    DeviceID := aDeviceID;
    if DeviceExists(DN) then
    begin
      DeviceLength := DeviceSize(DN);
      DL := FindDeviceByDriveLetter(DeviceID, true);
      try
        if GetDevicePartitionInfo(DN, DLR) then
        begin
          SetLength(VIR, DLR.PartitionCount);
          for I := 0 to DLR.PartitionCount -1 do
          begin
            J := DL.IndexOf(IntToStr(DLR.PartitionEntry[I].PartitionNumber));
            if J > -1 then
            begin
              DLR.PartitionEntry[I].DriveLetter := TDriveInfoObject(DL.Objects[J]).DriveLetter;
              VIR[I].DriveLetter := DLR.PartitionEntry[I].DriveLetter;
            end;
          end;
          LayoutRecord := DLR;

          WqlStr := Format('SELECT * FROM Win32_DiskDrive WHERE DeviceID = ''\\\\.\\PHYSICALDRIVE%d''',[aDeviceID]);
          if GetWMIDeviceInfo(0, WqlStr, Data) then IdentRecord := Data;

          for I := 0 to Length(VIR) -1 do
            if VIR[I].DriveLetter <> 'then
            begin
              WqlStr := Format('SELECT DeviceID, FileSystem, FreeSpace, Size, VolumeName From win32_LogicalDisk WHERE DeviceID = ''%s:''', [VIR[I].DriveLetter]);
              GetWMIDeviceInfo(1, WqlStr, VIR[I]);
            end;
          InfoRecord := VIR;
        end;
      finally
        DL.Free;
      end;
    end;
  end;
end;

end.



VG

Geändert von Alter Mann (20. Apr 2013 um 08:51 Uhr)
  Mit Zitat antworten Zitat
 


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 06:13 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz