Diskuze: Lazarus a \.PhysicalDrive0

Ostatní jazyky Delphi Delphi (Pascal) Lazarus a \.PhysicalDrive0

Avatar
Začátečník
Neregistrovaný
Avatar
Začátečník:

Potřeboval bych hotový příklad, ve kterém se zjistí skutečná velikost fyzického disku (čili nikoli svazku nebo oddílu) a případně i počet fyzických disků a jejich typ (removable a podobně). A to výhradně pomocí zaklínadel typu DeviceIOcontrol, IOCTL_DISK_GET_DRI­VE_GEOMETRY, GetDriveGeometry, DISK_GEOMETRY, ev. podobných, které nevolají žádný framework, ale rovnou funkci API. Program chci spouštět pod Windows PE, kde žádné "vyšší" funkce k dispozici nejsou. Předem díky.

 
Odpovědět 17.3.2012 19:48
Avatar
Začátečník
Neregistrovaný
Avatar
Odpovídá na Začátečník
Začátečník:

Tak jsem si to nakonec dal dohromady z několika příkladů pro Delphi (v Lazarusu nefungujících) sám, zde je výsledek mého začátečnického snažení:

(* +++ Code starts +++ *)
uses JwaWinBase, JwaWinNT;

const
  ERROR_NOT_DEFINED  = -1;
  ERROR_DRIVE_NUMBER = -2;
  ERROR_NOT_EXIST    = -3;
  ERROR_IOCTL        = -4;

function GetPhysicalDiskSize(DriveNr:Integer;var strErrorMessage:String): Int64;
const
  IOCTL_DISK_GET_DRIVE_GEOMETRY : DWORD = $00070000;
type
  MEDIA_TYPE = (
     Unknown,       // Format is unknown
     F5_1Pt2_512,   // A 5.25" floppy, with 1.2MB and 512 bytes/sector.
     F3_1Pt44_512,  // A 3.5" floppy, with 1.44MB and 512 bytes/sector.
     F3_2Pt88_512,  // A 3.5" floppy, with 2.88MB and 512 bytes/sector.
     F3_20Pt8_512,  // A 3.5" floppy, with 20.8MB and 512 bytes/sector.
     F3_720_512,    // A 3.5" floppy, with 720KB and 512 bytes/sector.
     F5_360_512,    // A 5.25" floppy, with 360KB and 512 bytes/sector.
     F5_320_512,    // A 5.25" floppy, with 320KB and 512 bytes/sector.
     F5_320_1024,   // A 5.25" floppy, with 320KB and 1024 bytes/sector.
     F5_180_512,    // A 5.25" floppy, with 180KB and 512 bytes/sector
     F5_160_512,    // A 5.25" floppy, with 160KB and 512 bytes/sector
     RemovableMedia,// Removable media other than floppy.
     FixedMedia,    // Fixed hard disk media.
     F3_120M_512,   // A 3.5" floppy, with 120MB and 512 bytes/sector.
     F3_640_512,    // A 3.5" floppy, with 640MB and 512 bytes/sector.
     F5_640_512,    // A 3.5" floppy, with 640MB and 512 bytes/sector.
     F5_720_512,    // A 5.25" floppy, with 720KB and 512 bytes/sector.
     F3_1Pt2_512,   // A 3.5" floppy, with 1.2MB and 512 bytes/sector.
     F3_1Pt23_1024, // A 3.5" floppy, with 1.23MB and 1024 bytes/sector.
     F5_1Pt23_1024, // A 5.25" floppy, with 1.23KB and 1024 byts/sector.
     F3_128Mb_512,  // A 3.5" floppy, with 128MB and 512 bytes/sector.
     F3_230Mb_512,  // A 3.5" floppy, with 230MB and 512 bytes/sector.
     F8_256_128,    // An 8" floppy, with 256KB and 128 bytes/sector.
     F3_200Mb_512,  // A 3.5" floppy, with 200MB and 512 bytes/sector.(HiFD).
     F3_240M_512,   // A 3.5" floppy, with 240MB and 512 bytes/sector. (HiFD).
     F3_32M_512     // A 3.5" floppy, with 32MB and 512 bytes/sector.
     );

  DISK_GEOMETRY = record
                     Cylinders         : Int64;
                     MediaType         : MEDIA_TYPE;
                     TracksPerCylinder : DWORD;
                     SectorsPerTrack   : DWORD;
                     BytesPerSector    : DWORD;
                   end;
var
  iiDiskSize  : Int64;
  strDriveNr  : String;
  hDeviceDisk : THandle;
  dwReturned  : DWORD;
  rDiskInfo   : DISK_GEOMETRY;
  bResult     : Boolean;
begin
  iiDiskSize := ERROR_NOT_DEFINED;
  strErrorMessage := 'Unknown error';
  try
    strDriveNr := IntToStr(DriveNr);
    hDeviceDisk := CreateFile(PChar('\\.\PhysicalDrive'+strDriveNr),GENERIC_READ,FILE_SHARE_READ Or FILE_SHARE_WRITE,Nil,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,0);
    if hDeviceDisk <> INVALID_HANDLE_VALUE then
    begin
      FillChar(rDiskInfo,Sizeof(rDiskInfo),0);
      bResult := DeviceIOcontrol(hDeviceDisk,IOCTL_DISK_GET_DRIVE_GEOMETRY,Nil,0,@rDiskInfo,SizeOf(rDiskInfo),@dwReturned,Nil);
      CloseHandle(hDeviceDisk);
      if bResult then
      begin
        iiDiskSize := rDiskInfo.Cylinders*rDiskInfo.TracksPerCylinder*rDiskInfo.SectorsPerTrack*rDiskInfo.BytesPerSector;
      end
      else
      begin
        iiDiskSize := ERROR_IOCTL;
        strErrorMessage := 'DeviceIOcontrol error (Error #'+IntToStr(GetLastError())+') ';
      end;
    end
    else
    begin
      iiDiskSize := ERROR_NOT_EXIST;
      strErrorMessage := 'Invalid handle (Error #'+IntToStr(GetLastError())+') - physical disk '+strDriveNr+' does not exist.';
    end;
  except
    iiDiskSize := ERROR_DRIVE_NUMBER;
    strErrorMessage := 'Wrong Drive Number';
  end;
  Result := iiDiskSize;
end;
procedure ShowDisksSizes;
var
  intDiskIndex     : Integer;
  ReturnedDiskSize : Int64;
  strError         : String;
begin
  intDiskIndex := 0;
  repeat
    ReturnedDiskSize := GetPhysicalDiskSize(intDiskIndex,strError);
    if ReturnedDiskSize > ERROR_NOT_DEFINED  then WriteLn('Disk '+IntToStr(intDiskIndex)+': ',ReturnedDiskSize,' bytes = ',FloatToStrF((ReturnedDiskSize/1073741824),ffGeneral,8,8)+' GB = ',FloatToStrF((ReturnedDiskSize/1099511627776),ffGeneral,8,8)+' TB');
    if ReturnedDiskSize = ERROR_NOT_DEFINED  then WriteLn('Disk '+IntToStr(intDiskIndex)+': '+strError);
    if ReturnedDiskSize = ERROR_DRIVE_NUMBER then WriteLn('Disk '+IntToStr(intDiskIndex)+': '+strError);
//  if ReturnedDiskSize = ERROR_NOT_EXIST    then WriteLn('Disk '+IntToStr(intDiskIndex)+': '+strError);
    if ReturnedDiskSize = ERROR_IOCTL        then WriteLn('Disk '+IntToStr(intDiskIndex)+': '+strError);
    intDiskIndex := intDiskIndex + 1;
  until ReturnedDiskSize <= ERROR_NOT_DEFINED;
end;
(* --- Code ends --- *)
 
Nahoru Odpovědět 17.3.2012 23:52
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 2 zpráv z 2.