原文
6 P# o4 n4 `/ m+ Fhttp://pygments.org/demo/599/8 p: ]' i0 `# Q% H! u
d1 F1 ]' c: o3 d" v+ Y# @) L
CyroBF Extract$ Y- R# m" w! R7 s2 N7 n( d/ r
$ @* |9 \$ J4 r" v; B6 i4 dUse this style: manni perldoc borland colorful default murphy vs trac tango fruity autumn bw emacs pastie friendly native 0 U- k* z, ]' B2 r" h# `
Submitted by Ruzzz on Feb. 8, 2008 at 6:12 p.m. ; z' W( X* J9 Z: G1 l5 N
Language: Delphi. Code size: 4.0 KB.
+ R; {; V. b* w) F3 u, m4 {3 T" L4 K/ C# g& ^: m$ P) R, M4 z
procedure SaveFileFromStream(FileName: String; FileStream: TFileStream; FileOffset, FileSize: Cardinal);9 z& h. l, @/ Y" E+ \
var
( n# R8 `$ P! {" o3 @ SaveFile: TFileStream;; G, I5 C6 M( l
SaveCurrentPosition: Int64;
' N+ R" R7 s" Hbegin
1 y2 K" {7 g% ?- T SaveCurrentPosition := FileStream.Position;
1 m' Q) O+ Z' B+ [" d9 x0 V1 C SaveFile := TFileStream.Create(FileName, fmCreate);
/ R" `) _0 i% O' H1 Z) @ try6 Y3 d3 A/ Q6 f7 O C
FileStream.Position := FileOffset; O6 y$ V# D. A3 c J+ U; u
SaveFile.CopyFrom(FileStream, FileSize);3 b% M- f D9 j ^5 _4 @
finally1 ^9 J* v( U6 o* @
FileStream.Position := SaveCurrentPosition;
( a" W2 t/ m" z! I8 J SaveFile.Free;
! |/ w/ H8 I: C( P4 a end;, b* n7 I. m3 W, r8 w
end;
. ~+ n1 k3 i$ F. F* \9 b5 x8 s0 z/ t& o
function ReadArchive(filename: String): boolean;
2 a& w \9 y- ]9 iconst8 c D9 A, N& s' f2 a! n: H Z# E
Signature = 'CryoBF - 2.02.0';
) t4 m4 w3 |1 _var
. d. v* O* o' H; I f: TFileStream;
9 u5 h3 W! z. L9 E) `& a. ] FolderOffset, FirstFileOffset,
; c" k# ]. S, k# Q$ M$ i ObjectNameLength, TypeOfObject, FileSize, FileOffset: Cardinal;
8 ?9 `5 {% s$ M' k- a. s$ T2 _ TempString, FolderName, ObjectName: String;
* f- ]/ N* N, ?5 @$ D0 K8 O4 J* @- W( R& F6 H; r/ {6 }
procedure GetFolderContent(CurrentRootNode: TTreeNode);
% G q* N$ w/ t1 c2 W& G; C var
! p9 ~3 u$ F" u3 \$ f5 p; M6 o5 w3 j i, NumberOfObjects: Cardinal;! u. d* P8 |7 I" `/ Q: \
currentNode: TTreeNode;
$ A9 K! [! {& c6 [ begin: @9 X/ K% P( v+ C3 H5 W
/// Создаем текущую папку и переходим в нее
- C2 z* {: `$ Z: w, ~ /// CreateDir(FolderName);* j& Y. I& b% z$ Q }
/// ChDir(FolderName);
; f0 F: r% P' g' U; b% E. a8 k; w+ n, D' `3 f; \8 a
// Создаем ветку в дереве
5 t- @' S ? v F6 h+ R: ]4 ^ TempString := 'Папка: ' + FolderName + ' (Обьектов внутри: ' + IntToStr(NumberOfObjects) + ')';+ E) I4 u' h1 e2 M4 M& W* N1 X: P
currentNode := Form1.TreeView1.Items.AddChild(CurrentRootNode, TempString);: X7 y4 J) }7 U( T! T
! h2 \* \) s: _5 m2 u8 h) W7 M
// Читаем кол-во обьектов
7 h/ m5 \- n2 z' V! t1 l3 a f.Read(NumberOfObjects, SizeOf(NumberOfObjects));3 v0 l$ d# ]$ m& p0 O
- Y" }6 R4 B9 t7 _7 C2 t+ |# e, x& B
// Проходи по всем обьектам: b. T4 ?1 a% Q3 Q/ B0 n$ p8 G
for i := 1 to NumberOfObjects do begin3 |: W0 z9 m3 L- d
// Читаем имя обьекта
2 R% J! G" r% D' o" C5 @ f.Read(ObjectNameLength, SizeOf(ObjectNameLength));- w1 _" r5 P, b0 y5 N/ U0 M. x
SetLength(ObjectName, ObjectNameLength);- S m2 L; d# j4 A j4 h
f.ReadBuffer(ObjectName[1], ObjectNameLength);8 u: ^$ N4 H {- c# D
// Узнаем тип обьекта P& Q5 J8 ~4 l+ a$ v
f.Read(TypeOfObject, SizeOf(TypeOfObject));6 D, { z3 [ W9 t/ q
// Если это папка, то+ Q0 S( w7 E( X! d4 i2 L. N' T
if TypeOfObject = 1 then begin
& t! P3 A7 K+ |7 p* }! o- ? FolderName := ObjectName;
8 }5 q4 h4 z! X5 i9 C- ` // Проходим по ее содержимому
" J* K. [9 K& V$ R GetFolderContent(currentNode);7 ~# R7 b7 r3 x/ Z+ f
% a; s" j1 l N) i
/// Выходим из вложенной папки ~9 \# G1 v2 f% N
/// ChDir('..');! L4 g# d% c8 N& _8 S5 e7 G5 _ A
end% A+ X2 ?, U7 ^; w/ Y6 f
// Если это файл, то8 z9 H) m0 B6 u
else begin
& `7 T" L H/ D ~+ ], s" b // Читаем его размер% S, O5 ^8 t$ K% A
f.Read(FileSize, SizeOf(FileSize));# ~/ J7 O) F& b5 k- i
// Пропускаем 4 байта нулей
4 q8 q$ l" G6 G/ N9 _7 `' x2 _; V# J f.Position := f.Position + 4;
) @% Q$ g+ m% C) @9 }& B // Читаем смещение этого файла.( ?& N# Q5 j# f. N
// Не забываем, что это смещение относительно FirstFileOffset,1 I- q/ b, D$ n+ i* D0 T& l \
// а не начала файла!
5 E% b" l9 D( ^* \5 [8 z f.Read(FileOffset, SizeOf(FileOffset));, i3 q) M; X9 H' G: W) C4 h
2 A( p0 ] g2 z2 x/ Y' [ // Создаем в дереве соответв. ветку о файле
0 U5 p" c- l- w0 Q0 c7 u$ f TempString := 'Размер: ' + IntToHex(FileSize, 8) +
+ r! c9 K! _0 H/ D '; Смещение: ' + IntToHex(FileOffset, 8) +
, L; K7 y1 T& `" a& G '; Имя: ' + ObjectName;% e' S9 ~8 r; P: y. W' v- @
Form1.TreeView1.Items.AddChild(currentNode, TempString);( }2 a: N1 k! ]; K
' ?$ R. z- w% r# C' ]
/// Создаем соответв. файл. Т.е. распаковываем.6 |% V: k5 e3 y/ F
/// SaveFileFromStream(ObjectName, f, FirstFileOffset + FileOffset, FileSize);) H o @3 k+ w) _' W9 v
end;. ~& ~" A/ I# ?4 [3 H
end;
0 M+ Q; @0 |2 W0 h% c! a8 A" @, g end;' }& o0 o( k# _, M* N
, [3 \" e( i9 ~4 e: C! p9 l# K2 m8 D/ {/ ~7 I, v. M; E
begin
) N& T5 Z' L( G( F Result := false;
. e1 |( L1 j" M. R // Открываем файл архива для чтения% n, P$ i( C( k% E. q4 N4 u
f := TFileStream.Create(filename, fmOpenRead);8 e7 q4 w" D, D. V5 m+ N
try
9 V- J. v: f: z$ y9 h1 P' ~ // Проверяем сигнатуру файла :) На всякий случай!; c5 r$ ?2 n+ Y2 \; k6 Y# S5 Q) ?
SetLength(TempString, Length(Signature));
* K- c7 a. U( m5 v f.ReadBuffer(TempString[1], Length(Signature));
~$ N4 G7 i" F9 |6 d if TempString <> Signature then Exit;! [) Q) H; z' |" J# D$ ]- h
5 C8 S2 t9 O+ D+ `+ j // Пропускаем 9 "не нужных" байтов# Q( r- V! _5 G) {' b
f.Position := f.Position + 9;4 S( d4 N# V- v+ \+ F$ ?
// Читаем смещение корневой папки
/ p( L0 j' b7 Z9 z P f.Read(FolderOffset, SizeOf(FolderOffset));7 k! \, T+ v. s% K. h# c5 A! v
// Читаем смещение первого файла7 X1 Q& L1 R# S
f.Read(FirstFileOffset, SizeOf(FirstFileOffset));
+ Q. Y- Z3 G/ T6 g; o: B // Переходим к корневой папке! H( m B- ]- H2 a3 A
f.Position := FolderOffset;7 h& E' u1 K( X6 P) r4 P6 g
/ S+ g1 q: h0 n
/// Переходим в папку в которой будем расспаковывать архив
7 G6 R' e% B; z /// ChDir(ExtractFileDir(filename));
2 F" |" U h6 I' I1 X6 H( z- H+ ~& b2 b6 }" D5 z+ s
// Корневую папку назовем по имени файла2 c( _) s9 Y) J9 J
FolderName := (ExtractFileName(ChangeFileExt(filename,'')));7 p) Q) f! S9 H( J2 X
8 ~" |& z7 U: H, v
// Начинаем обход корневой папки
9 H* F f0 ~* N% f GetFolderContent(nil);9 o* U y! z1 K- d) }: U- G
0 F; x$ z5 r9 e/ L1 `# }# n Result := true;
& L- B0 B0 P0 M) B1 X, _ finally! J. A1 S' ~3 I' @2 g! b
f.Free;
/ ^8 a- J2 S" B- |/ z5 v- g0 G end;3 \/ ~# f$ `- q2 V# w4 |; x
end;
+ W' T/ D! F2 o$ C" |
* ^ z; h% y/ ^) B3 Zprocedure TForm1.Button1Click(Sender: TObject); v/ p7 v! e# j
begin
' D: z" I, }; \& _* q, I if OpenDialog1.Execute then begin
/ B) A) l" {4 I7 D. `0 i TreeView1.Items.Clear;
2 j' k/ q! O; e% U+ a H9 e TreeView1.Items.BeginUpdate;% l/ D; p# v% T) ?) G" T" ?0 `' {9 {
try
; W" G% U& d. l- G G if ReadArchive(OpenDialog1.FileName) then
' m8 b( \. M* e // Все нормально
* b3 m8 S' [+ z& w7 P/ B8 r6 T else1 ~1 S' a9 H: | m8 P$ Q" |
// Какая-то ошибка;; f4 t2 J: N1 ?
finally
& B! @( o- g$ z1 J TreeView1.Items.EndUpdate;0 |3 Y% h G3 A" o6 B1 x7 z
end;
0 ?: f* p$ Y5 K) b8 G* ]9 J- _ end;
9 ^( F4 D" n0 [! ~! p, [& ^* Eend; |