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