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 ListFileHeader(Archive &Arc,FileHeader &hd,bool &TitleShown,bool Verbose,bool Technical,bool Bare) { wchar *Name=hd.FileName; RARFORMAT Format=Arc.Format; if (Bare) { mprintf(L"%s\n",Name); return; } if (!TitleShown && !Technical) { if (Verbose) { mprintf(L"\n%ls",St(MListTitleV)); mprintf(L"\n----------- --------- -------- ----- -------- ----- -------- ----"); } else { mprintf(L"\n%ls",St(MListTitleL)); mprintf(L"\n----------- --------- -------- ----- ----"); } TitleShown=true; } wchar UnpSizeText[20],PackSizeText[20]; if (hd.UnpSize==INT64NDF) wcscpy(UnpSizeText,L"?"); else itoa(hd.UnpSize,UnpSizeText); itoa(hd.PackSize,PackSizeText); wchar AttrStr[30]; if (hd.HeaderType==HEAD_SERVICE) swprintf(AttrStr,ASIZE(AttrStr),L"%cB",hd.Inherited ? 'I' : '.'); else ListFileAttr(hd.FileAttr,hd.HSType,AttrStr,ASIZE(AttrStr)); wchar RatioStr[10]; if (hd.SplitBefore && hd.SplitAfter) wcscpy(RatioStr,L"<->"); else if (hd.SplitBefore) wcscpy(RatioStr,L"<--"); else if (hd.SplitAfter) wcscpy(RatioStr,L"-->"); else swprintf(RatioStr,ASIZE(RatioStr),L"%d%%",ToPercentUnlim(hd.PackSize,hd.UnpSize)); wchar DateStr[50]; hd.mtime.GetText(DateStr,ASIZE(DateStr),Technical,Technical); if (Technical) { mprintf(L"\n%12s: %s",St(MListName),Name); bool FileBlock=hd.HeaderType==HEAD_FILE; if (!FileBlock && Arc.SubHead.CmpName(SUBHEAD_TYPE_STREAM)) { mprintf(L"\n%12ls: %ls",St(MListType),St(MListStream)); wchar StreamName[NM]; GetStreamNameNTFS(Arc,StreamName,ASIZE(StreamName)); mprintf(L"\n%12ls: %ls",St(MListTarget),StreamName); } else { const wchar *Type=St(FileBlock ? (hd.Dir ? MListDir:MListFile):MListService); if (hd.RedirType!=FSREDIR_NONE) switch(hd.RedirType) { case FSREDIR_UNIXSYMLINK: Type=St(MListUSymlink); break; case FSREDIR_WINSYMLINK: Type=St(MListWSymlink); break; case FSREDIR_JUNCTION: Type=St(MListJunction); break; case FSREDIR_HARDLINK: Type=St(MListHardlink); break; case FSREDIR_FILECOPY: Type=St(MListCopy); break; } mprintf(L"\n%12ls: %ls",St(MListType),Type); if (hd.RedirType!=FSREDIR_NONE) if (Format==RARFMT15) { char LinkTargetA[NM]; if (Arc.FileHead.Encrypted) { // Link data are encrypted. We would need to ask for password // and initialize decryption routine to display the link target. strncpyz(LinkTargetA,"*<-?->",ASIZE(LinkTargetA)); } else { int DataSize=(int)Min(hd.PackSize,ASIZE(LinkTargetA)-1); Arc.Read(LinkTargetA,DataSize); LinkTargetA[DataSize > 0 ? DataSize : 0] = 0; } wchar LinkTarget[NM]; CharToWide(LinkTargetA,LinkTarget,ASIZE(LinkTarget)); mprintf(L"\n%12ls: %ls",St(MListTarget),LinkTarget); } else mprintf(L"\n%12ls: %ls",St(MListTarget),hd.RedirName); } if (!hd.Dir) { mprintf(L"\n%12ls: %ls",St(MListSize),UnpSizeText); mprintf(L"\n%12ls: %ls",St(MListPacked),PackSizeText); mprintf(L"\n%12ls: %ls",St(MListRatio),RatioStr); } if (hd.mtime.IsSet()) mprintf(L"\n%12ls: %ls",St(MListMtime),DateStr); if (hd.ctime.IsSet()) { hd.ctime.GetText(DateStr,ASIZE(DateStr),true,true); mprintf(L"\n%12ls: %ls",St(MListCtime),DateStr); } if (hd.atime.IsSet()) { hd.atime.GetText(DateStr,ASIZE(DateStr),true,true); mprintf(L"\n%12ls: %ls",St(MListAtime),DateStr); } mprintf(L"\n%12ls: %ls",St(MListAttr),AttrStr); if (hd.FileHash.Type==HASH_CRC32) mprintf(L"\n%12ls: %8.8X", hd.UseHashKey ? L"CRC32 MAC":hd.SplitAfter ? L"Pack-CRC32":L"CRC32", hd.FileHash.CRC32); if (hd.FileHash.Type==HASH_BLAKE2) { wchar BlakeStr[BLAKE2_DIGEST_SIZE*2+1]; BinToHex(hd.FileHash.Digest,BLAKE2_DIGEST_SIZE,NULL,BlakeStr,ASIZE(BlakeStr)); mprintf(L"\n%12ls: %ls", hd.UseHashKey ? L"BLAKE2 MAC":hd.SplitAfter ? L"Pack-BLAKE2":L"BLAKE2", BlakeStr); } const wchar *HostOS=L""; if (Format==RARFMT50 && hd.HSType!=HSYS_UNKNOWN) HostOS=hd.HSType==HSYS_WINDOWS ? L"Windows":L"Unix"; if (Format==RARFMT15) { static const wchar *RarOS[]={ L"DOS",L"OS/2",L"Windows",L"Unix",L"Mac OS",L"BeOS",L"WinCE",L"",L"",L"" }; if (hd.HostOS<ASIZE(RarOS)) HostOS=RarOS[hd.HostOS]; } if (*HostOS!=0) mprintf(L"\n%12ls: %ls",St(MListHostOS),HostOS); mprintf(L"\n%12ls: RAR %ls(v%d) -m%d -md=%d%s",St(MListCompInfo), Format==RARFMT15 ? L"3.0":L"5.0",hd.UnpVer,hd.Method, hd.WinSize>=0x100000 ? hd.WinSize/0x100000:hd.WinSize/0x400, hd.WinSize>=0x100000 ? L"M":L"K"); if (hd.Solid || hd.Encrypted) { mprintf(L"\n%12ls: ",St(MListFlags)); if (hd.Solid) mprintf(L"%ls ",St(MListSolid)); if (hd.Encrypted) mprintf(L"%ls ",St(MListEnc)); } if (hd.Version) { uint Version=ParseVersionFileName(Name,false); if (Version!=0) mprintf(L"\n%12ls: %u",St(MListFileVer),Version); } if (hd.UnixOwnerSet) { mprintf(L"\n%12ls: ",L"Unix owner"); if (*hd.UnixOwnerName!=0) mprintf(L"%ls:",GetWide(hd.UnixOwnerName)); if (*hd.UnixGroupName!=0) mprintf(L"%ls",GetWide(hd.UnixGroupName)); if ((*hd.UnixOwnerName!=0 || *hd.UnixGroupName!=0) && (hd.UnixOwnerNumeric || hd.UnixGroupNumeric)) mprintf(L" "); if (hd.UnixOwnerNumeric) mprintf(L"#%d:",hd.UnixOwnerID); if (hd.UnixGroupNumeric) mprintf(L"#%d:",hd.UnixGroupID); } mprintf(L"\n"); return; } mprintf(L"\n%c%10ls %9ls ",hd.Encrypted ? '*' : ' ',AttrStr,UnpSizeText); if (Verbose) mprintf(L"%9ls %4ls ",PackSizeText,RatioStr); mprintf(L" %ls ",DateStr); if (Verbose) { if (hd.FileHash.Type==HASH_CRC32) mprintf(L"%8.8X ",hd.FileHash.CRC32); else if (hd.FileHash.Type==HASH_BLAKE2) { byte *S=hd.FileHash.Digest; mprintf(L"%02x%02x..%02x ",S[0],S[1],S[31]); } else mprintf(L"???????? "); } mprintf(L"%-12ls",Name); }