📄 urarlib.c
字号:
sprintf(DebugMsg, "Extracted %u Bytes.", (unsigned int)*size); } debug_log(DebugMsg);#else }#endif *(DWORD*)output=(DWORD)temp_output_buffer;/* return pointer for unpacked*/ /* data */ return retcode;}int urarlib_list(void *rarfile, ArchiveList_struct *list){ ArchiveList_struct *tmp_List = NULL; int NoOfFilesInArchive = 0; /* number of files in archive */#ifdef _DEBUG_LOG if(debug_log_first_start) { debug_log_first_start=FALSE; /* only create a new log file */ debug_init(_DEBUG_LOG_FILE); /* on startup */ }#endif InitCRC(); /* init some vars */#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION
MemRARFile = rarfile; /* assign pointer to RAR file */
MemRARFile->offset = 0;
if (!IsArchive())
{
debug_log("Not a RAR file");
return NoOfFilesInArchive; /* error => exit! */
}
#else
/* open and identify archive */ if ((ArcPtr=fopen(rarfile,READBINARY))!=NULL) { if (!IsArchive()) { debug_log("Not a RAR file"); fclose(ArcPtr);
ArcPtr = NULL; return NoOfFilesInArchive; /* error => exit! */ }
}
else { debug_log("Error opening file."); return NoOfFilesInArchive; }#endif
if ((UnpMemory=malloc(UNP_MEMORY))==NULL) { debug_log("Can't allocate memory for decompression!"); return NoOfFilesInArchive; }#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION
MemRARFile->offset+=NewMhd.HeadSize-MainHeadSize;
#else tseek(ArcPtr,NewMhd.HeadSize-MainHeadSize,SEEK_CUR);
#endif (void*)(*(DWORD*)list) = NULL; /* init file list */ /* do while file is not extracted and there's no error */ while (TRUE) { if (ReadBlock(FILE_HEAD | READSUBBLOCK) <= 0) /* read name of the next */ { /* file within the RAR archive */ debug_log("Couldn't read next filename from archive (I/O error)."); break; /* error, file not found in */ } /* archive or I/O error */ if (BlockHead.HeadType==SUB_HEAD) { debug_log("Sorry, sub-headers not supported."); break; /* error => exit */ } if((void*)(*(DWORD*)list) == NULL) /* first entry */ { tmp_List = malloc(sizeof(ArchiveList_struct)); tmp_List->next = NULL; (void*)(*(DWORD*)list) = tmp_List; } else /* add entry */ { tmp_List->next = malloc(sizeof(ArchiveList_struct)); tmp_List = (ArchiveList_struct*) tmp_List->next; tmp_List->next = NULL; } tmp_List->item.Name = malloc(NewLhd.NameSize + 1); strcpy(tmp_List->item.Name, ArcFileName); tmp_List->item.NameSize = NewLhd.NameSize; tmp_List->item.PackSize = NewLhd.PackSize; tmp_List->item.UnpSize = NewLhd.UnpSize; tmp_List->item.HostOS = NewLhd.HostOS; tmp_List->item.FileCRC = NewLhd.FileCRC; tmp_List->item.FileTime = NewLhd.FileTime; tmp_List->item.UnpVer = NewLhd.UnpVer; tmp_List->item.Method = NewLhd.Method; tmp_List->item.FileAttr = NewLhd.FileAttr; NoOfFilesInArchive++; /* count files */
#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION
MemRARFile->offset = NextBlockPos;
#else if (ArcPtr!=NULL) tseek(ArcPtr,NextBlockPos,SEEK_SET);
#endif
}; /* free memory, clear password and close archive */
memset(Password,0,sizeof(Password)); /* clear password */#ifndef _USE_MEMORY_TO_MEMORY_DECOMPRESSION
if (ArcPtr!=NULL){
fclose(ArcPtr);
ArcPtr = NULL;
}
#endif
free(UnpMemory); /* free memory */ free(TempMemory); free(CommMemory); UnpMemory=NULL; TempMemory=NULL; CommMemory=NULL; return NoOfFilesInArchive;}/* ------------------------------------------------------------------------ *//**************************************************************************** **************************************************************************** **************************************************************************** **************************************************************************** ******* ******* ******* ******* ******* ******* ******* B L O C K I / O ******* ******* ******* ******* ******* ******* ******* **************************************************************************** **************************************************************************** **************************************************************************** ****************************************************************************/#define GetHeaderByte(N) Header[N]#define GetHeaderWord(N) (Header[N]+((UWORD)Header[N+1]<<8))#define GetHeaderDword(N) (Header[N]+((UWORD)Header[N+1]<<8)+\ ((UDWORD)Header[N+2]<<16)+\ ((UDWORD)Header[N+3]<<24))int ReadBlock(int BlockType){ struct NewFileHeader SaveFileHead; int Size=0,ReadSubBlock=0; static int LastBlock; memcpy(&SaveFileHead,&NewLhd,sizeof(SaveFileHead)); if (BlockType & READSUBBLOCK) ReadSubBlock=1; BlockType &= 0xff; { while (1) {#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION
CurBlockPos=MemRARFile->offset; /* get offset of mem-file */
#else
CurBlockPos=ftell(ArcPtr);
#endif Size=ReadHeader(FILE_HEAD); if (Size!=0) { if (NewLhd.HeadSize<SIZEOF_SHORTBLOCKHEAD) return(0); NextBlockPos=CurBlockPos+NewLhd.HeadSize; if (NewLhd.Flags & LONG_BLOCK) NextBlockPos+=NewLhd.PackSize; if (NextBlockPos<=CurBlockPos) return(0); } if (Size > 0 && BlockType!=SUB_HEAD) LastBlock=BlockType; if (Size==0 || BlockType==ALL_HEAD || NewLhd.HeadType==BlockType || (NewLhd.HeadType==SUB_HEAD && ReadSubBlock && LastBlock==BlockType)) break;
#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION
MemRARFile->offset = NextBlockPos;
#else tseek(ArcPtr, NextBlockPos, SEEK_SET);
#endif } } BlockHead.HeadCRC=NewLhd.HeadCRC; BlockHead.HeadType=NewLhd.HeadType; BlockHead.Flags=NewLhd.Flags; BlockHead.HeadSize=NewLhd.HeadSize; BlockHead.DataSize=NewLhd.PackSize; if (BlockType!=NewLhd.HeadType) BlockType=ALL_HEAD; if((FILE_HEAD == BlockType) && (Size>0)) { NewLhd.NameSize=Min(NewLhd.NameSize,sizeof(ArcFileName)-1);#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION
tread(MemRARFile, ArcFileName, NewLhd.NameSize);
#else
tread(ArcPtr,ArcFileName,NewLhd.NameSize);
#endif ArcFileName[NewLhd.NameSize]=0;#ifdef _DEBUG_LOG if (NewLhd.HeadCRC!=(UWORD)~CalcCRC32(HeaderCRC,(UBYTE*)&ArcFileName[0], NewLhd.NameSize)) { debug_log("file header broken"); }#endif Size+=NewLhd.NameSize; } else { memcpy(&NewLhd,&SaveFileHead,sizeof(NewLhd));#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION
MemRARFile->offset = CurBlockPos;
#else
tseek(ArcPtr,CurBlockPos,SEEK_SET);
#endif } return(Size);}int ReadHeader(int BlockType){ int Size = 0; unsigned char Header[64]; switch(BlockType) { case MAIN_HEAD:#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION
Size=tread(MemRARFile, Header, SIZEOF_NEWMHD);
#else
Size=tread(ArcPtr,Header,SIZEOF_NEWMHD);
#endif NewMhd.HeadCRC=(unsigned short)GetHeaderWord(0); NewMhd.HeadType=GetHeaderByte(2); NewMhd.Flags=(unsigned short)GetHeaderWord(3); NewMhd.HeadSize=(unsigned short)GetHeaderWord(5); NewMhd.Reserved=(unsigned short)GetHeaderWord(7); NewMhd.Reserved1=GetHeaderDword(9); HeaderCRC=CalcCRC32(0xFFFFFFFFL,&Header[2],SIZEOF_NEWMHD-2); break; case FILE_HEAD:#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION
Size=tread(MemRARFile, Header, SIZEOF_NEWLHD);
#else
Size=tread(ArcPtr,Header,SIZEOF_NEWLHD);
#endif NewLhd.HeadCRC=(unsigned short)GetHeaderWord(0); NewLhd.HeadType=GetHeaderByte(2); NewLhd.Flags=(unsigned short)GetHeaderWord(3); NewLhd.HeadSize=(unsigned short)GetHeaderWord(5); NewLhd.PackSize=GetHeaderDword(7); NewLhd.UnpSize=GetHeaderDword(11); NewLhd.HostOS=GetHeaderByte(15); NewLhd.FileCRC=GetHeaderDword(16); NewLhd.FileTime=GetHeaderDword(20); NewLhd.UnpVer=GetHeaderByte(24); NewLhd.Method=GetHeaderByte(25); NewLhd.NameSize=(unsigned short)GetHeaderWord(26); NewLhd.FileAttr=GetHeaderDword(28); HeaderCRC=CalcCRC32(0xFFFFFFFFL,&Header[2],SIZEOF_NEWLHD-2); break;#ifdef _DEBUG_LOG case COMM_HEAD: /* log errors in case of debug */ debug_log("Comment headers not supported! "\ "Please create archives without comments."); break; case PROTECT_HEAD: debug_log("Protected headers not supported!"); break; case ALL_HEAD: debug_log("ShortBlockHeader not supported!"); break; default: debug_log("Unknown//unsupported !");#else default: /* else do nothing */ break;#endif } return(Size);}/* ************************************************************************** **************************************************************************** **************************************************************************** ************************************************************************** *//* ************************************************************************** **************************************************************************** **************************************************************************** **************************************************************************** ******* ******* ******* ******* ******* ******* ******* E X T R A C T L O O P ******* ******* ******* ******* ******* ******* ******* **************************************************************************** **************************************************************************** **************************************************************************** ************************************************************************** */int IsArchive(void){#ifdef _DEBUG_LOG int str_offs; /* used for debug-strings */ char DebugMsg[500]; /* used to compose debug msg */#endif#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION
if (tread(MemRARFile, MarkHead.Mark, SIZEOF_MARKHEAD) != SIZEOF_MARKHEAD)
return(FALSE);
#else
if (tread(ArcPtr,MarkHead.Mark,SIZEOF_MARKHEAD)!=SIZEOF_MARKHEAD)
return(FALSE);
#endif /* Old archive => error */ if (MarkHead.Mark[0]==0x52 && MarkHead.Mark[1]==0x45 && MarkHead.Mark[2]==0x7e && MarkHead.Mark[3]==0x5e) { debug_log("Attention: format as OLD detected! Can't handel archive!"); } else /* original RAR v2.0 */ if ((MarkHead.Mark[0]==0x52 && MarkHead.Mark[1]==0x61 && /* original */ MarkHead.Mark[2]==0x72 && MarkHead.Mark[3]==0x21 && /* RAR header*/ MarkHead.Mark[4]==0x1a && MarkHead.Mark[5]==0x07 && MarkHead.Mark[6]==0x00) || /* "UniquE!" - header */ (MarkHead.Mark[0]=='U' && MarkHead.Mark[1]=='n' && /* "UniquE!" */ MarkHead.Mark[2]=='i' && MarkHead.Mark[3]=='q' && /* header */ MarkHead.Mark[4]=='u' && MarkHead.Mark[5]=='E' && MarkHead.Mark[6]=='!')) { if (ReadHeader(MAIN_HEAD)!=SIZEOF_NEWMHD) return(FALSE); } else {#ifdef _DEBUG_LOG /* sorry for this ugly code, but older SunOS gcc compilers don't */ /* support white spaces within strings */ str_offs = sprintf(DebugMsg, "unknown archive type (only plain RAR "); str_offs += sprintf(DebugMsg + str_offs, "supported (normal and solid "); str_offs += sprintf(DebugMsg + str_offs, "archives), SFX and Volumes "); str_offs += sprintf(DebugMsg + str_offs, "are NOT supported!)"); debug_log(DebugMsg);#endif } MainHeadSize=SIZEOF_NEWMHD; return(TRUE);}BOOL ExtrFile(void){ BOOL ReturnCode=TRUE; FileFound=FALSE; /* no file found by default */
#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION
MemRARFile->offset = 0; /* start reading from offset 0 */
if (!IsArchive())
{
debug_log("Not a RAR file");
return FALSE; /* error => exit! */
}
#else /* open and identify archive */ if ((ArcPtr=fopen(ArcName,READBINARY))!=NULL) { if (!IsArchive()) { debug_log("Not a RAR file"); fclose(ArcPtr);
ArcPtr = NULL; return FALSE; /* error => exit! */ } } else { debug_log("Error opening file."); return FALSE; }#endif
if ((UnpMemory=malloc(UNP_MEMORY))==NULL) { debug_log("Can't allocate memory for decompression!"); return FALSE; }#ifdef _USE_MEMORY_TO_MEMORY_DECOMPRESSION
MemRARFile->offset+=NewMhd.HeadSize-MainHeadSize;
#else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -