DelphiからHDDを直接読みたいのですが・・
最終的には数テラの容量があるハードディスクドライブを,Delphi6からWin32APIのSetFilePointerで位置付けて,ReadFileでセクタを直接読み取りたいと思っていますが,現在,125GB辺りでエラーが発生し,以降がのセクタが読めません。(DelphiXEでも同じエラーとなります)
参考にできる日本語のサンプルも乏しく困り果てています。
どなたか,お教えください。
m(_ _)m
よろしくお願いいたします。
【動作環境】
OS:Windows7 (32) professional
言語: Delphi6(personal) 及びDelphi XE
メモリ:2GB
対象ドライブ:USB外付けHDD 250GB(1論理ドライブWindows7でフォーマット)
名称:\\.\PHYSICALDRIVE1
CylindersLo : 30401
CylindersHi : 0
TracksPerCylinder : 255
SectorsPerTrack : 63
BytesPerSector: 512
【問題点】
セクタ0からセクタ245127535までは読める様なのですが,1セクタ進めて245127536セクタを読み込もうとすると,SetFilePointerはエラーなしで通過するも,ReadFileでエラーとなってしまいます。
エラーが起きた時のSetFilePointerとReadFileに与えたパラメータは次の通りです。
Stsector : 245,127,536
real ofset: 125,505,298,432
p_hi: 58
p_lo: 951,246,848
p_hiの戻り値: 58
【プログラムのソース】
var
DHandle : Thandle; // ハンドル
drv_cnt : integer; // 接続ドライブ数
drvname : String; // 扱おうとするドライブの名称
sectorSize: integer; // セクタのサイズ
SectorNum : word; // セクタ番号
Max_num : word; // 読み込もうとするバイト数
buf : array[0..4095*2] of byte; // 読み取りデータの格納域
STsector : int64; // 読み込み開始のセクタ番号
//-----------------------------------------------------------
function getSector:boolean; // ダイレクト読み取り
var
dwRet : integer; // Seekのリターンコード
dwSize : DWORD; // 読み取ったバイト数
iRet : Boolean; // Readのリターンコード
real_ofs : int64; // 読み込もうとする位置(先頭からのバイト数)
p_lo : integer; // SetFilePointerで使用するseek相対位置の下位32bit
p_hi : integer; // 上位32bit
begin
result := false;
SectorNum := 1; //一度に読むセクタ数
Max_num := SectorNum * SECTORSIZE; // 一度に読むバイト数
// ハンドルの取得
DHandle:=CreateFile(PChar(drvname),GENERIC_READ or GENERIC_WRITE,
0,nil,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0 );
if DHandle = INVALID_HANDLE_VALUE then begin // Openエラー処理
showmessage('open device エラー');
exit;
end
else
begin //
real_ofs := STsector * SECTORSIZE; // seek位置をバイト単位で取得
p_hi := real_ofs div 2147483648; // 上位32bitを計算
p_lo := real_ofs mod 2147483648; // 下位32bitを計算
dwRet:= SetFilePointer(DHandle, p_lo, @p_hi, FILE_BEGIN ); // seek
if dwRet <> -1 then
begin // 1セクタ分をbuf[]へ読み込み
iRet := ReadFile(DHandle,buf,Max_num,dwSize,nil);
if iRet = False then begin // Readエラー処理
showmessage('Read device エラー');
CloseHandle(DHandle);
exit;
end
// dump_Buf; 読み取ったバッファの16進ダンプルーチン呼び出し
end else
begin // seekエラー処理
showmessage('Seek エラー');
CloseHandle(DHandle);
exit;
end;
end;
CloseHandle(DHandle);
result := true;
end;
※申し訳ありません,先頭の空白がGooによって自動的に削除されてしまうようです。