Link to home
Start Free TrialLog in
Avatar of johnnyex
johnnyex

asked on

get size of pendrive physical

I need routine/function delphi which will check disk size physical.
I not mean volume size but physical.

There is Volume size dependable on formatting options.
And there is physical disk size not matter if drive 8gb will be formatted to 2gb.

I need to get know real drive size in bytes.

Similar info present program called USB image tool.

Disksize() function is not able to get this information sice it checks for volume logical size only.

Please advice
Avatar of Ferruccio Accalai
Ferruccio Accalai
Flag of Italy image

Here's an example using Windows Api IOCTL_DISK_GET_DRIVE_GEOMETRY
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363972%28v=vs.85%29.aspx

It get the disk structure giving the drive letters and returns the value calculated by
Cylinders * TracksPerCylinder * SectorsPerTrack * BytesPerSector
Of course it's the physical value, not just the volume size

Drop a TButton and a TDriveComboBox on a new form, then paste this code (assign the Tbutton Onclick)

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, FileCtrl;

type
  TForm1 = class(TForm)
    Button1: TButton;
    DriveComboBox1: TDriveComboBox;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

const
  IOCTL_DISK_GET_DRIVE_GEOMETRY = $00070000;

type
{$MINENUMSIZE 4}
  TMediaType = (Unknown, // Format is unknown
    F5_1Pt2_512, // 5.25", 1.2MB,  512 bytes/sector
    F3_1Pt44_512, // 3.5",  1.44MB, 512 bytes/sector
    F3_2Pt88_512, // 3.5",  2.88MB, 512 bytes/sector
    F3_20Pt8_512, // 3.5",  20.8MB, 512 bytes/sector
    F3_720_512, // 3.5",  720KB,  512 bytes/sector
    F5_360_512, // 5.25", 360KB,  512 bytes/sector
    F5_320_512, // 5.25", 320KB,  512 bytes/sector
    F5_320_1024, // 5.25", 320KB,  1024 bytes/sector
    F5_180_512, // 5.25", 180KB,  512 bytes/sector
    F5_160_512, // 5.25", 160KB,  512 bytes/sector
    RemovableMedia, // Removable media other than floppy
    FixedMedia, // Fixed hard disk media
    F3_120M_512 // 3.5", 120M Floppy
    );
{$MINENUMSIZE 1}
  PDiskGeometry = ^TDiskGeometry;

  TDiskGeometry = packed record
    Cylinders: int64;
    MediaType: TMediaType;
    TracksPerCylinder: DWORD;
    SectorsPerTrack: DWORD;
    BytesPerSector: DWORD;
  end;

procedure TForm1.Button1Click(Sender: TObject);
var
  H: THandle;
  BytesReturned: DWORD;
  DG: TDiskGeometry;
  DSize: int64;
begin
  H := CreateFile(PChar(Format('\\.\%s:', [DriveComboBox1.Drive])), GENERIC_READ, FILE_SHARE_WRITE or FILE_SHARE_READ, nil, OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL, 0);
  if Handle = INVALID_HANDLE_VALUE then
    raise Exception.Create('Invalid Handle Value!');
  if not DeviceIOControl(H, IOCTL_DISK_GET_DRIVE_GEOMETRY, nil, 0, @DG, SizeOf(TDiskGeometry), BytesReturned, nil) then
    raise Exception.Create('Drive Geometry cannot be retrieved!');
  DSize := DG.Cylinders * DG.TracksPerCylinder;
  DSize := DSize * (DG.SectorsPerTrack * DG.BytesPerSector);
  ShowMessage(Format('%d bytes', [DSize]));
end;

end.

Open in new window

Avatar of johnnyex
johnnyex

ASKER

thanks Ferruccio68 but Sth is wrong in this function or USB image tool app is buggy...
http://www.alexpage.de/usb-image-tool/

just compare any usb drive section DEVICE with your code provided, always slightly different :(
just download and check yourself: http://www.alexpage.de/usb-image-tool/download/

if you think this tool is buggy then and you think your function is ok then would be good to know this fact as well

I feel sth wrong is is provided code rather
ASKER CERTIFIED SOLUTION
Avatar of Sinisa Vuk
Sinisa Vuk
Flag of Croatia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
cannot compile second: [dcc32 Error] Unit1.pas(30): E2029 Expression expected but 'PACKED' found

so what result give first code if second is "raw size availiable for windows" ?
ok compiled but getting:
Drive Geometry cannot be retrieved!

can you provide full working code and explain difference between first method you posted and second ?
Sorry buddy, my fault while modyfing code, compiled and worked perfect.

Still I'm just curious about difference between fisrt time provided code and second  " raw size available to windows"

THANKS
Ferruccio68 gives you code to get physical "geometry" of usb device. Multiplying geometry components you will get theoretical maximum size, but few bytes usb needs for itself.
Go through:
https://en.wikipedia.org/wiki/Universal_Serial_Bus
...and especially part Screwed-up formatting on:
http://wiki.laptop.org/go/How_to_Damage_a_FLASH_Storage_Device