Delphi Pascal - Using SetFilePointerEx and GetFileSizeEx, Getting Physical Media exact size when reading as a file

Posted by SuicideClutchX2 on Stack Overflow See other posts from Stack Overflow or by SuicideClutchX2
Published on 2010-12-31T01:04:44Z Indexed on 2010/12/31 1:53 UTC
Read the original article Hit count: 644

Filed under:
|
|
|

I am having trouble understanding how to delcare GetFileSizeEx and SetFilePointerEx in Delphi 2009 so that I can use them since they are not in the RTL or Windows.pas.

I was able to compile with the following:

function GetFileSizeEx(hFile: THandle; lpFileSizeHigh: Pointer): DWORD; external 'kernel32';

Then using GetFileSizeEx(PD, Pointer(DriveSize)); to get the size.

But could not get it to work, the disk handle I am using is valid and I have had no problem reading the data or working under the 2gb mark with the older API's. GetFileSize of course returns 4294967295. I have had greater trouble trying to use SetFilePointerEx with the data types it uses.

The overall project needs to read the data from a flash card, which is not a problem at all I can do this. My problem is that I can not find the length or size of the media I will be reading. I have code I have used in the past to do this with media under 2GB. But now that I need to read media over 2GB it is a problem. If you still dont understand I am dumping a card with all data including the boot record, etc.

This is the code I would normally use to read from the physical disk to grab say the boot record and dump it to file:

SetFilePointer(PD,0,nil,FILE_BEGIN);
SetLength(Buffer,512);
ReadFile(PD,Buffer[0],512,BytesReturned,nil);

I just need to figure out how to find the end of an 8gb card and so on as well as being able to set a file pointer beyond the 2gb barrier. I guess any help in the external declarations as well as understand the values that SetFilePointerEx uses (I do not understand the whole High Low thing) would be of great help.

    var
  Form1: TForm1;

function GetFileSizeEx(hFile: THandle; var FileSize: Int64): DWORD; stdcall; external 'kernel32';

implementation

{$R *.dfm}

function GetLD(Drive: Char): Cardinal;
var
  Buffer : String;
begin
  Buffer := Format('\\.\%s:',[Drive]);
  Result := CreateFile(PChar(Buffer),GENERIC_READ Or GENERIC_WRITE,FILE_SHARE_READ,nil,OPEN_EXISTING,0,0);
  If Result = INVALID_HANDLE_VALUE Then
    begin
    Result := CreateFile(PChar(Buffer),GENERIC_READ,FILE_SHARE_READ,nil,OPEN_EXISTING,0,0);
  end;
end;

function GetPD(Drive: Byte): Cardinal;
var
  Buffer : String;
begin
  If Drive = 0 Then
    begin
    Result := INVALID_HANDLE_VALUE;
    Exit;
  end;
  Buffer := Format('\\.\PHYSICALDRIVE%d',[Drive]);
  Result := CreateFile(PChar(Buffer),GENERIC_READ Or GENERIC_WRITE,FILE_SHARE_READ,nil,OPEN_EXISTING,0,0);
  If Result = INVALID_HANDLE_VALUE Then
    begin
    Result := CreateFile(PChar(Buffer),GENERIC_READ,FILE_SHARE_READ,nil,OPEN_EXISTING,0,0);
  end;
end;

function GetPhysicalDiskNumber(Drive: Char): Byte;
var
  LD : DWORD;
  DiskExtents : PVolumeDiskExtents;
  DiskExtent : TDiskExtent;
  BytesReturned : Cardinal;
begin
  Result := 0;
  LD := GetLD(Drive);
  If LD = INVALID_HANDLE_VALUE Then Exit;
  Try
    DiskExtents := AllocMem(Max_Path);
    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;
    end;
  Finally
    CloseHandle(LD);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  PD : DWORD;
  BytesReturned : Cardinal;
  Buffer : Array Of Byte;
  myFile: File;
  DriveSize: Int64;
begin
  PD := GetPD(GetPhysicalDiskNumber(Edit1.Text[1]));
  If PD = INVALID_HANDLE_VALUE Then Exit;
  Try

    GetFileSizeEx(PD, DriveSize);


    //SetFilePointer(PD,0,nil,FILE_BEGIN);
    //etLength(Buffer,512);
    //ZeroMemory(@Buffer,SizeOf(Buffer));
    //ReadFile(PD,Buffer[0],512,BytesReturned,nil);
    //AssignFile(myFile, 'StickDump.bin');
    //ReWrite(myFile, 512);
    //BlockWrite(myFile, Buffer[0], 1);
    //CloseFile(myFile);
  Finally
    CloseHandle(PD);
  End;
end;

© Stack Overflow or respective owner

Related posts about delphi

Related posts about api