void ExtractStreams(Archive &Arc,const wchar *FileName,bool TestMode) { wchar FullName[NM+2]; if (FileName[0]!=0 && FileName[1]==0) { wcscpy(FullName,L".\\"); wcsncpyz(FullName+2,FileName,ASIZE(FullName)-2); } else wcsncpyz(FullName,FileName,ASIZE(FullName)); byte *Data=&Arc.SubHead.SubData[0]; size_t DataSize=Arc.SubHead.SubData.Size(); wchar StreamName[NM]; GetStreamNameNTFS(Arc,StreamName,ASIZE(StreamName)); if (*StreamName!=':') { uiMsg(UIERROR_STREAMBROKEN,Arc.FileName,FileName); ErrHandler.SetErrorCode(RARX_CRC); return; } if (TestMode) { Arc.ReadSubData(NULL,NULL); return; } wcsncatz(FullName,StreamName,ASIZE(FullName)); 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(FullName) && Arc.ReadSubData(NULL,&CurFile)) CurFile.Close(); File HostFile; if (Found && HostFile.Open(FileName,FMF_OPENSHARED|FMF_UPDATE)) SetFileTime(HostFile.GetHandle(),&fd.ftCreationTime,&fd.ftLastAccessTime, &fd.ftLastWriteTime); // Restoring original file attributes. Important if file was read only // or did not have "Archive" attribute SetFileAttr(FileName,fd.FileAttr); }
void ExtractACLNew(Archive &Arc,char *FileName,wchar *FileNameW) { #if defined(_XBOX) || defined(_LINUX) || (defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)) return; #else if (!WinNT()) return; Array<byte> SubData; if (!Arc.ReadSubData(&SubData,NULL)) return; SetPrivileges(); SECURITY_INFORMATION si=OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION| DACL_SECURITY_INFORMATION; if (ReadSacl) si|=SACL_SECURITY_INFORMATION; SECURITY_DESCRIPTOR *sd=(SECURITY_DESCRIPTOR *)&SubData[0]; int SetCode; if (FileNameW!=NULL) SetCode=SetFileSecurityW(FileNameW,si,sd); else SetCode=SetFileSecurity(FileName,si,sd); if (!SetCode) { RarLog(Arc.FileName,St(MACLSetError),FileName); ErrHandler.SysErrMsg(); ErrHandler.SetErrorCode(WARNING); } #endif }
void ExtractACLNew(Archive &Arc,char *FileName,wchar *FileNameW) { if (!WinNT()) return; Array<byte> SubData; if (!Arc.ReadSubData(&SubData,(File *) NULL)) return; SetPrivileges(); SECURITY_INFORMATION si=OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION| DACL_SECURITY_INFORMATION; if (ReadSacl) si|=SACL_SECURITY_INFORMATION; SECURITY_DESCRIPTOR *sd=(SECURITY_DESCRIPTOR *)&SubData[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 ExtractACL(Archive &Arc,const wchar *FileName) { Array<byte> SubData; if (!Arc.ReadSubData(&SubData,NULL)) return; SetACLPrivileges(); SECURITY_INFORMATION si=OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION| DACL_SECURITY_INFORMATION; if (ReadSacl) si|=SACL_SECURITY_INFORMATION; SECURITY_DESCRIPTOR *sd=(SECURITY_DESCRIPTOR *)&SubData[0]; int SetCode=SetFileSecurity(FileName,si,sd); if (!SetCode) { wchar LongName[NM]; if (GetWinLongPath(FileName,LongName,ASIZE(LongName))) SetCode=SetFileSecurity(LongName,si,sd); } if (!SetCode) { Log(Arc.FileName,St(MACLSetError),FileName); ErrHandler.SysErrMsg(); ErrHandler.SetErrorCode(RARX_WARNING); } }
void ExtractStreamsNew(Archive &Arc,char *FileName,wchar *FileNameW) { if (!WinNT()) return; wchar NameW[NM]; if (FileNameW!=NULL && *FileNameW!=0) strcpyw(NameW,FileNameW); else CharToWide(FileName,NameW); wchar StreamNameW[NM+2]; if (NameW[0]!=0 && NameW[1]==0) { strcpyw(StreamNameW,L".\\"); strcpyw(StreamNameW+2,NameW); } else strcpyw(StreamNameW,NameW); wchar *DestName=StreamNameW+strlenw(StreamNameW); byte *SrcName=&Arc.SubHead.SubData[0]; int DestSize=Arc.SubHead.SubData.Size()/2; if (strlenw(StreamNameW)+DestSize>=sizeof(StreamNameW)/sizeof(StreamNameW[0])) { #if !defined(SILENT) && !defined(SFX_MODULE) Log(Arc.FileName,St(MStreamBroken),FileName); #endif ErrHandler.SetErrorCode(CRC_ERROR); return; } RawToWide(SrcName,DestName,DestSize); DestName[DestSize]=0; FindData fd; bool Found=FindFile::FastFind(FileName,FileNameW,&fd); if (fd.FileAttr & FILE_ATTRIBUTE_READONLY) SetFileAttr(FileName,FileNameW,fd.FileAttr & ~FILE_ATTRIBUTE_READONLY); char StreamName[NM]; WideToChar(StreamNameW,StreamName); File CurFile; if (CurFile.WCreate(StreamName,StreamNameW) && Arc.ReadSubData(NULL,&CurFile)) 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); }
void ExtractBeEANew(Archive &Arc,char *FileName) { Array<byte> SubData; if (!Arc.ReadSubData(&SubData,NULL)) 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=&SubData[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)); }
void ExtractStreamsNew(Archive& Arc, char* FileName, wchar* FileNameW) { if (!WinNT()) return; wchar NameW[NM]; if (FileNameW != NULL && *FileNameW != 0) wcscpy(NameW, FileNameW); else CharToWide(FileName, NameW); wchar StreamNameW[NM + 2]; if (NameW[0] != 0 && NameW[1] == 0) { wcscpy(StreamNameW, L".\\"); wcscpy(StreamNameW + 2, NameW); } else wcscpy(StreamNameW, NameW); wchar* DestName = StreamNameW + wcslen(StreamNameW); byte* SrcName = &Arc.SubHead.SubData[0]; size_t DestSize = Arc.SubHead.SubData.Size() / 2; if (wcslen(StreamNameW) + DestSize >= ASIZE(StreamNameW)) { #if !defined(SILENT) && !defined(SFX_MODULE) Log(Arc.FileName, St(MStreamBroken), FileName); #endif ErrHandler.SetErrorCode(CRC_ERROR); return; } RawToWide(SrcName, DestName, DestSize); DestName[DestSize] = 0; if (*DestName != ':') { #if !defined(SILENT) && !defined(SFX_MODULE) Log(Arc.FileName, St(MStreamBroken), FileName); #endif ErrHandler.SetErrorCode(CRC_ERROR); return; } ConvertPath(DestName + 1, DestName + 1); FindData fd; bool Found = FindFile::FastFind(FileName, FileNameW, &fd); if (fd.FileAttr & FILE_ATTRIBUTE_READONLY) SetFileAttr(FileName, FileNameW, fd.FileAttr & ~FILE_ATTRIBUTE_READONLY); char StreamName[NM]; WideToChar(StreamNameW, StreamName); File CurFile; if (CurFile.WCreate(StreamName, StreamNameW) && Arc.ReadSubData(NULL, &CurFile)) CurFile.Close(); File HostFile; if (Found && HostFile.Open(FileName, FileNameW, true, true)) SetFileTime(HostFile.GetHandle(), &fd.ftCreationTime, &fd.ftLastAccessTime, &fd.ftLastWriteTime); // Restoring original file attributes. Important if file was read only // or did not have "Archive" attribute SetFileAttr(FileName, FileNameW, fd.FileAttr); }