![]() |
Festplattenzugriff / Imagedatei
Liste der Anhänge anzeigen (Anzahl: 1)
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:
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...).
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; meine Testroutine für die ReadSektor-Funktion funktioniert tadellos, jedoch in der Hauptroutine nicht....
Delphi-Quellcode:
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.
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; 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 |
Re: Festplattenzugriff / Imagedatei
keiner eine Idee, worans liegen kann? *push*
|
Re: Festplattenzugriff / Imagedatei
|
Re: Festplattenzugriff / Imagedatei
Delphi-Quellcode:
also wenn ich das seh, dann kann dieses nur auf die ersten 4 GB der Partition zugreifen.
SetFilePointer(hDevice, (Sector-1) * SectorSize, [color=#ff0000][b]nil[/b][/color], FILE_BEGIN );
ich hoffe seine Platte ist nicht größer, denn sonst werden bei Positionen über 4 GB (also ab Sektor 8388608) falsche Sektoren ausgelesen! das FileSeek ... sei froh, daß es da auch eine 64-Bitvariante von gibt (Delphi hat es da eigentlich nicht so mit solchen Funktionen (es mag immernoch seine 32 Bit zu sehr) PS: das 64-Bit-FileSeek macht intern das
Delphi-Quellcode:
PSS: das nächste mal bitte einach im MSDN/PSDK nachlesen wie gewüschte Funktionen verwendet werden müssen.
var i8: Int64;
i8 := Int64(Sector-1) * SectorSize; SetFilePointer(THandle(Handle), Int64Rec(i8).Lo, @Int64Rec(i8).Hi, FILE_BEGIN); Obwohl man eigentlich allein aus den Parameternamen den Grund hätte schon erkennen können
Code:
SetFilePointer(hFile: THandle; lDistanceToMove: [color=#ff0000]Longint;[/color]
lpDistanceToMoveHigh: [color=#ff0000]Pointer[/color]; dwMoveMethod: DWORD) Ach und mal eine Frage, warum leßt ihr denn nicht gleich die Platte selber komplett aus? |
Re: Festplattenzugriff / Imagedatei
Zitat:
Zitat:
Zitat:
Danke & Gruß Frank |
Re: Festplattenzugriff / Imagedatei
[quote="_frank_"]naja, ich fange erst bei Offset 500000000 an, sprich 20GB.
Zitat:
|
Re: Festplattenzugriff / Imagedatei
die Sache ist die, dass er zwischendurch immer mal beliebige sektoren nicht lesen kann. Nachdem die Platte mal "abgekühlt" ist, lassen sich diese sektoren wieder lesen. Jedochkann ich in dem bereich kein komplettes fehlerfreies 256MB-Image ziehen...daher der kleine trick. winhex stellt die fehlenden Sektoren ja schön mit dem string dar, so kann ich leicht danach suchen ;) ich hab das auch versucht mit hxd zu lesen, jedoch bekomme ich da nur CRC-Fehler, die ich scheinbar nicht ignorieren kann (also dass er nach dem fehlerhaften Block weitermacht).
das mit der 4GB-grenze leuchtet mir ein :) funktioniert auch ohne probleme...mittlerweile hab ich knapp 20GB komplett von der Platte gekratzt. Das suchen in dem Filestream könnte performanter sein (aktuell ca. 30 min wenn kein fehler vorhanden ist), aber geht auch so. Gruß Frank |
Re: Festplattenzugriff / Imagedatei
ich hatte(hab?) mal ein mini Programm, welches ich mir zwar zum auslesen von defekten CDs/DVDs mal gemacht hatte, da wurde alles gelesen und in 'ner 2. Datei wurde erfasst was nicht lesbar war, wo er dann später nochmal suchen konnte, aber *grübel* eigentlich müßte es hier auf meinem USB-Stick mit drauf sein, aber ich fand es nicht mehr o.O
sowas gibt's zwar schon, aber da war och noch 'ne ReCheckFunktion drin, zum nochmaligen gegenprüfen, oder früher Gelesenes mit aktuell Lesbarem übereinstimmt. ich schau daheim nochmal nach ... dacht jdenfalls ich hätte es nach meinem Systemchrasch nochmal sah :gruebel: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:45 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz