예제 #1
0
void ExtractACL(Archive &Arc,char *FileName,wchar *FileNameW)
{
  if (!WinNT())
    return;

  SetPrivileges();

  if (Arc.HeaderCRC!=Arc.EAHead.HeadCRC)
  {
    Log(Arc.FileName,St(MACLBroken),FileName);
    ErrHandler.SetErrorCode(CRC_ERROR);
    return;
  }

  if (Arc.EAHead.Method<0x31 || Arc.EAHead.Method>0x35 || Arc.EAHead.UnpVer>PACK_VER)
  {
    Log(Arc.FileName,St(MACLUnknown),FileName);
    ErrHandler.SetErrorCode(WARNING);
    return;
  }

  ComprDataIO DataIO;
  Unpack Unpack(&DataIO);
  Unpack.Init();

  Array<byte> UnpData(Arc.EAHead.UnpSize);
  DataIO.SetUnpackToMemory(&UnpData[0],Arc.EAHead.UnpSize);
  DataIO.SetPackedSizeToRead(Arc.EAHead.DataSize);
  DataIO.EnableShowProgress(false);
  DataIO.SetFiles(&Arc,NULL);
  Unpack.SetDestSize(Arc.EAHead.UnpSize);
  Unpack.DoUnpack(Arc.EAHead.UnpVer,false);

  if (Arc.EAHead.EACRC!=~DataIO.UnpFileCRC)
  {
    Log(Arc.FileName,St(MACLBroken),FileName);
    ErrHandler.SetErrorCode(CRC_ERROR);
    return;
  }

  SECURITY_INFORMATION  si=OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
                           DACL_SECURITY_INFORMATION;
  if (ReadSacl)
    si|=SACL_SECURITY_INFORMATION;
  SECURITY_DESCRIPTOR *sd=(SECURITY_DESCRIPTOR *)&UnpData[0];

  int SetCode;
  if (FileNameW!=NULL)
    SetCode=SetFileSecurityW(FileNameW,si,sd);
  else
    SetCode=SetFileSecurityA(FileName,si,sd);

  if (!SetCode)
  {
    Log(Arc.FileName,St(MACLSetError),FileName);
    ErrHandler.SysErrMsg();
    ErrHandler.SetErrorCode(WARNING);
  }
}
예제 #2
0
void ExtractACL20(Archive &Arc,const wchar *FileName)
{
  SetACLPrivileges();

  if (Arc.BrokenHeader)
  {
    Log(Arc.FileName,St(MACLBroken),FileName);
    ErrHandler.SetErrorCode(RARX_CRC);
    return;
  }

  if (Arc.EAHead.Method<0x31 || Arc.EAHead.Method>0x35 || Arc.EAHead.UnpVer>VER_PACK)
  {
    Log(Arc.FileName,St(MACLUnknown),FileName);
    ErrHandler.SetErrorCode(RARX_WARNING);
    return;
  }

  ComprDataIO DataIO;
  Unpack Unpack(&DataIO);
  Unpack.Init(0x10000,false);

  Array<byte> UnpData(Arc.EAHead.UnpSize);
  DataIO.SetUnpackToMemory(&UnpData[0],Arc.EAHead.UnpSize);
  DataIO.SetPackedSizeToRead(Arc.EAHead.DataSize);
  DataIO.EnableShowProgress(false);
  DataIO.SetFiles(&Arc,NULL);
  DataIO.UnpHash.Init(HASH_CRC32,1);
  Unpack.SetDestSize(Arc.EAHead.UnpSize);
  Unpack.DoUnpack(Arc.EAHead.UnpVer,false);

  if (Arc.EAHead.EACRC!=DataIO.UnpHash.GetCRC32())
  {
    Log(Arc.FileName,St(MACLBroken),FileName);
    ErrHandler.SetErrorCode(RARX_CRC);
    return;
  }

  SECURITY_INFORMATION  si=OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
                           DACL_SECURITY_INFORMATION;
  if (ReadSacl)
    si|=SACL_SECURITY_INFORMATION;
  SECURITY_DESCRIPTOR *sd=(SECURITY_DESCRIPTOR *)&UnpData[0];

  int SetCode=SetFileSecurityW(FileName,si,sd);

  if (!SetCode)
  {
    Log(Arc.FileName,St(MACLSetError),FileName);
    ErrHandler.SysErrMsg();
    ErrHandler.SetErrorCode(RARX_WARNING);
  }
}
예제 #3
0
파일: extract.cpp 프로젝트: ikvm/mpc-hc
void CmdExtract::UnstoreFile(ComprDataIO &DataIO,int64 DestUnpSize)
{
  Array<byte> Buffer(0x40000);
  while (1)
  {
    uint Code=DataIO.UnpRead(&Buffer[0],Buffer.Size());
    if (Code==0 || (int)Code==-1)
      break;
    Code=Code<DestUnpSize ? Code:(uint)DestUnpSize;
    DataIO.UnpWrite(&Buffer[0],Code);
    if (DestUnpSize>=0)
      DestUnpSize-=Code;
  }
}
예제 #4
0
bool ExtractLink(ComprDataIO &DataIO,Archive &Arc,const char *LinkName,uint &LinkCRC,bool Create)
{
#if defined(SAVE_LINKS) && defined(_UNIX)
  char LinkTarget[NM];
  if (IsLink(Arc.NewLhd.FileAttr))
  {
    int DataSize=Min(Arc.NewLhd.PackSize,sizeof(LinkTarget)-1);
    DataIO.UnpRead((byte *)LinkTarget,DataSize);
    LinkTarget[DataSize]=0;
    if (Create)
    {
      CreatePath(LinkName,NULL,true);
      if (symlink(LinkTarget,LinkName)==-1) // Error.
        if (errno==EEXIST)
          Log(Arc.FileName,St(MSymLinkExists),LinkName);
        else
        {
          Log(Arc.FileName,St(MErrCreateLnk),LinkName);
          ErrHandler.SetErrorCode(RARX_WARNING);
        }
      // We do not set time of created symlink, because utime changes
      // time of link target and lutimes is not available on all Linux
      // systems at the moment of writing this code.
    }
    int NameSize=Min(DataSize,strlen(LinkTarget));
    LinkCRC=CRC(0xffffffff,LinkTarget,NameSize);
    return(true);
  }
#endif
  return(false);
}
예제 #5
0
파일: ulinks.cpp 프로젝트: BITINT/DEFCON2
int ExtractLink(ComprDataIO &DataIO,Archive &Arc,char *DestName,unsigned int &LinkCRC,bool Create)
{
#if defined(SAVE_LINKS) && defined(_UNIX)
  char FileName[NM];
  if (IsLink(Arc.NewLhd.FileAttr))
  {
    int DataSize=Min(Arc.NewLhd.PackSize,sizeof(FileName)-1);
    DataIO.UnpRead((unsigned char *)FileName,DataSize);
    FileName[DataSize]=0;
    if (Create)
    {
      CreatePath(DestName,NULL,true);
      if (symlink(FileName,DestName)==-1)
        if (errno==EEXIST)
          Log(Arc.FileName,St(MSymLinkExists),DestName);
        else
        {
          Log(Arc.FileName,St(MErrCreateLnk),DestName);
          ErrHandler.SetErrorCode(WARNING);
        }
    }
    LinkCRC=CRC(0xffffffff,FileName,DataSize);
    return(1);
  }
#endif
  return(0);
}
예제 #6
0
파일: ulinks.cpp 프로젝트: 070499/xbmc
int ExtractLink(ComprDataIO &DataIO,Archive &Arc,char *DestName,uint &LinkCRC,bool Create)
{
#if defined(SAVE_LINKS) && defined(_UNIX)
  char FileName[NM];
  if (IsLink(Arc.NewLhd.FileAttr))
  {
    uint DataSize=Min(Arc.NewLhd.PackSize,sizeof(FileName)-1);
    DataIO.UnpRead((byte *)FileName,DataSize);
    FileName[DataSize]=0;
    if (Create)
    {
      CStdString strPath = URIUtils::GetDirectory(DestName);
      CUtil::CreateDirectoryEx(strPath);
      if (symlink(FileName,DestName)==-1)
      {
        if (errno==EEXIST)
          Log(Arc.FileName,St(MSymLinkExists),DestName);
        else
        {
          Log(Arc.FileName,St(MErrCreateLnk),DestName);
          ErrHandler.SetErrorCode(WARNING);
        }
      }
    }
    int NameSize=Min(DataSize,strlen(FileName));
    LinkCRC=CRC(0xffffffff,FileName,NameSize);    return(1);
  }
#endif
  return(0);
}
예제 #7
0
파일: extract.cpp 프로젝트: KastB/OpenCPN
void CmdExtract::UnstoreFile(ComprDataIO &DataIO,int64 DestUnpSize)
{
  // 512 KB and larger buffer reported to reduce performance on old XP
  // computers with WDC WD2000JD HDD. According to test made by user
  // 256 KB buffer is optimal.
  Array<byte> Buffer(0x40000);
  while (1)
  {
    uint Code=DataIO.UnpRead(&Buffer[0],Buffer.Size());
    if (Code==0 || (int)Code==-1)
      break;
    Code=Code<DestUnpSize ? Code:(uint)DestUnpSize;
    DataIO.UnpWrite(&Buffer[0],Code);
    if (DestUnpSize>=0)
      DestUnpSize-=Code;
  }
}
예제 #8
0
bool ExtractUnixLink30(ComprDataIO &DataIO,Archive &Arc,const wchar *LinkName)
{
  char Target[NM];
  if (IsLink(Arc.FileHead.FileAttr))
  {
    size_t DataSize=Min(Arc.FileHead.PackSize,ASIZE(Target)-1);
    DataIO.UnpRead((byte *)Target,DataSize);
    Target[DataSize]=0;

    DataIO.UnpHash.Init(Arc.FileHead.FileHash.Type,1);
    DataIO.UnpHash.Update(Target,strlen(Target));
    DataIO.UnpHash.Result(&Arc.FileHead.FileHash);

    // Return true in case of bad checksum, so link will be processed further
    // and extraction routine will report the checksum error.
    if (!DataIO.UnpHash.Cmp(&Arc.FileHead.FileHash,Arc.FileHead.UseHashKey ? Arc.FileHead.HashKey:NULL))
      return true;

    return UnixSymlink(Target,LinkName);
  }
  return false;
}
예제 #9
0
void CPsfRarArchive::ReadFileContents(const char* fileName, void* buffer, unsigned int bufferLength)
{
	Archive* arc(ConvertArchive(m_archive));
	if(!arc->IsOpened())
	{
		throw std::runtime_error("Archive isn't opened.");
	}

	std::string fixedFileName(fileName);
	boost::replace_all(fixedFileName, "/", "\\");

	arc->Seek(0, SEEK_SET);

	ComprDataIO dataIo;
	dataIo.Init();

	Unpack unpack(&dataIo);

	while(arc->ReadHeader() > 0)
	{
		if(arc->ShortBlock.HeaderType == HEAD_FILE)
		{
			if(!arc->IsArcDir())
			{
				bool isGoodFile = !stricmp(fixedFileName.c_str(), string_cast<std::string>(arc->FileHead.FileName).c_str());

				dataIo.SetFiles(arc, NULL);
				dataIo.SetPackedSizeToRead(arc->FileHead.PackSize);

				dataIo.CurUnpRead = 0;
				dataIo.CurUnpWrite = 0;
				dataIo.UnpHash.Init(arc->FileHead.FileHash.Type, 1);
				dataIo.PackedDataHash.Init(arc->FileHead.FileHash.Type, 1);
				dataIo.SetTestMode(!isGoodFile);

				if(isGoodFile)
				{
					dataIo.SetUnpackToMemory(reinterpret_cast<byte*>(buffer), bufferLength);
				}

				unpack.Init(arc->FileHead.WinSize, arc->FileHead.Solid);
				unpack.SetDestSize(arc->FileHead.UnpSize);

				if(arc->FileHead.Method == 0x30)
				{
					std::vector<byte> unstoreBuffer;
					unstoreBuffer.resize(0x10000);
					uint toReadSize = arc->FileHead.UnpSize;
					while(1)
					{
						uint code = dataIo.UnpRead(&unstoreBuffer[0], unstoreBuffer.size());
						if(code == 0 || code == -1) break;
						code = code < toReadSize ? code : toReadSize;
						dataIo.UnpWrite(&unstoreBuffer[0], code);
						if(toReadSize >= 0)
						{
							toReadSize -= code;
						}
					}
				}
				else
				{
					unpack.DoUnpack(arc->FileHead.UnpVer, arc->FileHead.Solid);
				}

				if(!dataIo.UnpHash.Cmp(&arc->FileHead.FileHash, arc->FileHead.UseHashKey ? arc->FileHead.HashKey : nullptr))
				{
					throw std::runtime_error("CRC check error.");
				}

				if(isGoodFile)
				{
					return;
				}
			}
		}
		arc->SeekToNext();
	}

	throw std::runtime_error("Couldn't read file from archive.");
}
예제 #10
0
bool Archive::GetComment(Array<byte> *CmtData,Array<wchar> *CmtDataW)
{
  if (!MainComment)
    return(false);
  SaveFilePos SavePos(*this);

#ifndef SFX_MODULE
  ushort CmtLength;
  if (OldFormat)
  {
    Seek(SFXSize+SIZEOF_OLDMHD,SEEK_SET);
    CmtLength=GetByte();
    CmtLength+=(GetByte()<<8);
  }
  else
#endif
  {
    if (NewMhd.Flags & MHD_COMMENT)
    {
      // Old style (RAR 2.9) archive comment embedded into the main 
      // archive header.
      Seek(SFXSize+SIZEOF_MARKHEAD+SIZEOF_NEWMHD,SEEK_SET);
      ReadHeader();
    }
    else
    {
      // Current (RAR 3.0+) version of archive comment.
      Seek(SFXSize+SIZEOF_MARKHEAD+NewMhd.HeadSize,SEEK_SET);
      return(SearchSubBlock(SUBHEAD_TYPE_CMT)!=0 && ReadCommentData(CmtData,CmtDataW)!=0);
    }
#ifndef SFX_MODULE
    // Old style (RAR 2.9) comment header embedded into the main 
    // archive header.
    if (CommHead.HeadCRC!=HeaderCRC)
    {
      Log(FileName,St(MLogCommHead));
      Alarm();
      return(false);
    }
    CmtLength=CommHead.HeadSize-SIZEOF_COMMHEAD;
#endif
  }
#ifndef SFX_MODULE
  if (OldFormat && (OldMhd.Flags & MHD_PACK_COMMENT) || !OldFormat && CommHead.Method!=0x30)
  {
    if (!OldFormat && (CommHead.UnpVer < 15 || CommHead.UnpVer > UNP_VER || CommHead.Method > 0x35))
      return(false);
    ComprDataIO DataIO;
    Unpack Unpack(&DataIO);
    Unpack.Init();
    DataIO.SetTestMode(true);
    uint UnpCmtLength;
    if (OldFormat)
    {
#ifdef RAR_NOCRYPT
      return(false);
#else
      UnpCmtLength=GetByte();
      UnpCmtLength+=(GetByte()<<8);
      CmtLength-=2;
      DataIO.SetCmt13Encryption();
#endif
    }
    else
      UnpCmtLength=CommHead.UnpSize;
    DataIO.SetFiles(this,NULL);
    DataIO.EnableShowProgress(false);
    DataIO.SetPackedSizeToRead(CmtLength);
    Unpack.SetDestSize(UnpCmtLength);
    Unpack.DoUnpack(CommHead.UnpVer,false);

    if (!OldFormat && ((~DataIO.UnpFileCRC)&0xffff)!=CommHead.CommCRC)
    {
      Log(FileName,St(MLogCommBrk));
      Alarm();
      return(false);
    }
    else
    {
      byte *UnpData;
      size_t UnpDataSize;
      DataIO.GetUnpackedData(&UnpData,&UnpDataSize);
      CmtData->Alloc(UnpDataSize);
      memcpy(&((*CmtData)[0]),UnpData,UnpDataSize);
    }
  }
  else
  {
    CmtData->Alloc(CmtLength);
    
    Read(&((*CmtData)[0]),CmtLength);
    if (!OldFormat && CommHead.CommCRC!=(~CRC(0xffffffff,&((*CmtData)[0]),CmtLength)&0xffff))
    {
      Log(FileName,St(MLogCommBrk));
      Alarm();
      CmtData->Reset();
      return(false);
    }
  }
#endif
#if defined(_WIN_ALL) && !defined(_WIN_CE)
  if (CmtData->Size()>0)
  {
    size_t CmtSize=CmtData->Size();
    char *DataA=(char *)CmtData->Addr();
    OemToCharBuffA(DataA,DataA,(DWORD)CmtSize);

    if (CmtDataW!=NULL)
    {
      CmtDataW->Alloc(CmtSize+1);
      CmtData->Push(0);
      CharToWide(DataA,CmtDataW->Addr(),CmtSize+1);
      CmtData->Alloc(CmtSize);
      CmtDataW->Alloc(wcslen(CmtDataW->Addr()));
    }
  }
#endif
  return(CmtData->Size()>0);
}
예제 #11
0
void ExtractStreams(Archive &Arc,char *FileName,wchar *FileNameW)
{
  if (!WinNT())
    return;

  if (Arc.HeaderCRC!=Arc.StreamHead.HeadCRC)
  {
#ifndef SILENT
    Log(Arc.FileName,St(MStreamBroken),FileName);
#endif
    ErrHandler.SetErrorCode(CRC_ERROR);
    return;
  }

  if (Arc.StreamHead.Method<0x31 || Arc.StreamHead.Method>0x35 || Arc.StreamHead.UnpVer>PACK_VER)
  {
#ifndef SILENT
    Log(Arc.FileName,St(MStreamUnknown),FileName);
#endif
    ErrHandler.SetErrorCode(WARNING);
    return;
  }

  char StreamName[NM+2];
  if (FileName[0]!=0 && FileName[1]==0)
  {
    strcpy(StreamName,".\\");
    strcpy(StreamName+2,FileName);
  }
  else
    strcpy(StreamName,FileName);
  if (strlen(StreamName)+strlen((char *)Arc.StreamHead.StreamName)>=sizeof(StreamName))
  {
#ifndef SILENT
    Log(Arc.FileName,St(MStreamBroken),FileName);
#endif
    ErrHandler.SetErrorCode(CRC_ERROR);
    return;
  }

  strcat(StreamName,(char *)Arc.StreamHead.StreamName);

  FindData fd;
  bool Found=FindFile::FastFind(FileName,FileNameW,&fd);

  if (fd.FileAttr & FILE_ATTRIBUTE_READONLY)
    SetFileAttr(FileName,FileNameW,fd.FileAttr & ~FILE_ATTRIBUTE_READONLY);

  File CurFile;
  if (CurFile.WCreate(StreamName))
  {
    ComprDataIO DataIO;
    Unpack Unpack(&DataIO);
    Unpack.Init();

    Array<unsigned char> UnpData(Arc.StreamHead.UnpSize);
    DataIO.SetPackedSizeToRead(Arc.StreamHead.DataSize);
    DataIO.EnableShowProgress(false);
    DataIO.SetFiles(&Arc,&CurFile);
    Unpack.SetDestSize(Arc.StreamHead.UnpSize);
    Unpack.DoUnpack(Arc.StreamHead.UnpVer,false);

    if (Arc.StreamHead.StreamCRC!=~DataIO.UnpFileCRC)
    {
#ifndef SILENT
      Log(Arc.FileName,St(MStreamBroken),StreamName);
#endif
      ErrHandler.SetErrorCode(CRC_ERROR);
    }
    else
      CurFile.Close();
  }
  File HostFile;
  if (Found && HostFile.Open(FileName,FileNameW,true,true))
    SetFileTime(HostFile.GetHandle(),&fd.ftCreationTime,&fd.ftLastAccessTime,
                &fd.ftLastWriteTime);
  if (fd.FileAttr & FILE_ATTRIBUTE_READONLY)
    SetFileAttr(FileName,FileNameW,fd.FileAttr);
}
예제 #12
0
파일: arccmt.cpp 프로젝트: Elzevir/xbmc
bool Archive::GetComment(Array<byte> &CmtData)
{
  if (!MainComment)
    return(false);
  SaveFilePos SavePos(*this);

  ushort CmtLength;
#ifndef SFX_MODULE
  if (OldFormat)
  {
    Seek(SFXSize+SIZEOF_OLDMHD,SEEK_SET);
    CmtLength=GetByte()+(GetByte()<<8);
  }
  else
#endif
  {
    if (NewMhd.Flags & MHD_COMMENT)
    {
      Seek(SFXSize+SIZEOF_MARKHEAD+SIZEOF_NEWMHD,SEEK_SET);
      ReadHeader();
    }
    else
    {
      Seek(SFXSize+SIZEOF_MARKHEAD+NewMhd.HeadSize,SEEK_SET);
      return(SearchSubBlock(SUBHEAD_TYPE_CMT)!=0 && ReadCommentData(CmtData)!=0);
    }
#ifndef SFX_MODULE
    if (CommHead.HeadCRC!=HeaderCRC)
    {
      Log(FileName,St(MLogCommHead));
      Alarm();
      return(false);
    }
    CmtLength=CommHead.HeadSize-SIZEOF_COMMHEAD;
#endif
  }
#ifndef SFX_MODULE
  if ((OldFormat && (OldMhd.Flags & MHD_PACK_COMMENT)) || (!OldFormat && CommHead.Method!=0x30))
  {
    if (!OldFormat && (CommHead.UnpVer < 15 || CommHead.UnpVer > UNP_VER || CommHead.Method > 0x35))
      return(false);
    ComprDataIO DataIO;
    Unpack Unpack(&DataIO);
    Unpack.Init();
    DataIO.SetTestMode(true);
    uint UnpCmtLength;
    if (OldFormat)
    {
      UnpCmtLength=GetByte()+(GetByte()<<8);
      CmtLength-=2;
      DataIO.SetCmt13Encryption();
    }
    else
      UnpCmtLength=CommHead.UnpSize;
    DataIO.SetFiles(this,NULL);
    DataIO.EnableShowProgress(false);
    DataIO.SetPackedSizeToRead(CmtLength);
    Unpack.SetDestSize(UnpCmtLength);
    Unpack.DoUnpack(CommHead.UnpVer,false);

    if (!OldFormat && ((~DataIO.UnpFileCRC)&0xffff)!=CommHead.CommCRC)
    {
      Log(FileName,St(MLogCommBrk));
      Alarm();
      return(false);
    }
    else
    {
      unsigned char *UnpData;
      uint UnpDataSize;
      DataIO.GetUnpackedData(&UnpData,&UnpDataSize);
      CmtData.Alloc(UnpDataSize);
      memcpy(&CmtData[0],UnpData,UnpDataSize);
    }
  }
  else
  {
    CmtData.Alloc(CmtLength);
    
    Read(&CmtData[0],CmtLength);
    if (!OldFormat && CommHead.CommCRC!=(~CRC(0xffffffff,&CmtData[0],CmtLength)&0xffff))
    {
      Log(FileName,St(MLogCommBrk));
      Alarm();
      CmtData.Reset();
      return(false);
    }
  }
#endif
#if defined(_WIN_32) && !defined(_WIN_CE) && !defined(_XBOX) && !defined(_LINUX)
  //if (CmtData.Size()>0)
  //  OemToCharBuff((char*)&CmtData[0],(char*)&CmtData[0],CmtData.Size());
#endif
  return(CmtData.Size()>0);
}
예제 #13
0
파일: win32stm.cpp 프로젝트: Cpasjuste/nzbm
void ExtractStreams20(Archive &Arc,const wchar *FileName)
{
  if (Arc.BrokenHeader)
  {
    uiMsg(UIERROR_STREAMBROKEN,Arc.FileName,FileName);
    ErrHandler.SetErrorCode(RARX_CRC);
    return;
  }

  if (Arc.StreamHead.Method<0x31 || Arc.StreamHead.Method>0x35 || Arc.StreamHead.UnpVer>VER_PACK)
  {
    uiMsg(UIERROR_STREAMUNKNOWN,Arc.FileName,FileName);
    ErrHandler.SetErrorCode(RARX_WARNING);
    return;
  }

  wchar StreamName[NM+2];
  if (FileName[0]!=0 && FileName[1]==0)
  {
    wcscpy(StreamName,L".\\");
    wcscpy(StreamName+2,FileName);
  }
  else
    wcscpy(StreamName,FileName);
  if (wcslen(StreamName)+strlen(Arc.StreamHead.StreamName)>=ASIZE(StreamName) ||
      Arc.StreamHead.StreamName[0]!=':')
  {
    uiMsg(UIERROR_STREAMBROKEN,Arc.FileName,FileName);
    ErrHandler.SetErrorCode(RARX_CRC);
    return;
  }

  wchar StoredName[NM];
  CharToWide(Arc.StreamHead.StreamName,StoredName,ASIZE(StoredName));
  ConvertPath(StoredName+1,StoredName+1);

  wcsncatz(StreamName,StoredName,ASIZE(StreamName));

  FindData fd;
  bool Found=FindFile::FastFind(FileName,&fd);

  if ((fd.FileAttr & FILE_ATTRIBUTE_READONLY)!=0)
    SetFileAttr(FileName,fd.FileAttr & ~FILE_ATTRIBUTE_READONLY);

  File CurFile;
  if (CurFile.WCreate(StreamName))
  {
    ComprDataIO DataIO;
    Unpack Unpack(&DataIO);
    Unpack.Init(0x10000,false);

    DataIO.SetPackedSizeToRead(Arc.StreamHead.DataSize);
    DataIO.EnableShowProgress(false);
    DataIO.SetFiles(&Arc,&CurFile);
    DataIO.UnpHash.Init(HASH_CRC32,1);
    Unpack.SetDestSize(Arc.StreamHead.UnpSize);
    Unpack.DoUnpack(Arc.StreamHead.UnpVer,false);

    if (Arc.StreamHead.StreamCRC!=DataIO.UnpHash.GetCRC32())
    {
      uiMsg(UIERROR_STREAMBROKEN,Arc.FileName,StreamName);
      ErrHandler.SetErrorCode(RARX_CRC);
    }
    else
      CurFile.Close();
  }
  File HostFile;
  if (Found && HostFile.Open(FileName,FMF_OPENSHARED|FMF_UPDATE))
    SetFileTime(HostFile.GetHandle(),&fd.ftCreationTime,&fd.ftLastAccessTime,
                &fd.ftLastWriteTime);
  if ((fd.FileAttr & FILE_ATTRIBUTE_READONLY)!=0)
    SetFileAttr(FileName,fd.FileAttr);
}
예제 #14
0
파일: beosea.cpp 프로젝트: 089git/calibre
void ExtractBeEA(Archive &Arc,char *FileName)
{
  if (Arc.HeaderCRC!=Arc.EAHead.HeadCRC)
  {
    Log(Arc.FileName,St(MEABroken),FileName);
    ErrHandler.SetErrorCode(RARX_CRC);
    return;
  }
  if (Arc.EAHead.Method<0x31 || Arc.EAHead.Method>0x35 || Arc.EAHead.UnpVer>PACK_VER)
  {
    Log(Arc.FileName,St(MEAUnknHeader),FileName);
    return;
  }

  ComprDataIO DataIO;
  Unpack Unpack(&DataIO);
  Unpack.Init();

  Array<byte> UnpData(Arc.EAHead.UnpSize);
  DataIO.SetUnpackToMemory(&UnpData[0],Arc.EAHead.UnpSize);
  DataIO.SetPackedSizeToRead(Arc.EAHead.DataSize);
  DataIO.EnableShowProgress(false);
  DataIO.SetFiles(&Arc,NULL);
  Unpack.SetDestSize(Arc.EAHead.UnpSize);
  Unpack.DoUnpack(Arc.EAHead.UnpVer,false);

  if (Arc.EAHead.EACRC!=~DataIO.UnpFileCRC)
  {
    Log(Arc.FileName,St(MEABroken),FileName);
    ErrHandler.SetErrorCode(RARX_CRC);
    return;
  }
  int fd = open(FileName,O_WRONLY);
  if (fd==-1)
  {
    Log(Arc.FileName,St(MCannotSetEA),FileName);
    ErrHandler.SetErrorCode(RARX_WARNING);
    return;
  }

  int AttrPos=0;
  while (AttrPos<Arc.EAHead.UnpSize)
  {
    unsigned char *CurItem=&UnpData[AttrPos];
    int NameSize=CurItem[0]+((int)CurItem[1]<<8);
    int Type=CurItem[2]+((int)CurItem[3]<<8)+((int)CurItem[4]<<16)+((int)CurItem[5]<<24);
    int Size=CurItem[6]+((int)CurItem[7]<<8)+((int)CurItem[8]<<16)+((int)CurItem[9]<<24);
    char Name[1024];
    if (NameSize>=sizeof(Name))
    {
      Log(Arc.FileName,St(MCannotSetEA),FileName);
      ErrHandler.SetErrorCode(RARX_WARNING);
      break;
    }
    memcpy(Name,CurItem+10,NameSize);
    Name[NameSize]=0;
    if (fs_write_attr(fd,Name,Type,0,CurItem+10+NameSize,Size)==-1)
    {
      Log(Arc.FileName,St(MCannotSetEA),FileName);
      ErrHandler.SetErrorCode(RARX_WARNING);
      break;
    }
    AttrPos+=10+NameSize+Size;
  }
  close(fd);
  mprintf(St(MShowEA));
}
예제 #15
0
파일: arccmt.cpp 프로젝트: 1ldk/mpc-hc
bool Archive::GetComment(Array<wchar> *CmtData)
{
  if (!MainComment)
    return false;
  SaveFilePos SavePos(*this);

#ifndef SFX_MODULE
  ushort CmtLength;
  if (Format==RARFMT14)
  {
    Seek(SFXSize+SIZEOF_MAINHEAD14,SEEK_SET);
    CmtLength=GetByte();
    CmtLength+=(GetByte()<<8);
  }
  else
#endif
  {
    if (MainHead.CommentInHeader)
    {
      // Old style (RAR 2.9) archive comment embedded into the main 
      // archive header.
      Seek(SFXSize+SIZEOF_MARKHEAD3+SIZEOF_MAINHEAD3,SEEK_SET);
      ReadHeader();
    }
    else
    {
      // Current (RAR 3.0+) version of archive comment.
      Seek(GetStartPos(),SEEK_SET);
      return SearchSubBlock(SUBHEAD_TYPE_CMT)!=0 && ReadCommentData(CmtData);
    }
#ifndef SFX_MODULE
    // Old style (RAR 2.9) comment header embedded into the main 
    // archive header.
    if (BrokenHeader)
    {
      uiMsg(UIERROR_CMTBROKEN,FileName);
      return false;
    }
    CmtLength=CommHead.HeadSize-SIZEOF_COMMHEAD;
#endif
  }
#ifndef SFX_MODULE
  if (Format==RARFMT14 && MainHead.PackComment || Format!=RARFMT14 && CommHead.Method!=0x30)
  {
    if (Format!=RARFMT14 && (CommHead.UnpVer < 15 || CommHead.UnpVer > VER_UNPACK || CommHead.Method > 0x35))
      return(false);
    ComprDataIO DataIO;
    DataIO.SetTestMode(true);
    uint UnpCmtLength;
    if (Format==RARFMT14)
    {
#ifdef RAR_NOCRYPT
      return(false);
#else
      UnpCmtLength=GetByte();
      UnpCmtLength+=(GetByte()<<8);
      CmtLength-=2;
      DataIO.SetCmt13Encryption();
      CommHead.UnpVer=15;
#endif
    }
    else
      UnpCmtLength=CommHead.UnpSize;
    DataIO.SetFiles(this,NULL);
    DataIO.EnableShowProgress(false);
    DataIO.SetPackedSizeToRead(CmtLength);
    DataIO.UnpHash.Init(HASH_CRC32,1);

    Unpack CmtUnpack(&DataIO);
    CmtUnpack.Init(0x10000,false);
    CmtUnpack.SetDestSize(UnpCmtLength);
    CmtUnpack.DoUnpack(CommHead.UnpVer,false);

    if (Format!=RARFMT14 && (DataIO.UnpHash.GetCRC32()&0xffff)!=CommHead.CommCRC)
    {
      uiMsg(UIERROR_CMTBROKEN,FileName);
      return false;
    }
    else
    {
      byte *UnpData;
      size_t UnpDataSize;
      DataIO.GetUnpackedData(&UnpData,&UnpDataSize);
#ifdef _WIN_ALL
      OemToCharBuffA((char *)UnpData,(char *)UnpData,(DWORD)UnpDataSize);
#endif
      CmtData->Alloc(UnpDataSize+1);
      memset(CmtData->Addr(0),0,CmtData->Size()*sizeof(wchar));
      CharToWide((char *)UnpData,CmtData->Addr(0),UnpDataSize);
      CmtData->Alloc(wcslen(CmtData->Addr(0)));
    }
  }
  else
  {
    Array<byte> CmtRaw(CmtLength);
    Read(&CmtRaw[0],CmtLength);

    if (Format!=RARFMT14 && CommHead.CommCRC!=(~CRC32(0xffffffff,&CmtRaw[0],CmtLength)&0xffff))
    {
      uiMsg(UIERROR_CMTBROKEN,FileName);
      return false;
    }
    CmtData->Alloc(CmtLength+1);
    CmtRaw.Push(0);
#ifdef _WIN_ALL
    OemToCharA((char *)&CmtRaw[0],(char *)&CmtRaw[0]);
#endif
    CharToWide((char *)&CmtRaw[0],CmtData->Addr(0),CmtLength);
    CmtData->Alloc(wcslen(CmtData->Addr(0)));
  }
#endif
  return CmtData->Size() > 0;
}