⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 urarlib.c

📁 一个解RAR文件的开发库源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    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 + -