Moin,
aus Gründen der Datenrettung bin ich dabei, von nem Kumpel seiner Festplatte ein Image mit Winhex zu ziehen. Funktioniert, wenn auch träge, ganz gut. Zwischendurch sind immer mal nicht lesbare Sektoren, die Winhex mit dem String ' ? BAD SECTOR ? ' kennzeichnet. soweit so gut. Da das eine ziemliche fummelei ist, diese Blöcke manuell neu von der Platte zu kratzen, hab ich mir gedacht, schreib ich mir ein Programm dafür.
die hauptroutine (scant das image nach dem string durch und schreibt die Offsets in eine Textdatei+länge).Funktioniert super
Wenn ich das programm nicht mit D3 kompiliere (wegen Int64), soll die datenrecovery-Funktion aktiv sein (Compilerschalter). Diese macht nichts weiter, als den offset im Image zu einem gegebenen Startoffset hinzuaddieren (um so auf den Festplattenoffset zu kommen) und durch 512 zu teilen = Sektornummer. Dann soll er einen Sektor laden und diesen an der jeweiligen Stelle in die Imagedatei schreiben. nur komischerweise bricht die readsektor-funktion immer ab und der Buffer ist leer (nur Null-Bytes).
in Edit3 steht der Festplatten-Startoffset: '500000000' (20GB-Grenze, beginn des ersten Images)
Combobox1 ist gespickt mit der Laufwerksbezeichnung 'PhysicalDrive0'.
Delphi-Quellcode:
function ReadSector(Sector: Integer; buffer: pointer; Drive: string):Boolean;
const
SectorSize = 512;
var
hDevice: THandle;
DevName: string;
nb: {$IFDEF VER100}Integer{$ELSE}Cardinal{$ENDIF};
begin
result:=false;
if WIN32PLATFORM = VER_PLATFORM_WIN32_NT then
begin
DevName := '\\.\'+Drive;
hDevice := CreateFile(pChar(DevName), GENERIC_READ,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if (hDevice = INVALID_HANDLE_VALUE) then
begin
Result:=False;
Exit;
end;
SetFilePointer(hDevice, (Sector-1) * SectorSize,
nil, FILE_BEGIN );
Result := ReadFile(hDevice, buffer^, SectorSize, nb, nil) and
(nb=SectorSize);
CloseHandle(hDevice);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var fs:TFileStream;
sl:TStringlist;
buf:string[16];
b:array[0..511] of byte;
s,e,n,c,i:cardinal;
{$IFNDEF VER100}
fpbase,fpSector:Int64;
{$ENDIF}
begin
abort:=false;
fs:=TFilestream.Create(edit1.text,fmOpenReadWrite);
sl:=TStringlist.create;
s:=0;
n:=0;
{$IFNDEF VER100}
fpBase:=StrToInt64('$'+edit3.Text) div 512; //calc Base-Sector from Offset given
{$ENDIF}
while not abort and (fs.Position<fs.Size) do
begin
fs.read(buf[0],16);
if pos('BAD SECTOR',buf)>0 then
begin
inc(n);
s:=fs.Position-16;
while pos('BAD SECTOR',buf)>0 do
begin
fs.read(buf[0],16);
end;
e:=fs.position-16;
sl.Add(IntToHex(s,8)+' - '+IntToHex(e,8)+' ('+IntToHex(e-s,4)+')');
{$IFNDEF VER100}
if CheckBox1.checked then
begin
fpSector:=fpBase+(s div 512);
c:=(e-s) div 512;
for i:=0 to c-1 do
begin
fs.position:=s;
if not ReadSector(fpSector,@b,combobox1.text) then
ShowMessage('Can''t read from disc');
fs.write(b,sizeOf(b));
inc(fpSector);
inc(s,512);
end;
end;
{$ENDIF}
end;
Label1.caption:='Offset: '+IntToHex(fs.position,8)+' ('+Inttostr(n)+'-'+IntToHex(s,8)+')';
application.ProcessMessages;
end;
sl.SaveToFile(edit2.text);
sl.free;
fs.free;
end;
was mich noch wundert ist, dass sich die Streamposition innerhalb der for-schleife nicht verändert, obwohl ich explizit den Startwert s um 512 erhöhe und im nächsten Schleifendurchlauf der position zuweise (eigentlich sollte das write reichen, oder? darüber schweigt sich meine DOH aus...).
meine Testroutine für die ReadSektor-Funktion funktioniert tadellos, jedoch in der Hauptroutine nicht....
Delphi-Quellcode:
procedure TForm1.Button4Click(Sender: TObject);
var buf:array[0..511] of byte;
fs:TFilestream;
begin
ReadSector(0,@buf,combobox1.text);
fs:=TFilestream.create('test2.dat',fmCreate or fmOpenReadWrite);
fs.Write(buf,sizeOf(buf));
fs.free;
end;
ich hoffe mal, ich habe alle Infos zusammen, und ihr könnt mir helfen. Habe langsam keine Idee mehr, warum der abbricht bzw. wie man das umgeht. ich habe den offset zum testen mal geringer angesetzt, um selbst innerhalb des Int32-Wertebereichs zu bleiben, trotzdem Abbruch.
leider hab ich kaum demo-Programme gefunden, um mir da mehr infos zu holen (bei Luckies seh ich nicht so ganz durch *g*)
//edit: Programm angehängt
Gruß Frank