Autor Beitrag
Karlson
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 2088



BeitragVerfasst: So 20.04.08 16:35 
Servus :)

Ich habe ein bestimmtes Dateiformat welches simple analysieren möchte, ohne das die Datei vom Programm geöffnet werden muss (da dies etwas länger dauert, es handelt sich um eine "Replay-Datei" eines Computerspiels).

Ich habe eine super Dokumentation, in der steht welche Information ich an welchem Offset zu erwarten habe. Was ich jetzt brauche ist

a) eine Funktion die mir den Wert am Offset XYZ zurückgibt.
b) Evt. ein Tutorial oder ähnliches, dass mir ein wenig den allgemeinen Aufbau von Dateien erklärt. Was mich jetzt nämlich noch etwas verwirrt ist, dass es 3 verschiedene Header gibt, in denen immer die gleichen Offsets genannt werden. Zum Beispiel:

1.) Header:

ausblenden Quelltext
1:
2:
3:
4:
offset | size/type | Description
-------+-----------+-----------------------------------------------------------
0x0000 | 28 chars  | zero terminated string
0x001c |  1 dword  | fileoffset of first compressed data block (header size)


2.) Subheader:

ausblenden Quelltext
1:
2:
0x0000 |  1  word  | unknown (always zero so far)
0x0002 |  1  word  | version number (corresponds to patch 1.xx)


Das finde ich etwas seltsam, da ich dachte, dass man das Offset einfach als "Hausnummer" des jeweiligen Speicherblocks bezeichnen könnte. Jetzt werden die "Hausnummern" in der gleichen Datei aber ja mehrfach vergeben, desewegen bräuchte ich wohl auch noch eine Funktion in der ich irgendwie sagen kann auf welchen Header sich meine "Hausnummerangabe" bezieht.

Okay, vielen dank für Links oder Hilfen,

Lg.
Chryzler
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1097
Erhaltene Danke: 2



BeitragVerfasst: So 20.04.08 17:04 
Die Datei mit TFileStream öffnen, mittels Seek an die gewünschte Position springen, und mit Read deine Daten in eine Variable einlesen.
user profile iconKarlson hat folgendes geschrieben:
Das finde ich etwas seltsam, da ich dachte, dass man das Offset einfach als "Hausnummer" des jeweiligen Speicherblocks bezeichnen könnte.

Die Offsets sind natürlich relativ. Du musst schon wissen wo genau die einzelnen Header in der Datei liegen. Angenommen der Subheader würde direkt nach dem Header kommen, dann müsstest du zu jedem Offset im Subheader noch die Größe des Headers addieren.
Karlson Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 2088



BeitragVerfasst: So 20.04.08 17:26 
Aah, gut, danke. Da steht nämlich in der Dokumentation auch dabei:

Zitat:

The size of the header excluding the subheader is 0x30 bytes so far.


Also um auf das Offset 0x0002 the Subheaders zuzugreifen müsste ich an der Stelle (0x30+0x0002) suchen?

So, servus, ich hätt jetzt doch nochmal ein praktisches Problem:

Ich hab mir diesen Code "zusammenausprobiert":

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure TForm1.Button1Click(Sender: TObject);
var c : cardinal;
    ch : array[0..27] of Char;
    cd : cardinal;
    i : integer;
begin
c := FileOpen('c:\test\test.rep', fmOpenReadWrite);
 ReadFile(c, ch, 27, cd,  nil);
  try
   for i:=0 to 27 do
    begin
     memo1.lines.add(ch[i]);
    end;
   except end;
end;


So, der Test hat schonmal funktioniert, denn im Memo steht: "blablabla Replay File" (und noch ein paar nicht näher definierbare Zeichen^^ )

Jetzt mal zur ReadFile Funktion, ich hoffe ich hab das richtig verstanden:

1. Parameter: Ja, halt der beim FileOpen ermittelte Cardinal-Wert.
2. Parameter: In diesen werden dann die gelesen Dateien gespeichert?!
3. Parameter: Hieß ja BytesRead, also nehm ich dort wird halt gespeichert wieviel Bytes gelesen wurden. Was der soll weiss ich aber noch nicht so wirklich.
4. Parameter: Dieses POverlapped, was auch immer das ist, mit nil funktioniert es jedenfalls.

1.) Wie kann ich da jetzt an eine bestimmte Stelle springen, ich hab nach ein paar Beispielen zu Seek gesucht aber muss ehrlich sagen, die nicht auf meinen Fall übertragen zu können.
2.) Wenn ich dann mal irgendwann soweit bin an eine Stelle gesprungen zu sein, an der z.B. 2 Word-Werte gelesen werden sollen, dann ersetze ich den zweiten Parameter durch ein 2-Elementiges Word-Array?

Lg.

EDIT

Nächster Ansatz: Ich hab jetzt nach langem Suchen in der DP einen besseren Code gefunden, mit dem könnte man so arbeiten:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
  hFile := FileOpen('c:\test\test.rep[b][/b]', $0000);
  FileSeek(hFile, offset, 0);
  FileRead(hFile, mword, sizeOf(dWord));
  memo1.lines.add(inttostr(mword)) ;



Also damit funktioniert es!


Jetzt hätte ich aber noch eine Frage, die ist etwas knifflig, und weil ich hier schon zum 4 mal editiere füg ich einen neuen Post hinzu, damit es etwas übersichtlicher wird...