原文
2 Y- G9 \3 L% Chttp://pygments.org/demo/599/& F! I$ r8 ~7 Y2 T2 E9 ^
$ y5 l5 P! Q& Z" J
CyroBF Extract
. g- v5 j/ I: b6 c6 F P
1 n9 q+ y6 s1 W! t+ T/ Q( {! J# cUse this style: manni perldoc borland colorful default murphy vs trac tango fruity autumn bw emacs pastie friendly native 5 k+ ?" ]; B1 t: X- R' M
Submitted by Ruzzz on Feb. 8, 2008 at 6:12 p.m. - F6 s0 ]( G4 a' U6 o# |
Language: Delphi. Code size: 4.0 KB.
0 z( B* N1 w" w
6 C+ W& Z: i0 K! L& Mprocedure SaveFileFromStream(FileName: String; FileStream: TFileStream; FileOffset, FileSize: Cardinal);; N$ ]! M) y% i# t
var6 I1 k. |% A, o/ z8 h4 v7 T
SaveFile: TFileStream;$ M5 i* r8 l! E6 G! a% o0 M. c2 g
SaveCurrentPosition: Int64;
! P( N& f/ Y/ r4 D' ~$ Ybegin
& d) k. }7 m0 J% @; E- { SaveCurrentPosition := FileStream.Position;
1 E2 }( z' A, T7 f* i4 w" c9 ^: Q SaveFile := TFileStream.Create(FileName, fmCreate);4 Z. b7 o5 m) T1 U4 B
try
: |# t/ a0 m e FileStream.Position := FileOffset;
/ j ?8 B* K3 |2 s, n1 k SaveFile.CopyFrom(FileStream, FileSize);. S2 D" d6 q1 U
finally
' _9 D3 n, K9 S FileStream.Position := SaveCurrentPosition;
+ i2 [ c c0 O% v& F SaveFile.Free;4 f; @) e5 B4 u1 P! t6 s/ l
end;" c7 b( T) U% ~: H
end;
) y9 O7 q) b) s+ e( C, ^2 s8 k: h( W5 D( h( Q: p
function ReadArchive(filename: String): boolean;
0 F) b" S5 R! S% k# y: r p& zconst
+ q/ D. X* Y" z; B( o Signature = 'CryoBF - 2.02.0';0 z! `! G3 ~' }( L( V$ A
var
0 x4 }& I* A2 f f: TFileStream;
) b& {& m! Z; Y e' `1 S FolderOffset, FirstFileOffset,
" G. x' K" t& | ObjectNameLength, TypeOfObject, FileSize, FileOffset: Cardinal;, N0 t, s: w8 M0 M. w
TempString, FolderName, ObjectName: String;
$ x5 l- d. j* P! x4 A) V/ W; }
$ N3 T K+ E5 i6 t$ Z9 U procedure GetFolderContent(CurrentRootNode: TTreeNode);7 B; E8 q1 D) U
var
' G3 X$ {0 }8 q1 a# R i, NumberOfObjects: Cardinal;( w7 K9 K0 ^& C" P
currentNode: TTreeNode;
9 O0 U4 `! P" s# z" G' d. ` begin! x7 B7 G% O5 p- _5 ~) O+ q
/// Создаем текущую папку и переходим в нее- E3 d. \& @1 D. {
/// CreateDir(FolderName);9 B" T7 {& c, z) I. J
/// ChDir(FolderName);! W/ Z( K' x' ~% O6 h
: t$ }3 I( Y, }+ `1 O, V9 O; e
// Создаем ветку в дереве# w1 z1 B7 r" ^5 H; M# m0 A
TempString := 'Папка: ' + FolderName + ' (Обьектов внутри: ' + IntToStr(NumberOfObjects) + ')';* s2 y; v' K1 }( t# _9 {* f
currentNode := Form1.TreeView1.Items.AddChild(CurrentRootNode, TempString);" k( G* m' Y# K9 ~' i! Q
$ Q! L7 d" k9 R& j$ t, |; _
// Читаем кол-во обьектов
) E( h. A$ ^9 q# b7 E f.Read(NumberOfObjects, SizeOf(NumberOfObjects));
5 z3 T$ v7 Y4 N( }. v8 Q
8 T y0 T& B+ l& S4 O8 V" f5 s // Проходи по всем обьектам
5 N; u* p! F& B/ Z& x' E for i := 1 to NumberOfObjects do begin' k L8 c' r5 D( r: B. X
// Читаем имя обьекта3 m6 p4 C- f7 y, h! A! Y# Q
f.Read(ObjectNameLength, SizeOf(ObjectNameLength));
7 h4 t; B& D3 W7 m4 Z, l+ { SetLength(ObjectName, ObjectNameLength);. N: R* X0 P, P+ H" b
f.ReadBuffer(ObjectName[1], ObjectNameLength);
9 k: y1 ? [5 f/ G# C. K9 A // Узнаем тип обьекта8 [ ~: i. M4 a; `9 `$ R0 l
f.Read(TypeOfObject, SizeOf(TypeOfObject));
6 r$ e t: J* U, S0 B; J // Если это папка, то
1 _8 h8 i2 H2 p- X& A- ~ if TypeOfObject = 1 then begin( e" E: _8 H3 y: X( G$ Z, Y; `
FolderName := ObjectName;, ^8 K0 N- X7 L: Q2 H+ n
// Проходим по ее содержимому( t1 I' |0 s/ w( A8 j
GetFolderContent(currentNode);
. L* ]4 U" V7 b8 s9 D
. t; M. Z0 B `. @8 t6 q' g/ q /// Выходим из вложенной папки8 E& f- V8 P6 D: n! t
/// ChDir('..');
) Y$ L5 r1 f3 x/ e6 r end- M# d% ]% b3 q. J8 o+ l
// Если это файл, то
- U' I' Z1 H' } else begin$ k/ P' M0 G9 k) o) k
// Читаем его размер
: ?; S8 W; ~# C+ U5 X( u1 k f.Read(FileSize, SizeOf(FileSize));/ b g; @- i/ O, Q/ b* J5 P
// Пропускаем 4 байта нулей( }0 C/ k0 }' V) H
f.Position := f.Position + 4;
' c- c* P+ u" r2 Q$ Y: K: Z // Читаем смещение этого файла.! c+ B: y* o' ]7 y
// Не забываем, что это смещение относительно FirstFileOffset,
/ ~+ d! O5 k: l! a- `4 s // а не начала файла!% N& O$ @* b: Y# }( l
f.Read(FileOffset, SizeOf(FileOffset));; _8 a) g' f" P: }# D
3 R% ~( N! H0 |
// Создаем в дереве соответв. ветку о файле- H5 j" i8 f+ }- T' |' b
TempString := 'Размер: ' + IntToHex(FileSize, 8) +
6 c4 D4 t& r0 G" F, L9 ? '; Смещение: ' + IntToHex(FileOffset, 8) +
! z F; O; y8 K+ u9 g1 B* X '; Имя: ' + ObjectName;) O% p% Z Z; r6 i0 Y% {6 Y# O
Form1.TreeView1.Items.AddChild(currentNode, TempString);
, {! f- b) r& x; d$ p; z: P, K( w" K( h9 J+ Y
/// Создаем соответв. файл. Т.е. распаковываем.+ Y/ i/ v0 m7 I5 c+ A
/// SaveFileFromStream(ObjectName, f, FirstFileOffset + FileOffset, FileSize);
' r! a, }0 _/ |# N) S- { end;
$ `7 N* u& {: X% g0 R, I end;3 Y4 ~9 ?, d+ j6 H9 w8 c, L3 M
end;
; ~6 |0 M7 ]% ]
0 k3 `% h) i1 k2 c4 D: |; F" T9 Y' R0 }8 w5 C* z
begin9 M! D9 o/ P! e6 k
Result := false;
0 l3 _2 P: a: `; ] // Открываем файл архива для чтения# P# {* u H7 Q3 C* T) c8 z
f := TFileStream.Create(filename, fmOpenRead);
1 l G! N( P: g try
3 N i0 N$ A9 _! w% j _ // Проверяем сигнатуру файла :) На всякий случай!* X# w) w1 F% A) @9 x9 [: I! u
SetLength(TempString, Length(Signature));
+ |& W* O; |+ G1 t, B f.ReadBuffer(TempString[1], Length(Signature));
! o4 Z- `+ l, d# U4 f1 x. s if TempString <> Signature then Exit;
4 W* N; h2 V; e6 O. P
* a! n0 m' a# y2 ^ // Пропускаем 9 "не нужных" байтов
- o1 v7 S1 `$ R$ U4 Z3 s f.Position := f.Position + 9;
0 M/ m. m- [9 q% }6 V- K. r // Читаем смещение корневой папки: j. W! P/ q7 ^; d/ S
f.Read(FolderOffset, SizeOf(FolderOffset));9 k: z( K9 h9 ]% _9 q7 J
// Читаем смещение первого файла
/ D4 n& m( |. P. r6 Q) k f.Read(FirstFileOffset, SizeOf(FirstFileOffset));3 X+ }8 y% ^9 n$ |3 s6 m5 p
// Переходим к корневой папке
N, m6 Q8 ]+ O% i" ]' v% X- E f.Position := FolderOffset;! k$ C+ }: Z+ g# p5 @
' W9 }; q* v8 v/ J /// Переходим в папку в которой будем расспаковывать архив
3 \" n/ g7 t ]8 H /// ChDir(ExtractFileDir(filename));
0 m8 ~. s) k* I v. V
; ?6 V# I) Q; r4 n2 n // Корневую папку назовем по имени файла; ~% J1 Q0 T6 ^
FolderName := (ExtractFileName(ChangeFileExt(filename,'')));6 `' C# S! h! D4 h+ V
% p0 _2 l7 Q$ d- _
// Начинаем обход корневой папки
$ F x" S) I5 L5 I GetFolderContent(nil); c1 m8 e% Y1 p4 \, x
3 S, y* _& q( G0 {9 U% ^
Result := true;8 Q% w+ ^' G& u) \* }
finally7 U& u7 A- O- i0 k `
f.Free;( h9 w8 _+ ]" h1 c3 D/ u
end;
$ r" w3 X9 h9 u! |7 ?- j! _end;
+ {/ y0 e5 M6 Q" z( G( M& |: W" ]4 b' T6 Z7 f
procedure TForm1.Button1Click(Sender: TObject);, {; e7 B3 k. A \
begin
& i3 @' L' P- q* g if OpenDialog1.Execute then begin
" J7 b5 y; k8 A& B! }* c9 l TreeView1.Items.Clear;0 n/ w. Z+ }4 o$ p- X' `- J
TreeView1.Items.BeginUpdate;. S3 h, @6 `% Q
try6 L6 |, q, c& h! j" Y
if ReadArchive(OpenDialog1.FileName) then. k: E% d* ?- _% N7 P+ j
// Все нормально! i) n" ?: I- E# \4 H$ }3 v, C
else
. o" H5 ?4 R# M* c( b // Какая-то ошибка;
( B, I( R: w6 e finally
3 J% e$ D- y y. v6 {! [! a. p O TreeView1.Items.EndUpdate;
' r j& ]$ ~3 ]; X/ B end;
/ y+ [0 X6 B# W end;$ P- Z2 h2 I( @0 }9 e( X
end; |