原文; l# |2 L9 [* P' |. i+ m" U
http://pygments.org/demo/599/
1 C% m9 t/ [+ p* F4 ]8 h9 e% N4 }' a! B. @% g0 T- A
CyroBF Extract1 A+ @2 B) B4 D% p0 a
' d, s9 N6 r# r0 D K+ \7 tUse this style: manni perldoc borland colorful default murphy vs trac tango fruity autumn bw emacs pastie friendly native
; P2 Y( K3 S0 F6 G# J OSubmitted by Ruzzz on Feb. 8, 2008 at 6:12 p.m. $ S2 m' p7 j8 ^4 U
Language: Delphi. Code size: 4.0 KB.
/ I# R0 S0 q! t: `& g' N/ s% _. E
% o# J h( w4 \, a9 \procedure SaveFileFromStream(FileName: String; FileStream: TFileStream; FileOffset, FileSize: Cardinal);
, a9 R8 N+ C" b+ ^0 U# r* {+ w6 ivar2 j% w6 X6 f4 E
SaveFile: TFileStream;$ Q* d; A. [+ F9 V- |* E
SaveCurrentPosition: Int64;
' J% v, m% c' f( D0 ] nbegin
/ J" o" p, Y) ]( { SaveCurrentPosition := FileStream.Position;% l; U- L Q, e9 j! {8 L7 f. f- {
SaveFile := TFileStream.Create(FileName, fmCreate);
: k# ?* m( m# G9 V. X8 { try S9 v, Z9 [* d( r
FileStream.Position := FileOffset;, U# l. k7 w( W7 [5 _+ D
SaveFile.CopyFrom(FileStream, FileSize);
6 h; A2 t. l) Z9 G6 H$ u. Y finally0 E0 U9 u# U; e. c4 w
FileStream.Position := SaveCurrentPosition;
: {4 D$ `+ l! u0 H7 C' x+ ^ SaveFile.Free;0 L- j4 ~8 J6 o3 O
end;: u; y- W: B$ ^
end;# K7 V8 t! D. O$ D" W9 M* R
/ `7 ^. s+ X* q) n, @
function ReadArchive(filename: String): boolean;
% T& J1 X1 y( \- n& d l0 _7 cconst. p+ }5 x& w1 F% n2 b
Signature = 'CryoBF - 2.02.0';
, t9 X& y% L' e1 p- k, Gvar7 l6 a; ~& e! k% k9 Y
f: TFileStream;
8 Y! h: ~2 r' X, U) o- `! ^& b FolderOffset, FirstFileOffset,
3 r/ u) i$ Z+ [$ b% } ObjectNameLength, TypeOfObject, FileSize, FileOffset: Cardinal;3 P$ k. [/ l" c
TempString, FolderName, ObjectName: String;
7 L+ n% L3 ^$ X2 |- ?" f' R1 ?
5 K! ^6 K3 s. h6 g1 ^, |3 c procedure GetFolderContent(CurrentRootNode: TTreeNode);
5 ]$ a; K5 r- r) {. v var
/ J0 a' B0 ]& X, @* T$ e i, NumberOfObjects: Cardinal;
( p1 U' K6 o( {/ j currentNode: TTreeNode;
7 L, i: _: I" `. H9 F begin% J& W5 j* _9 G: I7 V/ s- [
/// Создаем текущую папку и переходим в нее
9 u4 d9 Y+ Y3 Y/ u; u# V /// CreateDir(FolderName);1 K9 P5 O. Y) K) A+ ~% Q& s$ Q' M. f
/// ChDir(FolderName);9 N( \2 j0 T4 h. J
% Z) F% E8 ^6 ]/ A
// Создаем ветку в дереве0 A4 h/ m' d- w, O, Z* r8 d
TempString := 'Папка: ' + FolderName + ' (Обьектов внутри: ' + IntToStr(NumberOfObjects) + ')';& b8 \( Z% o7 @1 z5 M7 l
currentNode := Form1.TreeView1.Items.AddChild(CurrentRootNode, TempString);
+ M+ b) k" q6 o# d3 w$ {$ d6 h, \9 Z& \$ s% u `& [4 Z
// Читаем кол-во обьектов# u+ C/ ^; D, V' ~# y5 Y
f.Read(NumberOfObjects, SizeOf(NumberOfObjects));
$ p E& H2 h! E* D( v# n9 L4 @& \# g( o
// Проходи по всем обьектам
( G# ^( K7 x5 M* c! F8 p for i := 1 to NumberOfObjects do begin4 h; q: k4 T$ w$ t, K
// Читаем имя обьекта
/ i2 d: E+ l9 L f.Read(ObjectNameLength, SizeOf(ObjectNameLength));
8 z) |& U$ T: c9 p: `, X SetLength(ObjectName, ObjectNameLength);
0 s8 O( |7 L( Y& z. m$ Y f.ReadBuffer(ObjectName[1], ObjectNameLength);" [, p- `2 B( G+ Z- ^4 ^2 C$ T
// Узнаем тип обьекта
7 |6 z5 Q+ |: D5 f0 g f.Read(TypeOfObject, SizeOf(TypeOfObject));
5 q7 q4 B, z J9 G4 V // Если это папка, то
1 F. }3 u9 @# s" n1 e; @# y) {7 k if TypeOfObject = 1 then begin
9 o7 M/ N/ B% |# a" X; ~ FolderName := ObjectName;5 f4 D4 P8 X3 \6 d# x# Z8 @3 A
// Проходим по ее содержимому9 W o. o" m8 W! G
GetFolderContent(currentNode);
2 E& n( ~! u/ d: s) V
" f1 d: F8 d; ~' H7 a5 Q /// Выходим из вложенной папки
, ?& a* F3 V% g& f5 ]/ T) u, H+ q /// ChDir('..');
# Q9 `. }9 |# s( u' v, H; I end
% G! L/ r, `( l1 ] // Если это файл, то3 v* u) Z7 v( K) w% u8 S+ U
else begin
' I4 r% c% g$ \" k; G9 d! c" m // Читаем его размер! d- a3 T) E, {# T; C% H V
f.Read(FileSize, SizeOf(FileSize));8 e3 x% M% L+ T. F- n M: }2 g6 e
// Пропускаем 4 байта нулей
2 z; P6 r3 R: v0 ?' F' i$ ]+ R: H f.Position := f.Position + 4;* M' F$ P& `) d3 p( `# r5 ^
// Читаем смещение этого файла.
* ~, f( z* \& R# a* g) P // Не забываем, что это смещение относительно FirstFileOffset,. @) H6 C4 j, H
// а не начала файла!" G9 P' T! j$ @# n
f.Read(FileOffset, SizeOf(FileOffset));6 K& E+ e- ~# `
: a6 n# l/ m8 d4 m' j# j( ^
// Создаем в дереве соответв. ветку о файле
* r# @6 |$ R) _+ e8 k TempString := 'Размер: ' + IntToHex(FileSize, 8) +6 I9 s& U/ ?) N6 P
'; Смещение: ' + IntToHex(FileOffset, 8) +
8 ?* h% {1 r0 i; E' W/ Y% ` '; Имя: ' + ObjectName;$ E- n$ @/ H6 p: |1 ?, g' L
Form1.TreeView1.Items.AddChild(currentNode, TempString);
' t3 j2 H6 j% `. C# `/ D. v; z, i! A2 d+ ]4 Q2 U# e# e
/// Создаем соответв. файл. Т.е. распаковываем.
5 V9 ^: f5 w8 \- S. A& R8 _# p /// SaveFileFromStream(ObjectName, f, FirstFileOffset + FileOffset, FileSize);$ U C. q" e/ g R3 u
end;
. l3 i, V7 @' X2 y end;# o# H+ F" @- T: E9 l; E" R$ [
end;5 b6 k L2 I9 x9 |
3 Y0 u& i. j7 i4 W/ i* ~! s1 H3 P6 i" _- z
begin* I0 l" [$ {( X: ?) U0 Y/ z3 Z
Result := false;" I% p) y# V. L/ ?
// Открываем файл архива для чтения @) K3 a% ]. H' N. x
f := TFileStream.Create(filename, fmOpenRead);3 Y6 o/ D' w' X/ c1 j. _
try& p7 B6 N9 T. q, R: P+ l D7 t
// Проверяем сигнатуру файла :) На всякий случай!
' Q1 K3 N, \5 ~* W3 O9 I- o! B SetLength(TempString, Length(Signature));
: T) K, N! M) w, K c8 ]) |- R f.ReadBuffer(TempString[1], Length(Signature));: p/ W; {% v! q
if TempString <> Signature then Exit;$ h% h0 M! E$ a
7 c+ F& y8 }6 g; W // Пропускаем 9 "не нужных" байтов2 T+ Q" e6 C- g3 Z( T5 I# z9 U
f.Position := f.Position + 9;
3 h; k4 W9 e- D5 v5 j: i // Читаем смещение корневой папки2 `& f! N: V% O
f.Read(FolderOffset, SizeOf(FolderOffset));) i, \- @6 \8 x& U# {! K8 z
// Читаем смещение первого файла, V0 X1 M* x; {, l& V9 [- L
f.Read(FirstFileOffset, SizeOf(FirstFileOffset));! [ Z6 m- A7 e
// Переходим к корневой папке& {; f0 X- ]5 u4 H& B+ S
f.Position := FolderOffset;
: i* q) O6 e+ D% v; K
* L" ], j6 {) m, t; |- u# ]2 \ /// Переходим в папку в которой будем расспаковывать архив9 ~$ h3 I- C. j* H8 X
/// ChDir(ExtractFileDir(filename));
# S' F$ l, }' U4 J7 m, k
; Y7 ]2 r1 L. S) m$ f0 A3 C // Корневую папку назовем по имени файла: d E7 |* E7 r/ G0 J+ Z2 D& V+ a( O
FolderName := (ExtractFileName(ChangeFileExt(filename,'')));7 U. Z0 Y! S+ v# g) b& N, O
* s* V% \4 x- V7 q // Начинаем обход корневой папки$ {- c+ G# H( P* _4 }
GetFolderContent(nil);( F- |+ U8 _3 A& B% E( |4 |
! h( V5 R y2 j+ @ Result := true;' F' u. ?* w! @6 @2 n$ U' c
finally+ z. c0 n; E+ }
f.Free;
9 y6 {. w' `/ s7 J end;
' d+ c. {- {- o+ {end;
" |+ F6 W$ I$ p) ~$ t
[1 t+ z3 `) k) @procedure TForm1.Button1Click(Sender: TObject);
# ?$ j: i, \0 B' [- p) |; R2 pbegin
0 ^1 O2 ^2 s9 N1 C if OpenDialog1.Execute then begin
8 A9 B: r5 O8 t4 P TreeView1.Items.Clear;$ w3 z Q0 Z$ l# y, h1 C# y& `# e( \
TreeView1.Items.BeginUpdate;
: w! E, V I J' N2 H try* E$ l3 F7 c0 ]' _6 b3 M
if ReadArchive(OpenDialog1.FileName) then
8 e6 v7 _3 ]$ J' H: [) \! s // Все нормально
& l' ?$ o1 v8 ]( U* B else' r# A+ @' { x3 @0 j
// Какая-то ошибка;
" P C7 e! d5 Q( E4 { finally1 |* l6 k7 w2 Y0 T4 P' u3 `& s
TreeView1.Items.EndUpdate;
* c$ L! b8 @ \' ~1 k' J end;2 C2 D6 A; z: f, {% U; U: y
end;
9 t9 p E- ?7 X/ L6 ?. rend; |