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