예제 #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
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.");
}
예제 #4
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));
}