📄 urarlib.c
字号:
tseek(ArcPtr,NewMhd.HeadSize-MainHeadSize,SEEK_CUR);
#endif /* do while file is not extracted and there's no error */ do { if (ReadBlock(FILE_HEAD | READSUBBLOCK) <= 0) /* read name of the next */ { /* file within the RAR archive *//* * * 21.11.2000 UnQ There's a problem with some linux distros when a file * can not be found in an archive. * * debug_log("Couldn't read next filename from archive (I/O error)."); **/ ReturnCode=FALSE; break; /* error, file not found in */ } /* archive or I/O error */ if (BlockHead.HeadType==SUB_HEAD) { debug_log("Sorry, sub-headers not supported."); ReturnCode=FALSE; break; /* error => exit */ } if(TRUE == (FileFound=(stricomp(ArgName, ArcFileName) == 0))) /* *** file found! *** */ { { temp_output_buffer=malloc(NewLhd.UnpSize);/* allocate memory for the*/ } *temp_output_buffer_offset=0; /* file. The default offset */ /* within the buffer is 0 */ if(temp_output_buffer == NULL) { debug_log("can't allocate memory for the file decompression"); ReturnCode=FALSE; break; /* error, can't extract file! */ } } /* in case of a solid archive, we need to decompress any single file till * we have found the one we are looking for. In case of normal archives * (recommended!!), we skip the files until we are sure that it is the * one we want. */ if((NewMhd.Flags & 0x08) || FileFound) { if (NewLhd.UnpVer<13 || NewLhd.UnpVer>UNP_VER) { debug_log("unknown compression method"); ReturnCode=FALSE; break; /* error, can't extract file! */ } CurUnpRead=CurUnpWrite=0; if ((*Password!=0) && (NewLhd.Flags & LHD_PASSWORD)) Encryption=NewLhd.UnpVer; else Encryption=0; if (Encryption) SetCryptKeys(Password); UnpPackedSize=NewLhd.PackSize; DestUnpSize=NewLhd.UnpSize;
if (NewLhd.Method==0x30) { UnstoreFile(); } else { Unpack(UnpMemory); } #ifdef _DO_CRC32_CHECK /* calculate CRC32 */ if((UBYTE*)temp_output_buffer != NULL) { if(NewLhd.FileCRC!=~CalcCRC32(0xFFFFFFFFL, (UBYTE*)temp_output_buffer, NewLhd.UnpSize)) { debug_log("CRC32 error - file couldn't be decompressed correctly!"); ReturnCode=FALSE; break; /* error, can't extract file! */ } }#endif }#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION
MemRARFile->offset = NextBlockPos;
#else
if (ArcPtr!=NULL) tseek(ArcPtr,NextBlockPos,SEEK_SET);
#endif } while(stricomp(ArgName, ArcFileName) != 0);/* exit if file is extracted */ /* free memory, clear password and close archive */ free(UnpMemory); UnpMemory=NULL;#ifndef _USE_MEMORY_TO_MEMORY_DECOMPRESSION
if (ArcPtr!=NULL){
fclose(ArcPtr);
ArcPtr = NULL;
}
#endif return ReturnCode; /* file extracted successful! */}/* ************************************************************************** **************************************************************************** **************************************************************************** ************************************************************************** *//* ************************************************************************** **************************************************************************** **************************************************************************** **************************************************************************** ******* ******* ******* ******* ******* ******* ******* G L O B A L F U N C T I O N S ******* ******* ******* ******* ******* ******* ******* **************************************************************************** **************************************************************************** **************************************************************************** ************************************************************************** */int tread(void *stream,void *buf,unsigned len){
#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION
if(((MemRARFile->offset + len) > MemRARFile->size) || (len == 0))
return 0;
memcpy(buf,
(BYTE*)(((MemoryFile*)stream)->data)+((MemoryFile*)stream)->offset,
len % ((((MemoryFile*)stream)->size) - 1));
MemRARFile->offset+=len; /* update read pointer */
return len % ((((MemoryFile*)stream)->size) - 1);
#else return(fread(buf,1,len,(FILE*)stream));
#endif}#ifndef _USE_MEMORY_TO_MEMORY_DECOMPRESSION
int tseek(void *stream,long offset,int fromwhere){
return(fseek((FILE*)stream,offset,fromwhere));
}
#endif
char* strupper(char *Str){ char *ChPtr; for (ChPtr=Str;*ChPtr;ChPtr++) *ChPtr=(char)toupper(*ChPtr); return(Str);}int stricomp(char *Str1,char *Str2)/* compare strings without regard of '\' and '/' */{ char S1[512],S2[512]; char *chptr; strncpy(S1,Str1,sizeof(S1)); strncpy(S2,Str2,sizeof(S2)); while((chptr = strchr(S1, '\\')) != NULL) /* ignore backslash */ { *chptr = '_'; } while((chptr = strchr(S2, '\\')) != NULL) /* ignore backslash */ { *chptr = '_'; } while((chptr = strchr(S1, '/')) != NULL) /* ignore slash */ { *chptr = '_'; } while((chptr = strchr(S2, '/')) != NULL) /* ignore slash */ { *chptr = '_'; } return(strcmp(strupper(S1),strupper(S2)));}/* ************************************************************************** **************************************************************************** **************************************************************************** ************************************************************************** *//* ************************************************************************** **************************************************************************** **************************************************************************** **************************************************************************** ******* ******* ******* ******* ******* ******* ******* U N P A C K C O D E ******* ******* ******* ******* ******* ******* ******* **************************************************************************** **************************************************************************** **************************************************************************** ************************************************************************** *//* ***************************** * ** unpack stored RAR files ** * *****************************/BOOL UnstoreFile(void){ if ((long)(*temp_output_buffer_offset=UnpRead(temp_output_buffer, NewLhd.UnpSize))==-1) { debug_log("Read error of stored file!"); return FALSE; } return TRUE;}/* **************************************** * ** RAR decompression code starts here ** * ****************************************/#define NC 298 /* alphabet = {0,1,2, .,NC - 1} */#define DC 48#define RC 28#define BC 19#define MC 257enum {CODE_HUFFMAN=0,CODE_LZ=1,CODE_LZ2=2,CODE_REPEATLZ=3,CODE_CACHELZ=4, CODE_STARTFILE=5,CODE_ENDFILE=6,CODE_STARTMM=8,CODE_ENDMM=7, CODE_MMDELTA=9};struct AudioVariables{ int K1,K2,K3,K4,K5; int D1,D2,D3,D4; int LastDelta; unsigned int Dif[11]; unsigned int ByteCount; int LastChar;};#define NC 298 /* alphabet = {0, 1, 2, ..., NC - 1} */#define DC 48#define RC 28#define BC 19#define MC 257struct AudioVariables AudV[4];#define GetBits() \ BitField = ( ( ( (UDWORD)InBuf[InAddr] << 16 ) | \ ( (UWORD) InBuf[InAddr+1] << 8 ) | \ ( InBuf[InAddr+2] ) ) \ >> (8-InBit) ) & 0xffff;#define AddBits(Bits) \ InAddr += ( InBit + (Bits) ) >> 3; \ InBit = ( InBit + (Bits) ) & 7;static unsigned char *UnpBuf;static unsigned int BitField;static unsigned int Number;unsigned char InBuf[8192]; /* input read buffer */unsigned char UnpOldTable[MC*4];unsigned int InAddr,InBit,ReadTop;unsigned int LastDist,LastLength;static unsigned int Length,Distance;unsigned int OldDist[4],OldDistPtr;struct LitDecode{ unsigned int MaxNum; unsigned int DecodeLen[16]; unsigned int DecodePos[16]; unsigned int DecodeNum[NC];} LD;struct DistDecode{ unsigned int MaxNum; unsigned int DecodeLen[16]; unsigned int DecodePos[16]; unsigned int DecodeNum[DC];} DD;struct RepDecode{ unsigned int MaxNum; unsigned int DecodeLen[16]; unsigned int DecodePos[16]; unsigned int DecodeNum[RC];} RD;struct MultDecode{ unsigned int MaxNum; unsigned int DecodeLen[16]; unsigned int DecodePos[16]; unsigned int DecodeNum[MC];} MD[4];struct BitDecode{ unsigned int MaxNum; unsigned int DecodeLen[16]; unsigned int DecodePos[16]; unsigned int DecodeNum[BC];} BD;static struct MultDecode *MDPtr[4]={&MD[0],&MD[1],&MD[2],&MD[3]};int UnpAudioBlock,UnpChannels,CurChannel,ChannelDelta;void Unpack(unsigned char *UnpAddr)/* *** 38.3% of all CPU time is spent within this function!!! */{ static unsigned char LDecode[]={0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32, 40,48,56,64,80,96,112,128,160,192,224}; static unsigned char LBits[]= {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3, 3,3,3,4,4,4,4,5,5,5,5}; static int DDecode[]={0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384, 512,768,1024,1536,2048,3072,4096,6144,8192,12288, 16384,24576,32768U,49152U,65536,98304,131072,196608, 262144,327680,393216,458752,524288,589824,655360, 720896,786432,851968,917504,983040}; 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, 9,10,10,11,11,12,12,13,13,14,14,15,15,16, 16,16,16,16,16,16,16,16,16,16,16,16,16}; static unsigned char SDDecode[]={0,4,8,16,32,64,128,192}; static unsigned char SDBits[]={2,2,3, 4, 5, 6, 6, 6}; unsigned int Bits; UnpBuf=UnpAddr; /* UnpAddr is a pointer to the */ UnpInitData(); /* unpack buffer */ UnpReadBuf(1); if (!(NewLhd.Flags & LHD_SOLID)) ReadTables(); DestUnpSize--; while (DestUnpSize>=0) { UnpPtr&=MAXWINMASK; if (InAddr>sizeof(InBuf)-30) UnpReadBuf(0); if (((WrPtr-UnpPtr) & MAXWINMASK)<270 && WrPtr!=UnpPtr) { if (FileFound) { if (UnpPtr<WrPtr) { if((*temp_output_buffer_offset + UnpPtr) > NewLhd.UnpSize) { debug_log("Fatal! Buffer overrun during decompression!"); DestUnpSize=-1; } else { /* copy extracted data to output buffer */ memcpy(temp_output_buffer + *temp_output_buffer_offset, &UnpBuf[WrPtr], (0-WrPtr) & MAXWINMASK); /* update offset within buffer */ *temp_output_buffer_offset+= (0-WrPtr) & MAXWINMASK; /* copy extracted data to output buffer */ memcpy(temp_output_buffer + *temp_output_buffer_offset, UnpBuf, UnpPtr); /* update offset within buffer */ *temp_output_buffer_offset+=UnpPtr; } } else { if((*temp_output_buffer_offset + (UnpPtr-WrPtr)) > NewLhd.UnpSize) { debug_log("Fatal! Buffer overrun during decompression!"); DestUnpSize=-1; } else { /* copy extracted data to output buffer */ memcpy(temp_output_buffer + *temp_output_buffer_offset, &UnpBuf[WrPtr], UnpPtr-WrPtr); *temp_output_buffer_offset+=UnpPtr-WrPtr; /* update offset within buffer */ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -