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