Mercurial > mplayer.hg
annotate unrarlib.c @ 24517:db41bc3d5b20
avoid rivatv_lock_nv40() from trashing the screen (patch by Guillaume Lecerf <fox at geexbox dot org>)
author | ben |
---|---|
date | Sat, 15 Sep 2007 18:44:54 +0000 |
parents | 0783dd397f74 |
children |
rev | line source |
---|---|
7446 | 1 /* *************************************************************************** |
2 ** | |
3 ** This file is part of the UniquE RAR File Library. | |
4 ** | |
5 ** Copyright (C) 2000-2002 by Christian Scheurer (www.ChristianScheurer.ch) | |
6 ** UNIX port copyright (c) 2000-2002 by Johannes Winkelmann (jw@tks6.net) | |
7 ** | |
18783 | 8 ** Modified for use with MPlayer, detailed changelog at |
9 ** http://svn.mplayerhq.hu/mplayer/trunk/ | |
15165
775330fe3889
Mark unrarlib imported files as changed to comply with GPL ¡ø2a.
diego
parents:
11013
diff
changeset
|
10 ** $Id$ |
775330fe3889
Mark unrarlib imported files as changed to comply with GPL ¡ø2a.
diego
parents:
11013
diff
changeset
|
11 ** |
7446 | 12 ** The contents of this file are subject to the UniquE RAR File Library |
13 ** License (the "unrarlib-license.txt"). You may not use this file except | |
14 ** in compliance with the License. You may obtain a copy of the License | |
15 ** at http://www.unrarlib.org/license.html. | |
16 ** Software distributed under the License is distributed on an "AS IS" | |
17 ** basis, WITHOUT WARRANTY OF ANY KIND, either express or implied warranty. | |
18 ** | |
19 ** Alternatively, the contents of this file may be used under the terms | |
20 ** of the GNU General Public License Version 2 or later (the "GPL"), in | |
21 ** which case the provisions of the GPL are applicable instead of those | |
22 ** above. If you wish to allow use of your version of this file only | |
23 ** under the terms of the GPL and not to allow others to use your version | |
24 ** of this file under the terms of the UniquE RAR File Library License, | |
25 ** indicate your decision by deleting the provisions above and replace | |
26 ** them with the notice and other provisions required by the GPL. If you | |
27 ** do not delete the provisions above, a recipient may use your version | |
28 ** of this file under the terms of the GPL or the UniquE RAR File Library | |
29 ** License. | |
30 ** | |
31 ************************************************************************** */ | |
32 | |
33 /* *************************************************************************** | |
34 ** | |
35 ** UniquE RAR File Library | |
36 ** The free file lib for the demoscene | |
37 ** multi-OS version (Win32, Linux and SunOS) | |
38 ** | |
39 ***************************************************************************** | |
40 ** | |
41 ** ==> Please configure the program in "unrarlib.h". <== | |
42 ** | |
43 ** RAR decompression code: | |
44 ** (C) Eugene Roshal | |
45 ** Modifications to a FileLib: | |
46 ** (C) 2000-2002 Christian Scheurer aka. UniquE/Vantage (cs@unrarlib.org) | |
47 ** Linux port: | |
48 ** (C) 2000-2002 Johannes Winkelmann (jw@tks6.net) | |
49 ** | |
50 ** The UniquE RAR File Library gives you the ability to access RAR archives | |
51 ** (any compression method supported in RAR v2.0 including Multimedia | |
52 ** Compression and encryption) directly from your program with ease an by | |
53 ** adding only 12kB (6kB UPX-compressed) additional code to your program. | |
54 ** Both solid and normal (recommended for fast random access to the files!) | |
55 ** archives are supported. This FileLib is made for the Demo scene, so it's | |
56 ** designed for easy use within your demos and intros. | |
57 ** Please read "licence.txt" to learn more about how you may use URARFileLib | |
58 ** in your productions. | |
59 ** | |
60 ***************************************************************************** | |
61 ** | |
62 ** ==> see the "CHANGES" file to see what's new | |
63 ** | |
64 ************************************************************************** */ | |
65 | |
66 /* -- include files ------------------------------------------------------- */ | |
67 #include "unrarlib.h" /* include global configuration */ | |
68 /* ------------------------------------------------------------------------ */ | |
69 | |
70 | |
71 | |
72 /* -- global stuff -------------------------------------------------------- */ | |
73 #ifdef _WIN_32 | |
74 | |
75 #include <windows.h> /* WIN32 definitions */ | |
76 #include <stdio.h> | |
77 #include <string.h> | |
78 | |
79 | |
80 #define ENABLE_ACCESS | |
81 | |
82 #define HOST_OS WIN_32 | |
83 | |
84 #define FM_NORMAL 0x00 | |
85 #define FM_RDONLY 0x01 | |
86 #define FM_HIDDEN 0x02 | |
87 #define FM_SYSTEM 0x04 | |
88 #define FM_LABEL 0x08 | |
89 #define FM_DIREC 0x10 | |
90 #define FM_ARCH 0x20 | |
91 | |
92 #define PATHDIVIDER "\\" | |
93 #define CPATHDIVIDER '\\' | |
94 #define MASKALL "*.*" | |
95 | |
96 #define READBINARY "rb" | |
97 #define READTEXT "rt" | |
98 #define UPDATEBINARY "r+b" | |
99 #define CREATEBINARY "w+b" | |
100 #define CREATETEXT "w" | |
101 #define APPENDTEXT "at" | |
102 | |
103 #endif | |
104 | |
105 #ifdef _UNIX | |
106 | |
107 #include <stdio.h> /* LINUX/UNIX definitions */ | |
108 #include <stdlib.h> | |
109 #include <ctype.h> | |
110 #include <string.h> | |
111 | |
112 #define ENABLE_ACCESS | |
113 | |
114 #define HOST_OS UNIX | |
115 | |
116 #define FM_LABEL 0x0000 | |
117 #define FM_DIREC 0x4000 | |
118 | |
119 #define PATHDIVIDER "/" | |
120 #define CPATHDIVIDER '/' | |
121 #define MASKALL "*.*" | |
122 | |
123 #define READBINARY "r" | |
124 #define READTEXT "r" | |
125 #define UPDATEBINARY "r+" | |
126 #define CREATEBINARY "w+" | |
127 #define CREATETEXT "w" | |
128 #define APPENDTEXT "a" | |
129 | |
130 | |
131 /* emulation of the windows API and data types */ | |
132 /* 20-08-2000 Johannes Winkelmann, jw@tks6.net */ | |
133 | |
134 typedef long DWORD; | |
135 typedef short BOOL; | |
136 #define TRUE 1 | |
137 #define FALSE 0 | |
138 | |
139 | |
140 #ifdef _DEBUG_LOG /* define macros for debugging */ | |
141 #include <unistd.h> | |
142 #include <sys/time.h> | |
143 | |
144 DWORD GetTickCount() | |
145 { | |
146 struct timeval tv; | |
147 gettimeofday( &tv, 0 ); | |
148 return (tv.tv_usec / 1000); | |
149 } | |
150 #endif | |
151 | |
152 #endif | |
153 | |
154 | |
155 | |
156 | |
157 | |
158 #ifdef _DEBUG_LOG /* define macros for debugging */ | |
159 | |
160 BOOL debug_log_first_start = TRUE; | |
161 | |
162 #define debug_log(a); debug_log_proc(a, __FILE__, __LINE__); | |
163 #define debug_init(a); debug_init_proc(a); | |
164 | |
165 void debug_log_proc(char *text, char *sourcefile, int sourceline); | |
166 void debug_init_proc(char *file_name); | |
167 | |
168 #else | |
169 #define debug_log(a); /* no debug this time */ | |
170 #define debug_init(a); /* no debug this time */ | |
171 #endif | |
172 | |
173 | |
174 | |
175 | |
176 | |
177 #define MAXWINSIZE 0x100000 | |
178 #define MAXWINMASK (MAXWINSIZE-1) | |
179 #define UNP_MEMORY MAXWINSIZE | |
180 #define Min(x,y) (((x)<(y)) ? (x):(y)) | |
181 #define Max(x,y) (((x)>(y)) ? (x):(y)) | |
182 #define NM 260 | |
183 | |
184 #define SIZEOF_MARKHEAD 7 | |
185 #define SIZEOF_OLDMHD 7 | |
186 #define SIZEOF_NEWMHD 13 | |
187 #define SIZEOF_OLDLHD 21 | |
188 #define SIZEOF_NEWLHD 32 | |
189 #define SIZEOF_SHORTBLOCKHEAD 7 | |
190 #define SIZEOF_LONGBLOCKHEAD 11 | |
191 #define SIZEOF_COMMHEAD 13 | |
192 #define SIZEOF_PROTECTHEAD 26 | |
193 | |
194 | |
195 #define PACK_VER 20 /* version of decompression code*/ | |
196 #define UNP_VER 20 | |
197 #define PROTECT_VER 20 | |
198 | |
199 | |
200 enum { M_DENYREAD,M_DENYWRITE,M_DENYNONE,M_DENYALL }; | |
201 enum { FILE_EMPTY,FILE_ADD,FILE_UPDATE,FILE_COPYOLD,FILE_COPYBLOCK }; | |
202 enum { SUCCESS,WARNING,FATAL_ERROR,CRC_ERROR,LOCK_ERROR,WRITE_ERROR, | |
203 OPEN_ERROR,USER_ERROR,MEMORY_ERROR,USER_BREAK=255,IMM_ABORT=0x8000 }; | |
204 enum { EN_LOCK=1,EN_VOL=2 }; | |
205 enum { SD_MEMORY=1,SD_FILES=2 }; | |
206 enum { NAMES_DONTCHANGE }; | |
207 enum { LOG_ARC=1,LOG_FILE=2 }; | |
208 enum { OLD_DECODE=0,OLD_ENCODE=1,NEW_CRYPT=2 }; | |
209 enum { OLD_UNPACK,NEW_UNPACK }; | |
210 | |
211 | |
212 #define MHD_COMMENT 2 | |
213 #define MHD_LOCK 4 | |
214 #define MHD_PACK_COMMENT 16 | |
215 #define MHD_AV 32 | |
216 #define MHD_PROTECT 64 | |
217 | |
218 #define LHD_SPLIT_BEFORE 1 | |
219 #define LHD_SPLIT_AFTER 2 | |
220 #define LHD_PASSWORD 4 | |
221 #define LHD_COMMENT 8 | |
222 #define LHD_SOLID 16 | |
223 | |
224 #define LHD_WINDOWMASK 0x00e0 | |
225 #define LHD_WINDOW64 0 | |
226 #define LHD_WINDOW128 32 | |
227 #define LHD_WINDOW256 64 | |
228 #define LHD_WINDOW512 96 | |
229 #define LHD_WINDOW1024 128 | |
230 #define LHD_DIRECTORY 0x00e0 | |
231 | |
232 #define LONG_BLOCK 0x8000 | |
233 #define READSUBBLOCK 0x8000 | |
234 | |
235 enum { ALL_HEAD=0,MARK_HEAD=0x72,MAIN_HEAD=0x73,FILE_HEAD=0x74, | |
236 COMM_HEAD=0x75,AV_HEAD=0x76,SUB_HEAD=0x77,PROTECT_HEAD=0x78}; | |
237 enum { EA_HEAD=0x100 }; | |
238 enum { MS_DOS=0,OS2=1,WIN_32=2,UNIX=3 }; | |
239 | |
240 | |
241 struct MarkHeader | |
242 { | |
243 UBYTE Mark[7]; | |
244 }; | |
245 | |
246 | |
247 struct NewMainArchiveHeader | |
248 { | |
249 UWORD HeadCRC; | |
250 UBYTE HeadType; | |
251 UWORD Flags; | |
252 UWORD HeadSize; | |
253 UWORD Reserved; | |
254 UDWORD Reserved1; | |
255 }; | |
256 | |
257 | |
258 struct NewFileHeader | |
259 { | |
260 UWORD HeadCRC; | |
261 UBYTE HeadType; | |
262 UWORD Flags; | |
263 UWORD HeadSize; | |
264 UDWORD PackSize; | |
265 UDWORD UnpSize; | |
266 UBYTE HostOS; | |
267 UDWORD FileCRC; | |
268 UDWORD FileTime; | |
269 UBYTE UnpVer; | |
270 UBYTE Method; | |
271 UWORD NameSize; | |
272 UDWORD FileAttr; | |
273 }; | |
274 | |
275 | |
276 struct BlockHeader | |
277 { | |
278 UWORD HeadCRC; | |
279 UBYTE HeadType; | |
280 UWORD Flags; | |
281 UWORD HeadSize; | |
282 UDWORD DataSize; | |
283 }; | |
284 | |
285 | |
286 struct Decode | |
287 { | |
288 unsigned int MaxNum; | |
289 unsigned int DecodeLen[16]; | |
290 unsigned int DecodePos[16]; | |
291 unsigned int DecodeNum[2]; | |
292 }; | |
293 | |
294 | |
295 struct MarkHeader MarkHead; | |
296 struct NewMainArchiveHeader NewMhd; | |
297 struct NewFileHeader NewLhd; | |
298 struct BlockHeader BlockHead; | |
299 | |
10815
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
300 static UBYTE *TempMemory = NULL; /* temporary unpack-buffer */ |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
301 static char *CommMemory = NULL; |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
302 |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
303 |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
304 static UBYTE *UnpMemory = NULL; |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
305 static char* ArgName = NULL; /* current file in rar archive */ |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
306 static char* ArcFileName = NULL; /* file to decompress */ |
7446 | 307 |
308 #ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION /* mem-to-mem decompression */ | |
10815
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
309 static MemoryFile *MemRARFile; /* pointer to RAR file in memory*/ |
7446 | 310 #else |
10815
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
311 static char* ArcName = NULL; /* RAR archive name */ |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
312 static FILE *ArcPtr; /* input RAR file handler */ |
7446 | 313 #endif |
10815
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
314 static char *Password = NULL; /* password to decrypt files */ |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
315 |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
316 static unsigned char *temp_output_buffer; /* extract files to this pointer*/ |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
317 static unsigned long *temp_output_buffer_offset; /* size of temp. extract buffer */ |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
318 |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
319 static BOOL FileFound; /* TRUE=use current extracted */ |
7446 | 320 /* data FALSE=throw data away, */ |
321 /* wrong file */ | |
10815
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
322 static int MainHeadSize; |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
323 static long CurBlockPos,NextBlockPos; |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
324 |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
325 static unsigned long CurUnpRead, CurUnpWrite; |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
326 static long UnpPackedSize; |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
327 static long DestUnpSize; |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
328 |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
329 static UDWORD HeaderCRC; |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
330 static int Encryption; |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
331 |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
332 //static unsigned int UnpWrSize; |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
333 //static unsigned char *UnpWrAddr; |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
334 static unsigned int UnpPtr,WrPtr; |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
335 |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
336 static unsigned char PN1,PN2,PN3; |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
337 static unsigned short OldKey[4]; |
7446 | 338 |
339 | |
340 | |
341 /* function header definitions */ | |
10815
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
342 static int ReadHeader(int BlockType); |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
343 static BOOL ExtrFile(void); |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
344 //BOOL ListFile(void); |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
345 static int tread(void *stream,void *buf,unsigned len); |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
346 static int tseek(void *stream,long offset,int fromwhere); |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
347 static BOOL UnstoreFile(void); |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
348 static int IsArchive(void); |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
349 static int ReadBlock(int BlockType); |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
350 static unsigned int UnpRead(unsigned char *Addr,unsigned int Count); |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
351 static void UnpInitData(void); |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
352 static void Unpack(unsigned char *UnpAddr); |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
353 static UBYTE DecodeAudio(int Delta); |
7446 | 354 static void DecodeNumber(struct Decode *Dec); |
10815
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
355 static void UpdKeys(UBYTE *Buf); |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
356 static void SetCryptKeys(char *Password); |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
357 static void SetOldKeys(char *Password); |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
358 static void DecryptBlock(unsigned char *Buf); |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
359 static void InitCRC(void); |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
360 static UDWORD CalcCRC32(UDWORD StartCRC,UBYTE *Addr,UDWORD Size); |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
361 static void UnpReadBuf(int FirstBuf); |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
362 static void ReadTables(void); |
7446 | 363 static void ReadLastTables(void); |
364 static void MakeDecodeTables(unsigned char *LenTab, | |
365 struct Decode *Dec, | |
366 int Size); | |
10127
228a767a51fd
avoid symbol clash with never samba versions (btw, unrarlib.c is full of global variables, with common names :( and it's a bit bloated, I think)
alex
parents:
9584
diff
changeset
|
367 static int my_stricomp(char *Str1,char *Str2); |
7446 | 368 /* ------------------------------------------------------------------------ */ |
369 | |
370 | |
371 /* -- global functions ---------------------------------------------------- */ | |
372 | |
373 int urarlib_get(void *output, | |
374 unsigned long *size, | |
375 char *filename, | |
376 void *rarfile, | |
377 char *libpassword) | |
378 /* Get a file from a RAR file to the "output" buffer. The UniquE RAR FileLib | |
379 * does everything from allocating memory, decrypting and unpacking the file | |
380 * from the archive. TRUE is returned if the file could be successfully | |
381 * extracted, else a FALSE indicates a failure. | |
382 */ | |
383 { | |
384 BOOL retcode = FALSE; | |
385 | |
386 #ifdef _DEBUG_LOG | |
387 int str_offs; /* used for debug-strings */ | |
388 char DebugMsg[500]; /* used to compose debug msg */ | |
389 | |
390 if(debug_log_first_start) | |
391 { | |
392 debug_log_first_start=FALSE; /* only create a new log file */ | |
393 debug_init(_DEBUG_LOG_FILE); /* on startup */ | |
394 } | |
395 | |
396 #endif | |
397 | |
398 InitCRC(); /* init some vars */ | |
399 | |
10815
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
400 if(ArgName) free(ArgName); |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
401 ArgName = strdup(filename); /* set file(s) to extract */ |
7446 | 402 #ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION |
403 MemRARFile = rarfile; /* set pointer to mem-RAR file */ | |
404 #else | |
10815
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
405 if(ArcName) free(ArcName); |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
406 ArcName = strdup(rarfile); /* set RAR file name */ |
7446 | 407 #endif |
10815
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
408 if(Password) free(Password); |
7446 | 409 if(libpassword != NULL) |
10815
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
410 Password = strdup(libpassword); /* init password */ |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
411 else |
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
412 Password = strdup(""); |
7446 | 413 |
414 temp_output_buffer = NULL; | |
415 temp_output_buffer_offset=size; /* set size of the temp buffer */ | |
416 | |
417 #ifdef _DEBUG_LOG | |
418 sprintf(DebugMsg, "Extracting >%s< from >%s< (password is >%s<)...", | |
419 filename, (char*)rarfile, libpassword); | |
420 debug_log(DebugMsg); | |
421 #endif | |
422 | |
423 retcode = ExtrFile(); /* unpack file now! */ | |
424 | |
10815
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
425 //memset(Password,0,sizeof(Password)); /* clear password */ |
7446 | 426 |
427 #ifndef _USE_MEMORY_TO_MEMORY_DECOMPRESSION | |
428 if (ArcPtr!=NULL){ | |
429 fclose(ArcPtr); | |
430 ArcPtr = NULL; | |
431 } | |
432 #endif | |
433 | |
9584 | 434 if(UnpMemory) free(UnpMemory); /* free memory */ |
435 if(TempMemory) free(TempMemory); | |
436 if(CommMemory) free(CommMemory); | |
7446 | 437 UnpMemory=NULL; |
438 TempMemory=NULL; | |
439 CommMemory=NULL; | |
440 | |
441 | |
442 if(retcode == FALSE) | |
443 { | |
9584 | 444 if(temp_output_buffer) /* free memory and return NULL */ |
445 free(temp_output_buffer); | |
7446 | 446 temp_output_buffer=NULL; |
447 *(DWORD*)output=0; /* pointer on errors */ | |
448 *size=0; | |
449 #ifdef _DEBUG_LOG | |
450 | |
451 | |
452 /* sorry for this ugly code, but older SunOS gcc compilers don't support */ | |
453 /* white spaces within strings */ | |
454 str_offs = sprintf(DebugMsg, "Error - couldn't extract "); | |
455 str_offs += sprintf(DebugMsg + str_offs, ">%s<", filename); | |
456 str_offs += sprintf(DebugMsg + str_offs, " and allocated "); | |
457 str_offs += sprintf(DebugMsg + str_offs, "%u Bytes", (unsigned int)*size); | |
458 str_offs += sprintf(DebugMsg + str_offs, " of unused memory!"); | |
459 | |
460 } else | |
461 { | |
462 sprintf(DebugMsg, "Extracted %u Bytes.", (unsigned int)*size); | |
463 } | |
464 debug_log(DebugMsg); | |
465 #else | |
466 } | |
467 #endif | |
468 *(DWORD*)output=(DWORD)temp_output_buffer;/* return pointer for unpacked*/ | |
469 /* data */ | |
470 | |
471 return retcode; | |
472 } | |
473 | |
474 | |
475 int urarlib_list(void *rarfile, ArchiveList_struct *list) | |
476 { | |
477 ArchiveList_struct *tmp_List = NULL; | |
478 int NoOfFilesInArchive = 0; /* number of files in archive */ | |
479 | |
480 #ifdef _DEBUG_LOG | |
481 if(debug_log_first_start) | |
482 { | |
483 debug_log_first_start=FALSE; /* only create a new log file */ | |
484 debug_init(_DEBUG_LOG_FILE); /* on startup */ | |
485 } | |
486 #endif | |
487 | |
488 InitCRC(); /* init some vars */ | |
489 | |
490 #ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION | |
491 MemRARFile = rarfile; /* assign pointer to RAR file */ | |
492 MemRARFile->offset = 0; | |
493 if (!IsArchive()) | |
494 { | |
495 debug_log("Not a RAR file"); | |
496 return NoOfFilesInArchive; /* error => exit! */ | |
497 } | |
498 #else | |
499 /* open and identify archive */ | |
500 if ((ArcPtr=fopen(rarfile,READBINARY))!=NULL) | |
501 { | |
502 if (!IsArchive()) | |
503 { | |
504 debug_log("Not a RAR file"); | |
505 fclose(ArcPtr); | |
506 ArcPtr = NULL; | |
507 return NoOfFilesInArchive; /* error => exit! */ | |
508 } | |
509 } | |
510 else { | |
511 debug_log("Error opening file."); | |
512 return NoOfFilesInArchive; | |
513 } | |
514 #endif | |
515 | |
516 if ((UnpMemory=malloc(UNP_MEMORY))==NULL) | |
517 { | |
518 debug_log("Can't allocate memory for decompression!"); | |
519 return NoOfFilesInArchive; | |
520 } | |
521 | |
522 #ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION | |
523 MemRARFile->offset+=NewMhd.HeadSize-MainHeadSize; | |
524 #else | |
525 tseek(ArcPtr,NewMhd.HeadSize-MainHeadSize,SEEK_CUR); | |
526 #endif | |
527 (*(DWORD*)list) = (DWORD)NULL; /* init file list */ | |
528 /* do while file is not extracted and there's no error */ | |
529 while (TRUE) | |
530 { | |
531 if (ReadBlock(FILE_HEAD | READSUBBLOCK) <= 0) /* read name of the next */ | |
532 { /* file within the RAR archive */ | |
533 debug_log("Couldn't read next filename from archive (I/O error)."); | |
534 break; /* error, file not found in */ | |
535 } /* archive or I/O error */ | |
536 if (BlockHead.HeadType==SUB_HEAD) | |
537 { | |
538 debug_log("Sorry, sub-headers not supported."); | |
539 break; /* error => exit */ | |
540 } | |
541 | |
542 if((void*)(*(DWORD*)list) == NULL) /* first entry */ | |
543 { | |
544 tmp_List = malloc(sizeof(ArchiveList_struct)); | |
545 tmp_List->next = NULL; | |
546 | |
547 (*(DWORD*)list) = (DWORD)tmp_List; | |
548 | |
549 } else /* add entry */ | |
550 { | |
551 tmp_List->next = malloc(sizeof(ArchiveList_struct)); | |
552 tmp_List = (ArchiveList_struct*) tmp_List->next; | |
553 tmp_List->next = NULL; | |
554 } | |
555 | |
556 tmp_List->item.Name = malloc(NewLhd.NameSize + 1); | |
557 strcpy(tmp_List->item.Name, ArcFileName); | |
558 tmp_List->item.NameSize = NewLhd.NameSize; | |
559 tmp_List->item.PackSize = NewLhd.PackSize; | |
560 tmp_List->item.UnpSize = NewLhd.UnpSize; | |
561 tmp_List->item.HostOS = NewLhd.HostOS; | |
562 tmp_List->item.FileCRC = NewLhd.FileCRC; | |
563 tmp_List->item.FileTime = NewLhd.FileTime; | |
564 tmp_List->item.UnpVer = NewLhd.UnpVer; | |
565 tmp_List->item.Method = NewLhd.Method; | |
566 tmp_List->item.FileAttr = NewLhd.FileAttr; | |
567 | |
568 NoOfFilesInArchive++; /* count files */ | |
569 | |
570 #ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION | |
571 MemRARFile->offset = NextBlockPos; | |
572 #else | |
573 if (ArcPtr!=NULL) tseek(ArcPtr,NextBlockPos,SEEK_SET); | |
574 #endif | |
575 | |
576 }; | |
577 | |
578 /* free memory, clear password and close archive */ | |
579 memset(Password,0,sizeof(Password)); /* clear password */ | |
580 #ifndef _USE_MEMORY_TO_MEMORY_DECOMPRESSION | |
581 if (ArcPtr!=NULL){ | |
582 fclose(ArcPtr); | |
583 ArcPtr = NULL; | |
584 } | |
585 #endif | |
586 | |
587 free(UnpMemory); /* free memory */ | |
588 free(TempMemory); | |
589 free(CommMemory); | |
590 UnpMemory=NULL; | |
591 TempMemory=NULL; | |
592 CommMemory=NULL; | |
593 | |
594 return NoOfFilesInArchive; | |
595 } | |
596 | |
597 | |
598 | |
599 /* urarlib_freelist: | |
600 * (after the suggestion and code of Duy Nguyen, Sean O'Blarney | |
601 * and Johannes Winkelmann who independently wrote a patch) | |
602 * free the memory of a ArchiveList_struct created by urarlib_list. | |
603 * | |
604 * input: *list pointer to an ArchiveList_struct | |
605 * output: - | |
606 */ | |
607 | |
608 void urarlib_freelist(ArchiveList_struct *list) | |
609 { | |
610 ArchiveList_struct* tmp = list; | |
611 | |
612 while ( list ) { | |
613 tmp = list->next; | |
614 free( list->item.Name ); | |
615 free( list ); | |
616 list = tmp; | |
617 } | |
618 } | |
619 | |
620 | |
621 /* ------------------------------------------------------------------------ */ | |
622 | |
623 | |
624 | |
625 | |
626 | |
627 | |
628 | |
629 | |
630 | |
631 | |
632 | |
633 | |
634 | |
635 | |
636 | |
637 | |
638 | |
639 /**************************************************************************** | |
640 **************************************************************************** | |
641 **************************************************************************** | |
642 **************************************************************************** | |
643 ******* ******* | |
644 ******* ******* | |
645 ******* ******* | |
646 ******* B L O C K I / O ******* | |
647 ******* ******* | |
648 ******* ******* | |
649 ******* ******* | |
650 **************************************************************************** | |
651 **************************************************************************** | |
652 **************************************************************************** | |
653 ****************************************************************************/ | |
654 | |
655 | |
656 | |
657 #define GetHeaderByte(N) Header[N] | |
658 | |
659 #define GetHeaderWord(N) (Header[N]+((UWORD)Header[N+1]<<8)) | |
660 | |
661 #define GetHeaderDword(N) (Header[N]+((UWORD)Header[N+1]<<8)+\ | |
662 ((UDWORD)Header[N+2]<<16)+\ | |
663 ((UDWORD)Header[N+3]<<24)) | |
664 | |
665 | |
666 int ReadBlock(int BlockType) | |
667 { | |
668 struct NewFileHeader SaveFileHead; | |
669 int Size=0,ReadSubBlock=0; | |
670 static int LastBlock; | |
671 memcpy(&SaveFileHead,&NewLhd,sizeof(SaveFileHead)); | |
672 if (BlockType & READSUBBLOCK) | |
673 ReadSubBlock=1; | |
674 BlockType &= 0xff; | |
675 { | |
676 while (1) | |
677 { | |
678 #ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION | |
679 CurBlockPos=MemRARFile->offset; /* get offset of mem-file */ | |
680 #else | |
681 CurBlockPos=ftell(ArcPtr); | |
682 #endif | |
683 Size=ReadHeader(FILE_HEAD); | |
684 if (Size!=0) | |
685 { | |
686 if (NewLhd.HeadSize<SIZEOF_SHORTBLOCKHEAD) | |
687 return(0); | |
688 NextBlockPos=CurBlockPos+NewLhd.HeadSize; | |
689 if (NewLhd.Flags & LONG_BLOCK) | |
690 NextBlockPos+=NewLhd.PackSize; | |
691 if (NextBlockPos<=CurBlockPos) | |
692 return(0); | |
693 } | |
694 | |
695 if (Size > 0 && BlockType!=SUB_HEAD) | |
696 LastBlock=BlockType; | |
697 if (Size==0 || BlockType==ALL_HEAD || NewLhd.HeadType==BlockType || | |
698 (NewLhd.HeadType==SUB_HEAD && ReadSubBlock && LastBlock==BlockType)) | |
699 break; | |
700 #ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION | |
701 MemRARFile->offset = NextBlockPos; | |
702 #else | |
703 tseek(ArcPtr, NextBlockPos, SEEK_SET); | |
704 #endif | |
705 } | |
706 } | |
707 | |
708 BlockHead.HeadCRC=NewLhd.HeadCRC; | |
709 BlockHead.HeadType=NewLhd.HeadType; | |
710 BlockHead.Flags=NewLhd.Flags; | |
711 BlockHead.HeadSize=NewLhd.HeadSize; | |
712 BlockHead.DataSize=NewLhd.PackSize; | |
713 | |
714 if (BlockType!=NewLhd.HeadType) BlockType=ALL_HEAD; | |
715 | |
716 if((FILE_HEAD == BlockType) && (Size>0)) | |
717 { | |
11013 | 718 ArcFileName=realloc(ArcFileName,NewLhd.NameSize+1); |
7446 | 719 #ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION |
720 tread(MemRARFile, ArcFileName, NewLhd.NameSize); | |
721 #else | |
722 tread(ArcPtr,ArcFileName,NewLhd.NameSize); | |
723 #endif | |
724 ArcFileName[NewLhd.NameSize]=0; | |
725 #ifdef _DEBUG_LOG | |
726 if (NewLhd.HeadCRC!=(UWORD)~CalcCRC32(HeaderCRC,(UBYTE*)&ArcFileName[0], | |
727 NewLhd.NameSize)) | |
728 { | |
729 debug_log("file header broken"); | |
730 } | |
731 #endif | |
732 Size+=NewLhd.NameSize; | |
733 } else | |
734 { | |
735 memcpy(&NewLhd,&SaveFileHead,sizeof(NewLhd)); | |
736 #ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION | |
737 MemRARFile->offset = CurBlockPos; | |
738 #else | |
739 tseek(ArcPtr,CurBlockPos,SEEK_SET); | |
740 #endif | |
741 } | |
742 | |
743 | |
744 return(Size); | |
745 } | |
746 | |
747 | |
748 int ReadHeader(int BlockType) | |
749 { | |
750 int Size = 0; | |
751 unsigned char Header[64]; | |
752 switch(BlockType) | |
753 { | |
754 case MAIN_HEAD: | |
755 #ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION | |
756 Size=tread(MemRARFile, Header, SIZEOF_NEWMHD); | |
757 #else | |
758 Size=tread(ArcPtr,Header,SIZEOF_NEWMHD); | |
759 #endif | |
760 NewMhd.HeadCRC=(unsigned short)GetHeaderWord(0); | |
761 NewMhd.HeadType=GetHeaderByte(2); | |
762 NewMhd.Flags=(unsigned short)GetHeaderWord(3); | |
763 NewMhd.HeadSize=(unsigned short)GetHeaderWord(5); | |
764 NewMhd.Reserved=(unsigned short)GetHeaderWord(7); | |
765 NewMhd.Reserved1=GetHeaderDword(9); | |
766 HeaderCRC=CalcCRC32(0xFFFFFFFFL,&Header[2],SIZEOF_NEWMHD-2); | |
767 break; | |
768 case FILE_HEAD: | |
769 #ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION | |
770 Size=tread(MemRARFile, Header, SIZEOF_NEWLHD); | |
771 #else | |
772 Size=tread(ArcPtr,Header,SIZEOF_NEWLHD); | |
773 #endif | |
774 NewLhd.HeadCRC=(unsigned short)GetHeaderWord(0); | |
775 NewLhd.HeadType=GetHeaderByte(2); | |
776 NewLhd.Flags=(unsigned short)GetHeaderWord(3); | |
777 NewLhd.HeadSize=(unsigned short)GetHeaderWord(5); | |
778 NewLhd.PackSize=GetHeaderDword(7); | |
779 NewLhd.UnpSize=GetHeaderDword(11); | |
780 NewLhd.HostOS=GetHeaderByte(15); | |
781 NewLhd.FileCRC=GetHeaderDword(16); | |
782 NewLhd.FileTime=GetHeaderDword(20); | |
783 NewLhd.UnpVer=GetHeaderByte(24); | |
784 NewLhd.Method=GetHeaderByte(25); | |
785 NewLhd.NameSize=(unsigned short)GetHeaderWord(26); | |
786 NewLhd.FileAttr=GetHeaderDword(28); | |
787 HeaderCRC=CalcCRC32(0xFFFFFFFFL,&Header[2],SIZEOF_NEWLHD-2); | |
788 break; | |
789 | |
790 #ifdef _DEBUG_LOG | |
791 case COMM_HEAD: /* log errors in case of debug */ | |
792 debug_log("Comment headers not supported! "\ | |
793 "Please create archives without comments."); | |
794 break; | |
795 case PROTECT_HEAD: | |
796 debug_log("Protected headers not supported!"); | |
797 break; | |
798 case ALL_HEAD: | |
799 debug_log("ShortBlockHeader not supported!"); | |
800 break; | |
801 default: | |
802 debug_log("Unknown//unsupported !"); | |
803 #else | |
804 default: /* else do nothing */ | |
805 break; | |
806 #endif | |
807 } | |
808 return(Size); | |
809 } | |
810 | |
811 /* ************************************************************************** | |
812 **************************************************************************** | |
813 **************************************************************************** | |
814 ************************************************************************** */ | |
815 | |
816 | |
817 | |
818 | |
819 | |
820 | |
821 | |
822 | |
823 | |
824 | |
825 | |
826 | |
827 | |
828 | |
829 | |
830 | |
831 | |
832 /* ************************************************************************** | |
833 **************************************************************************** | |
834 **************************************************************************** | |
835 **************************************************************************** | |
836 ******* ******* | |
837 ******* ******* | |
838 ******* ******* | |
839 ******* E X T R A C T L O O P ******* | |
840 ******* ******* | |
841 ******* ******* | |
842 ******* ******* | |
843 **************************************************************************** | |
844 **************************************************************************** | |
845 **************************************************************************** | |
846 ************************************************************************** */ | |
847 | |
848 | |
849 int IsArchive(void) | |
850 { | |
851 #ifdef _DEBUG_LOG | |
852 int str_offs; /* used for debug-strings */ | |
853 char DebugMsg[500]; /* used to compose debug msg */ | |
854 #endif | |
855 | |
856 #ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION | |
857 if (tread(MemRARFile, MarkHead.Mark, SIZEOF_MARKHEAD) != SIZEOF_MARKHEAD) | |
858 return(FALSE); | |
859 #else | |
860 if (tread(ArcPtr,MarkHead.Mark,SIZEOF_MARKHEAD)!=SIZEOF_MARKHEAD) | |
861 return(FALSE); | |
862 #endif | |
863 /* Old archive => error */ | |
864 if (MarkHead.Mark[0]==0x52 && MarkHead.Mark[1]==0x45 && | |
865 MarkHead.Mark[2]==0x7e && MarkHead.Mark[3]==0x5e) | |
866 { | |
867 debug_log("Attention: format as OLD detected! Can't handel archive!"); | |
868 } | |
869 else | |
870 /* original RAR v2.0 */ | |
871 if ((MarkHead.Mark[0]==0x52 && MarkHead.Mark[1]==0x61 && /* original */ | |
872 MarkHead.Mark[2]==0x72 && MarkHead.Mark[3]==0x21 && /* RAR header*/ | |
873 MarkHead.Mark[4]==0x1a && MarkHead.Mark[5]==0x07 && | |
874 MarkHead.Mark[6]==0x00) || | |
875 /* "UniquE!" - header */ | |
876 (MarkHead.Mark[0]=='U' && MarkHead.Mark[1]=='n' && /* "UniquE!" */ | |
877 MarkHead.Mark[2]=='i' && MarkHead.Mark[3]=='q' && /* header */ | |
878 MarkHead.Mark[4]=='u' && MarkHead.Mark[5]=='E' && | |
879 MarkHead.Mark[6]=='!')) | |
880 | |
881 { | |
882 if (ReadHeader(MAIN_HEAD)!=SIZEOF_NEWMHD) | |
883 return(FALSE); | |
884 } else | |
885 { | |
886 | |
887 #ifdef _DEBUG_LOG | |
888 /* sorry for this ugly code, but older SunOS gcc compilers don't */ | |
889 /* support white spaces within strings */ | |
890 str_offs = sprintf(DebugMsg, "unknown archive type (only plain RAR "); | |
891 str_offs += sprintf(DebugMsg + str_offs, "supported (normal and solid "); | |
892 str_offs += sprintf(DebugMsg + str_offs, "archives), SFX and Volumes "); | |
893 str_offs += sprintf(DebugMsg + str_offs, "are NOT supported!)"); | |
894 | |
895 debug_log(DebugMsg); | |
896 #endif | |
897 | |
898 } | |
899 | |
900 | |
901 MainHeadSize=SIZEOF_NEWMHD; | |
902 | |
903 return(TRUE); | |
904 } | |
905 | |
906 | |
907 BOOL ExtrFile(void) | |
908 { | |
909 BOOL ReturnCode=TRUE; | |
910 FileFound=FALSE; /* no file found by default */ | |
911 | |
912 #ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION | |
913 MemRARFile->offset = 0; /* start reading from offset 0 */ | |
914 if (!IsArchive()) | |
915 { | |
916 debug_log("Not a RAR file"); | |
917 return FALSE; /* error => exit! */ | |
918 } | |
919 | |
920 #else | |
921 /* open and identify archive */ | |
922 if ((ArcPtr=fopen(ArcName,READBINARY))!=NULL) | |
923 { | |
924 if (!IsArchive()) | |
925 { | |
926 debug_log("Not a RAR file"); | |
927 fclose(ArcPtr); | |
928 ArcPtr = NULL; | |
929 return FALSE; /* error => exit! */ | |
930 } | |
931 } else | |
932 { | |
933 debug_log("Error opening file."); | |
934 return FALSE; | |
935 } | |
936 #endif | |
937 | |
938 | |
939 if ((UnpMemory=malloc(UNP_MEMORY))==NULL) | |
940 { | |
941 debug_log("Can't allocate memory for decompression!"); | |
942 return FALSE; | |
943 } | |
944 | |
945 #ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION | |
946 MemRARFile->offset+=NewMhd.HeadSize-MainHeadSize; | |
947 #else | |
948 tseek(ArcPtr,NewMhd.HeadSize-MainHeadSize,SEEK_CUR); | |
949 #endif | |
950 | |
951 /* do while file is not extracted and there's no error */ | |
952 do | |
953 { | |
954 | |
955 if (ReadBlock(FILE_HEAD | READSUBBLOCK) <= 0) /* read name of the next */ | |
956 { /* file within the RAR archive */ | |
957 /* | |
958 * | |
959 * 21.11.2000 UnQ There's a problem with some linux distros when a file | |
960 * can not be found in an archive. | |
961 * | |
962 * debug_log("Couldn't read next filename from archive (I/O error)."); | |
963 * | |
964 */ | |
965 ReturnCode=FALSE; | |
966 break; /* error, file not found in */ | |
967 } /* archive or I/O error */ | |
968 if (BlockHead.HeadType==SUB_HEAD) | |
969 { | |
970 debug_log("Sorry, sub-headers not supported."); | |
971 ReturnCode=FALSE; | |
972 break; /* error => exit */ | |
973 } | |
974 | |
975 | |
10127
228a767a51fd
avoid symbol clash with never samba versions (btw, unrarlib.c is full of global variables, with common names :( and it's a bit bloated, I think)
alex
parents:
9584
diff
changeset
|
976 if(TRUE == (FileFound=(my_stricomp(ArgName, ArcFileName) == 0))) |
7446 | 977 /* *** file found! *** */ |
978 { | |
979 { | |
980 temp_output_buffer=malloc(NewLhd.UnpSize);/* allocate memory for the*/ | |
981 } | |
982 *temp_output_buffer_offset=0; /* file. The default offset */ | |
983 /* within the buffer is 0 */ | |
984 | |
985 if(temp_output_buffer == NULL) | |
986 { | |
987 debug_log("can't allocate memory for the file decompression"); | |
988 ReturnCode=FALSE; | |
989 break; /* error, can't extract file! */ | |
990 } | |
991 | |
992 | |
993 } | |
994 | |
995 /* in case of a solid archive, we need to decompress any single file till | |
996 * we have found the one we are looking for. In case of normal archives | |
997 * (recommended!!), we skip the files until we are sure that it is the | |
998 * one we want. | |
999 */ | |
1000 if((NewMhd.Flags & 0x08) || FileFound) | |
1001 { | |
1002 if (NewLhd.UnpVer<13 || NewLhd.UnpVer>UNP_VER) | |
1003 { | |
1004 debug_log("unknown compression method"); | |
1005 ReturnCode=FALSE; | |
1006 break; /* error, can't extract file! */ | |
1007 } | |
1008 | |
1009 CurUnpRead=CurUnpWrite=0; | |
1010 if ((*Password!=0) && (NewLhd.Flags & LHD_PASSWORD)) | |
1011 Encryption=NewLhd.UnpVer; | |
1012 else | |
1013 Encryption=0; | |
1014 if (Encryption) SetCryptKeys(Password); | |
1015 | |
1016 UnpPackedSize=NewLhd.PackSize; | |
1017 DestUnpSize=NewLhd.UnpSize; | |
1018 | |
1019 if (NewLhd.Method==0x30) | |
1020 { | |
1021 UnstoreFile(); | |
1022 } else | |
1023 { | |
1024 Unpack(UnpMemory); | |
1025 } | |
1026 | |
1027 | |
1028 | |
1029 #ifdef _DO_CRC32_CHECK /* calculate CRC32 */ | |
1030 if((UBYTE*)temp_output_buffer != NULL) | |
1031 { | |
1032 if(NewLhd.FileCRC!=~CalcCRC32(0xFFFFFFFFL, | |
1033 (UBYTE*)temp_output_buffer, | |
1034 NewLhd.UnpSize)) | |
1035 { | |
1036 debug_log("CRC32 error - file couldn't be decompressed correctly!"); | |
1037 ReturnCode=FALSE; | |
1038 break; /* error, can't extract file! */ | |
1039 } | |
1040 } | |
1041 #endif | |
1042 | |
1043 } | |
1044 | |
1045 #ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION | |
1046 MemRARFile->offset = NextBlockPos; | |
1047 #else | |
1048 if (ArcPtr!=NULL) tseek(ArcPtr,NextBlockPos,SEEK_SET); | |
1049 #endif | |
10127
228a767a51fd
avoid symbol clash with never samba versions (btw, unrarlib.c is full of global variables, with common names :( and it's a bit bloated, I think)
alex
parents:
9584
diff
changeset
|
1050 } while(my_stricomp(ArgName, ArcFileName) != 0);/* exit if file is extracted */ |
7446 | 1051 |
1052 /* free memory, clear password and close archive */ | |
1053 free(UnpMemory); | |
1054 UnpMemory=NULL; | |
1055 #ifndef _USE_MEMORY_TO_MEMORY_DECOMPRESSION | |
1056 if (ArcPtr!=NULL){ | |
1057 fclose(ArcPtr); | |
1058 ArcPtr = NULL; | |
1059 } | |
1060 #endif | |
1061 | |
1062 return ReturnCode; /* file extracted successful! */ | |
1063 } | |
1064 | |
1065 /* ************************************************************************** | |
1066 **************************************************************************** | |
1067 **************************************************************************** | |
1068 ************************************************************************** */ | |
1069 | |
1070 | |
1071 | |
1072 | |
1073 | |
1074 | |
1075 | |
1076 | |
1077 | |
1078 | |
1079 | |
1080 | |
1081 | |
1082 | |
1083 | |
1084 | |
1085 | |
1086 | |
1087 /* ************************************************************************** | |
1088 **************************************************************************** | |
1089 **************************************************************************** | |
1090 **************************************************************************** | |
1091 ******* ******* | |
1092 ******* ******* | |
1093 ******* ******* | |
1094 ******* G L O B A L F U N C T I O N S ******* | |
1095 ******* ******* | |
1096 ******* ******* | |
1097 ******* ******* | |
1098 **************************************************************************** | |
1099 **************************************************************************** | |
1100 **************************************************************************** | |
1101 ************************************************************************** */ | |
1102 | |
1103 | |
1104 int tread(void *stream,void *buf,unsigned len) | |
1105 { | |
1106 #ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION | |
1107 | |
1108 if(((MemRARFile->offset + len) > MemRARFile->size) || (len == 0)) | |
1109 return 0; | |
1110 | |
1111 memcpy(buf, | |
1112 (BYTE*)(((MemoryFile*)stream)->data)+((MemoryFile*)stream)->offset, | |
1113 len % ((((MemoryFile*)stream)->size) - 1)); | |
1114 | |
1115 MemRARFile->offset+=len; /* update read pointer */ | |
1116 return len % ((((MemoryFile*)stream)->size) - 1); | |
1117 #else | |
1118 return(fread(buf,1,len,(FILE*)stream)); | |
1119 #endif | |
1120 } | |
1121 | |
1122 | |
1123 #ifndef _USE_MEMORY_TO_MEMORY_DECOMPRESSION | |
1124 int tseek(void *stream,long offset,int fromwhere) | |
1125 { | |
1126 return(fseek((FILE*)stream,offset,fromwhere)); | |
1127 } | |
1128 #endif | |
1129 | |
1130 | |
10127
228a767a51fd
avoid symbol clash with never samba versions (btw, unrarlib.c is full of global variables, with common names :( and it's a bit bloated, I think)
alex
parents:
9584
diff
changeset
|
1131 static char* my_strupper(char *Str) |
7446 | 1132 { |
1133 char *ChPtr; | |
1134 for (ChPtr=Str;*ChPtr;ChPtr++) | |
1135 *ChPtr=(char)toupper(*ChPtr); | |
1136 return(Str); | |
1137 } | |
1138 | |
10127
228a767a51fd
avoid symbol clash with never samba versions (btw, unrarlib.c is full of global variables, with common names :( and it's a bit bloated, I think)
alex
parents:
9584
diff
changeset
|
1139 |
228a767a51fd
avoid symbol clash with never samba versions (btw, unrarlib.c is full of global variables, with common names :( and it's a bit bloated, I think)
alex
parents:
9584
diff
changeset
|
1140 static int my_stricomp(char *Str1,char *Str2) |
7446 | 1141 /* compare strings without regard of '\' and '/' */ |
1142 { | |
1143 char S1[512],S2[512]; | |
1144 char *chptr; | |
1145 | |
1146 strncpy(S1,Str1,sizeof(S1)); | |
1147 strncpy(S2,Str2,sizeof(S2)); | |
1148 | |
1149 while((chptr = strchr(S1, '\\')) != NULL) /* ignore backslash */ | |
1150 { | |
1151 *chptr = '_'; | |
1152 } | |
1153 | |
1154 while((chptr = strchr(S2, '\\')) != NULL) /* ignore backslash */ | |
1155 { | |
1156 *chptr = '_'; | |
1157 } | |
1158 | |
1159 while((chptr = strchr(S1, '/')) != NULL) /* ignore slash */ | |
1160 { | |
1161 *chptr = '_'; | |
1162 } | |
1163 | |
1164 while((chptr = strchr(S2, '/')) != NULL) /* ignore slash */ | |
1165 { | |
1166 *chptr = '_'; | |
1167 } | |
1168 | |
10127
228a767a51fd
avoid symbol clash with never samba versions (btw, unrarlib.c is full of global variables, with common names :( and it's a bit bloated, I think)
alex
parents:
9584
diff
changeset
|
1169 return(strcmp(my_strupper(S1),my_strupper(S2))); |
7446 | 1170 } |
1171 | |
1172 | |
1173 /* ************************************************************************** | |
1174 **************************************************************************** | |
1175 **************************************************************************** | |
1176 ************************************************************************** */ | |
1177 | |
1178 | |
1179 | |
1180 | |
1181 | |
1182 | |
1183 | |
1184 | |
1185 | |
1186 | |
1187 | |
1188 | |
1189 | |
1190 | |
1191 | |
1192 | |
1193 | |
1194 | |
1195 /* ************************************************************************** | |
1196 **************************************************************************** | |
1197 **************************************************************************** | |
1198 **************************************************************************** | |
1199 ******* ******* | |
1200 ******* ******* | |
1201 ******* ******* | |
1202 ******* U N P A C K C O D E ******* | |
1203 ******* ******* | |
1204 ******* ******* | |
1205 ******* ******* | |
1206 **************************************************************************** | |
1207 **************************************************************************** | |
1208 **************************************************************************** | |
1209 ************************************************************************** */ | |
1210 | |
1211 | |
1212 /* ***************************** | |
1213 * ** unpack stored RAR files ** | |
1214 * *****************************/ | |
1215 | |
1216 BOOL UnstoreFile(void) | |
1217 { | |
1218 if ((long)(*temp_output_buffer_offset=UnpRead(temp_output_buffer, | |
1219 NewLhd.UnpSize))==-1) | |
1220 { | |
1221 debug_log("Read error of stored file!"); | |
1222 return FALSE; | |
1223 } | |
1224 return TRUE; | |
1225 } | |
1226 | |
1227 | |
1228 | |
1229 | |
1230 /* **************************************** | |
1231 * ** RAR decompression code starts here ** | |
1232 * ****************************************/ | |
1233 | |
1234 #define NC 298 /* alphabet = {0,1,2, .,NC - 1} */ | |
1235 #define DC 48 | |
1236 #define RC 28 | |
1237 #define BC 19 | |
1238 #define MC 257 | |
1239 | |
1240 enum {CODE_HUFFMAN=0,CODE_LZ=1,CODE_LZ2=2,CODE_REPEATLZ=3,CODE_CACHELZ=4, | |
1241 CODE_STARTFILE=5,CODE_ENDFILE=6,CODE_STARTMM=8,CODE_ENDMM=7, | |
1242 CODE_MMDELTA=9}; | |
1243 | |
1244 struct AudioVariables | |
1245 { | |
1246 int K1,K2,K3,K4,K5; | |
1247 int D1,D2,D3,D4; | |
1248 int LastDelta; | |
1249 unsigned int Dif[11]; | |
1250 unsigned int ByteCount; | |
1251 int LastChar; | |
1252 }; | |
1253 | |
1254 | |
1255 #define NC 298 /* alphabet = {0, 1, 2, ..., NC - 1} */ | |
1256 #define DC 48 | |
1257 #define RC 28 | |
1258 #define BC 19 | |
1259 #define MC 257 | |
1260 | |
1261 | |
1262 struct AudioVariables AudV[4]; | |
1263 | |
1264 #define GetBits() \ | |
1265 BitField = ( ( ( (UDWORD)InBuf[InAddr] << 16 ) | \ | |
1266 ( (UWORD) InBuf[InAddr+1] << 8 ) | \ | |
1267 ( InBuf[InAddr+2] ) ) \ | |
1268 >> (8-InBit) ) & 0xffff; | |
1269 | |
1270 | |
1271 #define AddBits(Bits) \ | |
1272 InAddr += ( InBit + (Bits) ) >> 3; \ | |
1273 InBit = ( InBit + (Bits) ) & 7; | |
1274 | |
1275 static unsigned char *UnpBuf; | |
1276 static unsigned int BitField; | |
1277 static unsigned int Number; | |
1278 | |
1279 unsigned char InBuf[8192]; /* input read buffer */ | |
1280 | |
1281 unsigned char UnpOldTable[MC*4]; | |
1282 | |
1283 unsigned int InAddr,InBit,ReadTop; | |
1284 | |
1285 unsigned int LastDist,LastLength; | |
1286 static unsigned int Length,Distance; | |
1287 | |
1288 unsigned int OldDist[4],OldDistPtr; | |
1289 | |
1290 | |
1291 struct LitDecode | |
1292 { | |
1293 unsigned int MaxNum; | |
1294 unsigned int DecodeLen[16]; | |
1295 unsigned int DecodePos[16]; | |
1296 unsigned int DecodeNum[NC]; | |
1297 } LD; | |
1298 | |
1299 struct DistDecode | |
1300 { | |
1301 unsigned int MaxNum; | |
1302 unsigned int DecodeLen[16]; | |
1303 unsigned int DecodePos[16]; | |
1304 unsigned int DecodeNum[DC]; | |
1305 } DD; | |
1306 | |
1307 struct RepDecode | |
1308 { | |
1309 unsigned int MaxNum; | |
1310 unsigned int DecodeLen[16]; | |
1311 unsigned int DecodePos[16]; | |
1312 unsigned int DecodeNum[RC]; | |
1313 } RD; | |
1314 | |
1315 struct MultDecode | |
1316 { | |
1317 unsigned int MaxNum; | |
1318 unsigned int DecodeLen[16]; | |
1319 unsigned int DecodePos[16]; | |
1320 unsigned int DecodeNum[MC]; | |
1321 } MD[4]; | |
1322 | |
1323 struct BitDecode | |
1324 { | |
1325 unsigned int MaxNum; | |
1326 unsigned int DecodeLen[16]; | |
1327 unsigned int DecodePos[16]; | |
1328 unsigned int DecodeNum[BC]; | |
1329 } BD; | |
1330 | |
1331 static struct MultDecode *MDPtr[4]={&MD[0],&MD[1],&MD[2],&MD[3]}; | |
1332 | |
1333 int UnpAudioBlock,UnpChannels,CurChannel,ChannelDelta; | |
1334 | |
1335 | |
1336 void Unpack(unsigned char *UnpAddr) | |
1337 /* *** 38.3% of all CPU time is spent within this function!!! */ | |
1338 { | |
1339 static unsigned char LDecode[]={0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32, | |
1340 40,48,56,64,80,96,112,128,160,192,224}; | |
1341 static unsigned char LBits[]= {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3, | |
1342 3,3,3,4,4,4,4,5,5,5,5}; | |
1343 static int DDecode[]={0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384, | |
1344 512,768,1024,1536,2048,3072,4096,6144,8192,12288, | |
1345 16384,24576,32768U,49152U,65536,98304,131072,196608, | |
1346 262144,327680,393216,458752,524288,589824,655360, | |
1347 720896,786432,851968,917504,983040}; | |
1348 static unsigned char DBits[]= {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9, | |
1349 9,10,10,11,11,12,12,13,13,14,14,15,15,16, | |
1350 16,16,16,16,16,16,16,16,16,16,16,16,16}; | |
1351 static unsigned char SDDecode[]={0,4,8,16,32,64,128,192}; | |
1352 static unsigned char SDBits[]={2,2,3, 4, 5, 6, 6, 6}; | |
1353 unsigned int Bits; | |
1354 | |
1355 | |
1356 UnpBuf=UnpAddr; /* UnpAddr is a pointer to the */ | |
1357 UnpInitData(); /* unpack buffer */ | |
1358 UnpReadBuf(1); | |
1359 if (!(NewLhd.Flags & LHD_SOLID)) | |
1360 ReadTables(); | |
1361 DestUnpSize--; | |
1362 | |
1363 while (DestUnpSize>=0) | |
1364 { | |
1365 UnpPtr&=MAXWINMASK; | |
1366 | |
1367 if (InAddr>sizeof(InBuf)-30) | |
1368 UnpReadBuf(0); | |
1369 if (((WrPtr-UnpPtr) & MAXWINMASK)<270 && WrPtr!=UnpPtr) | |
1370 { | |
1371 | |
1372 | |
1373 if (FileFound) | |
1374 { | |
1375 | |
1376 if (UnpPtr<WrPtr) | |
1377 { | |
1378 if((*temp_output_buffer_offset + UnpPtr) > NewLhd.UnpSize) | |
1379 { | |
1380 debug_log("Fatal! Buffer overrun during decompression!"); | |
1381 DestUnpSize=-1; | |
1382 | |
1383 } else | |
1384 { | |
1385 /* copy extracted data to output buffer */ | |
1386 memcpy(temp_output_buffer + *temp_output_buffer_offset, | |
1387 &UnpBuf[WrPtr], (0-WrPtr) & MAXWINMASK); | |
1388 /* update offset within buffer */ | |
1389 *temp_output_buffer_offset+= (0-WrPtr) & MAXWINMASK; | |
1390 /* copy extracted data to output buffer */ | |
1391 memcpy(temp_output_buffer + *temp_output_buffer_offset, UnpBuf, | |
1392 UnpPtr); | |
1393 /* update offset within buffer */ | |
1394 *temp_output_buffer_offset+=UnpPtr; | |
1395 } | |
1396 } else | |
1397 { | |
1398 if((*temp_output_buffer_offset + (UnpPtr-WrPtr)) > NewLhd.UnpSize) | |
1399 { | |
1400 debug_log("Fatal! Buffer overrun during decompression!"); | |
1401 DestUnpSize=-1; | |
1402 } else | |
1403 { | |
1404 /* copy extracted data to output buffer */ | |
1405 memcpy(temp_output_buffer + *temp_output_buffer_offset, | |
1406 &UnpBuf[WrPtr], UnpPtr-WrPtr); | |
1407 *temp_output_buffer_offset+=UnpPtr-WrPtr; /* update offset within buffer */ | |
1408 } | |
1409 | |
1410 } | |
1411 } | |
1412 | |
1413 WrPtr=UnpPtr; | |
1414 } | |
1415 | |
1416 if (UnpAudioBlock) | |
1417 { | |
1418 DecodeNumber((struct Decode *)MDPtr[CurChannel]); | |
1419 if (Number==256) | |
1420 { | |
1421 ReadTables(); | |
1422 continue; | |
1423 } | |
1424 UnpBuf[UnpPtr++]=DecodeAudio(Number); | |
1425 if (++CurChannel==UnpChannels) | |
1426 CurChannel=0; | |
1427 DestUnpSize--; | |
1428 continue; | |
1429 } | |
1430 | |
1431 DecodeNumber((struct Decode *)&LD); | |
1432 if (Number<256) | |
1433 { | |
1434 UnpBuf[UnpPtr++]=(UBYTE)Number; | |
1435 DestUnpSize--; | |
1436 continue; | |
1437 } | |
1438 if (Number>269) | |
1439 { | |
1440 Length=LDecode[Number-=270]+3; | |
1441 if ((Bits=LBits[Number])>0) | |
1442 { | |
1443 GetBits(); | |
1444 Length+=BitField>>(16-Bits); | |
1445 AddBits(Bits); | |
1446 } | |
1447 | |
1448 DecodeNumber((struct Decode *)&DD); | |
1449 Distance=DDecode[Number]+1; | |
1450 if ((Bits=DBits[Number])>0) | |
1451 { | |
1452 GetBits(); | |
1453 Distance+=BitField>>(16-Bits); | |
1454 AddBits(Bits); | |
1455 } | |
1456 | |
1457 if (Distance>=0x40000L) | |
1458 Length++; | |
1459 | |
1460 if (Distance>=0x2000) | |
1461 Length++; | |
1462 | |
1463 LastDist=OldDist[OldDistPtr++ & 3]=Distance; | |
1464 DestUnpSize-=(LastLength=Length); | |
1465 while (Length--) | |
1466 { | |
1467 UnpBuf[UnpPtr]=UnpBuf[(UnpPtr-Distance) & MAXWINMASK]; | |
1468 UnpPtr=(UnpPtr+1) & MAXWINMASK; | |
1469 } | |
1470 | |
1471 continue; | |
1472 } | |
1473 if (Number==269) | |
1474 { | |
1475 ReadTables(); | |
1476 continue; | |
1477 } | |
1478 if (Number==256) | |
1479 { | |
1480 Length=LastLength; | |
1481 Distance=LastDist; | |
1482 LastDist=OldDist[OldDistPtr++ & 3]=Distance; | |
1483 DestUnpSize-=(LastLength=Length); | |
1484 while (Length--) | |
1485 { | |
1486 UnpBuf[UnpPtr]=UnpBuf[(UnpPtr-Distance) & MAXWINMASK]; | |
1487 UnpPtr=(UnpPtr+1) & MAXWINMASK; | |
1488 } | |
1489 continue; | |
1490 } | |
1491 if (Number<261) | |
1492 { | |
1493 Distance=OldDist[(OldDistPtr-(Number-256)) & 3]; | |
1494 DecodeNumber((struct Decode *)&RD); | |
1495 Length=LDecode[Number]+2; | |
1496 if ((Bits=LBits[Number])>0) | |
1497 { | |
1498 GetBits(); | |
1499 Length+=BitField>>(16-Bits); | |
1500 AddBits(Bits); | |
1501 } | |
1502 if (Distance>=0x40000) | |
1503 Length++; | |
1504 if (Distance>=0x2000) | |
1505 Length++; | |
1506 if (Distance>=0x101) | |
1507 Length++; | |
1508 LastDist=OldDist[OldDistPtr++ & 3]=Distance; | |
1509 DestUnpSize-=(LastLength=Length); | |
1510 while (Length--) | |
1511 { | |
1512 UnpBuf[UnpPtr]=UnpBuf[(UnpPtr-Distance) & MAXWINMASK]; | |
1513 UnpPtr=(UnpPtr+1) & MAXWINMASK; | |
1514 } | |
1515 continue; | |
1516 } | |
1517 if (Number<270) | |
1518 { | |
1519 Distance=SDDecode[Number-=261]+1; | |
1520 if ((Bits=SDBits[Number])>0) | |
1521 { | |
1522 GetBits(); | |
1523 Distance+=BitField>>(16-Bits); | |
1524 AddBits(Bits); | |
1525 } | |
1526 Length=2; | |
1527 LastDist=OldDist[OldDistPtr++ & 3]=Distance; | |
1528 DestUnpSize-=(LastLength=Length); | |
1529 while (Length--) | |
1530 { | |
1531 UnpBuf[UnpPtr]=UnpBuf[(UnpPtr-Distance) & MAXWINMASK]; | |
1532 UnpPtr=(UnpPtr+1) & MAXWINMASK; | |
1533 } | |
1534 continue; | |
1535 } | |
1536 } | |
1537 ReadLastTables(); | |
1538 | |
1539 if (FileFound) /* flush buffer */ | |
1540 { | |
1541 | |
1542 if (UnpPtr<WrPtr) | |
1543 { | |
1544 if((*temp_output_buffer_offset + UnpPtr) > NewLhd.UnpSize) | |
1545 { | |
1546 debug_log("Fatal! Buffer overrun during decompression!"); | |
1547 DestUnpSize=-1; | |
1548 } else | |
1549 { | |
1550 /* copy extracted data to output buffer */ | |
1551 memcpy(temp_output_buffer + *temp_output_buffer_offset, &UnpBuf[WrPtr], | |
1552 (0-WrPtr) & MAXWINMASK); | |
1553 /* update offset within buffer */ | |
1554 *temp_output_buffer_offset+= (0-WrPtr) & MAXWINMASK; | |
1555 /* copy extracted data to output buffer */ | |
1556 memcpy(temp_output_buffer + *temp_output_buffer_offset, UnpBuf, UnpPtr); | |
1557 /* update offset within buffer */ | |
1558 *temp_output_buffer_offset+=UnpPtr; | |
1559 } | |
1560 } else | |
1561 { | |
1562 if((*temp_output_buffer_offset + (UnpPtr-WrPtr)) > NewLhd.UnpSize) | |
1563 { | |
1564 debug_log("Fatal! Buffer overrun during decompression!"); | |
1565 DestUnpSize=-1; | |
1566 } else | |
1567 { | |
1568 /* copy extracted data to output buffer */ | |
1569 memcpy(temp_output_buffer + *temp_output_buffer_offset, &UnpBuf[WrPtr], | |
1570 UnpPtr-WrPtr); | |
1571 /* update offset within buffer */ | |
1572 *temp_output_buffer_offset+=UnpPtr-WrPtr; | |
1573 } | |
1574 } | |
1575 } | |
1576 | |
1577 WrPtr=UnpPtr; | |
1578 } | |
1579 | |
1580 | |
1581 unsigned int UnpRead(unsigned char *Addr,unsigned int Count) | |
1582 { | |
1583 int RetCode=0; | |
1584 unsigned int I,ReadSize,TotalRead=0; | |
1585 unsigned char *ReadAddr; | |
1586 ReadAddr=Addr; | |
1587 while (Count > 0) | |
1588 { | |
1589 ReadSize=(unsigned int)((Count>(unsigned long)UnpPackedSize) ? | |
10815
58c6f2998afa
Fix the segfault with long filenames. Also prevent some other buffer
albeu
parents:
10127
diff
changeset
|
1590 (unsigned int)UnpPackedSize : Count); |
7446 | 1591 #ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION |
1592 if(MemRARFile->data == NULL) | |
1593 return(0); | |
1594 RetCode=tread(MemRARFile, ReadAddr, ReadSize); | |
1595 #else | |
1596 if (ArcPtr==NULL) | |
1597 return(0); | |
1598 RetCode=tread(ArcPtr,ReadAddr,ReadSize); | |
1599 #endif | |
1600 CurUnpRead+=RetCode; | |
1601 ReadAddr+=RetCode; | |
1602 TotalRead+=RetCode; | |
1603 Count-=RetCode; | |
1604 UnpPackedSize-=RetCode; | |
1605 break; | |
1606 } | |
1607 if (RetCode!= -1) | |
1608 { | |
1609 RetCode=TotalRead; | |
1610 if (Encryption) | |
1611 { | |
1612 if (Encryption<20) | |
1613 { | |
1614 debug_log("Old Crypt() not supported!"); | |
1615 } | |
1616 else | |
1617 { | |
1618 for (I=0;I<(unsigned int)RetCode;I+=16) | |
1619 DecryptBlock(&Addr[I]); | |
1620 } | |
1621 } | |
1622 } | |
1623 return(RetCode); | |
1624 } | |
1625 | |
1626 | |
1627 void UnpReadBuf(int FirstBuf) | |
1628 { | |
1629 int RetCode; | |
1630 if (FirstBuf) | |
1631 { | |
1632 ReadTop=UnpRead(InBuf,sizeof(InBuf)); | |
1633 InAddr=0; | |
1634 } | |
1635 else | |
1636 { | |
1637 memcpy(InBuf,&InBuf[sizeof(InBuf)-32],32); | |
1638 InAddr&=0x1f; | |
1639 RetCode=UnpRead(&InBuf[32],sizeof(InBuf)-32); | |
1640 if (RetCode>0) | |
1641 ReadTop=RetCode+32; | |
1642 else | |
1643 ReadTop=InAddr; | |
1644 } | |
1645 } | |
1646 | |
1647 | |
1648 void ReadTables(void) | |
1649 { | |
1650 UBYTE BitLength[BC]; | |
1651 unsigned char Table[MC*4]; | |
1652 int TableSize,N,I; | |
1653 if (InAddr>sizeof(InBuf)-25) | |
1654 UnpReadBuf(0); | |
1655 GetBits(); | |
1656 UnpAudioBlock=(BitField & 0x8000); | |
1657 | |
1658 if (!(BitField & 0x4000)) | |
1659 memset(UnpOldTable,0,sizeof(UnpOldTable)); | |
1660 AddBits(2); | |
1661 | |
1662 | |
1663 if (UnpAudioBlock) | |
1664 { | |
1665 UnpChannels=((BitField>>12) & 3)+1; | |
1666 if (CurChannel>=UnpChannels) | |
1667 CurChannel=0; | |
1668 AddBits(2); | |
1669 TableSize=MC*UnpChannels; | |
1670 } | |
1671 else | |
1672 TableSize=NC+DC+RC; | |
1673 | |
1674 | |
1675 for (I=0;I<BC;I++) | |
1676 { | |
1677 GetBits(); | |
1678 BitLength[I]=(UBYTE)(BitField >> 12); | |
1679 AddBits(4); | |
1680 } | |
1681 MakeDecodeTables(BitLength,(struct Decode *)&BD,BC); | |
1682 I=0; | |
1683 while (I<TableSize) | |
1684 { | |
1685 if (InAddr>sizeof(InBuf)-5) | |
1686 UnpReadBuf(0); | |
1687 DecodeNumber((struct Decode *)&BD); | |
1688 if (Number<16) | |
8451 | 1689 { |
1690 Table[I]=(Number+UnpOldTable[I]) & 0xf; | |
1691 I++; | |
1692 } | |
7446 | 1693 else |
1694 if (Number==16) | |
1695 { | |
1696 GetBits(); | |
1697 N=(BitField >> 14)+3; | |
1698 AddBits(2); | |
1699 while (N-- > 0 && I<TableSize) | |
1700 { | |
1701 Table[I]=Table[I-1]; | |
1702 I++; | |
1703 } | |
1704 } | |
1705 else | |
1706 { | |
1707 if (Number==17) | |
1708 { | |
1709 GetBits(); | |
1710 N=(BitField >> 13)+3; | |
1711 AddBits(3); | |
1712 } | |
1713 else | |
1714 { | |
1715 GetBits(); | |
1716 N=(BitField >> 9)+11; | |
1717 AddBits(7); | |
1718 } | |
1719 while (N-- > 0 && I<TableSize) | |
1720 Table[I++]=0; | |
1721 } | |
1722 } | |
1723 if (UnpAudioBlock) | |
1724 for (I=0;I<UnpChannels;I++) | |
1725 MakeDecodeTables(&Table[I*MC],(struct Decode *)MDPtr[I],MC); | |
1726 else | |
1727 { | |
1728 MakeDecodeTables(&Table[0],(struct Decode *)&LD,NC); | |
1729 MakeDecodeTables(&Table[NC],(struct Decode *)&DD,DC); | |
1730 MakeDecodeTables(&Table[NC+DC],(struct Decode *)&RD,RC); | |
1731 } | |
1732 memcpy(UnpOldTable,Table,sizeof(UnpOldTable)); | |
1733 } | |
1734 | |
1735 | |
1736 static void ReadLastTables(void) | |
1737 { | |
1738 if (ReadTop>=InAddr+5) | |
1739 { | |
1740 if (UnpAudioBlock) | |
1741 { | |
1742 DecodeNumber((struct Decode *)MDPtr[CurChannel]); | |
1743 if (Number==256) | |
1744 ReadTables(); | |
1745 } | |
1746 else | |
1747 { | |
1748 DecodeNumber((struct Decode *)&LD); | |
1749 if (Number==269) | |
1750 ReadTables(); | |
1751 } | |
1752 } | |
1753 } | |
1754 | |
1755 | |
1756 static void MakeDecodeTables(unsigned char *LenTab, | |
1757 struct Decode *Dec, | |
1758 int Size) | |
1759 { | |
1760 int LenCount[16],TmpPos[16],I; | |
1761 long M,N; | |
1762 memset(LenCount,0,sizeof(LenCount)); | |
1763 for (I=0;I<Size;I++) | |
1764 LenCount[LenTab[I] & 0xF]++; | |
1765 | |
1766 LenCount[0]=0; | |
1767 for (TmpPos[0]=Dec->DecodePos[0]=Dec->DecodeLen[0]=0,N=0,I=1;I<16;I++) | |
1768 { | |
1769 N=2*(N+LenCount[I]); | |
1770 M=N<<(15-I); | |
1771 if (M>0xFFFF) | |
1772 M=0xFFFF; | |
1773 Dec->DecodeLen[I]=(unsigned int)M; | |
1774 TmpPos[I]=Dec->DecodePos[I]=Dec->DecodePos[I-1]+LenCount[I-1]; | |
1775 } | |
1776 | |
1777 for (I=0;I<Size;I++) | |
1778 if (LenTab[I]!=0) | |
1779 Dec->DecodeNum[TmpPos[LenTab[I] & 0xF]++]=I; | |
1780 Dec->MaxNum=Size; | |
1781 } | |
1782 | |
1783 | |
1784 static void DecodeNumber(struct Decode *Deco) | |
1785 /* *** 52.6% of all CPU time is spent within this function!!! */ | |
1786 { | |
1787 unsigned int I; | |
1788 register unsigned int N; | |
1789 GetBits(); | |
1790 | |
1791 #ifdef _USE_ASM | |
1792 | |
1793 #ifdef _WIN_32 | |
1794 __asm { | |
1795 | |
1796 xor eax, eax | |
1797 mov eax, BitField // N=BitField & 0xFFFE; | |
1798 and eax, 0xFFFFFFFE | |
1799 mov [N], eax | |
1800 mov edx, [Deco] // EAX=N, EDX=Deco | |
1801 | |
1802 cmp eax, dword ptr[edx + 8*4 + 4]// if (N<Dec->DecodeLen[8]) | |
1803 jae else_G | |
1804 | |
1805 cmp eax, dword ptr[edx + 4*4 + 4]// if (N<Dec->DecodeLen[4]) | |
1806 jae else_F | |
1807 | |
1808 | |
1809 cmp eax, dword ptr[edx + 2*4 + 4]// if (N<Dec->DecodeLen[2]) | |
1810 jae else_C | |
1811 | |
1812 cmp eax, dword ptr[edx + 1*4 + 4]// if (N<Dec->DecodeLen[1]) | |
1813 jae else_1 | |
1814 mov I, 1 // I=1; | |
1815 jmp next_1 | |
1816 else_1: // else | |
1817 mov I, 2 // I=2; | |
1818 next_1: | |
1819 | |
1820 jmp next_C | |
1821 else_C: // else | |
1822 | |
1823 cmp eax, dword ptr[edx + 3*4 + 4]// if (N<Dec->DecodeLen[3]) | |
1824 jae else_2 | |
1825 mov I, 3 // I=3; | |
1826 jmp next_2 | |
1827 else_2: // else | |
1828 mov I, 4 // I=4; | |
1829 next_2: | |
1830 | |
1831 next_C: // else | |
1832 | |
1833 jmp next_F | |
1834 else_F: | |
1835 | |
1836 | |
1837 cmp eax, dword ptr[edx + 6*4 + 4]// if (N<Dec->DecodeLen[6]) | |
1838 jae else_E | |
1839 | |
1840 cmp eax, dword ptr[edx + 5*4 + 4]// if (N<Dec->DecodeLen[5]) | |
1841 jae else_3 | |
1842 mov I, 5 // I=5; | |
1843 jmp next_3 | |
1844 else_3: // else | |
1845 mov I, 6 // I=6; | |
1846 next_3: | |
1847 | |
1848 jmp next_E | |
1849 else_E: // else | |
1850 | |
1851 cmp eax, dword ptr[edx + 7*4 + 4]// if (N<Dec->DecodeLen[7]) | |
1852 jae else_4 | |
1853 mov I, 7 // I=7; | |
1854 jmp next_4 | |
1855 else_4: // else | |
1856 mov I, 8 // I=8; | |
1857 next_4: | |
1858 | |
1859 next_E: | |
1860 | |
1861 next_F: | |
1862 | |
1863 jmp next_G | |
1864 else_G: | |
1865 | |
1866 cmp eax, dword ptr[edx + 12*4 + 4] // if (N<Dec->DecodeLen[12]) | |
1867 jae else_D | |
1868 | |
1869 cmp eax, dword ptr[edx + 10*4 + 4]// if (N<Dec->DecodeLen[10]) | |
1870 jae else_B | |
1871 | |
1872 cmp eax, dword ptr[edx + 9*4 + 4]// if (N<Dec->DecodeLen[9]) | |
1873 jae else_5 | |
1874 mov I, 9 // I=9; | |
1875 jmp next_5 | |
1876 else_5: // else | |
1877 mov I, 10 // I=10; | |
1878 next_5: | |
1879 | |
1880 jmp next_B | |
1881 else_B: // else | |
1882 | |
1883 cmp eax, dword ptr[edx + 11*4 + 4]// if (N<Dec->DecodeLen[11]) | |
1884 jae else_6 | |
1885 mov I, 11 // I=11; | |
1886 jmp next_6 | |
1887 else_6: // else | |
1888 mov I, 12 // I=12; | |
1889 next_6: | |
1890 | |
1891 next_B: | |
1892 | |
1893 | |
1894 jmp next_D | |
1895 else_D: // else | |
1896 | |
1897 cmp eax, dword ptr[edx + 14*4 + 4]// if (N<Dec->DecodeLen[14]) | |
1898 jae else_A | |
1899 | |
1900 cmp eax, dword ptr[edx + 13*4 + 4]// if (N<Dec->DecodeLen[13]) | |
1901 jae else_7 | |
1902 mov I, 13 // I=13; | |
1903 jmp next_7 | |
1904 else_7: // else | |
1905 mov I, 14 // I=14; | |
1906 next_7: | |
1907 | |
1908 jmp next_A | |
1909 else_A: // else | |
1910 mov I, 15 // I=15; | |
1911 next_A: | |
1912 | |
1913 next_D: | |
1914 next_G: | |
1915 } | |
1916 #else | |
1917 __asm__ __volatile__ ( | |
1918 "andl $0xFFFFFFFE, %%eax" | |
1919 " movl %%eax, %1" | |
1920 " cmpl 8*4(%%edx), %%eax /* 5379 */" | |
1921 " jae else_G" | |
1922 "" | |
1923 " cmpl 4*4(%%edx), %%eax" | |
1924 " jae else_F" | |
1925 "" | |
1926 " cmpl 2*4(%%edx), %%eax" | |
1927 " jae else_C" | |
1928 "" | |
1929 " cmpl 1*4(%%edx), %%eax" | |
1930 "" | |
1931 " jae else_1" | |
1932 " movl $1, %0" | |
1933 " jmp next_1" | |
1934 " else_1: " | |
1935 " movl $2, %0" | |
1936 " next_1:" | |
1937 " " | |
1938 " jmp next_C" | |
1939 " else_C: " | |
1940 "" | |
1941 " cmpl 3*4(%%edx), %%eax " | |
1942 " jae else_2" | |
1943 " movl $3, %0" | |
1944 " jmp next_2" | |
1945 " else_2: " | |
1946 " movl $4, %0" | |
1947 " next_2:" | |
1948 "" | |
1949 " next_C: " | |
1950 "" | |
1951 " jmp next_F" | |
1952 " else_F:" | |
1953 "" | |
1954 " cmpl 6*4(%%edx), %%eax" | |
1955 " jae else_E" | |
1956 "" | |
1957 " cmpl 5*4(%%edx), %%eax" | |
1958 " jae else_3" | |
1959 " movl $5, %0 " | |
1960 " jmp next_3" | |
1961 " else_3: " | |
1962 " movl $6, %0 " | |
1963 " next_3:" | |
1964 "" | |
1965 " jmp next_E" | |
1966 " else_E: " | |
1967 "" | |
1968 " cmpl 7*4(%%edx), %%eax" | |
1969 " jae else_4" | |
1970 " movl $7, %0 " | |
1971 " jmp next_4" | |
1972 " else_4: " | |
1973 " movl $8, %0 " | |
1974 " next_4:" | |
1975 "" | |
1976 " next_E:" | |
1977 "" | |
1978 " next_F:" | |
1979 "" | |
1980 " jmp next_G" | |
1981 " else_G:" | |
1982 "" | |
1983 " cmpl 12*4(%%edx), %%eax" | |
1984 " jae else_D" | |
1985 "" | |
1986 " cmpl 10*4(%%edx), %%eax" | |
1987 " jae else_B" | |
1988 "" | |
1989 " cmpl 9*4(%%edx), %%eax" | |
1990 " jae else_5" | |
1991 " movl $9, %0 " | |
1992 " jmp next_5" | |
1993 " else_5: " | |
1994 " movl $10, %0 " | |
1995 " next_5:" | |
1996 "" | |
1997 " jmp next_B" | |
1998 " else_B: " | |
1999 "" | |
2000 " cmpl 11*4(%%edx), %%eax" | |
2001 " " | |
2002 " jae else_6" | |
2003 " movl $11, %0 " | |
2004 " jmp next_6" | |
2005 " else_6: " | |
2006 " movl $12, %0 " | |
2007 " next_6:" | |
2008 "" | |
2009 " next_B:" | |
2010 " " | |
2011 " " | |
2012 " jmp next_D" | |
2013 " else_D: " | |
2014 "" | |
2015 " cmpl 14*4(%%edx), %%eax" | |
2016 " jae else_A" | |
2017 "" | |
2018 " cmpl 13*4(%%edx), %%eax" | |
2019 " jae else_7" | |
2020 " movl $13, %0" | |
2021 " jmp next_7" | |
2022 " else_7: " | |
2023 " movl $14, %0" | |
2024 " next_7:" | |
2025 "" | |
2026 " jmp next_A" | |
2027 " else_A: " | |
2028 " movl $15, %0 " | |
2029 " next_A:" | |
2030 " " | |
2031 " next_D: " | |
2032 " next_G:" | |
2033 : "=g" (I), "=r"(N) | |
2034 : "eax" ((long)BitField), "edx"((long)Deco->DecodeLen) | |
2035 : "memory" | |
2036 ); | |
2037 #endif /* #ifdef _WIN_32 ... #elif defined _X86_ASM_ */ | |
2038 | |
2039 #else | |
2040 N=BitField & 0xFFFE; | |
2041 if (N<Deco->DecodeLen[8]) { | |
2042 if (N<Deco->DecodeLen[4]) { | |
2043 if (N<Deco->DecodeLen[2]) { | |
2044 if (N<Deco->DecodeLen[1]) | |
2045 I=1; | |
2046 else | |
2047 I=2; | |
2048 } else { | |
2049 if (N<Deco->DecodeLen[3]) | |
2050 I=3; | |
2051 else | |
2052 I=4; | |
2053 } | |
2054 } else { | |
2055 if (N<Deco->DecodeLen[6]) { | |
2056 if (N<Deco->DecodeLen[5]) | |
2057 I=5; | |
2058 else | |
2059 I=6; | |
2060 } else { | |
2061 if (N<Deco->DecodeLen[7]) | |
2062 I=7; | |
2063 else | |
2064 I=8; | |
2065 } | |
2066 } | |
2067 } else { | |
2068 if (N<Deco->DecodeLen[12]) { | |
2069 if (N<Deco->DecodeLen[10]) { | |
2070 if (N<Deco->DecodeLen[9]) | |
2071 I=9; | |
2072 else | |
2073 I=10; | |
2074 } else { | |
2075 if (N<Deco->DecodeLen[11]) | |
2076 I=11; | |
2077 else | |
2078 I=12; | |
2079 } | |
2080 } else { | |
2081 if (N<Deco->DecodeLen[14]) { | |
2082 if (N<Deco->DecodeLen[13]) | |
2083 I=13; | |
2084 else | |
2085 I=14; | |
2086 | |
2087 } else { | |
2088 I=15; | |
2089 } | |
2090 } | |
2091 | |
2092 } | |
2093 #endif | |
2094 | |
2095 AddBits(I); | |
2096 if ((N=Deco->DecodePos[I]+((N-Deco->DecodeLen[I-1])>>(16-I)))>=Deco->MaxNum) | |
2097 N=0; | |
2098 Number=Deco->DecodeNum[N]; | |
2099 } | |
2100 | |
2101 | |
2102 void UnpInitData() | |
2103 { | |
2104 InAddr=InBit=0; | |
2105 if (!(NewLhd.Flags & LHD_SOLID)) | |
2106 { | |
2107 ChannelDelta=CurChannel=0; | |
2108 | |
2109 #ifdef _USE_ASM | |
2110 | |
2111 #ifdef _WIN_32 /* Win32 with VisualC */ | |
2112 | |
2113 __asm { | |
2114 push edi | |
2115 push eax | |
2116 push ecx | |
2117 | |
2118 cld /* increment EDI and ESI */ | |
2119 mov al, 0x00 | |
2120 mov ecx, SIZE AudV | |
2121 mov edi, Offset AudV | |
2122 rep stosb /* clear memory */ | |
2123 | |
2124 mov ecx, SIZE OldDist | |
2125 mov edi, Offset OldDist | |
2126 rep stosb /* clear memory */ | |
2127 | |
2128 mov ecx, SIZE UnpOldTable | |
2129 mov edi, Offset UnpOldTable | |
2130 rep stosb /* clear memory */ | |
2131 | |
2132 pop ecx | |
2133 pop eax | |
2134 pop edi | |
2135 | |
2136 | |
2137 mov [OldDistPtr], 0 | |
2138 mov [LastDist], 0 | |
2139 mov [LastLength], 0 | |
2140 mov [UnpPtr], 0 | |
2141 mov [WrPtr], 0 | |
2142 mov [OldDistPtr], 0 | |
2143 mov [LastLength], 0 | |
2144 mov [LastDist], 0 | |
2145 mov [UnpPtr], 0 | |
2146 mov [WrPtr], 0 | |
2147 | |
2148 } | |
2149 memset(UnpBuf,0,MAXWINSIZE); | |
2150 | |
2151 | |
2152 #else /* unix/linux on i386 cpus */ | |
2153 __asm__ __volatile ( | |
2154 " cld /* increment EDI and ESI */" | |
2155 " movb $0x00, %%al" | |
2156 " movl %0, %%ecx" | |
2157 " movl %1, %%edi" | |
2158 " rep " | |
2159 " stosb /* clear memory */" | |
2160 "" | |
2161 " movl %2, %%ecx" | |
2162 " mov %3, %%edi" | |
2163 " rep " | |
2164 " stosb /* clear memory */" | |
2165 "" | |
2166 " movl %4, %%ecx" | |
2167 " movl %5, %%edi" | |
2168 " rep " | |
2169 " stosb /* clear memory */" | |
2170 "" | |
2171 " movl $0, (OldDistPtr)" | |
2172 " movl $0, (LastDist)" | |
2173 " movl $0, (LastLength)" | |
2174 " movl $0, (UnpPtr)" | |
2175 " movl $0, (WrPtr)" | |
2176 " movl $0, (OldDistPtr)" | |
2177 " movl $0, (LastLength)" | |
2178 " movl $0, (LastDist)" | |
2179 " movl $0, (UnpPtr)" | |
2180 " movl $0, (WrPtr)" | |
2181 : | |
2182 : "m" ((long)sizeof(AudV)), | |
2183 "m" ((long)AudV), | |
2184 "m" ((long)sizeof(OldDist)), | |
2185 "m" ((long)OldDist), | |
2186 "m" ((long)sizeof(UnpOldTable)), | |
2187 "m" ((long)UnpOldTable) | |
2188 : "memory", "edi", "eax", "ecx" | |
2189 ); | |
2190 memset(UnpBuf,0,MAXWINSIZE); | |
2191 #endif | |
2192 | |
2193 #else /* unix/linux on non-i386 cpu */ | |
2194 memset(AudV,0,sizeof(AudV)); | |
2195 memset(OldDist,0,sizeof(OldDist)); | |
2196 OldDistPtr=0; | |
2197 LastDist=LastLength=0; | |
2198 memset(UnpBuf,0,MAXWINSIZE); | |
2199 memset(UnpOldTable,0,sizeof(UnpOldTable)); | |
2200 UnpPtr=WrPtr=0; | |
2201 #endif | |
2202 | |
2203 } | |
2204 } | |
2205 | |
2206 | |
2207 UBYTE DecodeAudio(int Delta) | |
2208 { | |
2209 struct AudioVariables *V; | |
2210 unsigned int Ch; | |
2211 unsigned int NumMinDif,MinDif; | |
2212 int PCh,I; | |
2213 | |
2214 V=&AudV[CurChannel]; | |
2215 V->ByteCount++; | |
2216 V->D4=V->D3; | |
2217 V->D3=V->D2; | |
2218 V->D2=V->LastDelta-V->D1; | |
2219 V->D1=V->LastDelta; | |
2220 PCh=8*V->LastChar+V->K1*V->D1+V->K2*V->D2+ | |
2221 V->K3*V->D3+V->K4*V->D4+V->K5*ChannelDelta; | |
2222 PCh=(PCh>>3) & 0xFF; | |
2223 | |
2224 Ch=PCh-Delta; | |
2225 | |
2226 I=((signed char)Delta)<<3; | |
2227 | |
2228 V->Dif[0]+=abs(I); | |
2229 V->Dif[1]+=abs(I-V->D1); | |
2230 V->Dif[2]+=abs(I+V->D1); | |
2231 V->Dif[3]+=abs(I-V->D2); | |
2232 V->Dif[4]+=abs(I+V->D2); | |
2233 V->Dif[5]+=abs(I-V->D3); | |
2234 V->Dif[6]+=abs(I+V->D3); | |
2235 V->Dif[7]+=abs(I-V->D4); | |
2236 V->Dif[8]+=abs(I+V->D4); | |
2237 V->Dif[9]+=abs(I-ChannelDelta); | |
2238 V->Dif[10]+=abs(I+ChannelDelta); | |
2239 | |
2240 ChannelDelta=V->LastDelta=(signed char)(Ch-V->LastChar); | |
2241 V->LastChar=Ch; | |
2242 | |
2243 if ((V->ByteCount & 0x1F)==0) | |
2244 { | |
2245 MinDif=V->Dif[0]; | |
2246 NumMinDif=0; | |
2247 V->Dif[0]=0; | |
2248 for (I=1;(unsigned int)I<sizeof(V->Dif)/sizeof(V->Dif[0]);I++) | |
2249 { | |
2250 if (V->Dif[I]<MinDif) | |
2251 { | |
2252 MinDif=V->Dif[I]; | |
2253 NumMinDif=I; | |
2254 } | |
2255 V->Dif[I]=0; | |
2256 } | |
2257 switch(NumMinDif) | |
2258 { | |
2259 case 1: | |
2260 if (V->K1>=-16) | |
2261 V->K1--; | |
2262 break; | |
2263 case 2: | |
2264 if (V->K1<16) | |
2265 V->K1++; | |
2266 break; | |
2267 case 3: | |
2268 if (V->K2>=-16) | |
2269 V->K2--; | |
2270 break; | |
2271 case 4: | |
2272 if (V->K2<16) | |
2273 V->K2++; | |
2274 break; | |
2275 case 5: | |
2276 if (V->K3>=-16) | |
2277 V->K3--; | |
2278 break; | |
2279 case 6: | |
2280 if (V->K3<16) | |
2281 V->K3++; | |
2282 break; | |
2283 case 7: | |
2284 if (V->K4>=-16) | |
2285 V->K4--; | |
2286 break; | |
2287 case 8: | |
2288 if (V->K4<16) | |
2289 V->K4++; | |
2290 break; | |
2291 case 9: | |
2292 if (V->K5>=-16) | |
2293 V->K5--; | |
2294 break; | |
2295 case 10: | |
2296 if (V->K5<16) | |
2297 V->K5++; | |
2298 break; | |
2299 } | |
2300 } | |
2301 return((UBYTE)Ch); | |
2302 } | |
2303 | |
2304 | |
2305 | |
2306 | |
2307 | |
2308 | |
2309 | |
2310 /* *************************************************** | |
2311 * ** CRCCrypt Code - decryption engine starts here ** | |
2312 * ***************************************************/ | |
2313 | |
2314 | |
2315 #define NROUNDS 32 | |
2316 | |
2317 #define rol(x,n) (((x)<<(n)) | ((x)>>(8*sizeof(x)-(n)))) | |
2318 #define ror(x,n) (((x)>>(n)) | ((x)<<(8*sizeof(x)-(n)))) | |
2319 | |
2320 #define substLong(t) ( (UDWORD)SubstTable[(int)t&255] | \ | |
2321 ((UDWORD)SubstTable[(int)(t>> 8)&255]<< 8) | \ | |
2322 ((UDWORD)SubstTable[(int)(t>>16)&255]<<16) | \ | |
2323 ((UDWORD)SubstTable[(int)(t>>24)&255]<<24) ) | |
2324 | |
2325 | |
2326 UDWORD CRCTab[256]; | |
2327 | |
2328 UBYTE SubstTable[256]; | |
2329 UBYTE InitSubstTable[256]={ | |
2330 215, 19,149, 35, 73,197,192,205,249, 28, 16,119, 48,221, 2, 42, | |
2331 232, 1,177,233, 14, 88,219, 25,223,195,244, 90, 87,239,153,137, | |
2332 255,199,147, 70, 92, 66,246, 13,216, 40, 62, 29,217,230, 86, 6, | |
2333 71, 24,171,196,101,113,218,123, 93, 91,163,178,202, 67, 44,235, | |
2334 107,250, 75,234, 49,167,125,211, 83,114,157,144, 32,193,143, 36, | |
2335 158,124,247,187, 89,214,141, 47,121,228, 61,130,213,194,174,251, | |
2336 97,110, 54,229,115, 57,152, 94,105,243,212, 55,209,245, 63, 11, | |
2337 164,200, 31,156, 81,176,227, 21, 76, 99,139,188,127, 17,248, 51, | |
2338 207,120,189,210, 8,226, 41, 72,183,203,135,165,166, 60, 98, 7, | |
2339 122, 38,155,170, 69,172,252,238, 39,134, 59,128,236, 27,240, 80, | |
2340 131, 3, 85,206,145, 79,154,142,159,220,201,133, 74, 64, 20,129, | |
2341 224,185,138,103,173,182, 43, 34,254, 82,198,151,231,180, 58, 10, | |
2342 118, 26,102, 12, 50,132, 22,191,136,111,162,179, 45, 4,148,108, | |
2343 161, 56, 78,126,242,222, 15,175,146, 23, 33,241,181,190, 77,225, | |
2344 0, 46,169,186, 68, 95,237, 65, 53,208,253,168, 9, 18,100, 52, | |
2345 116,184,160, 96,109, 37, 30,106,140,104,150, 5,204,117,112, 84 | |
2346 }; | |
2347 | |
2348 UDWORD Key[4]; | |
2349 | |
2350 | |
2351 void EncryptBlock(UBYTE *Buf) | |
2352 { | |
2353 int I; | |
2354 | |
2355 UDWORD A,B,C,D,T,TA,TB; | |
2356 #ifdef NON_INTEL_BYTE_ORDER | |
2357 A=((UDWORD)Buf[0]|((UDWORD)Buf[1]<<8)|((UDWORD)Buf[2]<<16)| | |
2358 ((UDWORD)Buf[3]<<24))^Key[0]; | |
2359 B=((UDWORD)Buf[4]|((UDWORD)Buf[5]<<8)|((UDWORD)Buf[6]<<16)| | |
2360 ((UDWORD)Buf[7]<<24))^Key[1]; | |
2361 C=((UDWORD)Buf[8]|((UDWORD)Buf[9]<<8)|((UDWORD)Buf[10]<<16)| | |
2362 ((UDWORD)Buf[11]<<24))^Key[2]; | |
2363 D=((UDWORD)Buf[12]|((UDWORD)Buf[13]<<8)|((UDWORD)Buf[14]<<16)| | |
2364 ((UDWORD)Buf[15]<<24))^Key[3]; | |
2365 #else | |
2366 UDWORD *BufPtr; | |
2367 BufPtr=(UDWORD *)Buf; | |
2368 A=BufPtr[0]^Key[0]; | |
2369 B=BufPtr[1]^Key[1]; | |
2370 C=BufPtr[2]^Key[2]; | |
2371 D=BufPtr[3]^Key[3]; | |
2372 #endif | |
2373 for(I=0;I<NROUNDS;I++) | |
2374 { | |
2375 T=((C+rol(D,11))^Key[I&3]); | |
2376 TA=A^substLong(T); | |
2377 T=((D^rol(C,17))+Key[I&3]); | |
2378 TB=B^substLong(T); | |
2379 A=C; | |
2380 B=D; | |
2381 C=TA; | |
2382 D=TB; | |
2383 } | |
2384 #ifdef NON_INTEL_BYTE_ORDER | |
2385 C^=Key[0]; | |
2386 Buf[0]=(UBYTE)C; | |
2387 Buf[1]=(UBYTE)(C>>8); | |
2388 Buf[2]=(UBYTE)(C>>16); | |
2389 Buf[3]=(UBYTE)(C>>24); | |
2390 D^=Key[1]; | |
2391 Buf[4]=(UBYTE)D; | |
2392 Buf[5]=(UBYTE)(D>>8); | |
2393 Buf[6]=(UBYTE)(D>>16); | |
2394 Buf[7]=(UBYTE)(D>>24); | |
2395 A^=Key[2]; | |
2396 Buf[8]=(UBYTE)A; | |
2397 Buf[9]=(UBYTE)(A>>8); | |
2398 Buf[10]=(UBYTE)(A>>16); | |
2399 Buf[11]=(UBYTE)(A>>24); | |
2400 B^=Key[3]; | |
2401 Buf[12]=(UBYTE)B; | |
2402 Buf[13]=(UBYTE)(B>>8); | |
2403 Buf[14]=(UBYTE)(B>>16); | |
2404 Buf[15]=(UBYTE)(B>>24); | |
2405 #else | |
2406 BufPtr[0]=C^Key[0]; | |
2407 BufPtr[1]=D^Key[1]; | |
2408 BufPtr[2]=A^Key[2]; | |
2409 BufPtr[3]=B^Key[3]; | |
2410 #endif | |
2411 UpdKeys(Buf); | |
2412 } | |
2413 | |
2414 | |
2415 void DecryptBlock(UBYTE *Buf) | |
2416 { | |
2417 int I; | |
2418 UBYTE InBuf[16]; | |
2419 UDWORD A,B,C,D,T,TA,TB; | |
2420 #ifdef NON_INTEL_BYTE_ORDER | |
2421 A=((UDWORD)Buf[0]|((UDWORD)Buf[1]<<8)|((UDWORD)Buf[2]<<16)| | |
2422 ((UDWORD)Buf[3]<<24))^Key[0]; | |
2423 B=((UDWORD)Buf[4]|((UDWORD)Buf[5]<<8)|((UDWORD)Buf[6]<<16)| | |
2424 ((UDWORD)Buf[7]<<24))^Key[1]; | |
2425 C=((UDWORD)Buf[8]|((UDWORD)Buf[9]<<8)|((UDWORD)Buf[10]<<16)| | |
2426 ((UDWORD)Buf[11]<<24))^Key[2]; | |
2427 D=((UDWORD)Buf[12]|((UDWORD)Buf[13]<<8)|((UDWORD)Buf[14]<<16)| | |
2428 ((UDWORD)Buf[15]<<24))^Key[3]; | |
2429 #else | |
2430 UDWORD *BufPtr; | |
2431 BufPtr=(UDWORD *)Buf; | |
2432 A=BufPtr[0]^Key[0]; /* xxx may be this can be */ | |
2433 B=BufPtr[1]^Key[1]; /* optimized in assembler */ | |
2434 C=BufPtr[2]^Key[2]; | |
2435 D=BufPtr[3]^Key[3]; | |
2436 #endif | |
2437 memcpy(InBuf,Buf,sizeof(InBuf)); | |
2438 for(I=NROUNDS-1;I>=0;I--) | |
2439 { | |
2440 T=((C+rol(D,11))^Key[I&3]); | |
2441 TA=A^substLong(T); | |
2442 T=((D^rol(C,17))+Key[I&3]); | |
2443 TB=B^substLong(T); | |
2444 A=C; | |
2445 B=D; | |
2446 C=TA; | |
2447 D=TB; | |
2448 } | |
2449 #ifdef NON_INTEL_BYTE_ORDER | |
2450 C^=Key[0]; | |
2451 Buf[0]=(UBYTE)C; | |
2452 Buf[1]=(UBYTE)(C>>8); | |
2453 Buf[2]=(UBYTE)(C>>16); | |
2454 Buf[3]=(UBYTE)(C>>24); | |
2455 D^=Key[1]; | |
2456 Buf[4]=(UBYTE)D; | |
2457 Buf[5]=(UBYTE)(D>>8); | |
2458 Buf[6]=(UBYTE)(D>>16); | |
2459 Buf[7]=(UBYTE)(D>>24); | |
2460 A^=Key[2]; | |
2461 Buf[8]=(UBYTE)A; | |
2462 Buf[9]=(UBYTE)(A>>8); | |
2463 Buf[10]=(UBYTE)(A>>16); | |
2464 Buf[11]=(UBYTE)(A>>24); | |
2465 B^=Key[3]; | |
2466 Buf[12]=(UBYTE)B; | |
2467 Buf[13]=(UBYTE)(B>>8); | |
2468 Buf[14]=(UBYTE)(B>>16); | |
2469 Buf[15]=(UBYTE)(B>>24); | |
2470 #else | |
2471 BufPtr[0]=C^Key[0]; | |
2472 BufPtr[1]=D^Key[1]; | |
2473 BufPtr[2]=A^Key[2]; | |
2474 BufPtr[3]=B^Key[3]; | |
2475 #endif | |
2476 UpdKeys(InBuf); | |
2477 } | |
2478 | |
2479 | |
2480 void UpdKeys(UBYTE *Buf) | |
2481 { | |
2482 int I; | |
2483 for (I=0;I<16;I+=4) | |
2484 { | |
2485 Key[0]^=CRCTab[Buf[I]]; /* xxx may be I'll rewrite this */ | |
2486 Key[1]^=CRCTab[Buf[I+1]]; /* in asm for speedup */ | |
2487 Key[2]^=CRCTab[Buf[I+2]]; | |
2488 Key[3]^=CRCTab[Buf[I+3]]; | |
2489 } | |
2490 } | |
2491 | |
2492 void SetCryptKeys(char *Password) | |
2493 { | |
2494 unsigned int I,J,K,PswLength; | |
2495 unsigned char N1,N2; | |
2496 unsigned char Psw[256]; | |
2497 | |
2498 #if !defined _USE_ASM | |
2499 UBYTE Ch; | |
2500 #endif | |
2501 | |
2502 SetOldKeys(Password); | |
2503 | |
2504 Key[0]=0xD3A3B879L; | |
2505 Key[1]=0x3F6D12F7L; | |
2506 Key[2]=0x7515A235L; | |
2507 Key[3]=0xA4E7F123L; | |
2508 memset(Psw,0,sizeof(Psw)); | |
2509 strcpy((char *)Psw,Password); | |
2510 PswLength=strlen(Password); | |
2511 memcpy(SubstTable,InitSubstTable,sizeof(SubstTable)); | |
2512 | |
2513 for (J=0;J<256;J++) | |
2514 for (I=0;I<PswLength;I+=2) | |
2515 { | |
2516 N2=(unsigned char)CRCTab[(Psw[I+1]+J)&0xFF]; | |
2517 for (K=1, N1=(unsigned char)CRCTab[(Psw[I]-J)&0xFF]; | |
2518 (N1!=N2) && (N1 < 256); /* I had to add "&& (N1 < 256)", */ | |
2519 N1++, K++) /* because the system crashed with */ | |
2520 { /* encrypted RARs */ | |
2521 #ifdef _USE_ASM | |
2522 | |
2523 #ifdef _WIN_32 | |
2524 __asm { | |
2525 | |
2526 mov ebx, Offset SubstTable | |
2527 mov edx, ebx | |
2528 | |
2529 xor ecx, ecx // read SubstTable[N1]... | |
2530 mov cl, N1 | |
2531 add ebx, ecx | |
2532 mov al, byte ptr[ebx] | |
2533 | |
2534 mov cl, N1 // read SubstTable[(N1+I+K)&0xFF]... | |
2535 add ecx, I | |
2536 add ecx, K | |
2537 and ecx, 0xFF | |
2538 add edx, ecx | |
2539 mov ah, byte ptr[edx] | |
2540 | |
2541 mov byte ptr[ebx], ah // and write back | |
2542 mov byte ptr[edx], al | |
2543 | |
2544 } | |
2545 #else | |
2546 __asm__ __volatile__ ( | |
2547 " xorl %%ecx, %%ecx" | |
2548 " movl %2, %%ecx /* ecx = N1 */" | |
2549 " mov %%ebx, %%edx" | |
2550 " addl %%ecx, %%ebx" | |
2551 "" | |
2552 " addl %0, %%ecx" | |
2553 " addl %1, %%ecx" | |
2554 " andl $0x000000FF, %%ecx" | |
2555 " addl %%ecx, %%edx" | |
2556 " " | |
2557 " movb (%%ebx), %%al" | |
2558 " movb (%%edx), %%ah" | |
2559 "" | |
2560 " movb %%ah, (%%ebx) /* and write back */" | |
2561 " movb %%al, (%%edx)" | |
2562 : : "g" ((long)I), | |
2563 "g" ((long)K), | |
2564 "g" ((long)N1), | |
2565 "ebx"((long)SubstTable) | |
2566 : "ecx", "edx" | |
2567 | |
2568 ); | |
2569 #endif | |
2570 | |
2571 #else | |
2572 /* Swap(&SubstTable[N1],&SubstTable[(N1+I+K)&0xFF]); */ | |
2573 Ch=SubstTable[N1]; | |
2574 SubstTable[N1]=SubstTable[(N1+I+K)&0xFF]; | |
2575 SubstTable[(N1+I+K)&0xFF]=Ch; | |
2576 #endif | |
2577 } | |
2578 } | |
2579 for (I=0;I<PswLength;I+=16) | |
2580 EncryptBlock(&Psw[I]); | |
2581 } | |
2582 | |
2583 | |
2584 void SetOldKeys(char *Password) | |
2585 { | |
2586 UDWORD PswCRC; | |
2587 UBYTE Ch; | |
2588 PswCRC=CalcCRC32(0xFFFFFFFFL,(UBYTE*)Password,strlen(Password)); | |
2589 OldKey[0]=(UWORD)PswCRC; | |
2590 OldKey[1]=(UWORD)(PswCRC>>16); | |
2591 OldKey[2]=OldKey[3]=0; | |
2592 PN1=PN2=PN3=0; | |
2593 while ((Ch=*Password)!=0) | |
2594 { | |
2595 PN1+=Ch; | |
2596 PN2^=Ch; | |
2597 PN3+=Ch; | |
2598 PN3=(UBYTE)rol(PN3,1); | |
2599 OldKey[2]^=((UWORD)(Ch^CRCTab[Ch])); | |
2600 OldKey[3]+=((UWORD)(Ch+(CRCTab[Ch]>>16))); | |
2601 Password++; | |
2602 } | |
2603 } | |
2604 | |
2605 void InitCRC(void) | |
2606 { | |
2607 int I, J; | |
2608 UDWORD C; | |
2609 for (I=0;I<256;I++) | |
2610 { | |
2611 for (C=I,J=0;J<8;J++) | |
2612 C=(C & 1) ? (C>>1)^0xEDB88320L : (C>>1); | |
2613 CRCTab[I]=C; | |
2614 } | |
2615 } | |
2616 | |
2617 | |
2618 UDWORD CalcCRC32(UDWORD StartCRC,UBYTE *Addr,UDWORD Size) | |
2619 { | |
2620 unsigned int I; | |
2621 for (I=0; I<Size; I++) | |
2622 StartCRC = CRCTab[(UBYTE)StartCRC ^ Addr[I]] ^ (StartCRC >> 8); | |
2623 return(StartCRC); | |
2624 } | |
2625 | |
2626 | |
2627 /* ************************************************************************** | |
2628 **************************************************************************** | |
2629 **************************************************************************** | |
2630 ************************************************************************** */ | |
2631 | |
2632 | |
2633 | |
2634 | |
2635 | |
2636 | |
2637 | |
2638 | |
2639 | |
2640 | |
2641 | |
2642 | |
2643 | |
2644 | |
2645 | |
2646 | |
2647 | |
2648 | |
2649 | |
2650 | |
2651 | |
2652 | |
2653 | |
2654 | |
2655 | |
2656 /* ************************************************************************** | |
2657 **************************************************************************** | |
2658 **************************************************************************** | |
2659 **************************************************************************** | |
2660 ******* ******* | |
2661 ******* ******* | |
2662 ******* ******* | |
2663 ******* D E B U G F U N C T I O N S ******* | |
2664 ******* ******* | |
2665 ******* ******* | |
2666 ******* ******* | |
2667 **************************************************************************** | |
2668 **************************************************************************** | |
2669 **************************************************************************** | |
2670 ************************************************************************** */ | |
2671 #ifdef _DEBUG_LOG | |
2672 | |
2673 | |
2674 /* -- global stuff -------------------------------------------------------- */ | |
2675 char log_file_name[256]; /* file name for the log file */ | |
2676 DWORD debug_start_time; /* starttime of debug */ | |
2677 BOOL debug_started = FALSE; /* debug_log writes only if */ | |
2678 /* this is TRUE */ | |
2679 /* ------------------------------------------------------------------------ */ | |
2680 | |
2681 | |
2682 /* -- global functions ---------------------------------------------------- */ | |
2683 void debug_init_proc(char *file_name) | |
2684 /* Create/Rewrite a log file */ | |
2685 { | |
2686 FILE *fp; | |
2687 char date[] = __DATE__; | |
2688 char time[] = __TIME__; | |
2689 | |
2690 debug_start_time = GetTickCount(); /* get start time */ | |
2691 strcpy(log_file_name, file_name); /* save file name */ | |
2692 | |
2693 if((fp = fopen(log_file_name, CREATETEXT)) != NULL) | |
2694 { | |
2695 debug_started = TRUE; /* enable debug */ | |
2696 fprintf(fp, "Debug log of UniquE's RARFileLib\n"\ | |
2697 "~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~\n"); | |
2698 fprintf(fp, "(executable compiled on %s at %s)\n\n", date, time); | |
2699 fclose(fp); | |
2700 } | |
2701 } | |
2702 | |
2703 | |
2704 void debug_log_proc(char *text, char *sourcefile, int sourceline) | |
2705 /* add a line to the log file */ | |
2706 { | |
2707 FILE *fp; | |
2708 | |
2709 if(debug_started == FALSE) return; /* exit if not initialized */ | |
2710 | |
2711 if((fp = fopen(log_file_name, APPENDTEXT)) != NULL) /* append to logfile */ | |
2712 | |
2713 { | |
2714 fprintf(fp, " %8u ms (line %u in %s):\n - %s\n", | |
2715 (unsigned int)(GetTickCount() - debug_start_time), | |
2716 sourceline, sourcefile, text); | |
2717 fclose(fp); | |
2718 } | |
2719 } | |
2720 | |
2721 /* ------------------------------------------------------------------------ */ | |
2722 #endif | |
2723 /* ************************************************************************** | |
2724 **************************************************************************** | |
2725 **************************************************************************** | |
2726 ************************************************************************** */ | |
2727 | |
2728 | |
2729 /* end of file urarlib.c */ |