AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Festplattenzugriff / Imagedatei

Ein Thema von _frank_ · begonnen am 12. Okt 2007 · letzter Beitrag vom 31. Okt 2007
Antwort Antwort
Benutzerbild von _frank_
_frank_

Registriert seit: 21. Feb 2003
Ort: Plauen / Bamberg
922 Beiträge
 
Delphi 3 Professional
 
#1

Festplattenzugriff / Imagedatei

  Alt 12. Okt 2007, 22:53
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
Angehängte Dateien
Dateityp: zip hddzugriff_156.zip (112,6 KB, 20x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von _frank_
_frank_

Registriert seit: 21. Feb 2003
Ort: Plauen / Bamberg
922 Beiträge
 
Delphi 3 Professional
 
#2

Re: Festplattenzugriff / Imagedatei

  Alt 14. Okt 2007, 13:56
keiner eine Idee, worans liegen kann? *push*
  Mit Zitat antworten Zitat
Benutzerbild von _frank_
_frank_

Registriert seit: 21. Feb 2003
Ort: Plauen / Bamberg
922 Beiträge
 
Delphi 3 Professional
 
#3

Re: Festplattenzugriff / Imagedatei

  Alt 16. Okt 2007, 16:43
ich habs mit der hier gezeigten Variante hinbekommen.

Gruß Frank
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.163 Beiträge
 
Delphi 12 Athens
 
#4

Re: Festplattenzugriff / Imagedatei

  Alt 30. Okt 2007, 20:09
SetFilePointer(hDevice, (Sector-1) * SectorSize, [color=#ff0000][b]nil[/b][/color], FILE_BEGIN ); also wenn ich das seh, dann kann dieses nur auf die ersten 4 GB der Partition zugreifen.
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:
var i8: Int64;

i8 := Int64(Sector-1) * SectorSize;
SetFilePointer(THandle(Handle), Int64Rec(i8).Lo, @Int64Rec(i8).Hi, FILE_BEGIN);
PSS: das nächste mal bitte einach im MSDN/PSDK nachlesen wie gewüschte Funktionen verwendet werden müssen.
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?
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von _frank_
_frank_

Registriert seit: 21. Feb 2003
Ort: Plauen / Bamberg
922 Beiträge
 
Delphi 3 Professional
 
#5

Re: Festplattenzugriff / Imagedatei

  Alt 31. Okt 2007, 11:43
Zitat von himitsu:
also wenn ich das seh, dann kann dieses nur auf die ersten 4 GB der Partition zugreifen.
ich hoffe seine Platte ist nicht größer, denn sonst werden bei Positionen über 4 GB (also ab Sektor 8388608) falsche Sektoren ausgelesen!
naja, ich fange erst bei Offset 500000000 an, sprich 20GB. Da fängt die erweiterete Partition an, welche ich sicher soll. Die Systempartition enthält keine wichtigen Daten, daher brauch ich die nicht sichern.
Zitat von himitsu:
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:
var i8: Int64;

i8 := Int64(Sector-1) * SectorSize;
SetFilePointer(THandle(Handle), Int64Rec(i8).Lo, @Int64Rec(i8).Hi, FILE_BEGIN);
PSS: das nächste mal bitte einach im MSDN/PSDK nachlesen wie gewüschte Funktionen verwendet werden müssen.
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)
frage mich grade, warum ich die funktion nicht nachgeschaut hatte, obwohl das eigentlich der logischste Fehler gewesen wäre...
Zitat von himitsu:
Ach und mal eine Frage, warum leßt ihr denn nicht gleich die Platte selber komplett aus?
weil ich kaum ein Image (256 MB) von der platte komplett runterbekomme wegen den Lesefehlern. Wenn es zu viele werden, kam es schon öfters vor, dass sich die Platte abmeldet.

Danke & Gruß Frank
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.163 Beiträge
 
Delphi 12 Athens
 
#6

Re: Festplattenzugriff / Imagedatei

  Alt 31. Okt 2007, 12:43
[quote="_frank_"]naja, ich fange erst bei Offset 500000000 an, sprich 20GB.
Zitat:
wenn nur mit dem 32-Bit-Cardinal gearbeitet wird, dann lieg die höchste deefinirbare Adresse bei unter 4 GB, da hilft uch kein Offset, denn dieses wird ja auch nur in diesen "begrenzten" Parameter eingerechnet.



quote="_frank_"]weil ich kaum ein Image (256 MB) von der platte komplett runterbekomme wegen den Lesefehlern.
ich dachte nur, weill ihr ja zuerst mit Winhex ausgelesen habt und dann versuchtet das was er nicht lesen konnte selber nochmal auszulesen ... wenn's Winhex nicht kann, hätt man's ja och weglassen können.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von _frank_
_frank_

Registriert seit: 21. Feb 2003
Ort: Plauen / Bamberg
922 Beiträge
 
Delphi 3 Professional
 
#7

Re: Festplattenzugriff / Imagedatei

  Alt 31. Okt 2007, 13:00
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
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.163 Beiträge
 
Delphi 12 Athens
 
#8

Re: Festplattenzugriff / Imagedatei

  Alt 31. Okt 2007, 13:51
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
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:36 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz