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); } }
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); } }
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; } }
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); }
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); }
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); }
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; } }
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; }
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."); }
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); }
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); }
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); }
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); }
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)); }
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; }