Mercurial > mplayer.hg
annotate unrarlib.c @ 24674:f6cf2c01315d
Format 0x01 cannot be used with "AMV IMA ADPCM", because it belongs to normal PCM.
Make lavf demuxer set codec tag to AMVA in this case.
No need to use -ac +ffadpcmimaamva anymore.
author | voroshil |
---|---|
date | Wed, 03 Oct 2007 15:27:02 +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 */ |