Update to 7-Zip Version 22.00

See: https://sourceforge.net/p/sevenzip/discussion/45797/thread/9c2d9061ce/
This commit is contained in:
Tino Reichardt
2022-08-07 09:59:33 +02:00
parent 6a4fe97fc3
commit 57558682a8
211 changed files with 15251 additions and 2482 deletions

View File

@@ -25,6 +25,10 @@ using namespace NWindows;
CCodecs *g_CodecsObj;
static const bool k_keepEmptyDirPrefixes =
false; // 22.00
// true; // 21.07
#ifdef EXTERNAL_CODECS
CExternalCodecs g_ExternalCodecs;
const CExternalCodecs *g_ExternalCodecs_Ptr;
@@ -114,9 +118,9 @@ void CAgentFolder::LoadFolder(unsigned proxyDirIndex)
item.Index = i;
_items.Add(item);
const CProxyFile2 &file = _proxy2->Files[dir.Items[i]];
if (file.DirIndex >= 0)
if (file.DirIndex != -1)
LoadFolder(file.DirIndex);
if (_loadAltStreams && file.AltDirIndex >= 0)
if (_loadAltStreams && file.AltDirIndex != -1)
LoadFolder(file.AltDirIndex);
}
return;
@@ -211,21 +215,21 @@ void CAgentFolder::GetPrefix(UInt32 index, UString &prefix) const
unsigned len = 0;
while (proxyIndex != _proxyDirIndex && proxyIndex >= k_Proxy2_NumRootDirs)
{
const CProxyFile2 &file = _proxy2->Files[_proxy2->Dirs[proxyIndex].ArcIndex];
const CProxyFile2 &file = _proxy2->Files[(unsigned)_proxy2->Dirs[proxyIndex].ArcIndex];
len += file.NameLen + 1;
proxyIndex = (file.Parent < 0) ? 0 : _proxy2->Files[file.Parent].GetDirIndex(file.IsAltStream);
proxyIndex = (file.Parent == -1) ? 0 : _proxy2->Files[(unsigned)file.Parent].GetDirIndex(file.IsAltStream);
}
wchar_t *p = prefix.GetBuf_SetEnd(len) + len;
proxyIndex = item.DirIndex;
while (proxyIndex != _proxyDirIndex && proxyIndex >= k_Proxy2_NumRootDirs)
{
const CProxyFile2 &file = _proxy2->Files[_proxy2->Dirs[proxyIndex].ArcIndex];
const CProxyFile2 &file = _proxy2->Files[(unsigned)_proxy2->Dirs[proxyIndex].ArcIndex];
p--;
*p = WCHAR_PATH_SEPARATOR;
p -= file.NameLen;
wmemcpy(p, file.Name, file.NameLen);
proxyIndex = (file.Parent < 0) ? 0 : _proxy2->Files[file.Parent].GetDirIndex(file.IsAltStream);
proxyIndex = (file.Parent == -1) ? 0 : _proxy2->Files[(unsigned)file.Parent].GetDirIndex(file.IsAltStream);
}
}
else
@@ -327,7 +331,7 @@ STDMETHODIMP CAgentFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT
/*
if (propID == kpidNumAltStreams)
{
if (item.AltDirIndex >= 0)
if (item.AltDirIndex != -1)
prop = _proxy2->Dirs[item.AltDirIndex].Items.Size();
}
else
@@ -887,12 +891,12 @@ STDMETHODIMP CAgentFolder::BindToFolder(const wchar_t *name, IFolderFolder **res
if (_proxy2)
{
int index = _proxy2->FindItem(_proxyDirIndex, name, true);
if (index < 0)
if (index == -1)
return E_INVALIDARG;
return BindToFolder_Internal(_proxy2->Files[_proxy2->Dirs[_proxyDirIndex].Items[index]].DirIndex, resultFolder);
}
int index = _proxy->FindSubDir(_proxyDirIndex, name);
if (index < 0)
if (index == -1)
return E_INVALIDARG;
return BindToFolder_Internal(index, resultFolder);
COM_TRY_END
@@ -956,7 +960,7 @@ STDMETHODIMP CAgentFolder::BindToAltStreams(UInt32 index, IFolderFolder **result
{
unsigned arcIndex = _proxy2->Dirs[_proxyDirIndex].ArcIndex;
const CProxyFile2 &item = _proxy2->Files[arcIndex];
if (item.AltDirIndex < 0)
if (item.AltDirIndex == -1)
return S_OK;
altDirIndex = item.AltDirIndex;
// parentFolder = _parentFolder;
@@ -972,7 +976,7 @@ STDMETHODIMP CAgentFolder::BindToAltStreams(UInt32 index, IFolderFolder **result
SET_realIndex_AND_dir_2
unsigned arcIndex = dir->Items[realIndex];
const CProxyFile2 &item = _proxy2->Files[arcIndex];
if (item.AltDirIndex < 0)
if (item.AltDirIndex == -1)
return S_OK;
return BindToAltStreams_Internal(item.AltDirIndex, resultFolder);
}
@@ -1000,7 +1004,7 @@ STDMETHODIMP CAgentFolder::BindToAltStreams(const wchar_t *name, IFolderFolder *
FOR_VECTOR (i, dir.Items)
{
const CProxyFile2 &file = _proxy2->Files[dir.Items[i]];
if (file.AltDirIndex >= 0)
if (file.AltDirIndex != -1)
if (CompareFileNames(file.Name, name) == 0)
return BindToAltStreams_Internal(file.AltDirIndex, resultFolder);
}
@@ -1036,7 +1040,7 @@ STDMETHODIMP CAgentFolder::AreAltStreamsSupported(UInt32 index, Int32 *isSupport
arcIndex = dir->Items[realIndex];
}
if (_proxy2->Files[arcIndex].AltDirIndex >= 0)
if (_proxy2->Files[arcIndex].AltDirIndex != -1)
*isSupported = BoolToInt(true);
return S_OK;
}
@@ -1062,18 +1066,18 @@ STDMETHODIMP CAgentFolder::BindToParentFolder(IFolderFolder **resultFolder)
else
{
const CProxyDir2 &fold = _proxy2->Dirs[_proxyDirIndex];
const CProxyFile2 &file = _proxy2->Files[fold.ArcIndex];
int parentIndex = file.Parent;
if (parentIndex < 0)
const CProxyFile2 &file = _proxy2->Files[(unsigned)fold.ArcIndex];
const int parentIndex = file.Parent;
if (parentIndex == -1)
proxyDirIndex = k_Proxy2_RootDirIndex;
else
proxyDirIndex = _proxy2->Files[parentIndex].DirIndex;
proxyDirIndex = _proxy2->Files[(unsigned)parentIndex].DirIndex;
}
}
else
{
int parent = _proxy->Dirs[_proxyDirIndex].ParentDir;
if (parent < 0)
if (parent == -1)
return S_OK;
proxyDirIndex = parent;
}
@@ -1239,8 +1243,8 @@ STDMETHODIMP CAgentFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)
const CProxyDir2 &dir = _proxy2->Dirs[_proxyDirIndex];
if (propID == kpidName)
{
if (dir.ArcIndex >= 0)
prop = _proxy2->Files[dir.ArcIndex].Name;
if (dir.ArcIndex != -1)
prop = _proxy2->Files[(unsigned)dir.ArcIndex].Name;
}
else if (propID == kpidPath)
{
@@ -1477,8 +1481,8 @@ STDMETHODIMP CAgentFolder::Extract(const UInt32 *indices,
false, // multiArchives
pathMode,
overwriteMode,
true // keepEmptyDirPrefixes
);
_zoneMode,
k_keepEmptyDirPrefixes);
if (extractCallback2)
extractCallback2->SetTotal(_agentSpec->GetArc().GetEstmatedPhySize());
@@ -1500,6 +1504,15 @@ STDMETHODIMP CAgentFolder::Extract(const UInt32 *indices,
extractNtOptions.ReplaceColonForAltStream = IntToBool(replaceAltStreamColon);
extractCallbackSpec->InitBeforeNewArchive();
#if defined(_WIN32) && !defined(UNDER_CE)
if (_zoneMode != NExtract::NZoneIdMode::kNone)
{
ReadZoneFile_Of_BaseFile(us2fs(_agentSpec->_archiveFilePath), extractCallbackSpec->ZoneBuf);
}
#endif
extractCallbackSpec->Init(
extractNtOptions,
NULL, &_agentSpec->GetArc(),
@@ -1645,8 +1658,8 @@ STDMETHODIMP CAgent::Open(
CArc &arc = _archiveLink.Arcs.Back();
if (!inStream)
{
arc.MTimeDefined = !fi.IsDevice;
arc.MTime = fi.MTime;
arc.MTime.Set_From_FiTime(fi.MTime);
arc.MTime.Def = !fi.IsDevice;
}
ArchiveType = GetTypeOfArc(arc);
@@ -1783,8 +1796,8 @@ STDMETHODIMP CAgent::Extract(
false, // multiArchives
pathMode,
overwriteMode,
true // keepEmptyDirPrefixes
);
NExtract::NZoneIdMode::kNone,
k_keepEmptyDirPrefixes);
CExtractNtOptions extractNtOptions;
extractNtOptions.AltStreams.Val = true; // change it!!!

View File

@@ -58,7 +58,7 @@ class CAgentFolder:
public IArchiveFolder,
public IArchiveFolderInternal,
public IInArchiveGetStream,
// public IFolderSetReplaceAltStreamCharsMode,
public IFolderSetZoneIdMode,
#ifdef NEW_FOLDER_INTERFACE
public IFolderOperations,
public IFolderSetFlatMode,
@@ -78,7 +78,7 @@ public:
MY_QUERYINTERFACE_ENTRY(IArchiveFolder)
MY_QUERYINTERFACE_ENTRY(IArchiveFolderInternal)
MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream)
// MY_QUERYINTERFACE_ENTRY(IFolderSetReplaceAltStreamCharsMode)
MY_QUERYINTERFACE_ENTRY(IFolderSetZoneIdMode)
#ifdef NEW_FOLDER_INTERFACE
MY_QUERYINTERFACE_ENTRY(IFolderOperations)
MY_QUERYINTERFACE_ENTRY(IFolderSetFlatMode)
@@ -92,7 +92,7 @@ public:
void GetRealIndices(const UInt32 *indices, UInt32 numItems,
bool includeAltStreams, bool includeFolderSubItemsInFlatMode, CUIntVector &realIndices) const;
// INTERFACE_FolderSetReplaceAltStreamCharsMode(;)
INTERFACE_IFolderSetZoneIdMode(;)
INTERFACE_FolderFolder(;)
INTERFACE_FolderAltStreams(;)
@@ -123,6 +123,7 @@ public:
_isAltStreamFolder(false),
_flatMode(false),
_loadAltStreams(false) // _loadAltStreams alt streams works in flat mode, but we don't use it now
, _zoneMode(NExtract::NZoneIdMode::kNone)
/* , _replaceAltStreamCharsMode(0) */
{}
@@ -169,6 +170,7 @@ public:
bool _flatMode;
bool _loadAltStreams; // in Flat mode
// Int32 _replaceAltStreamCharsMode;
NExtract::NZoneIdMode::EEnum _zoneMode;
};
class CAgent:

View File

@@ -12,6 +12,8 @@
#include "../../Common/FileStreams.h"
#include "../../Archive/Common/ItemNameUtils.h"
#include "Agent.h"
#include "UpdateCallbackAgent.h"
@@ -67,8 +69,8 @@ static HRESULT EnumerateArchiveItems(CAgent *agent,
unsigned arcIndex = item.SubFiles[i];
const CProxyFile &fileItem = agent->_proxy->Files[arcIndex];
CArcItem ai;
RINOK(agent->GetArc().GetItemMTime(arcIndex, ai.MTime, ai.MTimeDefined));
RINOK(agent->GetArc().GetItemSize(arcIndex, ai.Size, ai.SizeDefined));
RINOK(agent->GetArc().GetItem_MTime(arcIndex, ai.MTime));
RINOK(agent->GetArc().GetItem_Size(arcIndex, ai.Size, ai.Size_Defined));
ai.IsDir = false;
ai.Name = prefix + fileItem.Name;
ai.Censored = true; // test it
@@ -83,9 +85,9 @@ static HRESULT EnumerateArchiveItems(CAgent *agent,
if (dirItem.IsLeaf())
{
CArcItem ai;
RINOK(agent->GetArc().GetItemMTime(dirItem.ArcIndex, ai.MTime, ai.MTimeDefined));
RINOK(agent->GetArc().GetItem_MTime(dirItem.ArcIndex, ai.MTime));
ai.IsDir = true;
ai.SizeDefined = false;
ai.Size_Defined = false;
ai.Name = fullName;
ai.Censored = true; // test it
ai.IndexInServer = dirItem.ArcIndex;
@@ -111,18 +113,18 @@ static HRESULT EnumerateArchiveItems2(const CAgent *agent,
ai.IndexInServer = arcIndex;
ai.Name = prefix + file.Name;
ai.Censored = true; // test it
RINOK(agent->GetArc().GetItemMTime(arcIndex, ai.MTime, ai.MTimeDefined));
RINOK(agent->GetArc().GetItem_MTime(arcIndex, ai.MTime));
ai.IsDir = file.IsDir();
ai.SizeDefined = false;
ai.Size_Defined = false;
ai.IsAltStream = file.IsAltStream;
if (!ai.IsDir)
{
RINOK(agent->GetArc().GetItemSize(arcIndex, ai.Size, ai.SizeDefined));
RINOK(agent->GetArc().GetItem_Size(arcIndex, ai.Size, ai.Size_Defined));
ai.IsDir = false;
}
arcItems.Add(ai);
if (file.AltDirIndex >= 0)
if (file.AltDirIndex != -1)
{
RINOK(EnumerateArchiveItems2(agent, file.AltDirIndex, ai.Name + L':', arcItems));
}
@@ -264,10 +266,13 @@ STDMETHODIMP CAgent::DoOperation(
#endif
}
NFileTimeType::EEnum fileTimeType;
NFileTimeType::EEnum fileTimeType = NFileTimeType::kNotDefined;
UInt32 value;
RINOK(outArchive->GetFileTimeType(&value));
// we support any future fileType here.
// 22.00:
fileTimeType = (NFileTimeType::EEnum)value;
/*
switch (value)
{
case NFileTimeType::kWindows:
@@ -276,8 +281,11 @@ STDMETHODIMP CAgent::DoOperation(
fileTimeType = NFileTimeType::EEnum(value);
break;
default:
{
return E_FAIL;
}
}
*/
CObjectVector<CArcItem> arcItems;
@@ -389,11 +397,11 @@ STDMETHODIMP CAgent::DoOperation(
FOR_VECTOR(i, updatePairs2)
{
const CUpdatePair2 &up = updatePairs2[i];
if (up.DirIndex >= 0 && up.NewData)
if (up.DirIndex != -1 && up.NewData)
{
const CDirItem &di = dirItems.Items[up.DirIndex];
const CDirItem &di = dirItems.Items[(unsigned)up.DirIndex];
if (!di.IsDir() && di.Size == 0)
processedItems[up.DirIndex] = 1;
processedItems[(unsigned)up.DirIndex] = 1;
}
}
}
@@ -452,7 +460,7 @@ STDMETHODIMP CAgent::DeleteItems(ISequentialOutStream *outArchiveStream,
if (curIndex < realIndices.Size())
if (realIndices[curIndex] == i)
{
RINOK(GetArc().GetItemPath2(i, deletePath));
RINOK(GetArc().GetItem_Path2(i, deletePath));
RINOK(updateCallback100->DeleteOperation(deletePath));
curIndex++;
@@ -548,11 +556,14 @@ HRESULT CAgent::RenameItem(ISequentialOutStream *outArchiveStream,
true, // includeFolderSubItemsInFlatMode
realIndices);
int mainRealIndex = _agentFolder->GetRealIndex(indices[0]);
UString fullPrefix = _agentFolder->GetFullPrefix(indices[0]);
UString oldItemPath = fullPrefix + _agentFolder->GetName(indices[0]);
UString newItemPath = fullPrefix + newItemName;
const UInt32 ind0 = indices[0];
const int mainRealIndex = _agentFolder->GetRealIndex(ind0);
const UString fullPrefix = _agentFolder->GetFullPrefix(ind0);
UString name = _agentFolder->GetName(ind0);
// 22.00 : we normalize name
NArchive::NItemName::NormalizeSlashes_in_FileName_for_OsPath(name);
const UString oldItemPath = fullPrefix + name;
const UString newItemPath = fullPrefix + newItemName;
UStringVector newNames;
@@ -568,10 +579,10 @@ HRESULT CAgent::RenameItem(ISequentialOutStream *outArchiveStream,
if (realIndices[curIndex] == i)
{
up2.NewProps = true;
RINOK(GetArc().IsItemAnti(i, up2.IsAnti)); // it must work without that line too.
RINOK(GetArc().IsItem_Anti(i, up2.IsAnti)); // it must work without that line too.
UString oldFullPath;
RINOK(GetArc().GetItemPath2(i, oldFullPath));
RINOK(GetArc().GetItem_Path2(i, oldFullPath));
if (!IsPath1PrefixedByPath2(oldFullPath, oldItemPath))
return E_INVALIDARG;

View File

@@ -18,6 +18,8 @@
#include "../../../Windows/PropVariant.h"
#include "../../../Windows/PropVariantConv.h"
#include "../../Archive/Common/ItemNameUtils.h"
#include "AgentProxy.h"
using namespace NWindows;
@@ -33,12 +35,12 @@ int CProxyArc::FindSubDir(unsigned dirIndex, const wchar_t *name, unsigned &inse
insertPos = left;
return -1;
}
unsigned mid = (left + right) / 2;
unsigned dirIndex2 = subDirs[mid];
int compare = CompareFileNames(name, Dirs[dirIndex2].Name);
if (compare == 0)
const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
const unsigned dirIndex2 = subDirs[mid];
const int comp = CompareFileNames(name, Dirs[dirIndex2].Name);
if (comp == 0)
return dirIndex2;
if (compare < 0)
if (comp < 0)
right = mid;
else
left = mid + 1;
@@ -67,12 +69,12 @@ unsigned CProxyArc::AddDir(unsigned dirIndex, int arcIndex, const UString &name)
{
unsigned insertPos;
int subDirIndex = FindSubDir(dirIndex, name, insertPos);
if (subDirIndex >= 0)
if (subDirIndex != -1)
{
if (arcIndex >= 0)
if (arcIndex != -1)
{
CProxyDir &item = Dirs[subDirIndex];
if (item.ArcIndex < 0)
CProxyDir &item = Dirs[(unsigned)subDirIndex];
if (item.ArcIndex == -1)
item.ArcIndex = arcIndex;
}
return subDirIndex;
@@ -98,27 +100,31 @@ void CProxyDir::Clear()
void CProxyArc::GetDirPathParts(int dirIndex, UStringVector &pathParts) const
{
pathParts.Clear();
while (dirIndex >= 0)
while (dirIndex != -1)
{
const CProxyDir &dir = Dirs[dirIndex];
dirIndex = dir.ParentDir;
if (dirIndex < 0)
if (dirIndex == -1)
break;
pathParts.Insert(0, dir.Name);
// 22.00: we normalize name
NArchive::NItemName::NormalizeSlashes_in_FileName_for_OsPath(pathParts[0]);
}
}
UString CProxyArc::GetDirPath_as_Prefix(int dirIndex) const
{
UString s;
while (dirIndex >= 0)
while (dirIndex != -1)
{
const CProxyDir &dir = Dirs[dirIndex];
dirIndex = dir.ParentDir;
if (dirIndex < 0)
if (dirIndex == -1)
break;
s.InsertAtFront(WCHAR_PATH_SEPARATOR);
s.Insert(0, dir.Name);
// 22.00: we normalize name
NArchive::NItemName::NormalizeSlashes_in_FileName_for_OsPath(s.GetBuf(), MyStringLen(dir.Name));
}
return s;
}
@@ -251,7 +257,7 @@ HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress)
{
if (progress && (i & 0xFFFF) == 0)
{
UInt64 currentItemIndex = i;
const UInt64 currentItemIndex = i;
RINOK(progress->SetCompleted(&currentItemIndex));
}
@@ -259,9 +265,9 @@ HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress)
unsigned len = 0;
bool isPtrName = false;
#if WCHAR_PATH_SEPARATOR != L'/'
wchar_t replaceFromChar = 0;
#endif
#if WCHAR_PATH_SEPARATOR != L'/'
wchar_t separatorChar = WCHAR_PATH_SEPARATOR;
#endif
#if defined(MY_CPU_LE) && defined(_WIN32)
// it works only if (sizeof(wchar_t) == 2)
@@ -278,9 +284,9 @@ HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress)
len = size / 2 - 1;
s = (const wchar_t *)p;
isPtrName = true;
#if WCHAR_PATH_SEPARATOR != L'/'
replaceFromChar = L'\\';
#endif
#if WCHAR_PATH_SEPARATOR != L'/'
separatorChar = L'/'; // 0
#endif
}
}
if (!s)
@@ -297,7 +303,7 @@ HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress)
return E_FAIL;
if (len == 0)
{
RINOK(arc.GetDefaultItemPath(i, path));
RINOK(arc.GetItem_DefaultPath(i, path));
len = path.Len();
s = path;
}
@@ -328,16 +334,12 @@ HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress)
for (unsigned j = 0; j < len; j++)
{
const wchar_t c = s[j];
if (c == WCHAR_PATH_SEPARATOR || c == L'/')
{
if (c == L'/'
#if WCHAR_PATH_SEPARATOR != L'/'
if (c == replaceFromChar)
{
// s.ReplaceOneCharAtPos(j, WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT);
continue;
}
|| (c == separatorChar)
#endif
)
{
const unsigned kLevelLimit = 1 << 10;
if (numLevels <= kLevelLimit)
{
@@ -345,6 +347,8 @@ HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress)
name = "[LONG_PATH]";
else
name.SetFrom(s + namePos, j - namePos);
// 22.00: we can normalize dir here
// NArchive::NItemName::NormalizeSlashes_in_FileName_for_OsPath(name);
curItem = AddDir(curItem, -1, name);
}
namePos = j + 1;
@@ -384,6 +388,8 @@ HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress)
if (isDir)
{
name = s;
// 22.00: we can normalize dir here
// NArchive::NItemName::NormalizeSlashes_in_FileName_for_OsPath(name);
AddDir(curItem, (int)i, name);
}
else
@@ -418,14 +424,14 @@ void CProxyArc2::GetDirPathParts(int dirIndex, UStringVector &pathParts, bool &i
while (dirIndex >= (int)k_Proxy2_NumRootDirs)
{
const CProxyDir2 &dir = Dirs[dirIndex];
const CProxyFile2 &file = Files[dir.ArcIndex];
const CProxyFile2 &file = Files[(unsigned)dir.ArcIndex];
if (pathParts.IsEmpty() && dirIndex == file.AltDirIndex)
isAltStreamDir = true;
pathParts.Insert(0, file.Name);
int par = file.Parent;
if (par < 0)
if (par == -1)
break;
dirIndex = Files[par].DirIndex;
dirIndex = Files[(unsigned)par].DirIndex;
}
}
@@ -436,7 +442,7 @@ bool CProxyArc2::IsAltDir(unsigned dirIndex) const
if (dirIndex == k_Proxy2_AltRootDirIndex)
return true;
const CProxyDir2 &dir = Dirs[dirIndex];
const CProxyFile2 &file = Files[dir.ArcIndex];
const CProxyFile2 &file = Files[(unsigned)dir.ArcIndex];
return ((int)dirIndex == file.AltDirIndex);
}
@@ -448,7 +454,7 @@ UString CProxyArc2::GetDirPath_as_Prefix(unsigned dirIndex, bool &isAltStreamDir
isAltStreamDir = true;
else if (dirIndex >= k_Proxy2_NumRootDirs)
{
const CProxyFile2 &file = Files[dir.ArcIndex];
const CProxyFile2 &file = Files[(unsigned)dir.ArcIndex];
isAltStreamDir = ((int)dirIndex == file.AltDirIndex);
}
return dir.PathPrefix;
@@ -458,9 +464,9 @@ void CProxyArc2::AddRealIndices_of_ArcItem(unsigned arcIndex, bool includeAltStr
{
realIndices.Add(arcIndex);
const CProxyFile2 &file = Files[arcIndex];
if (file.DirIndex >= 0)
if (file.DirIndex != -1)
AddRealIndices_of_Dir(file.DirIndex, includeAltStreams, realIndices);
if (includeAltStreams && file.AltDirIndex >= 0)
if (includeAltStreams && file.AltDirIndex != -1)
AddRealIndices_of_Dir(file.AltDirIndex, includeAltStreams, realIndices);
}
@@ -520,15 +526,18 @@ void CProxyArc2::CalculateSizes(unsigned dirIndex, IInArchive *archive)
}
const CProxyFile2 &subFile = Files[index];
if (subFile.DirIndex < 0)
if (subFile.DirIndex == -1)
{
dir.NumSubFiles++;
}
else
{
// 22.00: we normalize name
UString s = subFile.Name;
NArchive::NItemName::NormalizeSlashes_in_FileName_for_OsPath(s);
dir.NumSubDirs++;
CProxyDir2 &f = Dirs[subFile.DirIndex];
f.PathPrefix = dir.PathPrefix + subFile.Name + WCHAR_PATH_SEPARATOR;
f.PathPrefix = dir.PathPrefix + s + WCHAR_PATH_SEPARATOR;
CalculateSizes(subFile.DirIndex, archive);
dir.Size += f.Size;
dir.PackSize += f.PackSize;
@@ -539,7 +548,7 @@ void CProxyArc2::CalculateSizes(unsigned dirIndex, IInArchive *archive)
dir.CrcIsDefined = false;
}
if (subFile.AltDirIndex < 0)
if (subFile.AltDirIndex == -1)
{
// dir.NumSubFiles++;
}
@@ -688,12 +697,12 @@ HRESULT CProxyArc2::Load(const CArc &arc, IProgress *progress)
if (file.IsAltStream)
{
if (file.Parent < 0)
if (file.Parent == -1)
dirIndex = k_Proxy2_AltRootDirIndex;
else
{
int &folderIndex2 = Files[file.Parent].AltDirIndex;
if (folderIndex2 < 0)
int &folderIndex2 = Files[(unsigned)file.Parent].AltDirIndex;
if (folderIndex2 == -1)
{
folderIndex2 = Dirs.Size();
CProxyDir2 &dir = Dirs.AddNew();
@@ -704,12 +713,12 @@ HRESULT CProxyArc2::Load(const CArc &arc, IProgress *progress)
}
else
{
if (file.Parent < 0)
if (file.Parent == -1)
dirIndex = k_Proxy2_RootDirIndex;
else
{
dirIndex = Files[file.Parent].DirIndex;
if (dirIndex < 0)
dirIndex = Files[(unsigned)file.Parent].DirIndex;
if (dirIndex == -1)
return E_FAIL;
}
}
@@ -731,7 +740,7 @@ int CProxyArc2::FindItem(unsigned dirIndex, const wchar_t *name, bool foldersOnl
FOR_VECTOR (i, dir.Items)
{
const CProxyFile2 &file = Files[dir.Items[i]];
if (foldersOnly && file.DirIndex < 0)
if (foldersOnly && file.DirIndex == -1)
continue;
if (CompareFileNames(file.Name, name) == 0)
return i;

View File

@@ -38,7 +38,7 @@ struct CProxyDir
~CProxyDir() { delete [](wchar_t *)(void *)Name; }
void Clear();
bool IsLeaf() const { return ArcIndex >= 0; }
bool IsLeaf() const { return ArcIndex != -1; }
};
class CProxyArc
@@ -82,7 +82,7 @@ struct CProxyFile2
int GetDirIndex(bool forAltStreams) const { return forAltStreams ? AltDirIndex : DirIndex; }
bool IsDir() const { return DirIndex >= 0; }
bool IsDir() const { return DirIndex != -1; }
CProxyFile2():
DirIndex(-1), AltDirIndex(-1), Parent(-1),
Name(NULL), NameLen(0),
@@ -145,7 +145,7 @@ public:
{
const CProxyFile2 &file = Files[arcIndex];
if (file.Parent < 0)
if (file.Parent == -1)
return file.IsAltStream ?
k_Proxy2_AltRootDirIndex :
k_Proxy2_RootDirIndex;

View File

@@ -16,6 +16,12 @@ STDMETHODIMP CAgentFolder::SetReplaceAltStreamCharsMode(Int32 replaceAltStreamCh
}
*/
STDMETHODIMP CAgentFolder::SetZoneIdMode(NExtract::NZoneIdMode::EEnum zoneMode)
{
_zoneMode = zoneMode;
return S_OK;
}
STDMETHODIMP CAgentFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 numItems,
Int32 includeAltStreams, Int32 replaceAltStreamCharsMode,
const wchar_t *path, IFolderOperationsExtractCallback *callback)

View File

@@ -210,7 +210,7 @@ HRESULT CAgentFolder::CommonUpdateOperation(
FOR_VECTOR (i, pathParts)
{
int next = _proxy->FindSubDir(_proxyDirIndex, pathParts[i]);
if (next < 0)
if (next == -1)
break;
_proxyDirIndex = next;
}
@@ -226,7 +226,7 @@ HRESULT CAgentFolder::CommonUpdateOperation(
{
bool dirOnly = (i + 1 < pathParts.Size() || !isAltStreamFolder);
int index = _proxy2->FindItem(_proxyDirIndex, pathParts[i], dirOnly);
if (index < 0)
if (index == -1)
break;
const CProxyFile2 &file = _proxy2->Files[_proxy2->Dirs[_proxyDirIndex].Items[index]];
@@ -235,7 +235,7 @@ HRESULT CAgentFolder::CommonUpdateOperation(
_proxyDirIndex = file.DirIndex;
else
{
if (file.AltDirIndex >= 0)
if (file.AltDirIndex != -1)
_proxyDirIndex = file.AltDirIndex;
break;
}
@@ -351,7 +351,7 @@ STDMETHODIMP CAgentFolder::CreateFolder(const wchar_t *name, IProgress *progress
}
else
{
if (_proxy->FindSubDir(_proxyDirIndex, name) >= 0)
if (_proxy->FindSubDir(_proxyDirIndex, name) != -1)
return ERROR_ALREADY_EXISTS;
}

View File

@@ -116,4 +116,13 @@ FOLDER_ARCHIVE_INTERFACE(IFolderScanProgress, 0x11)
INTERFACE_IFolderScanProgress(PURE)
};
#define INTERFACE_IFolderSetZoneIdMode(x) \
STDMETHOD(SetZoneIdMode)(NExtract::NZoneIdMode::EEnum zoneMode) x; \
FOLDER_ARCHIVE_INTERFACE(IFolderSetZoneIdMode, 0x12)
{
INTERFACE_IFolderSetZoneIdMode(PURE)
};
#endif

View File

@@ -33,17 +33,29 @@ HINSTANCE g_hInstance;
HINSTANCE g_hInstance = 0;
#endif
// You can find the list of all GUIDs in Guid.txt file.
// use another CLSIDs, if you want to support other formats (zip, rar, ...).
// {23170F69-40C1-278A-1000-000110070000}
// You can find full list of all GUIDs supported by 7-Zip in Guid.txt file.
// 7z format GUID: {23170F69-40C1-278A-1000-000110070000}
DEFINE_GUID(CLSID_CFormat7z,
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00);
DEFINE_GUID(CLSID_CFormatXz,
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x0C, 0x00, 0x00);
#define DEFINE_GUID_ARC(name, id) DEFINE_GUID(name, \
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, id, 0x00, 0x00);
#define CLSID_Format CLSID_CFormat7z
// #define CLSID_Format CLSID_CFormatXz
enum
{
kId_Zip = 1,
kId_BZip2 = 2,
kId_7z = 7,
kId_Xz = 0xC,
kId_Tar = 0xEE,
kId_GZip = 0xEF
};
// use another id, if you want to support other formats (zip, Xz, ...).
// DEFINE_GUID_ARC (CLSID_Format, kId_Zip)
// DEFINE_GUID_ARC (CLSID_Format, kId_BZip2)
// DEFINE_GUID_ARC (CLSID_Format, kId_Xz)
// DEFINE_GUID_ARC (CLSID_Format, kId_Tar)
// DEFINE_GUID_ARC (CLSID_Format, kId_GZip)
DEFINE_GUID_ARC (CLSID_Format, kId_7z)
using namespace NWindows;
using namespace NFile;
@@ -229,6 +241,86 @@ static const char * const kIsNotArc = "Is not archive";
static const char * const kHeadersError = "Headers Error";
struct CArcTime
{
FILETIME FT;
UInt16 Prec;
Byte Ns100;
bool Def;
CArcTime()
{
Clear();
}
void Clear()
{
FT.dwHighDateTime = FT.dwLowDateTime = 0;
Prec = 0;
Ns100 = 0;
Def = false;
}
bool IsZero() const
{
return FT.dwLowDateTime == 0 && FT.dwHighDateTime == 0 && Ns100 == 0;
}
int GetNumDigits() const
{
if (Prec == k_PropVar_TimePrec_Unix ||
Prec == k_PropVar_TimePrec_DOS)
return 0;
if (Prec == k_PropVar_TimePrec_HighPrec)
return 9;
if (Prec == k_PropVar_TimePrec_0)
return 7;
int digits = (int)Prec - (int)k_PropVar_TimePrec_Base;
if (digits < 0)
digits = 0;
return digits;
}
void Write_To_FiTime(CFiTime &dest) const
{
#ifdef _WIN32
dest = FT;
#else
if (FILETIME_To_timespec(FT, dest))
if ((Prec == k_PropVar_TimePrec_Base + 8 ||
Prec == k_PropVar_TimePrec_Base + 9)
&& Ns100 != 0)
{
dest.tv_nsec += Ns100;
}
#endif
}
void Set_From_Prop(const PROPVARIANT &prop)
{
FT = prop.filetime;
unsigned prec = 0;
unsigned ns100 = 0;
const unsigned prec_Temp = prop.wReserved1;
if (prec_Temp != 0
&& prec_Temp <= k_PropVar_TimePrec_1ns
&& prop.wReserved3 == 0)
{
const unsigned ns100_Temp = prop.wReserved2;
if (ns100_Temp < 100)
{
ns100 = ns100_Temp;
prec = prec_Temp;
}
}
Prec = (UInt16)prec;
Ns100 = (Byte)ns100;
Def = true;
}
};
class CArchiveExtractCallback:
public IArchiveExtractCallback,
public ICryptoGetTextPassword,
@@ -257,11 +349,10 @@ private:
bool _extractMode;
struct CProcessedFileInfo
{
FILETIME MTime;
CArcTime MTime;
UInt32 Attrib;
bool isDir;
bool AttribDefined;
bool MTimeDefined;
bool Attrib_Defined;
} _processedFileInfo;
COutFileStream *_outFileStreamSpec;
@@ -328,32 +419,31 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index,
if (prop.vt == VT_EMPTY)
{
_processedFileInfo.Attrib = 0;
_processedFileInfo.AttribDefined = false;
_processedFileInfo.Attrib_Defined = false;
}
else
{
if (prop.vt != VT_UI4)
return E_FAIL;
_processedFileInfo.Attrib = prop.ulVal;
_processedFileInfo.AttribDefined = true;
_processedFileInfo.Attrib_Defined = true;
}
}
RINOK(IsArchiveItemFolder(_archiveHandler, index, _processedFileInfo.isDir));
{
_processedFileInfo.MTime.Clear();
// Get Modified Time
NCOM::CPropVariant prop;
RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop));
_processedFileInfo.MTimeDefined = false;
switch (prop.vt)
{
case VT_EMPTY:
// _processedFileInfo.MTime = _utcMTimeDefault;
break;
case VT_FILETIME:
_processedFileInfo.MTime = prop.filetime;
_processedFileInfo.MTimeDefined = true;
_processedFileInfo.MTime.Set_From_Prop(prop);
break;
default:
return E_FAIL;
@@ -483,12 +573,16 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
if (_outFileStream)
{
if (_processedFileInfo.MTimeDefined)
_outFileStreamSpec->SetMTime(&_processedFileInfo.MTime);
if (_processedFileInfo.MTime.Def)
{
CFiTime ft;
_processedFileInfo.MTime.Write_To_FiTime(ft);
_outFileStreamSpec->SetMTime(&ft);
}
RINOK(_outFileStreamSpec->Close());
}
_outFileStream.Release();
if (_extractMode && _processedFileInfo.AttribDefined)
if (_extractMode && _processedFileInfo.Attrib_Defined)
SetFileAttrib_PosixHighDetect(_diskFilePath, _processedFileInfo.Attrib);
PrintNewLine();
return S_OK;
@@ -513,17 +607,14 @@ STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)
//////////////////////////////////////////////////////////////
// Archive Creating callback class
struct CDirItem
struct CDirItem: public NWindows::NFile::NFind::CFileInfoBase
{
UInt64 Size;
FILETIME CTime;
FILETIME ATime;
FILETIME MTime;
UString Name;
FString FullPath;
UInt32 Attrib;
UString Path_For_Handler;
FString FullPath; // for filesystem
bool isDir() const { return (Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0 ; }
CDirItem(const NWindows::NFile::NFind::CFileInfo &fi):
CFileInfoBase(fi)
{}
};
class CArchiveUpdateCallback:
@@ -618,16 +709,17 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
}
{
const CDirItem &dirItem = (*DirItems)[index];
const CDirItem &di = (*DirItems)[index];
switch (propID)
{
case kpidPath: prop = dirItem.Name; break;
case kpidIsDir: prop = dirItem.isDir(); break;
case kpidSize: prop = dirItem.Size; break;
case kpidAttrib: prop = dirItem.Attrib; break;
case kpidCTime: prop = dirItem.CTime; break;
case kpidATime: prop = dirItem.ATime; break;
case kpidMTime: prop = dirItem.MTime; break;
case kpidPath: prop = di.Path_For_Handler; break;
case kpidIsDir: prop = di.IsDir(); break;
case kpidSize: prop = di.Size; break;
case kpidCTime: PropVariant_SetFrom_FiTime(prop, di.CTime); break;
case kpidATime: PropVariant_SetFrom_FiTime(prop, di.ATime); break;
case kpidMTime: PropVariant_SetFrom_FiTime(prop, di.MTime); break;
case kpidAttrib: prop = (UInt32)di.GetWinAttrib(); break;
case kpidPosixAttrib: prop = (UInt32)di.GetPosixAttrib(); break;
}
}
prop.Detach(value);
@@ -657,9 +749,9 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream
RINOK(Finilize());
const CDirItem &dirItem = (*DirItems)[index];
GetStream2(dirItem.Name);
GetStream2(dirItem.Path_For_Handler);
if (dirItem.isDir())
if (dirItem.IsDir())
return S_OK;
{
@@ -848,7 +940,6 @@ int MY_CDECL main(int numArgs, const char *args[])
unsigned i;
for (i = 1; i < params.Size(); i++)
{
CDirItem di;
const FString &name = params[i];
NFind::CFileInfo fi;
@@ -857,13 +948,10 @@ int MY_CDECL main(int numArgs, const char *args[])
PrintError("Can't find file", name);
return 1;
}
CDirItem di(fi);
di.Attrib = fi.Attrib;
di.Size = fi.Size;
di.CTime = fi.CTime;
di.ATime = fi.ATime;
di.MTime = fi.MTime;
di.Name = fs2us(name);
di.Path_For_Handler = fs2us(name);
di.FullPath = name;
dirItems.Add(di);
}
@@ -894,12 +982,14 @@ int MY_CDECL main(int numArgs, const char *args[])
{
const wchar_t *names[] =
{
L"m",
L"s",
L"x"
};
const unsigned kNumProps = ARRAY_SIZE(names);
NCOM::CPropVariant values[kNumProps] =
{
L"lzma",
false, // solid mode OFF
(UInt32)9 // compression level = 9 - ultra
};
@@ -910,7 +1000,11 @@ int MY_CDECL main(int numArgs, const char *args[])
PrintError("ISetProperties unsupported");
return 1;
}
RINOK(setProperties->SetProperties(names, values, kNumProps));
if (setProperties->SetProperties(names, values, kNumProps) != S_OK)
{
PrintError("SetProperties() error");
return 1;
}
}
*/
@@ -1035,7 +1129,13 @@ int MY_CDECL main(int numArgs, const char *args[])
CMyComPtr<ISetProperties> setProperties;
archive->QueryInterface(IID_ISetProperties, (void **)&setProperties);
if (setProperties)
setProperties->SetProperties(names, values, kNumProps);
{
if (setProperties->SetProperties(names, values, kNumProps) != S_OK)
{
PrintError("SetProperties() error");
return 1;
}
}
*/
HRESULT result = archive->Extract(NULL, (UInt32)(Int32)(-1), false, extractCallback);

View File

@@ -160,7 +160,11 @@ enum Enum
kSymLinks_AllowDangerous,
kSymLinks,
kNtSecurity,
kStoreOwnerId,
kStoreOwnerName,
kZoneFile,
kAltStreams,
kReplaceColonForAltStream,
kWriteToAltStreamIfColon,
@@ -304,7 +308,11 @@ static const CSwitchForm kSwitchForms[] =
{ "snld", SWFRM_MINUS },
{ "snl", SWFRM_MINUS },
{ "sni", SWFRM_SIMPLE },
{ "snoi", SWFRM_MINUS },
{ "snon", SWFRM_MINUS },
{ "snz", SWFRM_STRING_SINGL(0) },
{ "sns", SWFRM_MINUS },
{ "snr", SWFRM_SIMPLE },
{ "snc", SWFRM_SIMPLE },
@@ -1032,9 +1040,9 @@ void CArcCmdLineParser::Parse1(const UStringVector &commandStrings,
if (parser[NKey::kCaseSensitive].ThereIs)
{
options.CaseSensitive =
g_CaseSensitive = !parser[NKey::kCaseSensitive].WithMinus;
options.CaseSensitiveChange = true;
options.CaseSensitive = g_CaseSensitive;
options.CaseSensitive_Change = true;
}
@@ -1367,6 +1375,9 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
SetBoolPair(parser, NKey::kAltStreams, options.AltStreams);
SetBoolPair(parser, NKey::kHardLinks, options.HardLinks);
SetBoolPair(parser, NKey::kSymLinks, options.SymLinks);
SetBoolPair(parser, NKey::kStoreOwnerId, options.StoreOwnerId);
SetBoolPair(parser, NKey::kStoreOwnerName, options.StoreOwnerName);
CBoolPair symLinks_AllowDangerous;
SetBoolPair(parser, NKey::kSymLinks_AllowDangerous, symLinks_AllowDangerous);
@@ -1420,12 +1431,28 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
nt.ReplaceColonForAltStream = parser[NKey::kReplaceColonForAltStream].ThereIs;
nt.WriteToAltStreamIfColon = parser[NKey::kWriteToAltStreamIfColon].ThereIs;
nt.ExtractOwner = options.StoreOwnerId.Val; // StoreOwnerName
if (parser[NKey::kPreserveATime].ThereIs)
nt.PreserveATime = true;
if (parser[NKey::kShareForWrite].ThereIs)
nt.OpenShareForWrite = true;
}
if (parser[NKey::kZoneFile].ThereIs)
{
eo.ZoneMode = NExtract::NZoneIdMode::kAll;
const UString &s = parser[NKey::kZoneFile].PostStrings[0];
if (!s.IsEmpty())
{
if (s == L"0") eo.ZoneMode = NExtract::NZoneIdMode::kNone;
else if (s == L"1") eo.ZoneMode = NExtract::NZoneIdMode::kAll;
else if (s == L"2") eo.ZoneMode = NExtract::NZoneIdMode::kOffice;
else
throw CArcCmdLineException("Unsupported -snz:", s);
}
}
options.Censor.AddPathsToCensor(NWildcard::k_AbsPath);
options.Censor.ExtendExclude();
@@ -1549,6 +1576,9 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
updateOptions.NtSecurity = options.NtSecurity;
updateOptions.HardLinks = options.HardLinks;
updateOptions.SymLinks = options.SymLinks;
updateOptions.StoreOwnerId = options.StoreOwnerId;
updateOptions.StoreOwnerName = options.StoreOwnerName;
updateOptions.EMailMode = parser[NKey::kEmail].ThereIs;
if (updateOptions.EMailMode)

View File

@@ -51,7 +51,7 @@ struct CArcCmdLineOptions
bool HelpMode;
// bool LargePages;
bool CaseSensitiveChange;
bool CaseSensitive_Change;
bool CaseSensitive;
bool IsInTerminal;
@@ -97,6 +97,9 @@ struct CArcCmdLineOptions
CBoolPair AltStreams;
CBoolPair HardLinks;
CBoolPair SymLinks;
CBoolPair StoreOwnerId;
CBoolPair StoreOwnerName;
CUpdateOptions UpdateOptions;
CHashOptions HashOptions;
@@ -117,7 +120,7 @@ struct CArcCmdLineOptions
CArcCmdLineOptions():
HelpMode(false),
// LargePages(false),
CaseSensitiveChange(false),
CaseSensitive_Change(false),
CaseSensitive(false),
IsInTerminal(false),

View File

@@ -95,6 +95,83 @@ bool InitLocalPrivileges()
#endif // _USE_SECURITY_CODE
#if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX)
static const char * const kOfficeExtensions =
" doc dot wbk"
" docx docm dotx dotm docb wll wwl"
" xls xlt xlm"
" xlsx xlsm xltx xltm xlsb xla xlam"
" ppt pot pps ppa ppam"
" pptx pptm potx potm ppam ppsx ppsm sldx sldm"
" ";
static bool FindExt2(const char *p, const UString &name)
{
const int pathPos = name.ReverseFind_PathSepar();
const int dotPos = name.ReverseFind_Dot();
if (dotPos < 0
|| dotPos < pathPos
|| dotPos == (int)name.Len() - 1)
return false;
AString s;
for (unsigned pos = dotPos + 1;; pos++)
{
const wchar_t c = name[pos];
if (c <= 0)
break;
if (c >= 0x80)
return false;
s += (char)MyCharLower_Ascii((char)c);
}
for (unsigned i = 0; p[i] != 0;)
{
unsigned j;
for (j = i; p[j] != ' '; j++);
if (s.Len() == j - i && memcmp(p + i, (const char *)s, s.Len()) == 0)
return true;
i = j + 1;
}
return false;
}
static const FChar * const k_ZoneId_StreamName = FTEXT(":Zone.Identifier");
void ReadZoneFile_Of_BaseFile(CFSTR fileName2, CByteBuffer &buf)
{
FString fileName = fileName2;
fileName += k_ZoneId_StreamName;
buf.Free();
NIO::CInFile file;
if (!file.Open(fileName))
return;
UInt64 fileSize;
if (!file.GetLength(fileSize))
return;
if (fileSize == 0 || fileSize >= ((UInt32)1 << 16))
return;
buf.Alloc((size_t)fileSize);
size_t processed;
if (file.ReadFull(buf, (size_t)fileSize, processed) && processed == fileSize)
return;
buf.Free();
}
static bool WriteZoneFile(CFSTR fileName, const CByteBuffer &buf)
{
NIO::COutFile file;
if (!file.Create(fileName, true))
return false;
return file.WriteFull(buf, buf.Size());
}
#endif
#ifdef SUPPORT_LINKS
int CHardLinkNode::Compare(const CHardLinkNode &a) const
@@ -190,9 +267,9 @@ HRESULT CArchiveExtractCallback::PrepareHardLinks(const CRecordVector<UInt32> *r
CArchiveExtractCallback::CArchiveExtractCallback():
_arc(NULL),
WriteCTime(true),
WriteATime(true),
WriteMTime(true),
Write_CTime(true),
Write_ATime(true),
Write_MTime(true),
_multiArchives(false)
{
LocalProgressSpec = new CLocalProgress();
@@ -204,6 +281,13 @@ CArchiveExtractCallback::CArchiveExtractCallback():
}
void CArchiveExtractCallback::InitBeforeNewArchive()
{
#if defined(_WIN32) && !defined(UNDER_CE)
ZoneBuf.Free();
#endif
}
void CArchiveExtractCallback::Init(
const CExtractNtOptions &ntOptions,
const NWildcard::CCensorNode *wildcardCensor,
@@ -240,13 +324,19 @@ void CArchiveExtractCallback::Init(
_progressTotal_Defined = true;
_extractCallback2 = extractCallback2;
_compressProgress.Release();
_extractCallback2.QueryInterface(IID_ICompressProgressInfo, &_compressProgress);
_callbackMessage.Release();
_extractCallback2.QueryInterface(IID_IArchiveExtractCallbackMessage, &_callbackMessage);
_folderArchiveExtractCallback2.Release();
_extractCallback2.QueryInterface(IID_IFolderArchiveExtractCallback2, &_folderArchiveExtractCallback2);
#ifndef _SFX
ExtractToStreamCallback.Release();
_extractCallback2.QueryInterface(IID_IFolderExtractToStreamCallback, &ExtractToStreamCallback);
if (ExtractToStreamCallback)
{
@@ -416,26 +506,22 @@ void CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPat
}
HRESULT CArchiveExtractCallback::GetTime(UInt32 index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined)
HRESULT CArchiveExtractCallback::GetTime(UInt32 index, PROPID propID, CArcTime &ft)
{
filetimeIsDefined = false;
filetime.dwLowDateTime = 0;
filetime.dwHighDateTime = 0;
ft.Clear();
NCOM::CPropVariant prop;
RINOK(_arc->Archive->GetProperty(index, propID, &prop));
if (prop.vt == VT_FILETIME)
{
filetime = prop.filetime;
filetimeIsDefined = (filetime.dwHighDateTime != 0 || filetime.dwLowDateTime != 0);
}
ft.Set_From_Prop(prop);
else if (prop.vt != VT_EMPTY)
return E_FAIL;
return S_OK;
}
HRESULT CArchiveExtractCallback::GetUnpackSize()
{
return _arc->GetItemSize(_index, _curSize, _curSizeDefined);
return _arc->GetItem_Size(_index, _curSize, _curSizeDefined);
}
static void AddPathToMessage(UString &s, const FString &path)
@@ -454,8 +540,9 @@ HRESULT CArchiveExtractCallback::SendMessageError(const char *message, const FSt
HRESULT CArchiveExtractCallback::SendMessageError_with_LastError(const char *message, const FString &path)
{
DWORD errorCode = GetLastError();
if (errorCode == 0)
errorCode = (DWORD)E_FAIL;
UString s (message);
if (errorCode != 0)
{
s += " : ";
s += NError::MyFormatMessage(errorCode);
@@ -843,13 +930,58 @@ HRESULT CArchiveExtractCallback::ReadLink()
#endif // SUPPORT_LINKS
#ifndef _WIN32
static HRESULT GetOwner(IInArchive *archive,
UInt32 index, UInt32 pidName, UInt32 pidId, COwnerInfo &res)
{
{
NWindows::NCOM::CPropVariant prop;
RINOK(archive->GetProperty(index, pidId, &prop));
if (prop.vt == VT_UI4)
{
res.Id_Defined = true;
res.Id = prop.ulVal; // for debug
// res.Id++; // for debug
// if (pidId == kpidGroupId) res.Id += 7; // for debug
// res.Id = 0; // for debug
}
else if (prop.vt != VT_EMPTY)
return E_INVALIDARG;
}
{
NWindows::NCOM::CPropVariant prop;
RINOK(archive->GetProperty(index, pidName, &prop));
if (prop.vt == VT_BSTR)
{
const UString s = prop.bstrVal;
ConvertUnicodeToUTF8(s, res.Name);
}
else if (prop.vt == VT_UI4)
{
res.Id_Defined = true;
res.Id = prop.ulVal;
}
else if (prop.vt != VT_EMPTY)
return E_INVALIDARG;
}
return S_OK;
}
#endif
HRESULT CArchiveExtractCallback::Read_fi_Props()
{
IInArchive *archive = _arc->Archive;
const UInt32 index = _index;
_fi.AttribDefined = false;
_fi.Attrib_Defined = false;
#ifndef _WIN32
_fi.Owner.Clear();
_fi.Group.Clear();
#endif
{
NCOM::CPropVariant prop;
@@ -868,15 +1000,25 @@ HRESULT CArchiveExtractCallback::Read_fi_Props()
if (prop.vt == VT_UI4)
{
_fi.Attrib = prop.ulVal;
_fi.AttribDefined = true;
_fi.Attrib_Defined = true;
}
else if (prop.vt != VT_EMPTY)
return E_FAIL;
}
RINOK(GetTime(index, kpidCTime, _fi.CTime, _fi.CTimeDefined));
RINOK(GetTime(index, kpidATime, _fi.ATime, _fi.ATimeDefined));
RINOK(GetTime(index, kpidMTime, _fi.MTime, _fi.MTimeDefined));
RINOK(GetTime(index, kpidCTime, _fi.CTime));
RINOK(GetTime(index, kpidATime, _fi.ATime));
RINOK(GetTime(index, kpidMTime, _fi.MTime));
#ifndef _WIN32
if (_ntOptions.ExtractOwner)
{
// SendMessageError_with_LastError("_ntOptions.ExtractOwner", _diskFilePath);
GetOwner(archive, index, kpidUser, kpidUserId, _fi.Owner);
GetOwner(archive, index, kpidGroup, kpidGroupId, _fi.Group);
}
#endif
return S_OK;
}
@@ -923,6 +1065,39 @@ void CArchiveExtractCallback::CorrectPathParts()
}
void CArchiveExtractCallback::GetFiTimesCAM(CFiTimesCAM &pt)
{
pt.CTime_Defined = false;
pt.ATime_Defined = false;
pt.MTime_Defined = false;
if (Write_MTime)
{
if (_fi.MTime.Def)
{
_fi.MTime.Write_To_FiTime(pt.MTime);
pt.MTime_Defined = true;
}
else if (_arc->MTime.Def)
{
_arc->MTime.Write_To_FiTime(pt.MTime);
pt.MTime_Defined = true;
}
}
if (Write_CTime && _fi.CTime.Def)
{
_fi.CTime.Write_To_FiTime(pt.CTime);
pt.CTime_Defined = true;
}
if (Write_ATime && _fi.ATime.Def)
{
_fi.ATime.Write_To_FiTime(pt.ATime);
pt.ATime_Defined = true;
}
}
void CArchiveExtractCallback::CreateFolders()
{
@@ -948,30 +1123,9 @@ void CArchiveExtractCallback::CreateFolders()
return;
CDirPathTime pt;
pt.CTime = _fi.CTime;
pt.CTimeDefined = (WriteCTime && _fi.CTimeDefined);
pt.ATime = _fi.ATime;
pt.ATimeDefined = (WriteATime && _fi.ATimeDefined);
pt.MTimeDefined = false;
if (WriteMTime)
{
if (_fi.MTimeDefined)
{
pt.MTime = _fi.MTime;
pt.MTimeDefined = true;
}
else if (_arc->MTimeDefined)
{
pt.MTime = _arc->MTime;
pt.MTimeDefined = true;
}
}
if (pt.MTimeDefined || pt.ATimeDefined || pt.CTimeDefined)
GetFiTimesCAM(pt);
if (pt.IsSomeTimeDefined())
{
pt.Path = fullPathNew;
pt.SetDirTime();
@@ -1006,10 +1160,13 @@ HRESULT CArchiveExtractCallback::CheckExistFile(FString &fullProcessedPath, bool
/* (fileInfo) can be symbolic link.
we can show final file properties here. */
FILETIME ft1;
FiTime_To_FILETIME(fileInfo.MTime, ft1);
Int32 overwriteResult;
RINOK(_extractCallback2->AskOverwrite(
fs2us(realFullProcessedPath), &fileInfo.MTime, &fileInfo.Size, _item.Path,
_fi.MTimeDefined ? &_fi.MTime : NULL,
fs2us(realFullProcessedPath), &ft1, &fileInfo.Size, _item.Path,
_fi.MTime.Def ? &_fi.MTime.FT : NULL,
_curSizeDefined ? &_curSize : NULL,
&overwriteResult))
@@ -1126,7 +1283,7 @@ HRESULT CArchiveExtractCallback::GetExtractStream(CMyComPtr<ISequentialOutStream
const UInt32 index = _index;
bool isAnti = false;
RINOK(_arc->IsItemAnti(index, isAnti));
RINOK(_arc->IsItem_Anti(index, isAnti));
CorrectPathParts();
UString processedPath (MakePathFromParts(_item.PathParts));
@@ -1147,8 +1304,8 @@ HRESULT CArchiveExtractCallback::GetExtractStream(CMyComPtr<ISequentialOutStream
#ifdef SUPPORT_ALT_STREAMS
if (_item.IsAltStream && _item.ParentIndex != (UInt32)(Int32)-1)
{
int renIndex = _renamedFiles.FindInSorted(CIndexToPathPair(_item.ParentIndex));
if (renIndex >= 0)
const int renIndex = _renamedFiles.FindInSorted(CIndexToPathPair(_item.ParentIndex));
if (renIndex != -1)
{
const CIndexToPathPair &pair = _renamedFiles[(unsigned)renIndex];
fullProcessedPath = pair.Path;
@@ -1224,8 +1381,8 @@ HRESULT CArchiveExtractCallback::GetExtractStream(CMyComPtr<ISequentialOutStream
RINOK(Archive_Get_HardLinkNode(archive, index, h, defined));
if (defined)
{
int linkIndex = _hardLinks.IDs.FindInSorted2(h);
if (linkIndex >= 0)
const int linkIndex = _hardLinks.IDs.FindInSorted2(h);
if (linkIndex != -1)
{
FString &hl = _hardLinks.Links[(unsigned)linkIndex];
if (hl.IsEmpty())
@@ -1733,11 +1890,34 @@ HRESULT CArchiveExtractCallback::CloseFile()
_curSize = processedSize;
_curSizeDefined = true;
#if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX)
if (ZoneBuf.Size() != 0
&& !_item.IsAltStream)
{
// if (NFind::DoesFileExist_Raw(tempFilePath))
if (ZoneMode != NExtract::NZoneIdMode::kOffice ||
FindExt2(kOfficeExtensions, _diskFilePath))
{
// we must write zone file before setting of timestamps
const FString path = _diskFilePath + k_ZoneId_StreamName;
if (!WriteZoneFile(path, ZoneBuf))
{
// we can't write it in FAT
// SendMessageError_with_LastError("Can't write Zone.Identifier stream", path);
}
}
}
#endif
CFiTimesCAM t;
GetFiTimesCAM(t);
// #ifdef _WIN32
_outFileStreamSpec->SetTime(
(WriteCTime && _fi.CTimeDefined) ? &_fi.CTime : NULL,
(WriteATime && _fi.ATimeDefined) ? &_fi.ATime : NULL,
(WriteMTime && _fi.MTimeDefined) ? &_fi.MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL));
if (t.IsSomeTimeDefined())
_outFileStreamSpec->SetTime(
t.CTime_Defined ? &t.CTime : NULL,
t.ATime_Defined ? &t.ATime : NULL,
t.MTime_Defined ? &t.MTime : NULL);
// #endif
RINOK(_outFileStreamSpec->Close());
@@ -2065,19 +2245,30 @@ HRESULT CArchiveExtractCallback::CloseReparseAndFile()
void CArchiveExtractCallback::SetAttrib()
{
#ifndef _WIN32
#ifndef _WIN32
// Linux now doesn't support permissions for symlinks
if (_isSymLinkCreated)
return;
#endif
#endif
if (_itemFailure
|| _diskFilePath.IsEmpty()
|| _stdOutMode
|| !_extractMode
|| !_fi.AttribDefined)
|| !_extractMode)
return;
#ifndef _WIN32
if (_fi.Owner.Id_Defined &&
_fi.Group.Id_Defined)
{
if (my_chown(_diskFilePath, _fi.Owner.Id, _fi.Group.Id) != 0)
{
SendMessageError_with_LastError("Cannot set owner", _diskFilePath);
}
}
#endif
if (_fi.Attrib_Defined)
{
// const AString s = GetAnsiString(_diskFilePath);
// printf("\nSetFileAttrib_PosixHighDetect: %s: hex:%x\n", s.Ptr(), _fi.Attrib);
@@ -2276,7 +2467,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream2(UInt32 index, ISequentialInStre
CInFileStream *inStreamSpec = new CInFileStream;
CMyComPtr<ISequentialInStream> inStreamRef = inStreamSpec;
inStreamSpec->File.PreserveATime = _ntOptions.PreserveATime;
inStreamSpec->Set_PreserveATime(_ntOptions.PreserveATime);
if (!inStreamSpec->OpenShared(fullProcessedPath, _ntOptions.OpenShareForWrite))
{
RINOK(SendMessageError_with_LastError(kCantOpenInFile, fullProcessedPath));
@@ -2318,9 +2509,9 @@ void CDirPathSortPair::SetNumSlashes(const FChar *s)
bool CDirPathTime::SetDirTime() const
{
return NDir::SetDirTime(Path,
CTimeDefined ? &CTime : NULL,
ATimeDefined ? &ATime : NULL,
MTimeDefined ? &MTime : NULL);
CTime_Defined ? &CTime : NULL,
ATime_Defined ? &ATime : NULL,
MTime_Defined ? &MTime : NULL);
}

View File

@@ -60,6 +60,8 @@ struct CExtractNtOptions
bool ReplaceColonForAltStream;
bool WriteToAltStreamIfColon;
bool ExtractOwner;
bool PreAllocateOutFile;
// used for hash arcs only, when we open external files
@@ -69,6 +71,7 @@ struct CExtractNtOptions
CExtractNtOptions():
ReplaceColonForAltStream(false),
WriteToAltStreamIfColon(false),
ExtractOwner(false),
PreserveATime(false),
OpenShareForWrite(false)
{
@@ -163,16 +166,27 @@ struct CIndexToPathPair
struct CDirPathTime
struct CFiTimesCAM
{
FILETIME CTime;
FILETIME ATime;
FILETIME MTime;
CFiTime CTime;
CFiTime ATime;
CFiTime MTime;
bool CTimeDefined;
bool ATimeDefined;
bool MTimeDefined;
bool CTime_Defined;
bool ATime_Defined;
bool MTime_Defined;
bool IsSomeTimeDefined() const
{
return
CTime_Defined |
ATime_Defined |
MTime_Defined;
}
};
struct CDirPathTime: public CFiTimesCAM
{
FString Path;
bool SetDirTime() const;
@@ -216,6 +230,25 @@ struct CLinkInfo
#endif // SUPPORT_LINKS
#ifndef _WIN32
struct COwnerInfo
{
bool Id_Defined;
UInt32 Id;
AString Name;
void Clear()
{
Id_Defined = false;
Id = 0;
Name.Empty();
}
};
#endif
class CArchiveExtractCallback:
public IArchiveExtractCallback,
public IArchiveExtractCallbackMessage,
@@ -256,32 +289,33 @@ class CArchiveExtractCallback:
bool _extractMode;
bool WriteCTime;
bool WriteATime;
bool WriteMTime;
bool Write_CTime;
bool Write_ATime;
bool Write_MTime;
bool _encrypted;
struct CProcessedFileInfo
{
FILETIME CTime;
FILETIME ATime;
FILETIME MTime;
CArcTime CTime;
CArcTime ATime;
CArcTime MTime;
UInt32 Attrib;
bool CTimeDefined;
bool ATimeDefined;
bool MTimeDefined;
bool AttribDefined;
bool Attrib_Defined;
#ifndef _WIN32
COwnerInfo Owner;
COwnerInfo Group;
#endif
bool IsReparse() const
{
return (AttribDefined && (Attrib & FILE_ATTRIBUTE_REPARSE_POINT) != 0);
return (Attrib_Defined && (Attrib & FILE_ATTRIBUTE_REPARSE_POINT) != 0);
}
bool IsLinuxSymLink() const
{
return (AttribDefined && MY_LIN_S_ISLNK(Attrib >> 16));
return (Attrib_Defined && MY_LIN_S_ISLNK(Attrib >> 16));
}
void SetFromPosixAttrib(UInt32 a)
@@ -294,10 +328,14 @@ class CArchiveExtractCallback:
FILE_ATTRIBUTE_ARCHIVE;
if ((a & 0222) == 0) // (& S_IWUSR) in p7zip
Attrib |= FILE_ATTRIBUTE_READONLY;
// 22.00 : we need type bits for (MY_LIN_S_IFLNK) for IsLinuxSymLink()
a &= MY_LIN_S_IFMT;
if (a == MY_LIN_S_IFLNK)
Attrib |= (a << 16);
#else
Attrib = (a << 16) | FILE_ATTRIBUTE_UNIX_EXTENSION;
#endif
AttribDefined = true;
Attrib_Defined = true;
}
} _fi;
@@ -359,7 +397,7 @@ class CArchiveExtractCallback:
#endif
void CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath);
HRESULT GetTime(UInt32 index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined);
HRESULT GetTime(UInt32 index, PROPID propID, CArcTime &ft);
HRESULT GetUnpackSize();
FString Hash_GetFullFilePath();
@@ -372,6 +410,10 @@ public:
HRESULT SendMessageError2(HRESULT errorCode, const char *message, const FString &path1, const FString &path2);
public:
#if defined(_WIN32) && !defined(UNDER_CE)
NExtract::NZoneIdMode::EEnum ZoneMode;
CByteBuffer ZoneBuf;
#endif
CLocalProgress *LocalProgressSpec;
@@ -405,11 +447,17 @@ public:
void InitForMulti(bool multiArchives,
NExtract::NPathMode::EEnum pathMode,
NExtract::NOverwriteMode::EEnum overwriteMode,
NExtract::NZoneIdMode::EEnum zoneMode,
bool keepAndReplaceEmptyDirPrefixes)
{
_multiArchives = multiArchives;
_pathMode = pathMode;
_overwriteMode = overwriteMode;
#if defined(_WIN32) && !defined(UNDER_CE)
ZoneMode = zoneMode;
#else
UNUSED_VAR(zoneMode)
#endif
_keepAndReplaceEmptyDirPrefixes = keepAndReplaceEmptyDirPrefixes;
NumFolders = NumFiles = NumAltStreams = UnpackSize = AltStreams_UnpackSize = 0;
}
@@ -427,6 +475,8 @@ public:
#endif
void InitBeforeNewArchive();
void Init(
const CExtractNtOptions &ntOptions,
const NWildcard::CCensorNode *wildcardCensor,
@@ -483,6 +533,7 @@ private:
HRESULT Read_fi_Props();
void CorrectPathParts();
void GetFiTimesCAM(CFiTimesCAM &pt);
void CreateFolders();
bool _isRenamed;
@@ -533,4 +584,6 @@ struct CArchiveExtractCallback_Closer
bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item);
void ReadZoneFile_Of_BaseFile(CFSTR fileName2, CByteBuffer &buf);
#endif

View File

@@ -34,7 +34,8 @@ STDMETHODIMP COpenCallbackImp::SetCompleted(const UInt64 *files, const UInt64 *b
return Callback->Open_SetCompleted(files, bytes);
COM_TRY_END
}
STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
@@ -51,10 +52,11 @@ STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)
case kpidName: prop = fs2us(_fileInfo.Name); break;
case kpidIsDir: prop = _fileInfo.IsDir(); break;
case kpidSize: prop = _fileInfo.Size; break;
case kpidAttrib: prop = (UInt32)_fileInfo.Attrib; break;
case kpidCTime: prop = _fileInfo.CTime; break;
case kpidATime: prop = _fileInfo.ATime; break;
case kpidMTime: prop = _fileInfo.MTime; break;
case kpidAttrib: prop = (UInt32)_fileInfo.GetWinAttrib(); break;
case kpidPosixAttrib: prop = (UInt32)_fileInfo.GetPosixAttrib(); break;
case kpidCTime: PropVariant_SetFrom_FiTime(prop, _fileInfo.CTime); break;
case kpidATime: PropVariant_SetFrom_FiTime(prop, _fileInfo.ATime); break;
case kpidMTime: PropVariant_SetFrom_FiTime(prop, _fileInfo.MTime); break;
}
prop.Detach(value);
return S_OK;

View File

@@ -334,7 +334,7 @@ static void ExtractGroupCommand(const UStringVector &arcPaths, UString &params,
ErrorMessageHRESULT(result);
}
void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog, bool elimDup)
void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog, bool elimDup, UInt32 writeZone)
{
MY_TRY_BEGIN
UString params ('x');
@@ -345,6 +345,11 @@ void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bo
}
if (elimDup)
params += " -spe";
if (writeZone != (UInt32)(Int32)-1)
{
params += " -snz";
params.Add_UInt32(writeZone);
}
if (showDialog)
params += kShowDialogSwitch;
ExtractGroupCommand(arcPaths, params, false);

View File

@@ -15,7 +15,7 @@ HRESULT CompressFiles(
const UStringVector &names,
bool email, bool showDialog, bool waitFinish);
void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog, bool elimDup);
void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog, bool elimDup, UInt32 writeZone);
void TestArchives(const UStringVector &arcPaths, bool hashMode = false);
void CalcChecksum(const UStringVector &paths,

View File

@@ -152,19 +152,12 @@ HRESULT CompressFiles(
static HRESULT ExtractGroupCommand(const UStringVector &arcPaths,
bool showDialog, const UString &outFolder, bool testMode, bool elimDup = false,
const char *kType = NULL)
bool showDialog, CExtractOptions &eo, const char *kType = NULL)
{
MY_TRY_BEGIN
CREATE_CODECS
CExtractOptions eo;
eo.OutputDir = us2fs(outFolder);
eo.TestMode = testMode;
eo.ElimDup.Val = elimDup;
eo.ElimDup.Def = elimDup;
CExtractCallbackImp *ecs = new CExtractCallbackImp;
CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
@@ -228,15 +221,26 @@ static HRESULT ExtractGroupCommand(const UStringVector &arcPaths,
return result;
}
void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog, bool elimDup)
void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder,
bool showDialog, bool elimDup, UInt32 writeZone)
{
ExtractGroupCommand(arcPaths, showDialog, outFolder, false, elimDup);
CExtractOptions eo;
eo.OutputDir = us2fs(outFolder);
eo.TestMode = false;
eo.ElimDup.Val = elimDup;
eo.ElimDup.Def = elimDup;
if (writeZone != (UInt32)(Int32)-1)
eo.ZoneMode = (NExtract::NZoneIdMode::EEnum)writeZone;
ExtractGroupCommand(arcPaths, showDialog, eo);
}
void TestArchives(const UStringVector &arcPaths, bool hashMode)
{
ExtractGroupCommand(arcPaths, true, UString(), true,
false, // elimDup
CExtractOptions eo;
eo.TestMode = true;
ExtractGroupCommand(arcPaths,
true, // showDialog
eo,
hashMode ? "hash" : NULL);
}

View File

@@ -10,6 +10,8 @@
#include "../../../Common/MyString.h"
#include "../../../Windows/FileFind.h"
#include "../../../Windows/PropVariant.h"
#include "../../../Windows/TimeUtils.h"
#include "../../Common/UniqBlocks.h"
@@ -80,50 +82,213 @@ struct IDirItemsCallback
INTERFACE_IDirItemsCallback(=0)
};
struct CDirItem
struct CArcTime
{
FILETIME FT;
UInt16 Prec;
Byte Ns100;
bool Def;
CArcTime()
{
Clear();
}
void Clear()
{
FT.dwHighDateTime = FT.dwLowDateTime = 0;
Prec = 0;
Ns100 = 0;
Def = false;
}
bool IsZero() const
{
return FT.dwLowDateTime == 0 && FT.dwHighDateTime == 0 && Ns100 == 0;
}
int CompareWith(const CArcTime &a) const
{
const int res = CompareFileTime(&FT, &a.FT);
if (res != 0)
return res;
if (Ns100 < a.Ns100) return -1;
if (Ns100 > a.Ns100) return 1;
return 0;
}
UInt64 Get_FILETIME_as_UInt64() const
{
return (((UInt64)FT.dwHighDateTime) << 32) + FT.dwLowDateTime;
}
UInt32 Get_DosTime() const
{
FILETIME ft2 = FT;
if ((Prec == k_PropVar_TimePrec_Base + 8 ||
Prec == k_PropVar_TimePrec_Base + 9)
&& Ns100 != 0)
{
UInt64 u64 = Get_FILETIME_as_UInt64();
// we round up even small (ns < 100ns) as FileTimeToDosTime()
if (u64 % 20000000 == 0)
{
u64++;
ft2.dwHighDateTime = (DWORD)(u64 >> 32);
ft2.dwHighDateTime = (DWORD)u64;
}
}
// FileTimeToDosTime() is expected to round up in Windows
UInt32 dosTime;
// we use simplified code with utctime->dos.
// do we need local time instead here?
NWindows::NTime::FileTime_To_DosTime(ft2, dosTime);
return dosTime;
}
int GetNumDigits() const
{
if (Prec == k_PropVar_TimePrec_Unix ||
Prec == k_PropVar_TimePrec_DOS)
return 0;
if (Prec == k_PropVar_TimePrec_HighPrec)
return 9;
if (Prec == k_PropVar_TimePrec_0)
return 7;
int digits = (int)Prec - (int)k_PropVar_TimePrec_Base;
if (digits < 0)
digits = 0;
return digits;
}
void Write_To_FiTime(CFiTime &dest) const
{
#ifdef _WIN32
dest = FT;
#else
if (FILETIME_To_timespec(FT, dest))
if ((Prec == k_PropVar_TimePrec_Base + 8 ||
Prec == k_PropVar_TimePrec_Base + 9)
&& Ns100 != 0)
{
dest.tv_nsec += Ns100;
}
#endif
}
// (Def) is not set
void Set_From_FILETIME(const FILETIME &ft)
{
FT = ft;
// Prec = k_PropVar_TimePrec_CompatNTFS;
Prec = k_PropVar_TimePrec_Base + 7;
Ns100 = 0;
}
// (Def) is not set
// it set full form precision: k_PropVar_TimePrec_Base + numDigits
void Set_From_FiTime(const CFiTime &ts)
{
#ifdef _WIN32
FT = ts;
Prec = k_PropVar_TimePrec_Base + 7;
// Prec = k_PropVar_TimePrec_Base; // for debug
// Prec = 0; // for debug
Ns100 = 0;
#else
unsigned ns100;
FiTime_To_FILETIME_ns100(ts, FT, ns100);
Ns100 = (Byte)ns100;
Prec = k_PropVar_TimePrec_Base + 9;
#endif
}
void Set_From_Prop(const PROPVARIANT &prop)
{
FT = prop.filetime;
unsigned prec = 0;
unsigned ns100 = 0;
const unsigned prec_Temp = prop.wReserved1;
if (prec_Temp != 0
&& prec_Temp <= k_PropVar_TimePrec_1ns
&& prop.wReserved3 == 0)
{
const unsigned ns100_Temp = prop.wReserved2;
if (ns100_Temp < 100)
{
ns100 = ns100_Temp;
prec = prec_Temp;
}
}
Prec = (UInt16)prec;
Ns100 = (Byte)ns100;
Def = true;
}
};
struct CDirItem: public NWindows::NFile::NFind::CFileInfoBase
{
UInt64 Size;
FILETIME CTime;
FILETIME ATime;
FILETIME MTime;
UString Name;
#ifndef UNDER_CE
#ifndef UNDER_CE
CByteBuffer ReparseData;
#ifdef _WIN32
#ifdef _WIN32
// UString ShortName;
CByteBuffer ReparseData2; // fixed (reduced) absolute links for WIM format
bool AreReparseData() const { return ReparseData.Size() != 0 || ReparseData2.Size() != 0; }
#else
#else
bool AreReparseData() const { return ReparseData.Size() != 0; }
#endif // _WIN32
#endif // _WIN32
#endif // !UNDER_CE
#endif // !UNDER_CE
UInt32 Attrib;
void Copy_From_FileInfoBase(const NWindows::NFile::NFind::CFileInfoBase &fi)
{
(NWindows::NFile::NFind::CFileInfoBase &)*this = fi;
}
int PhyParent;
int LogParent;
int SecureIndex;
bool IsAltStream;
CDirItem(): PhyParent(-1), LogParent(-1), SecureIndex(-1), IsAltStream(false) {}
bool IsDir() const { return (Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0; }
bool IsReadOnly() const { return (Attrib & FILE_ATTRIBUTE_READONLY) != 0; }
bool Has_Attrib_ReparsePoint() const { return (Attrib & FILE_ATTRIBUTE_REPARSE_POINT) != 0; }
#ifdef _WIN32
#else
int OwnerNameIndex;
int OwnerGroupIndex;
#endif
#ifdef _WIN32
UInt32 GetPosixAttrib() const
CDirItem():
PhyParent(-1)
, LogParent(-1)
, SecureIndex(-1)
#ifdef _WIN32
#else
, OwnerNameIndex(-1)
, OwnerGroupIndex(-1)
#endif
{
UInt32 v = IsDir() ? MY_LIN_S_IFDIR : MY_LIN_S_IFREG;
/* 21.06: as WSL we allow write permissions (0222) for directories even for (FILE_ATTRIBUTE_READONLY).
So extracting at Linux will be allowed to write files inside (0777) directories. */
v |= ((IsReadOnly() && !IsDir()) ? 0555 : 0777);
return v;
}
#endif
CDirItem(const NWindows::NFile::NFind::CFileInfo &fi,
int phyParent, int logParent, int secureIndex):
CFileInfoBase(fi)
, Name(fs2us(fi.Name))
#if defined(_WIN32) && !defined(UNDER_CE)
// , ShortName(fs2us(fi.ShortName))
#endif
, PhyParent(phyParent)
, LogParent(logParent)
, SecureIndex(secureIndex)
#ifdef _WIN32
#else
, OwnerNameIndex(-1)
, OwnerGroupIndex(-1)
#endif
{}
};
@@ -145,6 +310,7 @@ public:
bool ScanAltStreams;
bool ExcludeDirItems;
bool ExcludeFileItems;
bool ShareForWrite;
/* it must be called after anotrher checks */
bool CanIncludeItem(bool isDir) const
@@ -160,7 +326,7 @@ public:
const FString &phyPrefix);
#endif
#if defined(_WIN32) && !defined(UNDER_CE)
#if defined(_WIN32) && !defined(UNDER_CE)
CUniqBlocks SecureBlocks;
CByteBuffer TempSecureBuf;
@@ -170,7 +336,17 @@ public:
HRESULT AddSecurityItem(const FString &path, int &secureIndex);
HRESULT FillFixedReparse();
#endif
#endif
#ifndef _WIN32
C_UInt32_UString_Map OwnerNameMap;
C_UInt32_UString_Map OwnerGroupMap;
bool StoreOwnerName;
HRESULT FillDeviceSizes();
#endif
IDirItemsCallback *Callback;
@@ -204,20 +380,25 @@ public:
};
struct CArcItem
{
UInt64 Size;
FILETIME MTime;
UString Name;
CArcTime MTime; // it can be mtime of archive file, if MTime is not defined for item in archive
bool IsDir;
bool IsAltStream;
bool SizeDefined;
bool MTimeDefined;
bool Size_Defined;
bool Censored;
UInt32 IndexInServer;
int TimeType;
CArcItem(): IsDir(false), IsAltStream(false), SizeDefined(false), MTimeDefined(false), Censored(false), TimeType(-1) {}
CArcItem():
IsDir(false),
IsAltStream(false),
Size_Defined(false),
Censored(false)
{}
};
#endif

View File

@@ -5,6 +5,12 @@
#include <wchar.h>
// #include <stdio.h>
#ifndef _WIN32
#include <grp.h>
#include <pwd.h>
#include "../../../Common/UTFConvert.h"
#endif
#include "../../../Common/Wildcard.h"
#include "../../../Windows/FileDir.h"
@@ -23,32 +29,60 @@ using namespace NWindows;
using namespace NFile;
using namespace NName;
static bool FindFile_KeepDots(NFile::NFind::CFileInfo &fi, const FString &path, bool followLink)
{
const bool res = fi.Find(path, followLink);
if (!res)
return res;
if (path.IsEmpty())
return res;
// we keep name "." and "..", if it's without tail slash
const FChar *p = path.RightPtr(1);
if (*p != '.')
return res;
if (p != path.Ptr())
{
FChar c = p[-1];
if (!IS_PATH_SEPAR(c))
{
if (c != '.')
return res;
p--;
if (p != path.Ptr())
{
c = p[-1];
if (!IS_PATH_SEPAR(c))
return res;
}
}
}
fi.Name = p;
return res;
}
void CDirItems::AddDirFileInfo(int phyParent, int logParent, int secureIndex,
const NFind::CFileInfo &fi)
{
CDirItem di;
di.Size = fi.Size;
di.CTime = fi.CTime;
di.ATime = fi.ATime;
di.MTime = fi.MTime;
di.Attrib = fi.Attrib;
di.IsAltStream = fi.IsAltStream;
/*
CDirItem di(fi);
di.PhyParent = phyParent;
di.LogParent = logParent;
di.SecureIndex = secureIndex;
di.Name = fs2us(fi.Name);
#if defined(_WIN32) && !defined(UNDER_CE)
// di.ShortName = fs2us(fi.ShortName);
#endif
Items.Add(di);
*/
VECTOR_ADD_NEW_OBJECT (Items, CDirItem(fi, phyParent, logParent, secureIndex))
if (fi.IsDir())
Stat.NumDirs++;
#ifdef _WIN32
else if (fi.IsAltStream)
{
Stat.NumAltStreams++;
Stat.AltStreamsSize += fi.Size;
}
#endif
else
{
Stat.NumFiles++;
@@ -148,9 +182,13 @@ CDirItems::CDirItems():
ScanAltStreams(false)
, ExcludeDirItems(false)
, ExcludeFileItems(false)
#ifdef _USE_SECURITY_CODE
, ShareForWrite(false)
#ifdef _USE_SECURITY_CODE
, ReadSecure(false)
#endif
#endif
#ifndef _WIN32
, StoreOwnerName(true)
#endif
, Callback(NULL)
{
#ifdef _USE_SECURITY_CODE
@@ -379,7 +417,7 @@ HRESULT CDirItems::EnumerateItems2(
const FString &filePath = filePaths[i];
NFind::CFileInfo fi;
const FString phyPath = phyPrefix + filePath;
if (!fi.Find(phyPath FOLLOW_LINK_PARAM))
if (!FindFile_KeepDots(fi, phyPath FOLLOW_LINK_PARAM))
{
RINOK(AddError(phyPath));
continue;
@@ -658,15 +696,14 @@ static HRESULT EnumerateForItem(
if (!enterToSubFolders)
return S_OK;
#ifndef _WIN32
#ifndef _WIN32
if (fi.IsPosixLink())
{
// here we can try to resolve posix link
// if the link to dir, then can we follow it
return S_OK; // we don't follow posix link
}
#endif
#else
if (dirItems.SymLinks && fi.HasReparsePoint())
{
/* 20.03: in SymLinks mode: we don't enter to directory that
@@ -677,6 +714,7 @@ static HRESULT EnumerateForItem(
*/
return S_OK;
}
#endif
nextNode = &curNode;
}
@@ -826,7 +864,7 @@ static HRESULT EnumerateDirItems(
}
else
#endif
if (!fi.Find(fullPath FOLLOW_LINK_PARAM2))
if (!FindFile_KeepDots(fi, fullPath FOLLOW_LINK_PARAM2))
{
RINOK(dirItems.AddError(fullPath));
continue;
@@ -914,15 +952,14 @@ static HRESULT EnumerateDirItems(
}
else
{
#ifndef _WIN32
#ifndef _WIN32
if (fi.IsPosixLink())
{
// here we can try to resolve posix link
// if the link to dir, then can we follow it
continue; // we don't follow posix link
}
#endif
#else
if (dirItems.SymLinks)
{
if (fi.HasReparsePoint())
@@ -932,6 +969,7 @@ static HRESULT EnumerateDirItems(
continue;
}
}
#endif
nextNode = &curNode;
newParts.Add(name); // don't change it to fi.Name. It's for shortnames support
}
@@ -973,7 +1011,7 @@ static HRESULT EnumerateDirItems(
}
else
{
if (!fi.Find(fullPath FOLLOW_LINK_PARAM2))
if (!FindFile_KeepDots(fi, fullPath FOLLOW_LINK_PARAM2))
{
if (!nextNode.AreThereIncludeItems())
continue;
@@ -1136,15 +1174,18 @@ HRESULT EnumerateItems(
}
dirItems.ReserveDown();
#if defined(_WIN32) && !defined(UNDER_CE)
#if defined(_WIN32) && !defined(UNDER_CE)
RINOK(dirItems.FillFixedReparse());
#endif
#endif
#ifndef _WIN32
RINOK(dirItems.FillDeviceSizes());
#endif
return S_OK;
}
#if defined(_WIN32) && !defined(UNDER_CE)
HRESULT CDirItems::FillFixedReparse()
@@ -1281,6 +1322,148 @@ HRESULT CDirItems::FillFixedReparse()
#endif
#ifndef _WIN32
HRESULT CDirItems::FillDeviceSizes()
{
{
FOR_VECTOR (i, Items)
{
CDirItem &item = Items[i];
if (S_ISBLK(item.mode) && item.Size == 0)
{
const FString phyPath = GetPhyPath(i);
NIO::CInFile inFile;
inFile.PreserveATime = true;
if (inFile.OpenShared(phyPath, ShareForWrite)) // fixme: OpenShared ??
{
UInt64 size = 0;
if (inFile.GetLength(size))
item.Size = size;
}
}
if (StoreOwnerName)
{
OwnerNameMap.Add_UInt32(item.uid);
OwnerGroupMap.Add_UInt32(item.gid);
}
}
}
if (StoreOwnerName)
{
UString u;
AString a;
{
FOR_VECTOR (i, OwnerNameMap.Numbers)
{
// 200K/sec speed
u.Empty();
const passwd *pw = getpwuid(OwnerNameMap.Numbers[i]);
if (pw)
{
a = pw->pw_name;
ConvertUTF8ToUnicode(a, u);
}
OwnerNameMap.Strings.Add(u);
}
}
{
FOR_VECTOR (i, OwnerGroupMap.Numbers)
{
u.Empty();
const group *gr = getgrgid(OwnerGroupMap.Numbers[i]);
if (gr)
{
// printf("\ngetgrgid %d %s\n", OwnerGroupMap.Numbers[i], gr->gr_name);
a = gr->gr_name;
ConvertUTF8ToUnicode(a, u);
}
OwnerGroupMap.Strings.Add(u);
}
}
FOR_VECTOR (i, Items)
{
CDirItem &item = Items[i];
{
const int index = OwnerNameMap.Find(item.uid);
if (index < 0) throw 1;
item.OwnerNameIndex = index;
}
{
const int index = OwnerGroupMap.Find(item.gid);
if (index < 0) throw 1;
item.OwnerGroupIndex = index;
}
}
}
// if (NeedOwnerNames)
{
/*
{
for (unsigned i = 0 ; i < 10000; i++)
{
const passwd *pw = getpwuid(i);
if (pw)
{
UString u;
ConvertUTF8ToUnicode(AString(pw->pw_name), u);
OwnerNameMap.Add(i, u);
OwnerNameMap.Add(i, u);
OwnerNameMap.Add(i, u);
}
const group *gr = getgrgid(i);
if (gr)
{
// we can use utf-8 here.
UString u;
ConvertUTF8ToUnicode(AString(gr->gr_name), u);
OwnerGroupMap.Add(i, u);
}
}
}
*/
/*
{
FOR_VECTOR (i, OwnerNameMap.Strings)
{
AString s;
ConvertUnicodeToUTF8(OwnerNameMap.Strings[i], s);
printf("\n%5d %s", (unsigned)OwnerNameMap.Numbers[i], s.Ptr());
}
}
{
printf("\n\n=========Groups\n");
FOR_VECTOR (i, OwnerGroupMap.Strings)
{
AString s;
ConvertUnicodeToUTF8(OwnerGroupMap.Strings[i], s);
printf("\n%5d %s", (unsigned)OwnerGroupMap.Numbers[i], s.Ptr());
}
}
*/
}
/*
for (unsigned i = 0 ; i < 100000000; i++)
{
// const passwd *pw = getpwuid(1000);
// pw = pw;
int pos = OwnerNameMap.Find(1000);
if (pos < 0 - (int)i)
throw 1;
}
*/
return S_OK;
}
#endif
static const char * const kCannotFindArchive = "Cannot find archive";
@@ -1351,11 +1534,18 @@ HRESULT EnumerateDirItemsAndSort(
#ifdef _WIN32
static bool IsDotsName(const wchar_t *s)
{
return s[0] == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0));
}
// This code converts all short file names to long file names.
static void ConvertToLongName(const UString &prefix, UString &name)
{
if (name.IsEmpty() || DoesNameContainWildcard(name))
if (name.IsEmpty()
|| DoesNameContainWildcard(name)
|| IsDotsName(name))
return;
NFind::CFileInfo fi;
const FString path (us2fs(prefix + name));

View File

@@ -239,18 +239,18 @@ static HRESULT DecompressArchive(
Sorted list for file paths was sorted with case insensitive compare function.
But FindInSorted function did binary search via case sensitive compare function */
int Find_FileName_InSortedVector(const UStringVector &fileName, const UString &name);
int Find_FileName_InSortedVector(const UStringVector &fileName, const UString &name)
int Find_FileName_InSortedVector(const UStringVector &fileNames, const UString &name);
int Find_FileName_InSortedVector(const UStringVector &fileNames, const UString &name)
{
unsigned left = 0, right = fileName.Size();
unsigned left = 0, right = fileNames.Size();
while (left != right)
{
unsigned mid = (left + right) / 2;
const UString &midValue = fileName[mid];
int compare = CompareFileNames(name, midValue);
if (compare == 0)
const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
const UString &midVal = fileNames[mid];
const int comp = CompareFileNames(name, midVal);
if (comp == 0)
return (int)mid;
if (compare < 0)
if (comp < 0)
right = mid;
else
left = mid + 1;
@@ -314,8 +314,13 @@ HRESULT Extract(
CArchiveExtractCallback *ecs = new CArchiveExtractCallback;
CMyComPtr<IArchiveExtractCallback> ec(ecs);
bool multi = (numArcs > 1);
ecs->InitForMulti(multi, options.PathMode, options.OverwriteMode,
const bool multi = (numArcs > 1);
ecs->InitForMulti(multi,
options.PathMode,
options.OverwriteMode,
options.ZoneMode,
false // keepEmptyDirParts
);
#ifndef _SFX
@@ -335,12 +340,18 @@ HRESULT Extract(
if (skipArcs[i])
continue;
ecs->InitBeforeNewArchive();
const UString &arcPath = arcPaths[i];
NFind::CFileInfo fi;
if (options.StdInMode)
{
fi.Size = 0;
fi.Attrib = 0;
// do we need ctime and mtime?
fi.ClearBase();
fi.Size = 0; // (UInt64)(Int64)-1;
fi.SetAsFile();
// NTime::GetCurUtc_FiTime(fi.MTime);
// fi.CTime = fi.ATime = fi.MTime;
}
else
{
@@ -417,6 +428,15 @@ HRESULT Extract(
continue;
}
#if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX)
if (options.ZoneMode != NExtract::NZoneIdMode::kNone
&& !options.StdInMode)
{
ReadZoneFile_Of_BaseFile(us2fs(arcPath), ecs->ZoneBuf);
}
#endif
if (arcLink.Arcs.Size() != 0)
{
if (arcLink.GetArc()->IsHashHandler(op))
@@ -490,11 +510,16 @@ HRESULT Extract(
*/
CArc &arc = arcLink.Arcs.Back();
arc.MTimeDefined = (!options.StdInMode && !fi.IsDevice);
arc.MTime = fi.MTime;
arc.MTime.Def = !options.StdInMode
#ifdef _WIN32
&& !fi.IsDevice
#endif
;
if (arc.MTime.Def)
arc.MTime.Set_From_FiTime(fi.MTime);
UInt64 packProcessed;
bool calcCrc =
const bool calcCrc =
#ifndef _SFX
(hash != NULL);
#else

View File

@@ -25,6 +25,7 @@ struct CExtractOptionsBase
bool OverwriteMode_Force;
NExtract::NPathMode::EEnum PathMode;
NExtract::NOverwriteMode::EEnum OverwriteMode;
NExtract::NZoneIdMode::EEnum ZoneMode;
FString OutputDir;
CExtractNtOptions NtOptions;
@@ -36,7 +37,8 @@ struct CExtractOptionsBase
PathMode_Force(false),
OverwriteMode_Force(false),
PathMode(NExtract::NPathMode::kFullPaths),
OverwriteMode(NExtract::NOverwriteMode::kAsk)
OverwriteMode(NExtract::NOverwriteMode::kAsk),
ZoneMode(NExtract::NZoneIdMode::kNone)
{}
};

View File

@@ -29,6 +29,16 @@ namespace NOverwriteMode
};
}
namespace NZoneIdMode
{
enum EEnum
{
kNone,
kAll,
kOffice
};
}
}
#endif

View File

@@ -34,10 +34,19 @@ static void ReplaceIncorrectChars(UString &s)
||
#endif
c == WCHAR_PATH_SEPARATOR)
{
#if WCHAR_PATH_SEPARATOR != L'/'
// 22.00 : WSL replacement for backslash
if (c == WCHAR_PATH_SEPARATOR)
c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT;
else
#endif
c = '_';
s.ReplaceOneCharAtPos(i,
'_' // default
c
// (wchar_t)(0xf000 + c) // 21.02 debug: WSL encoding for unsupported characters
);
}
}
}

View File

@@ -15,6 +15,7 @@
#include "../../Common/StreamUtils.h"
#include "../../Archive/Common/ItemNameUtils.h"
#include "../../Archive/IArchive.h"
#ifdef WANT_OPTIONAL_LOWERCASE
#include "../FileManager/RegistryUtils.h"
@@ -313,8 +314,6 @@ static unsigned GetColumnWidth(unsigned digestSize)
}
void HashHexToString(char *dest, const Byte *data, UInt32 size);
static void AddHashResultLine(
AString &_s,
// bool showHash,
@@ -467,10 +466,7 @@ HRESULT HashCalc(
{
CDirItem di;
di.Size = (UInt64)(Int64)-1;
di.Attrib = 0;
di.MTime.dwLowDateTime = 0;
di.MTime.dwHighDateTime = 0;
di.CTime = di.ATime = di.MTime;
di.SetAsFile();
dirItems.Items.Add(di);
}
else
@@ -482,6 +478,8 @@ HRESULT HashCalc(
dirItems.ExcludeDirItems = censor.ExcludeDirItems;
dirItems.ExcludeFileItems = censor.ExcludeFileItems;
dirItems.ShareForWrite = options.OpenShareForWrite;
HRESULT res = EnumerateItems(censor,
options.PathMode,
UString(),
@@ -502,14 +500,16 @@ HRESULT HashCalc(
// hb.Init();
hb.NumErrors = dirItems.Stat.NumErrors;
UInt64 totalSize = 0;
if (options.StdInMode)
{
RINOK(callback->SetNumFiles(1));
}
else
{
RINOK(callback->SetTotal(dirItems.Stat.GetTotalBytes()));
totalSize = dirItems.Stat.GetTotalBytes();
RINOK(callback->SetTotal(totalSize));
}
const UInt32 kBufSize = 1 << 15;
@@ -541,7 +541,9 @@ HRESULT HashCalc(
{
path = dirItems.GetLogPath(i);
const CDirItem &di = dirItems.Items[i];
#ifdef _WIN32
isAltStream = di.IsAltStream;
#endif
#ifndef UNDER_CE
// if (di.AreReparseData())
@@ -555,7 +557,7 @@ HRESULT HashCalc(
#endif
{
CInFileStream *inStreamSpec = new CInFileStream;
inStreamSpec->File.PreserveATime = options.PreserveATime;
inStreamSpec->Set_PreserveATime(options.PreserveATime);
inStream = inStreamSpec;
isDir = di.IsDir();
if (!isDir)
@@ -569,6 +571,20 @@ HRESULT HashCalc(
return res;
continue;
}
if (!options.StdInMode)
{
UInt64 curSize = 0;
if (inStreamSpec->GetSize(&curSize) == S_OK)
{
if (curSize > di.Size)
{
totalSize += curSize - di.Size;
RINOK(callback->SetTotal(totalSize));
// printf("\ntotal = %d MiB\n", (unsigned)(totalSize >> 20));
}
}
}
// inStreamSpec->ReloadProps();
}
}
}
@@ -584,6 +600,7 @@ HRESULT HashCalc(
{
if ((step & 0xFF) == 0)
{
// printf("\ncompl = %d\n", (unsigned)(completeValue >> 20));
RINOK(callback->SetCompleted(&completeValue));
}
UInt32 size;
@@ -1689,8 +1706,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (_isArc && !CanUpdate())
return E_NOTIMPL;
// const UINT codePage = CP_UTF8; // // (_forceCodePage ? _specifiedCodePage : _openCodePage);
// const unsigned utfFlags = g_Unicode_To_UTF8_Flags;
/*
CMyComPtr<IArchiveUpdateCallbackArcProp> reportArcProp;
callback->QueryInterface(IID_IArchiveUpdateCallbackArcProp, (void **)&reportArcProp);
*/
CObjectVector<CUpdateItem> updateItems;
UInt64 complexity = 0;
@@ -1837,6 +1857,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (ui.NewData)
{
UInt64 currentComplexity = ui.Size;
UInt64 fileSize = 0;
CMyComPtr<ISequentialInStream> fileInStream;
bool needWrite = true;
{
@@ -1850,6 +1872,15 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (fileInStream)
{
CMyComPtr<IStreamGetSize> streamGetSize;
fileInStream->QueryInterface(IID_IStreamGetSize, (void **)&streamGetSize);
if (streamGetSize)
{
UInt64 size;
if (streamGetSize->GetSize(&size) == S_OK)
currentComplexity = size;
}
/*
CMyComPtr<IStreamGetProps> getProps;
fileInStream->QueryInterface(IID_IStreamGetProps, (void **)&getProps);
if (getProps)
@@ -1862,6 +1893,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
// item.MTime = NWindows::NTime::FileTimeToUnixTime64(mTime);;
}
}
*/
}
else
{
@@ -1875,7 +1907,6 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (needWrite && fileInStream && !isDir)
{
UInt64 fileSize = 0;
for (UInt32 step = 0;; step++)
{
if ((step & 0xFF) == 0)
@@ -1911,6 +1942,36 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
}
complexity += currentComplexity;
/*
if (reportArcProp)
{
PROPVARIANT prop;
prop.vt = VT_EMPTY;
prop.wReserved1 = 0;
NCOM::PropVarEm_Set_UInt64(&prop, fileSize);
RINOK(reportArcProp->ReportProp(NArchive::NEventIndexType::kOutArcIndex, ui.IndexInClient, kpidSize, &prop));
for (unsigned k = 0; k < hb.Hashers.Size(); k++)
{
const CHasherState &hs = hb.Hashers[k];
if (hs.DigestSize == 4 && hs.Name.IsEqualTo_Ascii_NoCase("crc32"))
{
NCOM::PropVarEm_Set_UInt32(&prop, GetUi32(hs.Digests[k_HashCalc_Index_Current]));
RINOK(reportArcProp->ReportProp(NArchive::NEventIndexType::kOutArcIndex, ui.IndexInClient, kpidCRC, &prop));
}
else
{
RINOK(reportArcProp->ReportRawProp(NArchive::NEventIndexType::kOutArcIndex, ui.IndexInClient,
kpidChecksum, hs.Digests[k_HashCalc_Index_Current],
hs.DigestSize, NPropDataType::kRaw));
}
RINOK(reportArcProp->ReportFinished(NArchive::NEventIndexType::kOutArcIndex, ui.IndexInClient, NArchive::NUpdate::NOperationResult::kOK));
}
}
*/
RINOK(callback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
}
else

View File

@@ -16,6 +16,12 @@ const unsigned k_HashCalc_DigestSize_Max = 64;
const unsigned k_HashCalc_ExtraSize = 8;
const unsigned k_HashCalc_NumGroups = 4;
/*
if (size <= 8) : upper case : reversed byte order : it shows 32-bit/64-bit number, if data contains little-endian number
if (size > 8) : lower case : original byte order (as big-endian byte sequence)
*/
void HashHexToString(char *dest, const Byte *data, UInt32 size);
enum
{
k_HashCalc_Index_Current,

View File

@@ -33,8 +33,6 @@ EXPORT_CODECS
#include "StdAfx.h"
#include "../../../../C/7zVersion.h"
#include "../../../Common/MyCom.h"
#include "../../../Common/StringToInt.h"
#include "../../../Common/StringConvert.h"
@@ -275,6 +273,9 @@ static HRESULT GetMethodBoolProp(Func_GetMethodProperty getMethodProperty, UInt3
#define MY_GET_FUNC(dest, type, func) *(void **)(&dest) = (func);
// #define MY_GET_FUNC(dest, type, func) dest = (type)(func);
#define MY_GET_FUNC_LOC(dest, type, func) \
type dest; MY_GET_FUNC(dest, type, func)
HRESULT CCodecs::LoadCodecs()
{
CCodecLib &lib = Libs.Back();
@@ -286,8 +287,7 @@ HRESULT CCodecs::LoadCodecs()
if (lib.GetMethodProperty)
{
UInt32 numMethods = 1;
Func_GetNumberOfMethods getNumberOfMethods;
MY_GET_FUNC (getNumberOfMethods, Func_GetNumberOfMethods, lib.Lib.GetProc("GetNumberOfMethods"));
MY_GET_FUNC_LOC (getNumberOfMethods, Func_GetNumberOfMethods, lib.Lib.GetProc("GetNumberOfMethods"));
if (getNumberOfMethods)
{
RINOK(getNumberOfMethods(&numMethods));
@@ -304,8 +304,7 @@ HRESULT CCodecs::LoadCodecs()
}
}
Func_GetHashers getHashers;
MY_GET_FUNC (getHashers, Func_GetHashers, lib.Lib.GetProc("GetHashers"));
MY_GET_FUNC_LOC (getHashers, Func_GetHashers, lib.Lib.GetProc("GetHashers"));
if (getHashers)
{
RINOK(getHashers(&lib.ComHashers));
@@ -414,17 +413,14 @@ HRESULT CCodecs::LoadFormats()
const NDLL::CLibrary &lib = Libs.Back().Lib;
Func_GetHandlerProperty getProp = NULL;
Func_GetHandlerProperty2 getProp2;
MY_GET_FUNC (getProp2, Func_GetHandlerProperty2, lib.GetProc("GetHandlerProperty2"));
Func_GetIsArc getIsArc;
MY_GET_FUNC (getIsArc, Func_GetIsArc, lib.GetProc("GetIsArc"));
MY_GET_FUNC_LOC (getProp2, Func_GetHandlerProperty2, lib.GetProc("GetHandlerProperty2"));
MY_GET_FUNC_LOC (getIsArc, Func_GetIsArc, lib.GetProc("GetIsArc"));
UInt32 numFormats = 1;
if (getProp2)
{
Func_GetNumberOfFormats getNumberOfFormats;
MY_GET_FUNC (getNumberOfFormats, Func_GetNumberOfFormats, lib.GetProc("GetNumberOfFormats"));
MY_GET_FUNC_LOC (getNumberOfFormats, Func_GetNumberOfFormats, lib.GetProc("GetNumberOfFormats"));
if (getNumberOfFormats)
{
RINOK(getNumberOfFormats(&numFormats));
@@ -477,6 +473,11 @@ HRESULT CCodecs::LoadFormats()
item.Flags |= kArcFlagsPars[j + 1];
}
}
{
bool defined = false;
RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kTimeFlags, item.TimeFlags, defined));
}
CByteBuffer sig;
RINOK(GetProp_RawData(getProp, getProp2, i, NArchive::NHandlerPropID::kSignature, sig));
@@ -567,8 +568,7 @@ HRESULT CCodecs::LoadDll(const FString &dllPath, bool needCheckDll, bool *loaded
/*
{
Func_LibStartup _LibStartup;
MY_GET_FUNC (_LibStartup, Func_LibStartup, lib.Lib.GetProc("LibStartup"));
MY_GET_FUNC_LOC (_LibStartup, Func_LibStartup, lib.Lib.GetProc("LibStartup"));
if (_LibStartup)
{
HRESULT res = _LibStartup();
@@ -585,21 +585,31 @@ HRESULT CCodecs::LoadDll(const FString &dllPath, bool needCheckDll, bool *loaded
#ifdef _7ZIP_LARGE_PAGES
if (g_LargePageSize != 0)
{
Func_SetLargePageMode setLargePageMode;
MY_GET_FUNC (setLargePageMode, Func_SetLargePageMode, lib.Lib.GetProc("SetLargePageMode"));
MY_GET_FUNC_LOC (setLargePageMode, Func_SetLargePageMode, lib.Lib.GetProc("SetLargePageMode"));
if (setLargePageMode)
setLargePageMode();
}
#endif
if (CaseSensitiveChange)
if (CaseSensitive_Change)
{
Func_SetCaseSensitive setCaseSensitive;
MY_GET_FUNC (setCaseSensitive, Func_SetCaseSensitive, lib.Lib.GetProc("SetCaseSensitive"));
MY_GET_FUNC_LOC (setCaseSensitive, Func_SetCaseSensitive, lib.Lib.GetProc("SetCaseSensitive"));
if (setCaseSensitive)
setCaseSensitive(CaseSensitive ? 1 : 0);
}
/*
{
MY_GET_FUNC_LOC (setClientVersion, Func_SetClientVersion, lib.Lib.GetProc("SetClientVersion"));
if (setClientVersion)
{
// const UInt32 kVersion = (MY_VER_MAJOR << 16) | MY_VER_MINOR;
setClientVersion(g_ClientVersion);
}
}
*/
MY_GET_FUNC (lib.CreateObject, Func_CreateObject, lib.Lib.GetProc("CreateObject"));
{
unsigned startSize = Codecs.Size() + Hashers.Size();

View File

@@ -96,6 +96,7 @@ struct CArcExtInfo
struct CArcInfoEx
{
UInt32 Flags;
UInt32 TimeFlags;
Func_CreateInArchive CreateInArchive;
Func_IsArc IsArcFunc;
@@ -142,7 +143,7 @@ struct CArcInfoEx
bool Flags_FindSignature() const { return (Flags & NArcInfoFlags::kFindSignature) != 0; }
bool Flags_AltStreams() const { return (Flags & NArcInfoFlags::kAltStreams) != 0; }
bool Flags_NtSecure() const { return (Flags & NArcInfoFlags::kNtSecure) != 0; }
bool Flags_NtSecurity() const { return (Flags & NArcInfoFlags::kNtSecure) != 0; }
bool Flags_SymLinks() const { return (Flags & NArcInfoFlags::kSymLinks) != 0; }
bool Flags_HardLinks() const { return (Flags & NArcInfoFlags::kHardLinks) != 0; }
@@ -154,6 +155,27 @@ struct CArcInfoEx
bool Flags_ByExtOnlyOpen() const { return (Flags & NArcInfoFlags::kByExtOnlyOpen) != 0; }
bool Flags_HashHandler() const { return (Flags & NArcInfoFlags::kHashHandler) != 0; }
bool Flags_CTime() const { return (Flags & NArcInfoFlags::kCTime) != 0; }
bool Flags_ATime() const { return (Flags & NArcInfoFlags::kATime) != 0; }
bool Flags_MTime() const { return (Flags & NArcInfoFlags::kMTime) != 0; }
bool Flags_CTime_Default() const { return (Flags & NArcInfoFlags::kCTime_Default) != 0; }
bool Flags_ATime_Default() const { return (Flags & NArcInfoFlags::kATime_Default) != 0; }
bool Flags_MTime_Default() const { return (Flags & NArcInfoFlags::kMTime_Default) != 0; }
UInt32 Get_TimePrecFlags() const
{
return (TimeFlags >> NArcInfoTimeFlags::kTime_Prec_Mask_bit_index) &
(((UInt32)1 << NArcInfoTimeFlags::kTime_Prec_Mask_num_bits) - 1);
}
UInt32 Get_DefaultTimePrec() const
{
return (TimeFlags >> NArcInfoTimeFlags::kTime_Prec_Default_bit_index) &
(((UInt32)1 << NArcInfoTimeFlags::kTime_Prec_Default_num_bits) - 1);
}
UString GetMainExt() const
{
if (Exts.IsEmpty())
@@ -162,6 +184,15 @@ struct CArcInfoEx
}
int FindExtension(const UString &ext) const;
bool Is_7z() const { return Name.IsEqualTo_Ascii_NoCase("7z"); }
bool Is_Split() const { return Name.IsEqualTo_Ascii_NoCase("Split"); }
bool Is_Xz() const { return Name.IsEqualTo_Ascii_NoCase("xz"); }
bool Is_BZip2() const { return Name.IsEqualTo_Ascii_NoCase("bzip2"); }
bool Is_GZip() const { return Name.IsEqualTo_Ascii_NoCase("gzip"); }
bool Is_Tar() const { return Name.IsEqualTo_Ascii_NoCase("tar"); }
bool Is_Zip() const { return Name.IsEqualTo_Ascii_NoCase("zip"); }
bool Is_Rar() const { return Name.IsEqualTo_Ascii_NoCase("rar"); }
/*
UString GetAllExtensions() const
{
@@ -178,11 +209,10 @@ struct CArcInfoEx
void AddExts(const UString &ext, const UString &addExt);
bool IsSplit() const { return StringsAreEqualNoCase_Ascii(Name, "Split"); }
// bool IsRar() const { return StringsAreEqualNoCase_Ascii(Name, "Rar"); }
CArcInfoEx():
Flags(0),
TimeFlags(0),
CreateInArchive(NULL),
IsArcFunc(NULL)
#ifndef _SFX
@@ -333,14 +363,14 @@ public:
CRecordVector<CDllHasherInfo> Hashers;
#endif
bool CaseSensitiveChange;
bool CaseSensitive_Change;
bool CaseSensitive;
CCodecs():
#ifdef EXTERNAL_CODECS
NeedSetLibCodecs(true),
#endif
CaseSensitiveChange(false),
CaseSensitive_Change(false),
CaseSensitive(false)
{}

View File

@@ -209,8 +209,8 @@ int CHandler::FindInsertPos(const CParseItem &item) const
unsigned left = 0, right = _items.Size();
while (left != right)
{
unsigned mid = (left + right) / 2;
const CParseItem & midItem = _items[mid];
const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
const CParseItem &midItem = _items[mid];
if (item.Offset < midItem.Offset)
right = mid;
else if (item.Offset > midItem.Offset)
@@ -262,8 +262,8 @@ void CHandler::AddUnknownItem(UInt64 next)
void CHandler::AddItem(const CParseItem &item)
{
AddUnknownItem(item.Offset);
int pos = FindInsertPos(item);
if (pos >= 0)
const int pos = FindInsertPos(item);
if (pos != -1)
{
_items.Insert((unsigned)pos, item);
UInt64 next = item.Offset + item.Size;
@@ -482,7 +482,7 @@ HRESULT Archive_IsItem_Deleted(IInArchive *arc, UInt32 index, bool &result) thro
return Archive_GetItemBoolProp(arc, index, kpidIsDeleted, result);
}
static HRESULT Archive_GetArcBoolProp(IInArchive *arc, PROPID propid, bool &result) throw()
static HRESULT Archive_GetArcProp_Bool(IInArchive *arc, PROPID propid, bool &result) throw()
{
NCOM::CPropVariant prop;
result = false;
@@ -532,7 +532,7 @@ static HRESULT Archive_GetArcProp_Int(IInArchive *arc, PROPID propid, Int64 &res
#ifndef _SFX
HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const
HRESULT CArc::GetItem_PathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const
{
if (!GetRawProps)
return E_FAIL;
@@ -616,7 +616,7 @@ HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &pa
HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
HRESULT CArc::GetItem_Path(UInt32 index, UString &result) const
{
#ifdef MY_CPU_LE
if (GetRawProps)
@@ -752,13 +752,13 @@ HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
}
if (result.IsEmpty())
return GetDefaultItemPath(index, result);
return GetItem_DefaultPath(index, result);
Convert_UnicodeEsc16_To_UnicodeEscHigh(result);
return S_OK;
}
HRESULT CArc::GetDefaultItemPath(UInt32 index, UString &result) const
HRESULT CArc::GetItem_DefaultPath(UInt32 index, UString &result) const
{
result.Empty();
bool isDir;
@@ -779,9 +779,9 @@ HRESULT CArc::GetDefaultItemPath(UInt32 index, UString &result) const
return S_OK;
}
HRESULT CArc::GetItemPath2(UInt32 index, UString &result) const
HRESULT CArc::GetItem_Path2(UInt32 index, UString &result) const
{
RINOK(GetItemPath(index, result));
RINOK(GetItem_Path(index, result));
if (Ask_Deleted)
{
bool isDeleted = false;
@@ -833,7 +833,7 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const
RINOK(Archive_IsItem_Dir(Archive, index, item.IsDir));
item.MainIsDir = item.IsDir;
RINOK(GetItemPath2(index, item.Path));
RINOK(GetItem_Path2(index, item.Path));
#ifndef _SFX
UInt32 mainIndex = index;
@@ -885,7 +885,7 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const
}
else
{
RINOK(GetItemPath2(parentIndex, item.MainPath));
RINOK(GetItem_Path2(parentIndex, item.MainPath));
RINOK(Archive_IsItem_Dir(Archive, parentIndex, item.MainIsDir));
}
}
@@ -911,7 +911,7 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const
#ifndef _SFX
if (item._use_baseParentFolder_mode)
{
RINOK(GetItemPathToParent(mainIndex, (unsigned)item._baseParentFolder, item.PathParts));
RINOK(GetItem_PathToParent(mainIndex, (unsigned)item._baseParentFolder, item.PathParts));
#ifdef SUPPORT_ALT_STREAMS
if ((item.WriteToAltStreamIfColon || needFindAltStream) && !item.PathParts.IsEmpty())
@@ -970,7 +970,7 @@ static HRESULT Archive_GetItem_Size(IInArchive *archive, UInt32 index, UInt64 &s
#endif
HRESULT CArc::GetItemSize(UInt32 index, UInt64 &size, bool &defined) const
HRESULT CArc::GetItem_Size(UInt32 index, UInt64 &size, bool &defined) const
{
NCOM::CPropVariant prop;
defined = false;
@@ -989,24 +989,52 @@ HRESULT CArc::GetItemSize(UInt32 index, UInt64 &size, bool &defined) const
return S_OK;
}
HRESULT CArc::GetItemMTime(UInt32 index, FILETIME &ft, bool &defined) const
HRESULT CArc::GetItem_MTime(UInt32 index, CArcTime &at) const
{
at.Clear();
NCOM::CPropVariant prop;
defined = false;
ft.dwHighDateTime = ft.dwLowDateTime = 0;
RINOK(Archive->GetProperty(index, kpidMTime, &prop));
if (prop.vt == VT_FILETIME)
{
ft = prop.filetime;
defined = true;
/*
// for debug
if (FILETIME_IsZero(prop.at) && MTime.Def)
{
at = MTime;
return S_OK;
}
*/
at.Set_From_Prop(prop);
if (at.Prec == 0)
{
// (at.Prec == 0) before version 22.
// so kpidTimeType is required for that code
prop.Clear();
RINOK(Archive->GetProperty(index, kpidTimeType, &prop));
if (prop.vt == VT_UI4)
{
UInt32 val = prop.ulVal;
if (val == NFileTimeType::kWindows)
val = k_PropVar_TimePrec_100ns;
/*
else if (val > k_PropVar_TimePrec_1ns)
{
val = k_PropVar_TimePrec_100ns;
// val = k_PropVar_TimePrec_1ns;
// return E_FAIL; // for debug
}
*/
at.Prec = (UInt16)val;
}
}
return S_OK;
}
else if (prop.vt != VT_EMPTY)
if (prop.vt != VT_EMPTY)
return E_FAIL;
else if (MTimeDefined)
{
ft = MTime;
defined = true;
}
if (MTime.Def)
at = MTime;
return S_OK;
}
@@ -1020,6 +1048,7 @@ static inline bool TestSignature(const Byte *p1, const Byte *p2, size_t size)
return true;
}
static void MakeCheckOrder(CCodecs *codecs,
CIntVector &orderIndices, unsigned numTypes, CIntVector &orderIndices2,
const Byte *data, size_t dataSize)
@@ -1034,7 +1063,7 @@ static void MakeCheckOrder(CCodecs *codecs,
{
if (ai.Signatures.IsEmpty())
{
if (dataSize != 0) // 21.04: no Sinature means Empty Signature
if (dataSize != 0) // 21.04: no Signature means Empty Signature
continue;
}
else
@@ -1230,7 +1259,7 @@ void CArcErrorInfo::ClearErrors()
HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openRes)
{
// OkPhySize_Defined = false;
PhySizeDefined = false;
PhySize_Defined = false;
PhySize = 0;
Offset = 0;
AvailPhySize = FileSize - startPos;
@@ -1263,12 +1292,12 @@ HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openR
if (openRes == S_OK || ErrorInfo.IsArc_After_NonOpen())
{
RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, PhySize, PhySizeDefined));
RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, PhySize, PhySize_Defined));
/*
RINOK(Archive_GetArcProp_UInt(archive, kpidOkPhySize, OkPhySize, OkPhySize_Defined));
if (!OkPhySize_Defined)
{
OkPhySize_Defined = PhySizeDefined;
OkPhySize_Defined = PhySize_Defined;
OkPhySize = PhySize;
}
*/
@@ -1278,7 +1307,7 @@ HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openR
Int64 globalOffset = (Int64)startPos + Offset;
AvailPhySize = (UInt64)((Int64)FileSize - globalOffset);
if (PhySizeDefined)
if (PhySize_Defined)
{
UInt64 endPos = (UInt64)(globalOffset + (Int64)PhySize);
if (endPos < FileSize)
@@ -1379,9 +1408,9 @@ static HRESULT ReadParseItemProps(IInArchive *archive, const CArcInfoEx &ai, NAr
pi.FileTime_Defined = false;
pi.ArcType = ai.Name;
RINOK(Archive_GetArcBoolProp(archive, kpidIsNotArcType, pi.IsNotArcType));
RINOK(Archive_GetArcProp_Bool(archive, kpidIsNotArcType, pi.IsNotArcType));
// RINOK(Archive_GetArcBoolProp(archive, kpidIsSelfExe, pi.IsSelfExe));
// RINOK(Archive_GetArcProp_Bool(archive, kpidIsSelfExe, pi.IsSelfExe));
pi.IsSelfExe = ai.Flags_PreArc();
{
@@ -1585,7 +1614,7 @@ static HRESULT OpenArchiveSpec(IInArchive *archive, bool needPhySize,
return S_OK;
bool phySizeCantBeDetected = false;
RINOK(Archive_GetArcBoolProp(archive, kpidPhySizeCantBeDetected, phySizeCantBeDetected));
RINOK(Archive_GetArcProp_Bool(archive, kpidPhySizeCantBeDetected, phySizeCantBeDetected));
if (!phySizeCantBeDetected)
{
@@ -1725,7 +1754,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
const CArcInfoEx &ai = op.codecs->Formats[i];
if (IgnoreSplit || !op.openType.CanReturnArc)
if (ai.IsSplit())
if (ai.Is_Split())
continue;
if (op.excludedFormats->FindInSorted((int)i) >= 0)
continue;
@@ -1737,8 +1766,8 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
if (ai.FindExtension(extension) >= 0
#ifndef _SFX
|| (isZip && StringsAreEqualNoCase_Ascii(ai.Name, "zip"))
|| (isRar && StringsAreEqualNoCase_Ascii(ai.Name, "rar"))
|| (isZip && ai.Is_Zip())
|| (isRar && ai.Is_Rar())
#endif
)
{
@@ -1812,11 +1841,27 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
/*
check type order:
1) matched extension, no signuature
2) matched extension, matched signuature
0) matched_extension && Backward
1) matched_extension && (no_signuature || SignatureOffset != 0)
2) matched_extension && (matched_signature)
// 3) no signuature
// 4) matched signuature
*/
// we move index from orderIndices to orderIndices2 for priority handlers.
for (unsigned i = 0; i < numFinded; i++)
{
const int index = orderIndices[i];
if (index < 0)
continue;
const CArcInfoEx &ai = op.codecs->Formats[(unsigned)index];
if (ai.Flags_BackwardOpen())
{
// backward doesn't need start signatures
orderIndices2.Add(index);
orderIndices[i] = -1;
}
}
MakeCheckOrder(op.codecs, orderIndices, numFinded, orderIndices2, NULL, 0);
MakeCheckOrder(op.codecs, orderIndices, numFinded, orderIndices2, byteBuffer, processedSize);
@@ -1907,6 +1952,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
// OutputDebugStringW(ai.Name);
if (i >= numMainTypes)
{
// here we allow mismatched extension only for backward handlers
if (!ai.Flags_BackwardOpen()
// && !ai.Flags_PureStartOpen()
)
@@ -2126,7 +2172,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
const CArcInfoEx &ai = op.codecs->Formats[form];
if (ai.IsSplit())
if (ai.Is_Split())
{
splitIndex = (int)form;
continue;
@@ -2235,7 +2281,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
// bool needScan = false;
if (!PhySizeDefined)
if (!PhySize_Defined)
{
// it's for Z format
pi.LenIsUnknown = true;
@@ -2727,14 +2773,14 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
continue;
}
if (!ErrorInfo.IsArc_After_NonOpen() || !PhySizeDefined || PhySize == 0)
if (!ErrorInfo.IsArc_After_NonOpen() || !PhySize_Defined || PhySize == 0)
continue;
}
else
{
if (PhySizeDefined && PhySize == 0)
if (PhySize_Defined && PhySize == 0)
{
PRF(printf(" phySizeDefined && PhySize == 0 "));
PRF(printf(" phySize_Defined && PhySize == 0 "));
// we skip that epmty archive case with unusual unexpected (PhySize == 0) from Code function.
continue;
}
@@ -2755,10 +2801,10 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
else if (Offset != 0)
return E_FAIL;
UInt64 arcRem = FileSize - pi.Offset;
const UInt64 arcRem = FileSize - pi.Offset;
UInt64 phySize = arcRem;
bool phySizeDefined = PhySizeDefined;
if (phySizeDefined)
const bool phySize_Defined = PhySize_Defined;
if (phySize_Defined)
{
if (pi.Offset + PhySize > FileSize)
{
@@ -2784,7 +2830,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
bool needScan = false;
if (isOpen && !phySizeDefined)
if (isOpen && !phySize_Defined)
{
// it's for Z format, or bzip2,gz,xz with phySize that was not detected
pi.LenIsUnknown = true;
@@ -2803,7 +2849,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
/*
if (needSkipFullArc)
if (pi.Offset == 0 && phySizeDefined && pi.Size >= fileSize)
if (pi.Offset == 0 && phySize_Defined && pi.Size >= fileSize)
continue;
*/
if (pi.Offset == 0 && !pi.LenIsUnknown && pi.Size >= FileSize)
@@ -2831,7 +2877,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
RINOK(ReadParseItemProps(archive, ai, pi));
if (pi.Offset < startArcPos && !mode.EachPos /* && phySizeDefined */)
if (pi.Offset < startArcPos && !mode.EachPos /* && phySize_Defined */)
{
/* It's for DMG format.
This code deletes all previous items that are included to current item */
@@ -2850,7 +2896,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
if (isOpen && mode.CanReturnArc && phySizeDefined)
if (isOpen && mode.CanReturnArc && phySize_Defined)
{
// if (pi.Offset + pi.Size >= fileSize)
bool openCur = false;
@@ -2994,12 +3040,12 @@ HRESULT CArc::OpenStream(const COpenOptions &op)
Archive->QueryInterface(IID_IArchiveGetRawProps, (void **)&GetRawProps);
Archive->QueryInterface(IID_IArchiveGetRootProps, (void **)&GetRootProps);
RINOK(Archive_GetArcBoolProp(Archive, kpidIsTree, IsTree));
RINOK(Archive_GetArcBoolProp(Archive, kpidIsDeleted, Ask_Deleted));
RINOK(Archive_GetArcBoolProp(Archive, kpidIsAltStream, Ask_AltStream));
RINOK(Archive_GetArcBoolProp(Archive, kpidIsAux, Ask_Aux));
RINOK(Archive_GetArcBoolProp(Archive, kpidINode, Ask_INode));
RINOK(Archive_GetArcBoolProp(Archive, kpidReadOnly, IsReadOnly));
RINOK(Archive_GetArcProp_Bool(Archive, kpidIsTree, IsTree));
RINOK(Archive_GetArcProp_Bool(Archive, kpidIsDeleted, Ask_Deleted));
RINOK(Archive_GetArcProp_Bool(Archive, kpidIsAltStream, Ask_AltStream));
RINOK(Archive_GetArcProp_Bool(Archive, kpidIsAux, Ask_Aux));
RINOK(Archive_GetArcProp_Bool(Archive, kpidINode, Ask_INode));
RINOK(Archive_GetArcProp_Bool(Archive, kpidReadOnly, IsReadOnly));
const UString fileName = ExtractFileNameFromPath(Path);
UString extension;
@@ -3093,7 +3139,7 @@ HRESULT CArc::OpenStreamOrFile(COpenOptions &op)
FOR_VECTOR (i, op.codecs->Formats)
{
const CArcInfoEx &ai = op.codecs->Formats[i];
if (ai.IsSplit())
if (ai.Is_Split())
continue;
UString path3 = path2;
path3 += '.';
@@ -3300,7 +3346,7 @@ HRESULT CArchiveLink::Open(COpenOptions &op)
break;
CArc arc2;
RINOK(arc.GetItemPath(mainSubfile, arc2.Path));
RINOK(arc.GetItem_Path(mainSubfile, arc2.Path));
bool zerosTailIsAllowed;
RINOK(Archive_GetItemBoolProp(arc.Archive, mainSubfile, kpidZerosTailIsAllowed, zerosTailIsAllowed));
@@ -3344,7 +3390,7 @@ HRESULT CArchiveLink::Open(COpenOptions &op)
break;
}
RINOK(result);
RINOK(arc.GetItemMTime(mainSubfile, arc2.MTime, arc2.MTimeDefined));
RINOK(arc.GetItem_MTime(mainSubfile, arc2.MTime));
Arcs.Add(arc2);
}
IsOpen = !Arcs.IsEmpty();

View File

@@ -8,6 +8,7 @@
#include "ArchiveOpenCallback.h"
#include "LoadCodecs.h"
#include "Property.h"
#include "DirItem.h"
#ifndef _SFX
@@ -260,6 +261,9 @@ struct CReadArcItem
}
};
class CArc
{
HRESULT PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyComPtr<IInArchive> &archive);
@@ -268,7 +272,7 @@ class CArc
#ifndef _SFX
// parts.Back() can contain alt stream name "nams:AltName"
HRESULT GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const;
HRESULT GetItem_PathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const;
#endif
public:
@@ -289,19 +293,21 @@ public:
UString DefaultName;
int FormatIndex; // -1 means Parser
UInt32 SubfileIndex; // (UInt32)(Int32)-1; means no subfile
FILETIME MTime;
bool MTimeDefined;
// CFiTime MTime;
// bool MTime_Defined;
CArcTime MTime;
Int64 Offset; // it's offset of start of archive inside stream that is open by Archive Handler
UInt64 PhySize;
// UInt64 OkPhySize;
bool PhySizeDefined;
bool PhySize_Defined;
// bool OkPhySize_Defined;
UInt64 FileSize;
UInt64 AvailPhySize; // PhySize, but it's reduced if exceed end of file
// bool offsetDefined;
UInt64 GetEstmatedPhySize() const { return PhySizeDefined ? PhySize : FileSize; }
UInt64 GetEstmatedPhySize() const { return PhySize_Defined ? PhySize : FileSize; }
UInt64 ArcStreamOffset; // offset of stream that is open by Archive Handler
Int64 GetGlobalOffset() const { return (Int64)ArcStreamOffset + Offset; } // it's global offset of archive
@@ -323,7 +329,7 @@ public:
// void Set_ErrorFlagsText();
CArc():
MTimeDefined(false),
// MTime_Defined(false),
IsTree(false),
IsReadOnly(false),
Ask_Deleted(false),
@@ -343,17 +349,29 @@ public:
return Archive->Close();
}
HRESULT GetItemPath(UInt32 index, UString &result) const;
HRESULT GetDefaultItemPath(UInt32 index, UString &result) const;
HRESULT GetItem_Path(UInt32 index, UString &result) const;
HRESULT GetItem_DefaultPath(UInt32 index, UString &result) const;
// GetItemPath2 adds [DELETED] dir prefix for deleted items.
HRESULT GetItemPath2(UInt32 index, UString &result) const;
HRESULT GetItem_Path2(UInt32 index, UString &result) const;
HRESULT GetItem(UInt32 index, CReadArcItem &item) const;
HRESULT GetItemSize(UInt32 index, UInt64 &size, bool &defined) const;
HRESULT GetItemMTime(UInt32 index, FILETIME &ft, bool &defined) const;
HRESULT IsItemAnti(UInt32 index, bool &result) const
HRESULT GetItem_Size(UInt32 index, UInt64 &size, bool &defined) const;
/* if (GetProperty() returns vt==VT_EMPTY), this function sets
timestamp from archive file timestamp (MTime).
So (at) will be set in most cases (at.Def == true)
if (at.Prec == 0)
{
it means that (Prec == 0) was returned for (kpidMTime),
and no value was returned for (kpidTimeType).
it can mean Windows precision or unknown precision.
}
*/
HRESULT GetItem_MTime(UInt32 index, CArcTime &at) const;
HRESULT IsItem_Anti(UInt32 index, bool &result) const
{ return Archive_GetItemBoolProp(Archive, index, kpidIsAnti, result); }

View File

@@ -136,10 +136,37 @@ void ConvertPropertyToShortString2(char *dest, const PROPVARIANT &prop, PROPID p
if (prop.vt == VT_FILETIME)
{
const FILETIME &ft = prop.filetime;
if ((ft.dwHighDateTime == 0 &&
ft.dwLowDateTime == 0))
unsigned ns100 = 0;
int numDigits = kTimestampPrintLevel_NTFS;
const unsigned prec = prop.wReserved1;
const unsigned ns100_Temp = prop.wReserved2;
if (prec != 0
&& prec <= k_PropVar_TimePrec_1ns
&& ns100_Temp < 100
&& prop.wReserved3 == 0)
{
ns100 = ns100_Temp;
if (prec == k_PropVar_TimePrec_Unix ||
prec == k_PropVar_TimePrec_DOS)
numDigits = 0;
else if (prec == k_PropVar_TimePrec_HighPrec)
numDigits = 9;
else
{
numDigits = (int)prec - (int)k_PropVar_TimePrec_Base;
if (
// numDigits < kTimestampPrintLevel_DAY // for debuf
numDigits < kTimestampPrintLevel_SEC
)
numDigits = kTimestampPrintLevel_NTFS;
}
}
if (ft.dwHighDateTime == 0 && ft.dwLowDateTime == 0 && ns100 == 0)
return;
ConvertUtcFileTimeToString(prop.filetime, dest, level);
if (level > numDigits)
level = numDigits;
ConvertUtcFileTimeToString2(ft, ns100, dest, level);
return;
}
@@ -198,6 +225,24 @@ void ConvertPropertyToShortString2(char *dest, const PROPVARIANT &prop, PROPID p
ConvertUInt64ToHex(v, dest + 2);
return;
}
/*
case kpidDevice:
{
UInt64 v = 0;
if (prop.vt == VT_UI4)
v = prop.ulVal;
else if (prop.vt == VT_UI8)
v = (UInt64)prop.uhVal.QuadPart;
else
break;
ConvertUInt32ToString(MY_dev_major(v), dest);
dest += strlen(dest);
*dest++ = ',';
ConvertUInt32ToString(MY_dev_minor(v), dest);
return;
}
*/
}
ConvertPropVariantToShortString(prop, dest);

View File

@@ -2,6 +2,8 @@
#include "StdAfx.h"
// #include <stdio.h>
#include "Update.h"
#include "../../../Common/StringConvert.h"
@@ -101,7 +103,7 @@ public:
_length = 0;
}
bool SetMTime(const FILETIME *mTime);
bool SetMTime(const CFiTime *mTime);
HRESULT Close();
UInt64 GetSize() const { return _length; }
@@ -131,7 +133,7 @@ HRESULT COutMultiVolStream::Close()
return res;
}
bool COutMultiVolStream::SetMTime(const FILETIME *mTime)
bool COutMultiVolStream::SetMTime(const CFiTime *mTime)
{
bool res = true;
FOR_VECTOR (i, Streams)
@@ -545,11 +547,46 @@ static HRESULT Compress(
if (!outArchive)
throw kUpdateIsNotSupoorted;
// we need to set properties to get fileTimeType.
RINOK(SetProperties(outArchive, options.MethodMode.Properties));
NFileTimeType::EEnum fileTimeType;
{
/*
how we compare file_in_archive::MTime with dirItem.MTime
for GetUpdatePairInfoList():
if (kpidMTime is not defined), external MTime of archive is used.
before 22.00:
if (kpidTimeType is defined)
{
kpidTimeType is used as precision.
(kpidTimeType > kDOS) is not allowed.
}
else GetFileTimeType() value is used as precision.
22.00:
if (kpidMTime is defined)
{
if (kpidMTime::precision != 0), then kpidMTime::precision is used as precision.
else
{
if (kpidTimeType is defined), kpidTimeType is used as precision.
else GetFileTimeType() value is used as precision.
}
}
else external MTime of archive is used as precision.
*/
UInt32 value;
RINOK(outArchive->GetFileTimeType(&value));
// we support any future fileType here.
fileTimeType = (NFileTimeType::EEnum)value;
/*
old 21.07 code:
switch (value)
{
case NFileTimeType::kWindows:
@@ -560,13 +597,26 @@ static HRESULT Compress(
default:
return E_FAIL;
}
*/
}
// bool noTimestampExpected = false;
{
const CArcInfoEx &arcInfo = codecs->Formats[(unsigned)formatIndex];
// if (arcInfo.Flags_KeepName()) noTimestampExpected = true;
if (arcInfo.Is_Xz() ||
arcInfo.Is_BZip2())
{
/* 7-zip before 22.00 returns NFileTimeType::kUnix for xz and bzip2,
but we want to set timestamp without reduction to unix. */
// noTimestampExpected = true;
fileTimeType = NFileTimeType::kNotDefined; // it means not defined
}
if (options.AltStreams.Val && !arcInfo.Flags_AltStreams())
return E_NOTIMPL;
if (options.NtSecurity.Val && !arcInfo.Flags_NtSecure())
if (options.NtSecurity.Val && !arcInfo.Flags_NtSecurity())
return E_NOTIMPL;
if (options.DeleteAfterCompressing && arcInfo.Flags_HashHandler())
return E_NOTIMPL;
@@ -626,7 +676,7 @@ static HRESULT Compress(
if (needRename)
{
up2.NewProps = true;
RINOK(arc->IsItemAnti(i, up2.IsAnti));
RINOK(arc->IsItem_Anti(i, up2.IsAnti));
up2.NewNameIndex = (int)newNames.Add(dest);
}
updatePairs2.Add(up2);
@@ -661,6 +711,7 @@ static HRESULT Compress(
else
stat.NumDirs++;
}
#ifdef _WIN32
else if (di.IsAltStream)
{
if (up.IsAnti)
@@ -671,6 +722,7 @@ static HRESULT Compress(
stat.AltStreamsSize += di.Size;
}
}
#endif
else
{
if (up.IsAnti)
@@ -740,6 +792,8 @@ static HRESULT Compress(
updateCallbackSpec->StoreNtSecurity = options.NtSecurity.Val;
updateCallbackSpec->StoreHardLinks = options.HardLinks.Val;
updateCallbackSpec->StoreSymLinks = options.SymLinks.Val;
updateCallbackSpec->StoreOwnerName = options.StoreOwnerName.Val;
updateCallbackSpec->StoreOwnerId = options.StoreOwnerId.Val;
updateCallbackSpec->Arc = arc;
updateCallbackSpec->ArcItems = &arcItems;
@@ -755,6 +809,12 @@ static HRESULT Compress(
if (options.RenamePairs.Size() != 0)
updateCallbackSpec->NewNames = &newNames;
if (options.SetArcMTime)
{
// updateCallbackSpec->Need_ArcMTime_Report = true;
updateCallbackSpec->Need_LatestMTime = true;
}
CMyComPtr<IOutStream> outSeekStream;
CMyComPtr<ISequentialOutStream> outStream;
@@ -838,8 +898,6 @@ static HRESULT Compress(
*/
}
RINOK(SetProperties(outArchive, options.MethodMode.Properties));
if (options.SfxMode)
{
CInFileStream *sfxStreamSpec = new CInFileStream;
@@ -909,24 +967,71 @@ static HRESULT Compress(
if (options.SetArcMTime)
{
FILETIME ft;
ft.dwLowDateTime = 0;
ft.dwHighDateTime = 0;
FOR_VECTOR (i, updatePairs2)
CFiTime ft;
FiTime_Clear(ft);
bool isDefined = false;
// bool needNormalizeAfterStream;
// needParse;
/*
if (updateCallbackSpec->ArcMTime_WasReported)
{
const CUpdatePair2 &pair2 = updatePairs2[i];
const FILETIME *ft2 = NULL;
if (pair2.NewProps && pair2.DirIndex >= 0)
ft2 = &dirItems.Items[(unsigned)pair2.DirIndex].MTime;
else if (pair2.UseArcProps && pair2.ArcIndex >= 0)
ft2 = &arcItems[(unsigned)pair2.ArcIndex].MTime;
if (ft2)
{
if (::CompareFileTime(&ft, ft2) < 0)
ft = *ft2;
}
isDefined = updateCallbackSpec->Reported_ArcMTime.Def;
if (isDefined)
updateCallbackSpec->Reported_ArcMTime.Write_To_FiTime(ft);
else
fileTimeType = NFileTimeType::kNotDefined;
}
if (ft.dwLowDateTime != 0 || ft.dwHighDateTime != 0)
if (!isDefined)
*/
{
if (updateCallbackSpec->LatestMTime_Defined)
{
// CArcTime at = StreamCallback_ArcMTime;
// updateCallbackSpec->StreamCallback_ArcMTime.Write_To_FiTime(ft);
// we must normalize with precision from archive;
ft = updateCallbackSpec->LatestMTime;
isDefined = true;
}
FOR_VECTOR (i, updatePairs2)
{
const CUpdatePair2 &pair2 = updatePairs2[i];
CFiTime ft2;
bool ft2_Defined = false;
/* we use full precision of dirItem, if dirItem is defined
and (dirItem will be used or dirItem is sameTime in dir and arc */
if (pair2.DirIndex >= 0 &&
(pair2.NewProps || pair2.IsSameTime))
{
ft2 = dirItems.Items[(unsigned)pair2.DirIndex].MTime;
ft2_Defined = true;
}
else if (pair2.UseArcProps && pair2.ArcIndex >= 0)
{
const CArcItem &arcItem = arcItems[(unsigned)pair2.ArcIndex];
if (arcItem.MTime.Def)
{
arcItem.MTime.Write_To_FiTime(ft2);
ft2_Defined = true;
}
}
if (ft2_Defined)
{
if (Compare_FiTime(&ft, &ft2) < 0)
{
ft = ft2;
isDefined = true;
}
}
}
/*
if (fileTimeType != NFileTimeType::kNotDefined)
FiTime_Normalize_With_Prec(ft, fileTimeType);
*/
}
// if (ft.dwLowDateTime != 0 || ft.dwHighDateTime != 0)
if (isDefined)
{
if (outStreamSpec)
outStreamSpec->SetMTime(&ft);
@@ -1046,26 +1151,9 @@ static HRESULT EnumerateInArchiveItems(
else
ai.Censored = Censor_CheckPath(censor, item);
RINOK(arc.GetItemMTime(i, ai.MTime, ai.MTimeDefined));
RINOK(arc.GetItemSize(i, ai.Size, ai.SizeDefined));
{
CPropVariant prop;
RINOK(archive->GetProperty(i, kpidTimeType, &prop));
if (prop.vt == VT_UI4)
{
ai.TimeType = (int)(NFileTimeType::EEnum)prop.ulVal;
switch (ai.TimeType)
{
case NFileTimeType::kWindows:
case NFileTimeType::kUnix:
case NFileTimeType::kDOS:
break;
default:
return E_FAIL;
}
}
}
// ai.MTime will be set to archive MTime, if not present in archive item
RINOK(arc.GetItem_MTime(i, ai.MTime));
RINOK(arc.GetItem_Size(i, ai.Size, ai.Size_Defined));
ai.IndexInServer = i;
arcItems.AddInReserved(ai);
@@ -1198,8 +1286,10 @@ HRESULT UpdateArchive(
EISDIR
#endif
);
#ifdef _WIN32
if (fi.IsDevice)
return E_NOTIMPL;
#endif
if (!options.StdOutMode && options.UpdateArchiveItself)
if (fi.IsReadOnly())
@@ -1262,8 +1352,14 @@ HRESULT UpdateArchive(
}
CArc &arc = arcLink.Arcs.Back();
arc.MTimeDefined = !fi.IsDevice;
arc.MTime = fi.MTime;
arc.MTime.Def =
#ifdef _WIN32
!fi.IsDevice;
#else
true;
#endif
if (arc.MTime.Def)
arc.MTime.Set_From_FiTime(fi.MTime);
if (arc.ErrorInfo.ThereIsTail)
{
@@ -1307,10 +1403,11 @@ HRESULT UpdateArchive(
if (options.StdInMode)
{
CDirItem di;
di.ClearBase();
di.Name = options.StdInFileName;
di.Size = (UInt64)(Int64)-1;
di.Attrib = 0;
NTime::GetCurUtcFileTime(di.MTime);
di.SetAsFile();
NTime::GetCurUtc_FiTime(di.MTime);
di.CTime = di.ATime = di.MTime;
dirItems.Items.Add(di);
}
@@ -1336,8 +1433,14 @@ HRESULT UpdateArchive(
dirItems.ScanAltStreams = options.AltStreams.Val;
dirItems.ExcludeDirItems = censor.ExcludeDirItems;
dirItems.ExcludeFileItems = censor.ExcludeFileItems;
dirItems.ShareForWrite = options.OpenShareForWrite;
HRESULT res = EnumerateItems(censor,
#ifndef _WIN32
dirItems.StoreOwnerName = options.StoreOwnerName.Val;
#endif
const HRESULT res = EnumerateItems(censor,
options.PathMode,
UString(), // options.AddPathPrefix,
dirItems);
@@ -1351,6 +1454,8 @@ HRESULT UpdateArchive(
RINOK(callback->FinishScanning(dirItems.Stat));
// 22.00: we don't need parent folder, if absolute path mode
if (options.PathMode != NWildcard::k_AbsPath)
if (censor.Pairs.Size() == 1)
{
NFind::CFileInfo fi;
@@ -1366,11 +1471,7 @@ HRESULT UpdateArchive(
if (fi.Find(prefix))
if (fi.IsDir())
{
parentDirItem.Size = fi.Size;
parentDirItem.CTime = fi.CTime;
parentDirItem.ATime = fi.ATime;
parentDirItem.MTime = fi.MTime;
parentDirItem.Attrib = fi.Attrib;
parentDirItem.Copy_From_FileInfoBase(fi);
parentDirItem_Ptr = &parentDirItem;
int secureIndex = -1;
@@ -1723,8 +1824,8 @@ HRESULT UpdateArchive(
is_SameSize = (fileInfo.Size == dirItem.Size);
if (is_SameSize
&& CompareFileTime(&fileInfo.MTime, &dirItem.MTime) == 0
&& CompareFileTime(&fileInfo.CTime, &dirItem.CTime) == 0)
&& Compare_FiTime(&fileInfo.MTime, &dirItem.MTime) == 0
&& Compare_FiTime(&fileInfo.CTime, &dirItem.CTime) == 0)
{
RINOK(callback->DeletingAfterArchiving(phyPath, false));
DeleteFileAlways(phyPath);

View File

@@ -112,6 +112,9 @@ struct CUpdateOptions
CBoolPair HardLinks;
CBoolPair SymLinks;
CBoolPair StoreOwnerId;
CBoolPair StoreOwnerName;
bool DeleteAfterCompressing;
bool SetArcMTime;

View File

@@ -4,6 +4,15 @@
// #include <stdio.h>
#ifndef _WIN32
// #include <grp.h>
// #include <pwd.h>
// for major minor:
// BSD: <sys/types.h>
#include <sys/sysmacros.h>
#endif
#ifndef _7ZIP_ST
#include "../../../Windows/Synchronization.h"
#endif
@@ -66,6 +75,18 @@ CArchiveUpdateCallback::CArchiveUpdateCallback():
StoreNtSecurity(false),
StoreHardLinks(false),
StoreSymLinks(false),
#ifndef _WIN32
StoreOwnerId(false),
StoreOwnerName(false),
#endif
/*
, Need_ArcMTime_Report(false),
, ArcMTime_WasReported(false),
*/
Need_LatestMTime(false),
LatestMTime_Defined(false),
ProcessedItemsStatuses(NULL)
{
@@ -134,16 +155,17 @@ STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index,
COM_TRY_END
}
STDMETHODIMP CArchiveUpdateCallback::GetRootProp(PROPID propID, PROPVARIANT *value)
{
NCOM::CPropVariant prop;
switch (propID)
{
case kpidIsDir: prop = true; break;
case kpidAttrib: if (ParentDirItem) prop = ParentDirItem->Attrib; break;
case kpidCTime: if (ParentDirItem) prop = ParentDirItem->CTime; break;
case kpidATime: if (ParentDirItem) prop = ParentDirItem->ATime; break;
case kpidMTime: if (ParentDirItem) prop = ParentDirItem->MTime; break;
case kpidAttrib: if (ParentDirItem) prop = ParentDirItem->GetWinAttrib(); break;
case kpidCTime: if (ParentDirItem) PropVariant_SetFrom_FiTime(prop, ParentDirItem->CTime); break;
case kpidATime: if (ParentDirItem) PropVariant_SetFrom_FiTime(prop, ParentDirItem->ATime); break;
case kpidMTime: if (ParentDirItem) PropVariant_SetFrom_FiTime(prop, ParentDirItem->MTime); break;
case kpidArcFileName: if (!ArcFileName.IsEmpty()) prop = ArcFileName; break;
}
prop.Detach(value);
@@ -446,25 +468,46 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
{
case kpidPath: prop = DirItems->GetLogPath((unsigned)up.DirIndex); break;
case kpidIsDir: prop = di.IsDir(); break;
case kpidSize: prop = di.IsDir() ? (UInt64)0 : di.Size; break;
case kpidAttrib: prop = di.Attrib; break;
case kpidCTime: prop = di.CTime; break;
case kpidATime: prop = di.ATime; break;
case kpidMTime: prop = di.MTime; break;
case kpidSize: prop = (UInt64)(di.IsDir() ? (UInt64)0 : di.Size); break;
case kpidCTime: PropVariant_SetFrom_FiTime(prop, di.CTime); break;
case kpidATime: PropVariant_SetFrom_FiTime(prop, di.ATime); break;
case kpidMTime: PropVariant_SetFrom_FiTime(prop, di.MTime); break;
case kpidAttrib: prop = (UInt32)di.GetWinAttrib(); break;
case kpidPosixAttrib: prop = (UInt32)di.GetPosixAttrib(); break;
#if defined(_WIN32)
case kpidIsAltStream: prop = di.IsAltStream; break;
#if defined(_WIN32) && !defined(UNDER_CE)
// case kpidShortName: prop = di.ShortName; break;
#endif
case kpidPosixAttrib:
{
#ifdef _WIN32
prop = di.GetPosixAttrib();
#else
if (di.Attrib & FILE_ATTRIBUTE_UNIX_EXTENSION)
prop = (UInt32)(di.Attrib >> 16);
#endif
#else
case kpidDeviceMajor:
/*
printf("\ndi.mode = %o\n", di.mode);
printf("\nst.st_rdev major = %d\n", (unsigned)major(di.rdev));
printf("\nst.st_rdev minor = %d\n", (unsigned)minor(di.rdev));
*/
if (S_ISCHR(di.mode) || S_ISBLK(di.mode))
prop = (UInt32)major(di.rdev);
break;
}
case kpidDeviceMinor:
if (S_ISCHR(di.mode) || S_ISBLK(di.mode))
prop = (UInt32)minor(di.rdev);
break;
// case kpidDevice: if (S_ISCHR(di.mode) || S_ISBLK(di.mode)) prop = (UInt64)(di.rdev); break;
case kpidUserId: if (StoreOwnerId) prop = (UInt32)di.uid; break;
case kpidGroupId: if (StoreOwnerId) prop = (UInt32)di.gid; break;
case kpidUser:
if (di.OwnerNameIndex >= 0)
prop = DirItems->OwnerNameMap.Strings[(unsigned)di.OwnerNameIndex];
break;
case kpidGroup:
if (di.OwnerGroupIndex >= 0)
prop = DirItems->OwnerGroupMap.Strings[(unsigned)di.OwnerGroupIndex];
break;
#endif
}
}
prop.Detach(value);
@@ -565,12 +608,41 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea
CInFileStream *inStreamSpec = new CInFileStream;
CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
/*
// for debug:
#ifdef _WIN32
inStreamSpec->StoreOwnerName = true;
inStreamSpec->OwnerName = "user_name";
inStreamSpec->OwnerName += di.Name;
inStreamSpec->OwnerName += "11111111112222222222222333333333333";
inStreamSpec->OwnerGroup = "gname_";
inStreamSpec->OwnerGroup += inStreamSpec->OwnerName;
#endif
*/
#ifndef _WIN32
inStreamSpec->StoreOwnerId = StoreOwnerId;
inStreamSpec->StoreOwnerName = StoreOwnerName;
// if (StoreOwner)
{
inStreamSpec->_uid = di.uid;
inStreamSpec->_gid = di.gid;
if (di.OwnerNameIndex >= 0)
inStreamSpec->OwnerName = DirItems->OwnerNameMap.Strings[(unsigned)di.OwnerNameIndex];
if (di.OwnerGroupIndex >= 0)
inStreamSpec->OwnerGroup = DirItems->OwnerGroupMap.Strings[(unsigned)di.OwnerGroupIndex];
}
#endif
inStreamSpec->SupportHardLinks = StoreHardLinks;
inStreamSpec->File.PreserveATime = PreserveATime;
inStreamSpec->Set_PreserveATime(PreserveATime
|| mode == NUpdateNotifyOp::kAnalyze); // 22.00 : we don't change access time in Analyze pass.
const FString path = DirItems->GetPhyPath((unsigned)up.DirIndex);
_openFiles_Indexes.Add(index);
_openFiles_Paths.Add(path);
// _openFiles_Streams.Add(inStreamSpec);
/* 21.02 : we set Callback/CallbackRef after _openFiles_Indexes adding
for correct working if exception was raised in GetPhyPath */
@@ -579,14 +651,30 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea
if (!inStreamSpec->OpenShared(path, ShareForWrite))
{
DWORD error = ::GetLastError();
HRESULT hres = Callback->OpenFileError(path, error);
const DWORD error = ::GetLastError();
const HRESULT hres = Callback->OpenFileError(path, error);
if (StopAfterOpenError)
if (hres == S_OK || hres == S_FALSE)
return HRESULT_FROM_WIN32(error);
return hres;
}
/*
{
// for debug:
Byte b = 0;
UInt32 processedSize = 0;
if (inStreamSpec->Read(&b, 1, &processedSize) != S_OK ||
processedSize != 1)
return E_FAIL;
}
*/
if (Need_LatestMTime)
{
inStreamSpec->ReloadProps();
}
// #if defined(USE_WIN_FILE) || !defined(_WIN32)
if (StoreHardLinks)
{
@@ -643,6 +731,8 @@ STDMETHODIMP CArchiveUpdateCallback::ReportOperation(UInt32 indexType, UInt32 in
{
COM_TRY_BEGIN
// if (op == NUpdateNotifyOp::kOpFinished) return Callback->ReportFinished(indexType, index);
bool isDir = false;
if (indexType == NArchive::NEventIndexType::kOutArcIndex)
@@ -676,7 +766,7 @@ STDMETHODIMP CArchiveUpdateCallback::ReportOperation(UInt32 indexType, UInt32 in
}
else if (Arc)
{
RINOK(Arc->GetItemPath(index, s2));
RINOK(Arc->GetItem_Path(index, s2));
s = s2;
RINOK(Archive_IsItem_Dir(Arc->Archive, index, isDir));
}
@@ -731,7 +821,7 @@ STDMETHODIMP CArchiveUpdateCallback::ReportExtractResult(UInt32 indexType, UInt3
s = (*ArcItems)[index].Name;
else if (Arc)
{
RINOK(Arc->GetItemPath(index, s2));
RINOK(Arc->GetItem_Path(index, s2));
s = s2;
}
if (Archive)
@@ -752,6 +842,51 @@ STDMETHODIMP CArchiveUpdateCallback::ReportExtractResult(UInt32 indexType, UInt3
COM_TRY_END
}
/*
STDMETHODIMP CArchiveUpdateCallback::DoNeedArcProp(PROPID propID, Int32 *answer)
{
*answer = 0;
if (Need_ArcMTime_Report && propID == kpidComboMTime)
*answer = 1;
return S_OK;
}
STDMETHODIMP CArchiveUpdateCallback::ReportProp(UInt32 indexType, UInt32 index, PROPID propID, const PROPVARIANT *value)
{
if (indexType == NArchive::NEventIndexType::kArcProp)
{
if (propID == kpidComboMTime)
{
ArcMTime_WasReported = true;
if (value->vt == VT_FILETIME)
{
Reported_ArcMTime.Set_From_Prop(*value);
Reported_ArcMTime.Def = true;
}
else
{
Reported_ArcMTime.Clear();
if (value->vt != VT_EMPTY)
return E_FAIL; // for debug
}
}
}
return Callback->ReportProp(indexType, index, propID, value);
}
STDMETHODIMP CArchiveUpdateCallback::ReportRawProp(UInt32 indexType, UInt32 index,
PROPID propID, const void *data, UInt32 dataSize, UInt32 propType)
{
return Callback->ReportRawProp(indexType, index, propID, data, dataSize, propType);
}
STDMETHODIMP CArchiveUpdateCallback::ReportFinished(UInt32 indexType, UInt32 index, Int32 opRes)
{
return Callback->ReportFinished(indexType, index, opRes);
}
*/
STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)
{
if (VolumesSizes.Size() == 0)
@@ -805,7 +940,7 @@ HRESULT CArchiveUpdateCallback::InFileStream_On_Error(UINT_PTR val, DWORD error)
#endif
{
MT_LOCK
UInt32 index = (UInt32)val;
const UInt32 index = (UInt32)val;
FOR_VECTOR(i, _openFiles_Indexes)
{
if (_openFiles_Indexes[i] == index)
@@ -818,21 +953,31 @@ HRESULT CArchiveUpdateCallback::InFileStream_On_Error(UINT_PTR val, DWORD error)
return HRESULT_FROM_WIN32(error);
}
void CArchiveUpdateCallback::InFileStream_On_Destroy(UINT_PTR val)
void CArchiveUpdateCallback::InFileStream_On_Destroy(CInFileStream *stream, UINT_PTR val)
{
{
MT_LOCK
UInt32 index = (UInt32)val;
if (Need_LatestMTime)
{
if (stream->_info_WasLoaded)
{
const CFiTime &ft = ST_MTIME(stream->_info);
if (!LatestMTime_Defined
|| Compare_FiTime(&LatestMTime, &ft) < 0)
LatestMTime = ft;
LatestMTime_Defined = true;
}
}
const UInt32 index = (UInt32)val;
FOR_VECTOR(i, _openFiles_Indexes)
{
if (_openFiles_Indexes[i] == index)
{
_openFiles_Indexes.Delete(i);
_openFiles_Paths.Delete(i);
// _openFiles_Streams.Delete(i);
return;
}
}
}
/* 21.02 : this function can be called in destructor.
And destructor can be called after some exception.
If we don't want to throw exception in desctructors or after another exceptions,

View File

@@ -45,6 +45,13 @@ struct CArcToDoStat
virtual HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) x; \
virtual HRESULT CryptoGetTextPassword(BSTR *password) x; \
virtual HRESULT ShowDeleteFile(const wchar_t *name, bool isDir) x; \
/*
virtual HRESULT ReportProp(UInt32 indexType, UInt32 index, PROPID propID, const PROPVARIANT *value) x; \
virtual HRESULT ReportRawProp(UInt32 indexType, UInt32 index, PROPID propID, const void *data, UInt32 dataSize, UInt32 propType) x; \
virtual HRESULT ReportFinished(UInt32 indexType, UInt32 index, Int32 opRes) x; \
*/
/* virtual HRESULT CloseProgress() { return S_OK; } */
struct IUpdateCallbackUI
@@ -70,6 +77,7 @@ struct CKeyKeyValPair
class CArchiveUpdateCallback:
public IArchiveUpdateCallback2,
public IArchiveUpdateCallbackFile,
// public IArchiveUpdateCallbackArcProp,
public IArchiveExtractCallbackMessage,
public IArchiveGetRawProps,
public IArchiveGetRootProps,
@@ -92,6 +100,7 @@ class CArchiveUpdateCallback:
public:
MY_QUERYINTERFACE_BEGIN2(IArchiveUpdateCallback2)
MY_QUERYINTERFACE_ENTRY(IArchiveUpdateCallbackFile)
// MY_QUERYINTERFACE_ENTRY(IArchiveUpdateCallbackArcProp)
MY_QUERYINTERFACE_ENTRY(IArchiveExtractCallbackMessage)
MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps)
MY_QUERYINTERFACE_ENTRY(IArchiveGetRootProps)
@@ -106,6 +115,7 @@ public:
INTERFACE_IArchiveUpdateCallback2(;)
INTERFACE_IArchiveUpdateCallbackFile(;)
// INTERFACE_IArchiveUpdateCallbackArcProp(;)
INTERFACE_IArchiveExtractCallbackMessage(;)
INTERFACE_IArchiveGetRawProps(;)
INTERFACE_IArchiveGetRootProps(;)
@@ -115,10 +125,11 @@ public:
CRecordVector<UInt32> _openFiles_Indexes;
FStringVector _openFiles_Paths;
// CRecordVector< CInFileStream* > _openFiles_Streams;
bool AreAllFilesClosed() const { return _openFiles_Indexes.IsEmpty(); }
virtual HRESULT InFileStream_On_Error(UINT_PTR val, DWORD error);
virtual void InFileStream_On_Destroy(UINT_PTR val);
virtual void InFileStream_On_Destroy(CInFileStream *stream, UINT_PTR val);
CRecordVector<UInt64> VolumesSizes;
FString VolName;
@@ -148,8 +159,22 @@ public:
bool StoreHardLinks;
bool StoreSymLinks;
bool StoreOwnerId;
bool StoreOwnerName;
/*
bool Need_ArcMTime_Report;
bool ArcMTime_WasReported;
CArcTime Reported_ArcMTime;
*/
bool Need_LatestMTime;
bool LatestMTime_Defined;
CFiTime LatestMTime;
Byte *ProcessedItemsStatuses;
CArchiveUpdateCallback();
bool IsDir(const CUpdatePair2 &up) const

View File

@@ -3,6 +3,7 @@
#include "StdAfx.h"
#include <time.h>
// #include <stdio.h>
#include "../../../Common/Wildcard.h"
@@ -14,30 +15,90 @@
using namespace NWindows;
using namespace NTime;
static int MyCompareTime(NFileTimeType::EEnum fileTimeType, const FILETIME &time1, const FILETIME &time2)
{
switch (fileTimeType)
/*
a2.Prec =
{
case NFileTimeType::kWindows:
return ::CompareFileTime(&time1, &time2);
case NFileTimeType::kUnix:
{
UInt32 unixTime1, unixTime2;
FileTimeToUnixTime(time1, unixTime1);
FileTimeToUnixTime(time2, unixTime2);
return MyCompare(unixTime1, unixTime2);
}
case NFileTimeType::kDOS:
{
UInt32 dosTime1, dosTime2;
FileTimeToDosTime(time1, dosTime1);
FileTimeToDosTime(time2, dosTime2);
return MyCompare(dosTime1, dosTime2);
}
0 (k_PropVar_TimePrec_0):
if GetProperty(kpidMTime) returned 0 and
GetProperty(kpidTimeType) did not returned VT_UI4.
7z, wim, tar in 7-Zip before v21)
in that case we use
(prec) that is set by IOutArchive::GetFileTimeType()
}
throw 4191618;
*/
static int MyCompareTime(unsigned prec, const CFiTime &f1, const CArcTime &a2)
{
// except of precision, we also have limitation, when timestamp is out of range
/* if (Prec) in archive item is defined, then use global (prec) */
if (a2.Prec != k_PropVar_TimePrec_0)
prec = a2.Prec;
CArcTime a1;
a1.Set_From_FiTime(f1);
/* Set_From_FiTime() must set full form precision:
k_PropVar_TimePrec_Base + numDigits
windows: 7 digits, non-windows: 9 digits */
if (prec == k_PropVar_TimePrec_DOS)
{
const UInt32 dosTime1 = a1.Get_DosTime();
const UInt32 dosTime2 = a2.Get_DosTime();
return MyCompare(dosTime1, dosTime2);
}
if (prec == k_PropVar_TimePrec_Unix)
{
const Int64 u2 = FileTime_To_UnixTime64(a2.FT);
if (u2 == 0 || u2 == (UInt32)0xFFFFFFFF)
{
// timestamp probably was saturated in archive to 32-bit
// so we use saturated 32-bit value for disk file too.
UInt32 u1;
FileTime_To_UnixTime(a1.FT, u1);
const UInt32 u2_32 = (UInt32)u2;
return MyCompare(u1, u2_32);
}
const Int64 u1 = FileTime_To_UnixTime64(a1.FT);
return MyCompare(u1, u2);
// prec = k_PropVar_TimePrec_Base; // for debug
}
if (prec == k_PropVar_TimePrec_0)
prec = k_PropVar_TimePrec_Base + 7;
else if (prec == k_PropVar_TimePrec_HighPrec)
prec = k_PropVar_TimePrec_Base + 9;
else if (prec < k_PropVar_TimePrec_Base)
prec = k_PropVar_TimePrec_Base;
else if (prec > k_PropVar_TimePrec_Base + 9)
prec = k_PropVar_TimePrec_Base + 7;
// prec now is full form: k_PropVar_TimePrec_Base + numDigits;
if (prec > a1.Prec && a1.Prec >= k_PropVar_TimePrec_Base)
prec = a1.Prec;
const unsigned numDigits = prec - k_PropVar_TimePrec_Base;
if (numDigits >= 7)
{
const int comp = CompareFileTime(&a1.FT, &a2.FT);
if (comp != 0 || numDigits == 7)
return comp;
return MyCompare(a1.Ns100, a2.Ns100);
}
UInt32 d = 1;
for (unsigned k = numDigits; k < 7; k++)
d *= 10;
const UInt64 v1 = a1.Get_FILETIME_as_UInt64() / d * d;
const UInt64 v2 = a2.Get_FILETIME_as_UInt64() / d * d;
// printf("\ndelta=%d numDigits=%d\n", (unsigned)(v1- v2), numDigits);
return MyCompare(v1, v2);
}
static const char * const k_Duplicate_inArc_Message = "Duplicate filename in archive:";
static const char * const k_Duplicate_inDir_Message = "Duplicate filename on disk:";
static const char * const k_NotCensoredCollision_Message = "Internal file name collision (file on disk, file in archive):";
@@ -64,8 +125,8 @@ static int CompareArcItemsBase(const CArcItem &ai1, const CArcItem &ai2)
static int CompareArcItems(const unsigned *p1, const unsigned *p2, void *param)
{
unsigned i1 = *p1;
unsigned i2 = *p2;
const unsigned i1 = *p1;
const unsigned i2 = *p2;
const CObjectVector<CArcItem> &arcItems = *(const CObjectVector<CArcItem> *)param;
int res = CompareArcItemsBase(arcItems[i1], arcItems[i2]);
if (res != 0)
@@ -81,8 +142,8 @@ void GetUpdatePairInfoList(
{
CUIntVector dirIndices, arcIndices;
unsigned numDirItems = dirItems.Items.Size();
unsigned numArcItems = arcItems.Size();
const unsigned numDirItems = dirItems.Items.Size();
const unsigned numArcItems = arcItems.Size();
CIntArr duplicatedArcItem(numArcItems);
{
@@ -184,7 +245,7 @@ void GetUpdatePairInfoList(
}
else
{
int dupl = duplicatedArcItem[arcIndex];
const int dupl = duplicatedArcItem[arcIndex];
if (dupl != 0)
ThrowError(k_Duplicate_inArc_Message, ai->Name, arcItems[arcIndices[(unsigned)((int)arcIndex + dupl)]].Name);
@@ -195,14 +256,17 @@ void GetUpdatePairInfoList(
pair.DirIndex = dirIndex2;
pair.ArcIndex = arcIndex2;
switch (ai->MTimeDefined ? MyCompareTime(
ai->TimeType != - 1 ? (NFileTimeType::EEnum)ai->TimeType : fileTimeType,
di->MTime, ai->MTime): 0)
int compResult = 0;
if (ai->MTime.Def)
{
compResult = MyCompareTime(fileTimeType, di->MTime, ai->MTime);
}
switch (compResult)
{
case -1: pair.State = NUpdateArchive::NPairState::kNewInArchive; break;
case 1: pair.State = NUpdateArchive::NPairState::kOldInArchive; break;
default:
pair.State = (ai->SizeDefined && di->Size == ai->Size) ?
pair.State = (ai->Size_Defined && di->Size == ai->Size) ?
NUpdateArchive::NPairState::kSameFiles :
NUpdateArchive::NPairState::kUnknowNewerFiles;
}
@@ -211,7 +275,10 @@ void GetUpdatePairInfoList(
arcIndex++;
}
if ((di && di->IsAltStream) ||
if (
#ifdef _WIN32
(di && di->IsAltStream) ||
#endif
(ai && ai->IsAltStream))
{
if (prevHostName)

View File

@@ -63,6 +63,8 @@ void UpdateProduce(
break;
}
up2.IsSameTime = ((unsigned)pair.State == NUpdateArchive::NPairState::kSameFiles);
operationChain.Add(up2);
}

View File

@@ -17,6 +17,7 @@ struct CUpdatePair2
int NewNameIndex;
bool IsMainRenameItem;
bool IsSameTime;
void SetAs_NoChangeArcItem(unsigned arcIndex) // int
{
@@ -37,7 +38,8 @@ struct CUpdatePair2
DirIndex(-1),
ArcIndex(-1),
NewNameIndex(-1),
IsMainRenameItem(false)
IsMainRenameItem(false),
IsSameTime(false)
{}
};

View File

@@ -33,12 +33,45 @@ static LONG CreateMainKey(CKey &key, LPCTSTR keyName)
return key.Create(HKEY_CURRENT_USER, GetKeyPath(keyName));
}
static void Key_Set_UInt32(CKey &key, LPCTSTR name, UInt32 value)
{
if (value == (UInt32)(Int32)-1)
key.DeleteValue(name);
else
key.SetValue(name, value);
}
static void Key_Get_UInt32(CKey &key, LPCTSTR name, UInt32 &value)
{
if (key.QueryValue(name, value) != ERROR_SUCCESS)
value = (UInt32)(Int32)-1;
}
static void Key_Set_BoolPair(CKey &key, LPCTSTR name, const CBoolPair &b)
{
if (b.Def)
key.SetValue(name, b.Val);
}
static void Key_Set_bool_if_Changed(CKey &key, LPCTSTR name, bool val)
{
bool oldVal = false;
if (key.GetValue_IfOk(name, oldVal) == ERROR_SUCCESS)
if (val == oldVal)
return;
key.SetValue(name, val);
}
static void Key_Set_BoolPair_Delete_IfNotDef(CKey &key, LPCTSTR name, const CBoolPair &b)
{
if (b.Def)
Key_Set_bool_if_Changed(key, name, b.Val);
else
key.DeleteValue(name);
}
static void Key_Get_BoolPair(CKey &key, LPCTSTR name, CBoolPair &b)
{
b.Val = false;
@@ -169,6 +202,13 @@ static LPCTSTR const kNtSecur = TEXT("Security");
static LPCTSTR const kAltStreams = TEXT("AltStreams");
static LPCTSTR const kHardLinks = TEXT("HardLinks");
static LPCTSTR const kSymLinks = TEXT("SymLinks");
static LPCTSTR const kPreserveATime = TEXT("PreserveATime");
static LPCTSTR const kTimePrec = TEXT("TimePrec");
static LPCTSTR const kMTime = TEXT("MTime");
static LPCTSTR const kATime = TEXT("ATime");
static LPCTSTR const kCTime = TEXT("CTime");
static LPCTSTR const kSetArcMTime = TEXT("SetArcMTime");
static void SetRegString(CKey &key, LPCWSTR name, const UString &value)
{
@@ -178,26 +218,12 @@ static void SetRegString(CKey &key, LPCWSTR name, const UString &value)
key.SetValue(name, value);
}
static void SetRegUInt32(CKey &key, LPCTSTR name, UInt32 value)
{
if (value == (UInt32)(Int32)-1)
key.DeleteValue(name);
else
key.SetValue(name, value);
}
static void GetRegString(CKey &key, LPCWSTR name, UString &value)
{
if (key.QueryValue(name, value) != ERROR_SUCCESS)
value.Empty();
}
static void GetRegUInt32(CKey &key, LPCTSTR name, UInt32 &value)
{
if (key.QueryValue(name, value) != ERROR_SUCCESS)
value = (UInt32)(Int32)-1;
}
static LPCWSTR const kMemUse = L"MemUse"
#if defined(MY_CPU_SIZEOF_POINTER) && (MY_CPU_SIZEOF_POINTER == 4)
L"32";
@@ -212,10 +238,11 @@ void CInfo::Save() const
CKey key;
CreateMainKey(key, kKeyName);
Key_Set_BoolPair(key, kNtSecur, NtSecurity);
Key_Set_BoolPair(key, kAltStreams, AltStreams);
Key_Set_BoolPair(key, kHardLinks, HardLinks);
Key_Set_BoolPair(key, kSymLinks, SymLinks);
Key_Set_BoolPair_Delete_IfNotDef (key, kNtSecur, NtSecurity);
Key_Set_BoolPair_Delete_IfNotDef (key, kAltStreams, AltStreams);
Key_Set_BoolPair_Delete_IfNotDef (key, kHardLinks, HardLinks);
Key_Set_BoolPair_Delete_IfNotDef (key, kSymLinks, SymLinks);
Key_Set_BoolPair_Delete_IfNotDef (key, kPreserveATime, PreserveATime);
key.SetValue(kShowPassword, ShowPassword);
key.SetValue(kLevel, (UInt32)Level);
@@ -235,16 +262,22 @@ void CInfo::Save() const
CKey fk;
fk.Create(optionsKey, fo.FormatID);
SetRegUInt32(fk, kLevel, fo.Level);
SetRegUInt32(fk, kDictionary, fo.Dictionary);
SetRegUInt32(fk, kOrder, fo.Order);
SetRegUInt32(fk, kBlockSize, fo.BlockLogSize);
SetRegUInt32(fk, kNumThreads, fo.NumThreads);
SetRegString(fk, kMethod, fo.Method);
SetRegString(fk, kOptions, fo.Options);
SetRegString(fk, kEncryptionMethod, fo.EncryptionMethod);
SetRegString(fk, kMemUse, fo.MemUse);
Key_Set_UInt32(fk, kLevel, fo.Level);
Key_Set_UInt32(fk, kDictionary, fo.Dictionary);
Key_Set_UInt32(fk, kOrder, fo.Order);
Key_Set_UInt32(fk, kBlockSize, fo.BlockLogSize);
Key_Set_UInt32(fk, kNumThreads, fo.NumThreads);
Key_Set_UInt32(fk, kTimePrec, fo.TimePrec);
Key_Set_BoolPair_Delete_IfNotDef (fk, kMTime, fo.MTime);
Key_Set_BoolPair_Delete_IfNotDef (fk, kATime, fo.ATime);
Key_Set_BoolPair_Delete_IfNotDef (fk, kCTime, fo.CTime);
Key_Set_BoolPair_Delete_IfNotDef (fk, kSetArcMTime, fo.SetArcMTime);
}
}
}
@@ -269,6 +302,7 @@ void CInfo::Load()
Key_Get_BoolPair(key, kAltStreams, AltStreams);
Key_Get_BoolPair(key, kHardLinks, HardLinks);
Key_Get_BoolPair(key, kSymLinks, SymLinks);
Key_Get_BoolPair(key, kPreserveATime, PreserveATime);
key.GetValue_Strings(kArcHistory, ArcPaths);
@@ -290,11 +324,17 @@ void CInfo::Load()
GetRegString(fk, kEncryptionMethod, fo.EncryptionMethod);
GetRegString(fk, kMemUse, fo.MemUse);
GetRegUInt32(fk, kLevel, fo.Level);
GetRegUInt32(fk, kDictionary, fo.Dictionary);
GetRegUInt32(fk, kOrder, fo.Order);
GetRegUInt32(fk, kBlockSize, fo.BlockLogSize);
GetRegUInt32(fk, kNumThreads, fo.NumThreads);
Key_Get_UInt32(fk, kLevel, fo.Level);
Key_Get_UInt32(fk, kDictionary, fo.Dictionary);
Key_Get_UInt32(fk, kOrder, fo.Order);
Key_Get_UInt32(fk, kBlockSize, fo.BlockLogSize);
Key_Get_UInt32(fk, kNumThreads, fo.NumThreads);
Key_Get_UInt32(fk, kTimePrec, fo.TimePrec);
Key_Get_BoolPair(fk, kMTime, fo.MTime);
Key_Get_BoolPair(fk, kATime, fo.ATime);
Key_Get_BoolPair(fk, kCTime, fo.CTime);
Key_Get_BoolPair(fk, kSetArcMTime, fo.SetArcMTime);
Formats.Add(fo);
}
@@ -478,6 +518,7 @@ static LPCTSTR const kCascadedMenu = TEXT("CascadedMenu");
static LPCTSTR const kContextMenu = TEXT("ContextMenu");
static LPCTSTR const kMenuIcons = TEXT("MenuIcons");
static LPCTSTR const kElimDup = TEXT("ElimDupExtract");
static LPCTSTR const kWriteZoneId = TEXT("WriteZoneIdExtract");
void CContextMenuInfo::Save() const
{
@@ -488,6 +529,8 @@ void CContextMenuInfo::Save() const
Key_Set_BoolPair(key, kCascadedMenu, Cascaded);
Key_Set_BoolPair(key, kMenuIcons, MenuIcons);
Key_Set_BoolPair(key, kElimDup, ElimDup);
Key_Set_UInt32(key, kWriteZoneId, WriteZone);
if (Flags_Def)
key.SetValue(kContextMenu, Flags);
@@ -504,6 +547,8 @@ void CContextMenuInfo::Load()
ElimDup.Val = true;
ElimDup.Def = false;
WriteZone = (UInt32)(Int32)-1;
Flags = (UInt32)(Int32)-1;
Flags_Def = false;
@@ -517,5 +562,7 @@ void CContextMenuInfo::Load()
Key_Get_BoolPair_true(key, kElimDup, ElimDup);
Key_Get_BoolPair(key, kMenuIcons, MenuIcons);
Key_Get_UInt32(key, kWriteZoneId, WriteZone);
Flags_Def = (key.GetValue_IfOk(kContextMenu, Flags) == ERROR_SUCCESS);
}

View File

@@ -10,6 +10,16 @@
#include "ExtractMode.h"
/*
CBoolPair::Def in writing functions means:
if ( CBoolPair::Def ), we write CBoolPair::Val
if ( !CBoolPair::Def )
{
in NCompression functions we delete registry value
in another functions we do nothing
}
*/
namespace NExtract
{
struct CInfo
@@ -75,12 +85,29 @@ namespace NCompression
UInt32 BlockLogSize;
UInt32 NumThreads;
UInt32 TimePrec;
CBoolPair MTime;
CBoolPair ATime;
CBoolPair CTime;
CBoolPair SetArcMTime;
CSysString FormatID;
UString Method;
UString Options;
UString EncryptionMethod;
UString MemUse;
void Reset_TimePrec()
{
TimePrec = (UInt32)(Int32)-1;
}
bool IsSet_TimePrec() const
{
return TimePrec != (UInt32)(Int32)-1;
}
void Reset_BlockLogSize()
{
BlockLogSize = (UInt32)(Int32)-1;
@@ -93,7 +120,12 @@ namespace NCompression
// Options.Empty();
// EncryptionMethod.Empty();
}
CFormatOptions() { ResetForLevelChange(); }
CFormatOptions()
{
// TimePrec = 0;
Reset_TimePrec();
ResetForLevelChange();
}
};
struct CInfo
@@ -111,6 +143,8 @@ namespace NCompression
CBoolPair HardLinks;
CBoolPair SymLinks;
CBoolPair PreserveATime;
void Save() const;
void Load();
};
@@ -152,9 +186,18 @@ struct CContextMenuInfo
CBoolPair Cascaded;
CBoolPair MenuIcons;
CBoolPair ElimDup;
bool Flags_Def;
UInt32 Flags;
UInt32 WriteZone;
/*
CContextMenuInfo():
Flags_Def(0),
WriteZone((UInt32)(Int32)-1),
Flags((UInt32)(Int32)-1)
{}
*/
void Save() const;
void Load();

View File

@@ -56,6 +56,9 @@ HRESULT CExtractScanConsole::ScanProgress(const CDirItemsStat &st, const FString
HRESULT CExtractScanConsole::ScanError(const FString &path, DWORD systemError)
{
// 22.00:
// ScanErrors.AddError(path, systemError);
ClosePercentsAndFlush();
if (_se)
@@ -66,6 +69,10 @@ HRESULT CExtractScanConsole::ScanError(const FString &path, DWORD systemError)
_se->Flush();
}
return HRESULT_FROM_WIN32(systemError);
// 22.00: commented
// CommonError(path, systemError, true);
// return S_OK;
}

View File

@@ -15,12 +15,33 @@
#include "OpenCallbackConsole.h"
/*
struct CErrorPathCodes2
{
FStringVector Paths;
CRecordVector<DWORD> Codes;
void AddError(const FString &path, DWORD systemError)
{
Paths.Add(path);
Codes.Add(systemError);
}
void Clear()
{
Paths.Clear();
Codes.Clear();
}
};
*/
class CExtractScanConsole: public IDirItemsCallback
{
CStdOutStream *_so;
CStdOutStream *_se;
CPercentPrinter _percent;
// CErrorPathCodes2 ScanErrors;
bool NeedPercents() const { return _percent._so != NULL; }
void ClosePercentsAndFlush()

View File

@@ -124,6 +124,13 @@ static const char * const kPropIdToName[] =
, "Read-only"
, "Out Name"
, "Copy Link"
, "ArcFileName"
, "IsHash"
, "Metadata Changed"
, "User ID"
, "Group ID"
, "Device Major"
, "Device Minor"
};
static const char kEmptyAttribChar = '.';
@@ -303,22 +310,18 @@ struct CListUInt64Def
void Add(const CListUInt64Def &v) { if (v.Def) Add(v.Val); }
};
struct CListFileTimeDef
{
FILETIME Val;
bool Def;
CListFileTimeDef(): Def(false) { Val.dwLowDateTime = 0; Val.dwHighDateTime = 0; }
struct CListFileTimeDef: public CArcTime
{
void Update(const CListFileTimeDef &t)
{
if (t.Def && (!Def || CompareFileTime(&Val, &t.Val) < 0))
{
Val = t.Val;
Def = true;
}
if (t.Def && (!Def || CompareWith(t) < 0))
(*this) = t;
}
};
struct CListStat
{
CListUInt64Def Size;
@@ -493,12 +496,24 @@ void CFieldPrinter::PrintTitleLines()
g_StdOut << LinesString;
}
static void PrintTime(char *dest, const FILETIME *ft)
static void PrintTime(char *dest, const CListFileTimeDef &t, bool showNS)
{
*dest = 0;
if (ft->dwLowDateTime == 0 && ft->dwHighDateTime == 0)
if (t.IsZero())
return;
ConvertUtcFileTimeToString(*ft, dest, kTimestampPrintLevel_SEC);
int prec = kTimestampPrintLevel_SEC;
if (showNS)
{
prec = kTimestampPrintLevel_NTFS;
if (t.Prec != 0)
{
prec = t.GetNumDigits();
if (prec < kTimestampPrintLevel_DAY)
prec = kTimestampPrintLevel_NTFS;
}
}
ConvertUtcFileTimeToString2(t.FT, t.Ns100, dest, prec);
}
#ifndef _SFX
@@ -631,7 +646,13 @@ HRESULT CFieldPrinter::PrintItemInfo(UInt32 index, const CListStat &st)
{
case kpidSize: if (st.Size.Def) prop = st.Size.Val; break;
case kpidPackSize: if (st.PackSize.Def) prop = st.PackSize.Val; break;
case kpidMTime: if (st.MTime.Def) prop = st.MTime.Val; break;
case kpidMTime:
{
const CListFileTimeDef &mtime = st.MTime;
if (mtime.Def)
prop.SetAsTimeFrom_FT_Prec_Ns100(mtime.FT, mtime.Prec, mtime.Ns100);
break;
}
default:
RINOK(Arc->Archive->GetProperty(index, f.PropID, &prop));
}
@@ -653,7 +674,9 @@ HRESULT CFieldPrinter::PrintItemInfo(UInt32 index, const CListStat &st)
}
else if (prop.vt == VT_FILETIME)
{
PrintTime(temp + tempPos, &prop.filetime);
CListFileTimeDef t;
t.Set_From_Prop(prop);
PrintTime(temp + tempPos, t, techMode);
if (techMode)
g_StdOut << temp + tempPos;
else
@@ -726,7 +749,7 @@ void CFieldPrinter::PrintSum(const CListStat &st, UInt64 numDirs, const char *st
char s[64];
s[0] = 0;
if (st.MTime.Def)
PrintTime(s, &st.MTime.Val);
PrintTime(s, st.MTime, false); // showNS
PrintString(f.TextAdjustment, f.Width, s);
}
else if (f.PropID == kpidPath)
@@ -770,16 +793,14 @@ static HRESULT GetUInt64Value(IInArchive *archive, UInt32 index, PROPID propID,
static HRESULT GetItemMTime(IInArchive *archive, UInt32 index, CListFileTimeDef &t)
{
t.Val.dwLowDateTime = 0;
t.Val.dwHighDateTime = 0;
t.Def = false;
/* maybe we could call CArc::GetItemMTime(UInt32 index, CArcTime &ft, bool &defined) here
that can set default timestamp, if not defined */
t.Clear();
// t.Def = false;
CPropVariant prop;
RINOK(archive->GetProperty(index, kpidMTime, &prop));
if (prop.vt == VT_FILETIME)
{
t.Val = prop.filetime;
t.Def = true;
}
t.Set_From_Prop(prop);
else if (prop.vt != VT_EMPTY)
return E_FAIL;
return S_OK;
@@ -879,7 +900,8 @@ static void PrintPropPair(CStdOutStream &so, const char *name, const wchar_t *va
static void PrintPropertyPair2(CStdOutStream &so, PROPID propID, const wchar_t *name, const CPropVariant &prop)
{
UString s;
ConvertPropertyToString2(s, prop, propID);
const int levelTopLimit = 9; // 1ns level
ConvertPropertyToString2(s, prop, propID, levelTopLimit);
if (!s.IsEmpty())
{
AString nameA;
@@ -1249,7 +1271,7 @@ HRESULT ListArchives(
if (NConsoleClose::TestBreakSignal())
return E_ABORT;
HRESULT res = arc.GetItemPath2(i, fp.FilePath);
HRESULT res = arc.GetItem_Path2(i, fp.FilePath);
if (stdInMode && res == E_INVALIDARG)
break;

View File

@@ -75,6 +75,8 @@ extern const CHasherInfo *g_Hashers[];
const CExternalCodecs *g_ExternalCodecs_Ptr;
#endif
DECLARE_AND_SET_CLIENT_VERSION_VAR
#if defined(PROG_VARIANT_Z)
#define PROG_POSTFIX "z"
#define PROG_POSTFIX_2 " (z)"
@@ -510,7 +512,7 @@ static void PrintStat()
, &creationTimeFT, &exitTimeFT, &kernelTimeFT, &userTimeFT))
return;
FILETIME curTimeFT;
NTime::GetCurUtcFileTime(curTimeFT);
NTime::GetCurUtc_FiTime(curTimeFT);
#ifndef UNDER_CE
@@ -845,7 +847,7 @@ int Main2(
#if !defined(UNDER_CE)
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo))
consoleWidth = (unsigned)consoleInfo.dwSize.X;
consoleWidth = (unsigned)(unsigned short)consoleInfo.dwSize.X;
#endif
#else
@@ -859,7 +861,7 @@ int Main2(
CREATE_CODECS_OBJECT
codecs->CaseSensitiveChange = options.CaseSensitiveChange;
codecs->CaseSensitive_Change = options.CaseSensitive_Change;
codecs->CaseSensitive = options.CaseSensitive;
ThrowException_if_Error(codecs->Load());
Codecs_AddHashArcHandler(codecs);
@@ -952,9 +954,11 @@ int Main2(
so << endl << "Formats:" << endl;
const char * const kArcFlags = "KSNFMGOPBELHXC";
const char * const kArcFlags = "KSNFMGOPBELHXCc+a+m+r+";
const char * const kArcTimeFlags = "wudn";
const unsigned kNumArcFlags = (unsigned)strlen(kArcFlags);
const unsigned kNumArcTimeFlags = (unsigned)strlen(kArcTimeFlags);
for (i = 0; i < codecs->Formats.Size(); i++)
{
const CArcInfoEx &arc = codecs->Formats[i];
@@ -967,12 +971,22 @@ int Main2(
so << (char)(arc.UpdateEnabled ? 'C' : ' ');
for (unsigned b = 0; b < kNumArcFlags; b++)
{
so << (char)
((arc.Flags & ((UInt32)1 << b)) != 0 ? kArcFlags[b] : ' ');
unsigned b;
for (b = 0; b < kNumArcFlags; b++)
so << (char)((arc.Flags & ((UInt32)1 << b)) != 0 ? kArcFlags[b] : '.');
so << ' ';
}
if (arc.TimeFlags != 0)
{
unsigned b;
for (b = 0; b < kNumArcTimeFlags; b++)
so << (char)((arc.TimeFlags & ((UInt32)1 << b)) != 0 ? kArcTimeFlags[b] : '.');
so << arc.Get_DefaultTimePrec();
so << ' ';
}
so << ' ';
PrintString(so, arc.Name, 8);
so << ' ';

View File

@@ -63,7 +63,8 @@ void CPercentPrinter::GetPercents()
{
char c = '%';
UInt64 val = 0;
if (Total == (UInt64)(Int64)-1)
if (Total == (UInt64)(Int64)-1 ||
(Total == 0 && Completed != 0))
{
val = Completed >> 20;
c = 'M';

View File

@@ -11,6 +11,8 @@
#include "../../../Windows/Synchronization.h"
#endif
// #include "../Common/PropIDUtils.h"
#include "ConsoleClose.h"
#include "UserInputUtils.h"
#include "UpdateCallbackConsole.h"
@@ -195,6 +197,22 @@ void CCallbackConsoleBase::CommonError(const FString &path, DWORD systemError, b
}
}
/*
void CCallbackConsoleBase::CommonError(const char *message)
{
ClosePercents2();
if (_se)
{
if (_so)
_so->Flush();
*_se << endl << kError << message << endl;
_se->Flush();
}
}
*/
HRESULT CCallbackConsoleBase::ScanError_Base(const FString &path, DWORD systemError)
{
@@ -519,6 +537,28 @@ HRESULT CCallbackConsoleBase::PrintProgress(const wchar_t *name, bool isDir, con
return CheckBreak2();
}
/*
void CCallbackConsoleBase::PrintInfoLine(const UString &s)
{
if (LogLevel < 1000)
return;
MT_LOCK
const bool show2 = (_so != NULL);
if (show2)
{
ClosePercents_for_so();
_so->PrintUString(s, _tempA);
*_so << endl;
if (NeedFlush)
_so->Flush();
}
}
*/
HRESULT CUpdateCallbackConsole::GetStream(const wchar_t *name, bool isDir, bool isAnti, UInt32 mode)
{
if (StdOutMode)
@@ -562,10 +602,19 @@ HRESULT CUpdateCallbackConsole::ReadingFileError(const FString &path, DWORD syst
return ReadingFileError_Base(path, systemError);
}
HRESULT CUpdateCallbackConsole::SetOperationResult(Int32)
HRESULT CUpdateCallbackConsole::SetOperationResult(Int32 /* opRes */)
{
MT_LOCK
_percent.Files++;
/*
if (opRes != NArchive::NUpdate::NOperationResult::kOK)
{
if (opRes == NArchive::NUpdate::NOperationResult::kError_FileChanged)
{
CommonError("Input file changed");
}
}
*/
return S_OK;
}
@@ -616,6 +665,8 @@ HRESULT CUpdateCallbackConsole::ReportUpdateOperation(UInt32 op, const wchar_t *
case NUpdateNotifyOp::kSkip: s = "."; requiredLevel = 2; break;
case NUpdateNotifyOp::kDelete: s = "D"; requiredLevel = 3; break;
case NUpdateNotifyOp::kHeader: s = "Header creation"; requiredLevel = 100; break;
case NUpdateNotifyOp::kInFileChanged: s = "Size of input file was changed:"; requiredLevel = 10; break;
// case NUpdateNotifyOp::kOpFinished: s = "Finished"; requiredLevel = 100; break;
default:
{
temp[0] = 'o';
@@ -710,3 +761,119 @@ HRESULT CUpdateCallbackConsole::ShowDeleteFile(const wchar_t *name, bool isDir)
}
return S_OK;
}
/*
void GetPropName(PROPID propID, const wchar_t *name, AString &nameA, UString &nameU);
static void GetPropName(PROPID propID, UString &nameU)
{
AString nameA;
GetPropName(propID, NULL, nameA, nameU);
// if (!nameA.IsEmpty())
nameU = nameA;
}
static void AddPropNamePrefix(UString &s, PROPID propID)
{
UString name;
GetPropName(propID, name);
s += name;
s += " = ";
}
void CCallbackConsoleBase::PrintPropInfo(UString &s, PROPID propID, const PROPVARIANT *value)
{
AddPropNamePrefix(s, propID);
{
UString dest;
const int level = 9; // we show up to ns precision level
ConvertPropertyToString2(dest, *value, propID, level);
s += dest;
}
PrintInfoLine(s);
}
static void Add_IndexType_Index(UString &s, UInt32 indexType, UInt32 index)
{
if (indexType == NArchive::NEventIndexType::kArcProp)
{
}
else
{
if (indexType == NArchive::NEventIndexType::kBlockIndex)
{
s += "#";
}
else if (indexType == NArchive::NEventIndexType::kOutArcIndex)
{
}
else
{
s += "indexType_";
s.Add_UInt32(indexType);
s.Add_Space();
}
s.Add_UInt32(index);
}
s += ": ";
}
HRESULT CUpdateCallbackConsole::ReportProp(UInt32 indexType, UInt32 index, PROPID propID, const PROPVARIANT *value)
{
UString s;
Add_IndexType_Index(s, indexType, index);
PrintPropInfo(s, propID, value);
return S_OK;
}
static inline char GetHex(Byte value)
{
return (char)((value < 10) ? ('0' + value) : ('a' + (value - 10)));
}
static void AddHexToString(UString &dest, const Byte *data, UInt32 size)
{
for (UInt32 i = 0; i < size; i++)
{
Byte b = data[i];
dest += GetHex((Byte)((b >> 4) & 0xF));
dest += GetHex((Byte)(b & 0xF));
}
}
void HashHexToString(char *dest, const Byte *data, UInt32 size);
HRESULT CUpdateCallbackConsole::ReportRawProp(UInt32 indexType, UInt32 index,
PROPID propID, const void *data, UInt32 dataSize, UInt32 propType)
{
UString s;
propType = propType;
Add_IndexType_Index(s, indexType, index);
AddPropNamePrefix(s, propID);
if (propID == kpidChecksum)
{
char temp[k_HashCalc_DigestSize_Max + 8];
HashHexToString(temp, (const Byte *)data, dataSize);
s += temp;
}
else
AddHexToString(s, (const Byte *)data, dataSize);
PrintInfoLine(s);
return S_OK;
}
HRESULT CUpdateCallbackConsole::ReportFinished(UInt32 indexType, UInt32 index, Int32 opRes)
{
UString s;
Add_IndexType_Index(s, indexType, index);
s += "finished";
if (opRes != NArchive::NUpdate::NOperationResult::kOK)
{
s += ": ";
s.Add_UInt32(opRes);
}
PrintInfoLine(s);
return S_OK;
}
*/

View File

@@ -35,7 +35,8 @@ protected:
CStdOutStream *_se;
void CommonError(const FString &path, DWORD systemError, bool isWarning);
// void CommonError(const char *message);
HRESULT ScanError_Base(const FString &path, DWORD systemError);
HRESULT OpenFileError_Base(const FString &name, DWORD systemError);
HRESULT ReadingFileError_Base(const FString &name, DWORD systemError);
@@ -89,6 +90,8 @@ public:
HRESULT PrintProgress(const wchar_t *name, bool isDir, const char *command, bool showInLog);
// void PrintInfoLine(const UString &s);
// void PrintPropInfo(UString &s, PROPID propID, const PROPVARIANT *value);
};
class CUpdateCallbackConsole: public IUpdateCallbackUI2, public CCallbackConsoleBase

View File

@@ -102,6 +102,7 @@ CZipContextMenu::CZipContextMenu():
_isMenuForFM(false),
_dropMode(false),
_bitmap(NULL),
_writeZone((UInt32)(Int32)-1),
IsSeparator(false),
IsRoot(true),
CurrentSubCommand(0)
@@ -574,6 +575,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
ci.Load();
_elimDup = ci.ElimDup;
_writeZone = ci.WriteZone;
HBITMAP bitmap = NULL;
if (ci.MenuIcons.Val)
@@ -1181,7 +1183,8 @@ HRESULT CZipContextMenu::InvokeCommandCommon(const CCommandMapItem &cmi)
{
ExtractArchives(_fileNames, cmi.Folder,
(cmdID == kExtract), // showDialog
(cmdID == kExtractTo) && _elimDup.Val // elimDup
(cmdID == kExtractTo) && _elimDup.Val, // elimDup
_writeZone
);
break;
}

View File

@@ -138,6 +138,7 @@ private:
HBITMAP _bitmap;
CBoolPair _elimDup;
UInt32 _writeZone;
bool IsSeparator;
bool IsRoot;

View File

@@ -2,11 +2,19 @@
#include "StdAfx.h"
#if defined(_MSC_VER)
#include <winternl.h>
#else
// mingw
#include <ddk/winddk.h>
#endif
#include "../../../Common/ComTry.h"
#include "../../../Common/Defs.h"
#include "../../../Common/StringConvert.h"
#include "../../../Common/UTFConvert.h"
#include "../../../Windows/DLL.h"
#include "../../../Windows/FileDir.h"
#include "../../../Windows/FileIO.h"
#include "../../../Windows/FileName.h"
@@ -56,12 +64,15 @@ static const Byte kProps[] =
kpidMTime,
kpidCTime,
kpidATime,
#ifdef FS_SHOW_LINKS_INFO
kpidChangeTime,
#endif
kpidAttrib,
kpidPackSize,
#ifdef FS_SHOW_LINKS_INFO
#ifdef FS_SHOW_LINKS_INFO
kpidINode,
kpidLinks,
#endif
#endif
kpidComment,
kpidNumSubDirs,
kpidNumSubFiles,
@@ -199,19 +210,23 @@ HRESULT CFSFolder::LoadSubItems(int dirItem, const FString &relPrefix)
*/
}
#ifndef UNDER_CE
#ifndef UNDER_CE
fi.Reparse.Free();
fi.PackSize_Defined = false;
#ifdef FS_SHOW_LINKS_INFO
#ifdef FS_SHOW_LINKS_INFO
fi.FileInfo_Defined = false;
fi.FileInfo_WasRequested = false;
fi.FileIndex = 0;
fi.NumLinks = 0;
#endif
fi.ChangeTime_Defined = false;
fi.ChangeTime_WasRequested = false;
#endif
fi.PackSize = fi.Size;
#ifdef FS_SHOW_LINKS_INFO
if (fi.HasReparsePoint())
{
fi.FileInfo_WasRequested = true;
@@ -221,8 +236,9 @@ HRESULT CFSFolder::LoadSubItems(int dirItem, const FString &relPrefix)
fi.FileIndex = (((UInt64)info.nFileIndexHigh) << 32) + info.nFileIndexLow;
fi.FileInfo_Defined = true;
}
#endif
#endif
#endif // UNDER_CE
/* unsigned fileIndex = */ Files.Add(fi);
@@ -396,7 +412,9 @@ STDMETHODIMP_(UInt64) CFSFolder::GetItemSize(UInt32 index)
#endif
#ifdef FS_SHOW_LINKS_INFO
bool CFSFolder::ReadFileInfo(CDirItem &di)
{
di.FileInfo_WasRequested = true;
@@ -409,7 +427,71 @@ bool CFSFolder::ReadFileInfo(CDirItem &di)
di.FileInfo_Defined = true;
return true;
}
#endif
typedef struct
{
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
ULONG FileAttributes;
UInt32 Reserved; // it's expected for alignment
}
MY__FILE_BASIC_INFORMATION;
typedef enum
{
MY__FileDirectoryInformation = 1,
MY__FileFullDirectoryInformation,
MY__FileBothDirectoryInformation,
MY__FileBasicInformation
}
MY__FILE_INFORMATION_CLASS;
typedef NTSTATUS (WINAPI * Func_NtQueryInformationFile)(
HANDLE handle, IO_STATUS_BLOCK *io,
void *ptr, LONG len, MY__FILE_INFORMATION_CLASS cls);
#define MY__STATUS_SUCCESS 0
static Func_NtQueryInformationFile f_NtQueryInformationFile;
static bool g_NtQueryInformationFile_WasRequested = false;
void CFSFolder::ReadChangeTime(CDirItem &di)
{
di.ChangeTime_WasRequested = true;
if (!g_NtQueryInformationFile_WasRequested)
{
g_NtQueryInformationFile_WasRequested = true;
f_NtQueryInformationFile = (Func_NtQueryInformationFile)
My_GetProcAddress(::GetModuleHandleW(L"ntdll.dll"),
"NtQueryInformationFile");
}
if (!f_NtQueryInformationFile)
return;
NIO::CInFile file;
if (!file.Open_for_ReadAttributes(_path + GetRelPath(di)))
return;
MY__FILE_BASIC_INFORMATION fbi;
IO_STATUS_BLOCK IoStatusBlock;
const NTSTATUS status = f_NtQueryInformationFile(file.GetHandle(), &IoStatusBlock,
&fbi, sizeof(fbi), MY__FileBasicInformation);
if (status != MY__STATUS_SUCCESS)
return;
if (IoStatusBlock.Information != sizeof(fbi))
return;
di.ChangeTime.dwLowDateTime = fbi.ChangeTime.u.LowPart;
di.ChangeTime.dwHighDateTime = fbi.ChangeTime.u.HighPart;
di.ChangeTime_Defined = true;
}
#endif // FS_SHOW_LINKS_INFO
STDMETHODIMP CFSFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
@@ -492,7 +574,14 @@ STDMETHODIMP CFSFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
prop = fi.FileIndex;
#endif
break;
case kpidChangeTime:
if (!fi.ChangeTime_WasRequested)
ReadChangeTime(fi);
if (fi.ChangeTime_Defined)
prop = fi.ChangeTime;
break;
#endif
case kpidAttrib: prop = (UInt32)fi.Attrib; break;

View File

@@ -18,6 +18,7 @@ namespace NFsFolder {
class CFSFolder;
#define FS_SHOW_LINKS_INFO
// #define FS_SHOW_CHANGE_TIME
struct CDirItem: public NWindows::NFile::NFind::CFileInfo
{
@@ -26,10 +27,13 @@ struct CDirItem: public NWindows::NFile::NFind::CFileInfo
#endif
#ifdef FS_SHOW_LINKS_INFO
FILETIME ChangeTime;
UInt64 FileIndex;
UInt32 NumLinks;
bool FileInfo_Defined;
bool FileInfo_WasRequested;
bool ChangeTime_Defined;
bool ChangeTime_WasRequested;
#endif
#ifndef UNDER_CE
@@ -158,6 +162,7 @@ private:
#ifdef FS_SHOW_LINKS_INFO
bool ReadFileInfo(CDirItem &di);
void ReadChangeTime(CDirItem &di);
#endif
public:

View File

@@ -12,7 +12,20 @@ void ShowHelpWindow(LPCSTR)
#else
// #define USE_EXTERNAL_HELP
#if defined(_MSC_VER)
#endif
#ifdef USE_EXTERNAL_HELP
#include "../../../Windows/ProcessUtils.h"
#include "../../../Windows/FileDir.h"
#include "../../../Windows/FileName.h"
#else
#include <HtmlHelp.h>
#endif
#include "../../../Common/StringConvert.h"
@@ -25,8 +38,37 @@ void ShowHelpWindow(LPCSTR topicFile)
FString path = NWindows::NDLL::GetModuleDirPrefix();
path += kHelpFileName;
path += topicFile;
#ifdef USE_EXTERNAL_HELP
FString prog;
#ifdef UNDER_CE
prog = "\\Windows\\";
#else
if (!NWindows::NFile::NDir::GetWindowsDir(prog))
return;
NWindows::NFile::NName::NormalizeDirPathPrefix(prog);
#endif
prog += "hh.exe";
UString params;
params += '"';
params += fs2us(path);
params += '"';
NWindows::CProcess process;
const WRes wres = process.Create(fs2us(prog), params, NULL); // curDir);
if (wres != 0)
{
/*
HRESULT hres = HRESULT_FROM_WIN32(wres);
ErrorMessageHRESULT(hres, imageName);
return hres;
*/
}
#else
// HWND hwnd = NULL;
HtmlHelp(NULL, GetSystemString(fs2us(path)), HH_DISPLAY_TOPIC, 0);
#endif
}
#endif

View File

@@ -32,6 +32,7 @@ static const UInt32 kLangIDs[] =
IDX_SYSTEM_CASCADED_MENU,
IDX_SYSTEM_ICON_IN_MENU,
IDX_EXTRACT_ELIM_DUP,
IDT_SYSTEM_ZONE,
IDT_SYSTEM_CONTEXT_MENU_ITEMS
};
@@ -80,6 +81,16 @@ extern bool g_Is_Wow64;
#define KEY_WOW64_32KEY (0x0200)
#endif
static void LoadLang_Spec(UString &s, UInt32 id, const char *eng)
{
LangString(id, s);
if (s.IsEmpty())
s = eng;
s.RemoveChar(L'&');
}
bool CMenuPage::OnInit()
{
_initMode = true;
@@ -176,6 +187,44 @@ bool CMenuPage::OnInit()
CheckButton(IDX_EXTRACT_ELIM_DUP, ci.ElimDup.Val);
_listView.Attach(GetItem(IDL_SYSTEM_OPTIONS));
_zoneCombo.Attach(GetItem(IDC_SYSTEM_ZONE));
{
unsigned wz = ci.WriteZone;
if (wz == (UInt32)(Int32)-1)
wz = 0;
for (unsigned i = 0; i <= 3; i++)
{
unsigned val = i;
UString s;
if (i == 3)
{
if (wz < 3)
break;
val = wz;
}
else
{
#define MY_IDYES 406
#define MY_IDNO 407
if (i == 0)
LoadLang_Spec(s, MY_IDNO, "No");
else if (i == 1)
LoadLang_Spec(s, MY_IDYES, "Yes");
else
LangString(IDT_ZONE_FOR_OFFICE, s);
}
if (s.IsEmpty())
s.Add_UInt32(val);
if (i == 0)
s.Insert(0, L"* ");
const int index = (int)_zoneCombo.AddString(s);
_zoneCombo.SetItemData(index, val);
if (val == wz)
_zoneCombo.SetCurSel(index);
}
}
const UInt32 newFlags = LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT;
_listView.SetExtendedListViewStyle(newFlags, newFlags);
@@ -266,7 +315,11 @@ LONG CMenuPage::OnApply()
#endif
if (_cascaded_Changed || _menuIcons_Changed || _elimDup_Changed || _flags_Changed)
if (_cascaded_Changed
|| _menuIcons_Changed
|| _elimDup_Changed
|| _writeZone_Changed
|| _flags_Changed)
{
CContextMenuInfo ci;
ci.Cascaded.Val = IsButtonCheckedBool(IDX_SYSTEM_CASCADED_MENU);
@@ -278,6 +331,13 @@ LONG CMenuPage::OnApply()
ci.ElimDup.Val = IsButtonCheckedBool(IDX_EXTRACT_ELIM_DUP);
ci.ElimDup.Def = _elimDup_Changed;
{
int zoneIndex = (int)_zoneCombo.GetItemData_of_CurSel();
if (zoneIndex <= 0)
zoneIndex = -1;
ci.WriteZone = (UInt32)(Int32)zoneIndex;
}
ci.Flags = 0;
for (unsigned i = 0; i < ARRAY_SIZE(kMenuItems); i++)
@@ -321,6 +381,7 @@ bool CMenuPage::OnButtonClicked(int buttonID, HWND buttonHWND)
case IDX_SYSTEM_CASCADED_MENU: _cascaded_Changed = true; break;
case IDX_SYSTEM_ICON_IN_MENU: _menuIcons_Changed = true; break;
case IDX_EXTRACT_ELIM_DUP: _elimDup_Changed = true; break;
// case IDX_EXTRACT_WRITE_ZONE: _writeZone_Changed = true; break;
default:
return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
@@ -330,6 +391,19 @@ bool CMenuPage::OnButtonClicked(int buttonID, HWND buttonHWND)
return true;
}
bool CMenuPage::OnCommand(int code, int itemID, LPARAM param)
{
if (code == CBN_SELCHANGE && itemID == IDC_SYSTEM_ZONE)
{
_writeZone_Changed = true;
Changed();
return true;
}
return CPropertyPage::OnCommand(code, itemID, param);
}
bool CMenuPage::OnNotify(UINT controlID, LPNMHDR lParam)
{
if (lParam->hwndFrom == HWND(_listView))

View File

@@ -4,6 +4,7 @@
#define __MENU_PAGE_H
#include "../../../Windows/Control/PropertyPage.h"
#include "../../../Windows/Control/ComboBox.h"
#include "../../../Windows/Control/ListView.h"
struct CShellDll
@@ -24,6 +25,7 @@ class CMenuPage: public NWindows::NControl::CPropertyPage
bool _cascaded_Changed;
bool _menuIcons_Changed;
bool _elimDup_Changed;
bool _writeZone_Changed;
bool _flags_Changed;
void Clear_MenuChanged()
@@ -31,6 +33,7 @@ class CMenuPage: public NWindows::NControl::CPropertyPage
_cascaded_Changed = false;
_menuIcons_Changed = false;
_elimDup_Changed = false;
_writeZone_Changed = false;
_flags_Changed = false;
}
@@ -39,6 +42,7 @@ class CMenuPage: public NWindows::NControl::CPropertyPage
#endif
NWindows::NControl::CListView _listView;
NWindows::NControl::CComboBox _zoneCombo;
virtual bool OnInit();
virtual void OnNotifyHelp();
@@ -46,6 +50,7 @@ class CMenuPage: public NWindows::NControl::CPropertyPage
virtual bool OnItemChanged(const NMLISTVIEW *info);
virtual LONG OnApply();
virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
virtual bool OnCommand(int code, int itemID, LPARAM param);
public:
};

View File

@@ -1,6 +1,8 @@
#include "../GUI/ExtractDialogRes.h"
#define y 82
#define y 96
#define zoneX 90
CAPTION "7-Zip ZS"
BEGIN
@@ -10,8 +12,17 @@ BEGIN
CONTROL "Icons in context menu", IDX_SYSTEM_ICON_IN_MENU, MY_CHECKBOX, m, m + 42, xc, 10
CONTROL "Eliminate duplication of root folder", IDX_EXTRACT_ELIM_DUP, MY_CHECKBOX, m, m + 56, xc, 10
LTEXT "Context menu items:", IDT_SYSTEM_CONTEXT_MENU_ITEMS, m, m + 70, xc, 8
LTEXT "Propagate Zone.Id stream:", IDT_SYSTEM_ZONE, m, m + 70, xc - zoneX, 8
COMBOBOX IDC_SYSTEM_ZONE, m + xc - zoneX, m + 70 - 2, zoneX, 50, MY_COMBO
LTEXT "Context menu items:", IDT_SYSTEM_CONTEXT_MENU_ITEMS, m, m + 84, xc, 8
CONTROL "List", IDL_SYSTEM_OPTIONS, "SysListView32",
LVS_REPORT | LVS_SINGLESEL | LVS_NOCOLUMNHEADER | WS_BORDER | WS_TABSTOP,
m, m + y, xc, yc - y
END
STRINGTABLE
BEGIN
IDT_ZONE_FOR_OFFICE "For Office files"
END

View File

@@ -8,4 +8,8 @@
#define IDX_SYSTEM_INTEGRATE_TO_MENU_2 2310
#define IDT_SYSTEM_ZONE 3440
#define IDT_ZONE_FOR_OFFICE 3441
#define IDL_SYSTEM_OPTIONS 100
#define IDC_SYSTEM_ZONE 101

View File

@@ -380,7 +380,8 @@ void OnMenuActivating(HWND /* hWnd */, HMENU hMenu, int position)
kTimestampPrintLevel_MIN,
kTimestampPrintLevel_SEC,
// 1,2,3,4,5,6,
kTimestampPrintLevel_NTFS
kTimestampPrintLevel_NTFS,
kTimestampPrintLevel_NS
};
unsigned last = kMenuID_Time;

View File

@@ -20,6 +20,7 @@
#include "../Common/ArchiveName.h"
#include "../Common/CompressCall.h"
#include "../Common/ZipRegistry.h"
#include "../Agent/IFolderArchive.h"
@@ -971,9 +972,13 @@ void CPanel::ExtractArchives()
outFolder += '*';
outFolder.Add_PathSepar();
CContextMenuInfo ci;
ci.Load();
::ExtractArchives(paths, outFolder
, true // showDialog
, false // elimDup
, ci.WriteZone
);
}

View File

@@ -244,6 +244,9 @@ struct CCopyToOptions
bool replaceAltStreamChars;
bool showErrorMessages;
bool NeedRegistryZone;
NExtract::NZoneIdMode::EEnum ZoneIdMode;
UString folder;
UStringVector hashMethods;
@@ -258,6 +261,8 @@ struct CCopyToOptions
includeAltStreams(true),
replaceAltStreamChars(false),
showErrorMessages(false),
NeedRegistryZone(true),
ZoneIdMode(NExtract::NZoneIdMode::kNone),
VirtFileSystemSpec(NULL),
VirtFileSystem(NULL)
{}

View File

@@ -4,6 +4,8 @@
#include "../../../Common/MyException.h"
#include "../Common/ZipRegistry.h"
#include "../GUI/HashGUI.h"
#include "ExtractCallback.h"
@@ -70,6 +72,15 @@ HRESULT CPanelCopyThread::ProcessVirt()
HRESULT result2;
{
CMyComPtr<IFolderSetZoneIdMode> setZoneMode;
FolderOperations.QueryInterface(IID_IFolderSetZoneIdMode, &setZoneMode);
if (setZoneMode)
{
RINOK(setZoneMode->SetZoneIdMode(options->ZoneIdMode));
}
}
if (options->testMode)
{
CMyComPtr<IArchiveFolder> archiveFolder;
@@ -126,6 +137,14 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
UStringVector *messages,
bool &usePassword, UString &password)
{
if (options.NeedRegistryZone && !options.testMode)
{
CContextMenuInfo ci;
ci.Load();
if (ci.WriteZone != (UInt32)(Int32)-1)
options.ZoneIdMode = (NExtract::NZoneIdMode::EEnum)(int)(Int32)ci.WriteZone;
}
if (IsHashFolder())
{
if (!options.testMode)
@@ -221,7 +240,7 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
title = LangString(titleID);
}
UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE);
const UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE);
extracter.MainWindow = GetParent();
extracter.MainTitle = progressWindowTitle;

View File

@@ -351,6 +351,7 @@ HRESULT CApp::CalculateCrc2(const UString &methodName)
options.streamMode = true;
options.showErrorMessages = true;
options.hashMethods.Add(methodName);
options.NeedRegistryZone = false;
UStringVector messages;
return srcPanel.CopyTo(options, indices, &messages);

View File

@@ -1403,7 +1403,7 @@ static THREAD_FUNC_DECL MyThreadFunction(void *param)
}
/*
#if defined(_WIN32) && !defined(UNDER_CE)
static const FChar * const k_ZoneId_StreamName = FTEXT(":Zone.Identifier");
#endif
@@ -1441,6 +1441,7 @@ static bool WriteZoneFile(CFSTR fileName, const CByteBuffer &buf)
}
#endif
*/
/*
class CBufSeqOutStream_WithFile:
@@ -1654,6 +1655,7 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
password = fl.Password;
}
/*
#if defined(_WIN32) && !defined(UNDER_CE)
CByteBuffer zoneBuf;
#ifndef _UNICODE
@@ -1666,16 +1668,25 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
ReadZoneFile(fl.FilePath + k_ZoneId_StreamName, zoneBuf);
}
#endif
*/
CVirtFileSystem *virtFileSystemSpec = NULL;
CMyComPtr<ISequentialOutStream> virtFileSystem;
bool isAltStream = IsItem_AltStream(index);
const bool isAltStream = IsItem_AltStream(index);
CCopyToOptions options;
options.includeAltStreams = true;
options.replaceAltStreamChars = isAltStream;
{
// CContextMenuInfo ci;
// ci.Load();
// if (ci.WriteZone != (UInt32)(Int32)-1)
// we use kAll when we unpack just one file.
options.ZoneIdMode = NExtract::NZoneIdMode::kAll;
options.NeedRegistryZone = false;
}
if (tryAsArchive)
{
@@ -1706,7 +1717,7 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
options.folder = fs2us(tempDirNorm);
options.showErrorMessages = true;
HRESULT result = CopyTo(options, indices, &messages, usePassword, password);
const HRESULT result = CopyTo(options, indices, &messages, usePassword, password);
if (_parentFolders.Size() > 0)
{
@@ -1759,6 +1770,7 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
}
/*
#if defined(_WIN32) && !defined(UNDER_CE)
if (zoneBuf.Size() != 0)
{
@@ -1768,6 +1780,7 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
}
}
#endif
*/
if (tryAsArchive)

View File

@@ -29,6 +29,7 @@ static bool GetColumnVisible(PROPID propID, bool isFsFolder)
switch (propID)
{
case kpidATime:
case kpidChangeTime:
case kpidAttrib:
case kpidPackSize:
case kpidINode:
@@ -56,6 +57,7 @@ static int GetColumnAlign(PROPID propID, VARTYPE varType)
case kpidCTime:
case kpidATime:
case kpidMTime:
case kpidChangeTime:
return LVCFMT_LEFT;
}
@@ -201,7 +203,7 @@ HRESULT CPanel::InitColumns()
for (i = 0; i < _listViewInfo.Columns.Size(); i++)
{
const CColumnInfo &columnInfo = _listViewInfo.Columns[i];
int index = _columns.FindItem_for_PropID(columnInfo.PropID);
const int index = _columns.FindItem_for_PropID(columnInfo.PropID);
if (index >= 0)
{
CPropColumn &item = _columns[index];
@@ -650,7 +652,7 @@ HRESULT CPanel::RefreshListCtrl(const CSelectedState &state)
relPath += name;
if (relPath == state.FocusedName)
cursorIndex = listViewItemCount;
if (state.SelectedNames.FindInSorted(relPath) >= 0)
if (state.SelectedNames.FindInSorted(relPath) != -1)
selected = true;
}

View File

@@ -111,7 +111,7 @@ static void AddPropertyString(PROPID propID, const wchar_t *nameBSTR,
val = ConvertSizeToString(v);
}
else
ConvertPropertyToString2(val, prop, propID);
ConvertPropertyToString2(val, prop, propID, 9); // we send 9 - is ns precision
}
if (!val.IsEmpty())

View File

@@ -97,4 +97,11 @@ BEGIN
IDS_PROP_READ_ONLY "Read-only"
IDS_PROP_OUT_NAME "Out Name"
IDS_PROP_COPY_LINK "Copy Link"
IDS_PROP_ARC_FILE_NAME "ArcFileName"
IDS_PROP_IS_HASH "IsHash"
IDS_PROP_CHANGE_TIME "Metadata Changed"
IDS_PROP_USER_ID "User ID"
IDS_PROP_GROUP_ID "Group ID"
IDS_PROP_DEVICE_MAJOR "Device Major"
IDS_PROP_DEVICE_MINOR "Device Minor"
END

View File

@@ -93,3 +93,10 @@
#define IDS_PROP_READ_ONLY 1093
#define IDS_PROP_OUT_NAME 1094
#define IDS_PROP_COPY_LINK 1095
#define IDS_PROP_ARC_FILE_NAME 1096
#define IDS_PROP_IS_HASH 1097
#define IDS_PROP_CHANGE_TIME 1098
#define IDS_PROP_USER_ID 1099
#define IDS_PROP_GROUP_ID 1100
#define IDS_PROP_DEVICE_MAJOR 1101
#define IDS_PROP_DEVICE_MINOR 1102

View File

@@ -16,6 +16,7 @@
#include "../FileManager/BrowseDialog.h"
#include "../FileManager/FormatUtils.h"
#include "../FileManager/HelpUtils.h"
#include "../FileManager/PropertyName.h"
#include "../FileManager/SplitUtils.h"
#include "../Explorer/MyMessages.h"
@@ -36,6 +37,9 @@ extern bool g_IsNT;
#include "ExtractRes.h"
#ifdef LANG
// #define IDS_OPTIONS 2100
static const UInt32 kLangIDs[] =
{
IDT_COMPRESS_ARCHIVE,
@@ -49,6 +53,8 @@ static const UInt32 kLangIDs[] =
IDT_COMPRESS_THREADS,
IDT_COMPRESS_PARAMETERS,
IDB_COMPRESS_OPTIONS, // IDS_OPTIONS
IDG_COMPRESS_OPTIONS,
IDX_COMPRESS_SFX,
IDX_COMPRESS_SHARED,
@@ -57,11 +63,6 @@ static const UInt32 kLangIDs[] =
IDT_COMPRESS_MEMORY,
IDT_COMPRESS_MEMORY_DE,
IDX_COMPRESS_NT_SYM_LINKS,
IDX_COMPRESS_NT_HARD_LINKS,
IDX_COMPRESS_NT_ALT_STREAMS,
IDX_COMPRESS_NT_SECUR,
IDG_COMPRESS_ENCRYPTION,
IDT_COMPRESS_ENCRYPTION_METHOD,
IDX_COMPRESS_ENCRYPT_FILE_NAMES,
@@ -71,7 +72,7 @@ static const UInt32 kLangIDs[] =
IDX_PASSWORD_SHOW,
IDT_SPLIT_TO_VOLUMES,
IDT_COMPRESS_PATH_MODE
IDT_COMPRESS_PATH_MODE,
};
#endif
@@ -89,8 +90,6 @@ static const UInt32 kLzmaMaxDictSize = (UInt32)15 << 28;
static LPCSTR const kExeExt = ".exe";
#define k7zFormat "7z"
static const UInt32 g_Levels[] =
{
IDS_METHOD_STORE,
@@ -119,6 +118,8 @@ enum EMethodID
kSha1,
kCrc32,
kCrc64,
kGnu,
kPosix
};
static LPCSTR const kMethodsNames[] =
@@ -135,6 +136,8 @@ static LPCSTR const kMethodsNames[] =
, "SHA1"
, "CRC32"
, "CRC64"
, "GNU"
, "POSIX"
};
static const EMethodID g_7zMethods[] =
@@ -186,6 +189,12 @@ static const EMethodID g_SwfcMethods[] =
// kLZMA
};
static const EMethodID g_TarMethods[] =
{
kGnu,
kPosix
};
static const EMethodID g_HashMethods[] =
{
kSha256
@@ -202,6 +211,13 @@ static const UInt32 kFF_EncryptFileNames = 1 << 4;
static const UInt32 kFF_MemUse = 1 << 5;
static const UInt32 kFF_SFX = 1 << 6;
/*
static const UInt32 kFF_Time_Win = 1 << 10;
static const UInt32 kFF_Time_Unix = 1 << 11;
static const UInt32 kFF_Time_DOS = 1 << 12;
static const UInt32 kFF_Time_1ns = 1 << 13;
*/
struct CFormatInfo
{
LPCSTR Name;
@@ -233,23 +249,26 @@ static const CFormatInfo g_Formats[] =
kFF_MultiThread | kFF_MemUse
},
{
k7zFormat,
"7z",
(1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
METHODS_PAIR(g_7zMethods),
kFF_Filter | kFF_Solid | kFF_MultiThread | kFF_Encrypt |
kFF_EncryptFileNames | kFF_MemUse | kFF_SFX
// | kFF_Time_Win
},
{
"Zip",
(1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
METHODS_PAIR(g_ZipMethods),
kFF_MultiThread | kFF_Encrypt | kFF_MemUse
// | kFF_Time_Win | kFF_Time_Unix | kFF_Time_DOS
},
{
"GZip",
(1 << 1) | (1 << 5) | (1 << 7) | (1 << 9),
METHODS_PAIR(g_GZipMethods),
kFF_MemUse
// | kFF_Time_Unix
},
{
"BZip2",
@@ -272,14 +291,15 @@ static const CFormatInfo g_Formats[] =
{
"Tar",
(1 << 0),
0, NULL,
0
METHODS_PAIR(g_TarMethods),
// kFF_Time_Unix | kFF_Time_Win // | kFF_Time_1ns
},
{
"wim",
(1 << 0),
0, NULL,
0
// | kFF_Time_Win
},
{
"Hash",
@@ -335,22 +355,6 @@ static const UInt32 k_PathMode_IDs[] =
};
void AddComboItems(NControl::CComboBox &combo, const UInt32 *langIDs, unsigned numItems, const int *values, int curVal);
bool GetBoolsVal(const CBoolPair &b1, const CBoolPair &b2);
void CCompressDialog::CheckButton_TwoBools(UINT id, const CBoolPair &b1, const CBoolPair &b2)
{
CheckButton(id, GetBoolsVal(b1, b2));
}
void CCompressDialog::GetButton_Bools(UINT id, CBoolPair &b1, CBoolPair &b2)
{
bool val = IsButtonCheckedBool(id);
bool oldVal = GetBoolsVal(b1, b2);
if (val != oldVal)
b1.Def = b2.Def = true;
b1.Val = b2.Val = val;
}
void CCompressDialog::SetMethods(const CObjectVector<CCodecInfoUser> &userCodecs)
{
@@ -375,12 +379,13 @@ void CCompressDialog::SetMethods(const CObjectVector<CCodecInfoUser> &userCodecs
}
}
bool CCompressDialog::OnInit()
{
#ifdef LANG
LangSetWindowText(*this, IDD_COMPRESS);
LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs));
// LangSetDlgItemText(*this, IDB_COMPRESS_OPTIONS, IDS_OPTIONS); // IDG_COMPRESS_OPTIONS
#endif
{
@@ -435,11 +440,6 @@ bool CCompressDialog::OnInit()
CheckButton(IDX_PASSWORD_SHOW, m_RegistryInfo.ShowPassword);
CheckButton(IDX_COMPRESS_ENCRYPT_FILE_NAMES, m_RegistryInfo.EncryptHeaders);
CheckButton_TwoBools(IDX_COMPRESS_NT_SYM_LINKS, Info.SymLinks, m_RegistryInfo.SymLinks);
CheckButton_TwoBools(IDX_COMPRESS_NT_HARD_LINKS, Info.HardLinks, m_RegistryInfo.HardLinks);
CheckButton_TwoBools(IDX_COMPRESS_NT_ALT_STREAMS, Info.AltStreams, m_RegistryInfo.AltStreams);
CheckButton_TwoBools(IDX_COMPRESS_NT_SECUR, Info.NtSecurity, m_RegistryInfo.NtSecurity);
UpdatePasswordControl();
{
@@ -490,7 +490,7 @@ bool CCompressDialog::OnInit()
CheckButton(IDX_COMPRESS_SHARED, Info.OpenShareForWrite);
CheckButton(IDX_COMPRESS_DEL, Info.DeleteAfterCompressing);
FormatChanged();
FormatChanged(false); // isChanged
// OnButtonSFX();
@@ -552,6 +552,13 @@ bool CCompressDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
UpdatePasswordControl();
return true;
}
case IDB_COMPRESS_OPTIONS:
{
COptionsDialog dialog(this);
if (dialog.Create(*this) == IDOK)
ShowOptionsString();
return true;
}
}
return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
}
@@ -588,8 +595,44 @@ void CCompressDialog::EnableMultiCombo(unsigned id)
EnableItem(id, enable);
}
static LRESULT ComboBox_AddStringAscii(NControl::CComboBox &cb, const char *s);
static void FormatOptions_To_String(const NCompression::CFormatOptions &fo, AString &s);
void CCompressDialog::FormatChanged()
static void Combine_Two_BoolPairs(const CBoolPair &b1, const CBoolPair &b2, CBool1 &res)
{
if (!b1.Def && b2.Def)
res.Val = b2.Val;
else
res.Val = b1.Val;
}
#define SET_GUI_BOOL(name) \
Combine_Two_BoolPairs(Info. ## name, m_RegistryInfo. ## name, name)
static void Set_Final_BoolPairs(
const CBool1 &gui,
CBoolPair &cmd,
CBoolPair &reg)
{
if (!cmd.Def)
{
reg.Val = gui.Val;
reg.Def = gui.Val;
}
if (gui.Supported)
{
cmd.Val = gui.Val;
cmd.Def = gui.Val;
}
else
cmd.Init();
}
#define SET_FINAL_BOOL_PAIRS(name) \
Set_Final_BoolPairs(name, Info. ## name, m_RegistryInfo. ## name)
void CCompressDialog::FormatChanged(bool isChanged)
{
SetLevel();
SetSolidBlockSize();
@@ -615,18 +658,26 @@ void CCompressDialog::FormatChanged()
CheckSFXControlsEnable();
{
const CArcInfoEx &ai = Get_ArcInfoEx();
ShowItem_Bool(IDX_COMPRESS_NT_SYM_LINKS, ai.Flags_SymLinks());
ShowItem_Bool(IDX_COMPRESS_NT_HARD_LINKS, ai.Flags_HardLinks());
ShowItem_Bool(IDX_COMPRESS_NT_ALT_STREAMS, ai.Flags_AltStreams());
ShowItem_Bool(IDX_COMPRESS_NT_SECUR, ai.Flags_NtSecure());
if (!isChanged)
{
SET_GUI_BOOL (SymLinks);
SET_GUI_BOOL (HardLinks);
SET_GUI_BOOL (AltStreams);
SET_GUI_BOOL (NtSecurity);
SET_GUI_BOOL (PreserveATime);
}
ShowItem_Bool(IDG_COMPRESS_NTFS,
ai.Flags_SymLinks()
|| ai.Flags_HardLinks()
|| ai.Flags_AltStreams()
|| ai.Flags_NtSecure());
PreserveATime.Supported = true;
{
const CArcInfoEx &ai = Get_ArcInfoEx();
SymLinks.Supported = ai.Flags_SymLinks();
HardLinks.Supported = ai.Flags_HardLinks();
AltStreams.Supported = ai.Flags_AltStreams();
NtSecurity.Supported = ai.Flags_NtSecurity();
}
ShowOptionsString();
}
// CheckVolumeEnable();
@@ -821,7 +872,7 @@ void SetErrorMessage_MemUsage(UString &s, UInt64 reqSize, UInt64 ramSize, UInt64
s.Add_LF();
s.Add_LF();
s += LangString(IDS_MEM_ERROR);
AddLangString(s, IDS_MEM_ERROR);
}
@@ -933,17 +984,32 @@ void CCompressDialog::OnOK()
Info.EncryptHeaders = IsButtonCheckedBool(IDX_COMPRESS_ENCRYPT_FILE_NAMES);
GetButton_Bools(IDX_COMPRESS_NT_SYM_LINKS, Info.SymLinks, m_RegistryInfo.SymLinks);
GetButton_Bools(IDX_COMPRESS_NT_HARD_LINKS, Info.HardLinks, m_RegistryInfo.HardLinks);
GetButton_Bools(IDX_COMPRESS_NT_ALT_STREAMS, Info.AltStreams, m_RegistryInfo.AltStreams);
GetButton_Bools(IDX_COMPRESS_NT_SECUR, Info.NtSecurity, m_RegistryInfo.NtSecurity);
/* (Info) is for saving to registry:
(CBoolPair::Val) will be set as (false), if it was (false)
in registry at dialog creation, and user didn't click checkbox.
in another case (CBoolPair::Val) will be set as (true) */
{
const CArcInfoEx &ai = Get_ArcInfoEx();
if (!ai.Flags_SymLinks()) Info.SymLinks.Val = false;
if (!ai.Flags_HardLinks()) Info.HardLinks.Val = false;
if (!ai.Flags_AltStreams()) Info.AltStreams.Val = false;
if (!ai.Flags_NtSecure()) Info.NtSecurity.Val = false;
/* Info properties could be for another archive types.
so we disable unsupported properties in Info */
// const CArcInfoEx &ai = Get_ArcInfoEx();
SET_FINAL_BOOL_PAIRS (SymLinks);
SET_FINAL_BOOL_PAIRS (HardLinks);
SET_FINAL_BOOL_PAIRS (AltStreams);
SET_FINAL_BOOL_PAIRS (NtSecurity);
SET_FINAL_BOOL_PAIRS (PreserveATime);
}
{
const NCompression::CFormatOptions &fo = Get_FormatOptions();
Info.TimePrec = fo.TimePrec;
Info.MTime = fo.MTime;
Info.CTime = fo.CTime;
Info.ATime = fo.ATime;
Info.SetArcMTime = fo.SetArcMTime;
}
m_Params.GetText(Info.Options);
@@ -1031,7 +1097,7 @@ bool CCompressDialog::OnCommand(int code, int itemID, LPARAM lParam)
{
const bool isSFX = IsSFX();
SaveOptionsInMem();
FormatChanged();
FormatChanged(true); // isChanged
SetArchiveName2(isSFX);
return true;
}
@@ -1057,6 +1123,7 @@ bool CCompressDialog::OnCommand(int code, int itemID, LPARAM lParam)
SetMemoryUsage();
if (Get_ArcInfoEx().Flags_HashHandler())
SetArchiveName2(false);
return true;
}
@@ -1188,6 +1255,7 @@ void CCompressDialog::SetArchiveName(const UString &name)
m_ArchivePath.SetText(fileName);
}
int CCompressDialog::FindRegistryFormat(const UString &name)
{
FOR_VECTOR (i, m_RegistryInfo.Formats)
@@ -1199,7 +1267,8 @@ int CCompressDialog::FindRegistryFormat(const UString &name)
return -1;
}
int CCompressDialog::FindRegistryFormatAlways(const UString &name)
unsigned CCompressDialog::FindRegistryFormat_Always(const UString &name)
{
int index = FindRegistryFormat(name);
if (index < 0)
@@ -1211,6 +1280,14 @@ int CCompressDialog::FindRegistryFormatAlways(const UString &name)
return index;
}
NCompression::CFormatOptions &CCompressDialog::Get_FormatOptions()
{
const CArcInfoEx &ai = Get_ArcInfoEx();
return m_RegistryInfo.Formats[FindRegistryFormat_Always(ai.Name)];
}
int CCompressDialog::GetStaticFormatIndex()
{
const CArcInfoEx &ai = Get_ArcInfoEx();
@@ -1293,8 +1370,11 @@ void CCompressDialog::SetMethod2(int keepMethodId)
const CArcInfoEx &ai = Get_ArcInfoEx();
if (GetLevel() == 0 && !ai.Flags_HashHandler())
{
MethodChanged();
return;
if (!ai.Is_Tar())
{
MethodChanged();
return;
}
}
UString defaultMethod;
{
@@ -1308,7 +1388,7 @@ void CCompressDialog::SetMethod2(int keepMethodId)
const bool isSfx = IsSFX();
bool weUseSameMethod = false;
const bool is7z = ai.Name.IsEqualTo_Ascii_NoCase("7z");
const bool is7z = ai.Is_7z();
for (unsigned m = 0;; m++)
{
@@ -1367,12 +1447,12 @@ void CCompressDialog::SetMethod2(int keepMethodId)
bool CCompressDialog::IsZipFormat()
{
return Get_ArcInfoEx().Name.IsEqualTo_Ascii_NoCase("zip");
return Get_ArcInfoEx().Is_Zip();
}
bool CCompressDialog::IsXzFormat()
{
return Get_ArcInfoEx().Name.IsEqualTo_Ascii_NoCase("xz");
return Get_ArcInfoEx().Is_Xz();
}
void CCompressDialog::SetEncryptionMethod()
@@ -1380,13 +1460,13 @@ void CCompressDialog::SetEncryptionMethod()
_encryptionMethod.ResetContent();
_default_encryptionMethod_Index = -1;
const CArcInfoEx &ai = Get_ArcInfoEx();
if (ai.Name.IsEqualTo_Ascii_NoCase("7z"))
if (ai.Is_7z())
{
ComboBox_AddStringAscii(_encryptionMethod, "AES-256");
_encryptionMethod.SetCurSel(0);
_default_encryptionMethod_Index = 0;
}
else if (ai.Name.IsEqualTo_Ascii_NoCase("zip"))
else if (ai.Is_Zip())
{
int index = FindRegistryFormat(ai.Name);
UString encryptionMethod;
@@ -1929,7 +2009,7 @@ void CCompressDialog::SetSolidBlockSize2()
}
}
const bool is7z = ai.Name.IsEqualTo_Ascii_NoCase("7z");
const bool is7z = ai.Is_7z();
const UInt64 cs = Get_Lzma2_ChunkSize(dict);
@@ -2549,11 +2629,16 @@ void CCompressDialog::SetParams()
void CCompressDialog::SaveOptionsInMem()
{
/* these options are for (Info.FormatIndex).
If it's called just after format changing,
then it's format that was selected before format changing
So we store previous format properties */
m_Params.GetText(Info.Options);
Info.Options.Trim();
const CArcInfoEx &ai = (*ArcFormats)[Info.FormatIndex];
const int index = FindRegistryFormatAlways(ai.Name);
const unsigned index = FindRegistryFormat_Always(ai.Name);
NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index];
fo.Options = Info.Options;
fo.Level = GetLevelSpec();
@@ -2587,7 +2672,512 @@ void CCompressDialog::SaveOptionsInMem()
fo.MemUse = Get_MemUse_Spec();
}
unsigned CCompressDialog::GetFormatIndex()
{
return (unsigned)m_Format.GetItemData_of_CurSel();
}
static void AddText_from_BoolPair(AString &s, const char *name, const CBoolPair &bp)
{
if (bp.Def)
{
s.Add_OptSpaced(name);
if (!bp.Val)
s += "-";
}
/*
else if (bp.Val)
{
s.Add_OptSpaced("[");
s += name;
s += "]";
}
*/
}
static void AddText_from_Bool1(AString &s, const char *name, const CBool1 &b)
{
if (b.Supported && b.Val)
s.Add_OptSpaced(name);
}
void CCompressDialog::ShowOptionsString()
{
NCompression::CFormatOptions &fo = Get_FormatOptions();
AString s;
if (fo.TimePrec != -1)
{
s.Add_OptSpaced("tp");
s.Add_UInt32(fo.TimePrec);
}
AddText_from_BoolPair(s, "tm", fo.MTime);
AddText_from_BoolPair(s, "tc", fo.CTime);
AddText_from_BoolPair(s, "ta", fo.ATime);
AddText_from_BoolPair(s, "-stl", fo.SetArcMTime);
// const CArcInfoEx &ai = Get_ArcInfoEx();
AddText_from_Bool1(s, "SL", SymLinks);
AddText_from_Bool1(s, "HL", HardLinks);
AddText_from_Bool1(s, "AS", AltStreams);
AddText_from_Bool1(s, "Sec", NtSecurity);
// AddText_from_Bool1(s, "Preserve", PreserveATime);
SetItemText(IDT_COMPRESS_OPTIONS, GetUnicodeString(s));
}
// ---------- OPTIONS ----------
void COptionsDialog::CheckButton_Bool1(UINT id, const CBool1 &b1)
{
CheckButton(id, b1.Val);
}
void COptionsDialog::GetButton_Bool1(UINT id, CBool1 &b1)
{
b1.Val = IsButtonCheckedBool(id);
}
void COptionsDialog::CheckButton_BoolBox(
bool supported, const CBoolPair &b2, CBoolBox &bb)
{
const bool isSet = b2.Def;
const bool val = isSet ? b2.Val : bb.DefaultVal;
bb.IsSupported = supported;
CheckButton (bb.Set_Id, isSet);
ShowItem_Bool (bb.Set_Id, supported);
CheckButton (bb.Id, val);
EnableItem (bb.Id, isSet);
ShowItem_Bool (bb.Id, supported);
}
void COptionsDialog::GetButton_BoolBox(CBoolBox &bb)
{
// we save value for invisible buttons too
bb.BoolPair.Val = IsButtonCheckedBool (bb.Id);
bb.BoolPair.Def = IsButtonCheckedBool (bb.Set_Id);
}
void COptionsDialog::Store_TimeBoxes()
{
TimePrec = GetPrecSpec();
GetButton_BoolBox (MTime);
GetButton_BoolBox (CTime);
GetButton_BoolBox (ATime);
GetButton_BoolBox (ZTime);
}
UInt32 COptionsDialog::GetComboValue(NWindows::NControl::CComboBox &c, int defMax)
{
if (c.GetCount() <= defMax)
return (UInt32)(Int32)-1;
return (UInt32)c.GetItemData_of_CurSel();
}
static const unsigned kTimePrec_Win = 0;
static const unsigned kTimePrec_Unix = 1;
static const unsigned kTimePrec_DOS = 2;
static const unsigned kTimePrec_1ns = 3;
static void AddTimeOption(UString &s, UInt32 val, const UString &unit, const char *sys = NULL)
{
// s += " : ";
{
AString s2;
s2.Add_UInt32(val);
s += s2;
}
s.Add_Space();
s += unit;
if (sys)
{
s += " : ";
s += sys;
}
}
int COptionsDialog::AddPrec(unsigned prec, bool isDefault)
{
UString s;
UInt32 writePrec = prec;
if (isDefault)
{
// s += "* ";
// writePrec = (UInt32)(Int32)-1;
}
if (prec == kTimePrec_Win) AddTimeOption(s, 100, NsString, "Windows");
else if (prec == kTimePrec_Unix) AddTimeOption(s, 1, SecString, "Unix");
else if (prec == kTimePrec_DOS) AddTimeOption(s, 2, SecString, "DOS");
else if (prec == kTimePrec_1ns) AddTimeOption(s, 1, NsString, "Linux");
else if (prec == k_PropVar_TimePrec_Base) AddTimeOption(s, 1, SecString);
else if (prec >= k_PropVar_TimePrec_Base)
{
UInt32 d = 1;
for (unsigned i = prec; i < k_PropVar_TimePrec_Base + 9; i++)
d *= 10;
AddTimeOption(s, d, NsString);
}
else
s.Add_UInt32(prec);
const int index = (int)m_Prec.AddString(s);
m_Prec.SetItemData(index, writePrec);
return index;
}
void COptionsDialog::SetPrec()
{
// const CFormatInfo &fi = g_Formats[cd->GetStaticFormatIndex()];
const CArcInfoEx &ai = cd->Get_ArcInfoEx();
// UInt32 flags = fi.Flags;
UInt32 flags = ai.Get_TimePrecFlags();
UInt32 defaultPrec = ai.Get_DefaultTimePrec();
if (defaultPrec != 0)
flags |= ((UInt32)1 << defaultPrec);
// const NCompression::CFormatOptions &fo = cd->Get_FormatOptions();
// unsigned defaultPrec = kTimePrec_Win;
if (ai.Is_GZip())
defaultPrec = kTimePrec_Unix;
{
UString s;
s += GetNameOfProperty(kpidType, L"type");
s += ": ";
s += ai.Name;
if (ai.Is_Tar())
{
const int methodID = cd->GetMethodID();
// for debug
// defaultPrec = kTimePrec_Unix;
// flags = (UInt32)1 << kTimePrec_Unix;
s += ":";
if (methodID >= 0 && (unsigned)methodID < ARRAY_SIZE(kMethodsNames))
s += kMethodsNames[methodID];
if (methodID == kPosix)
{
// for debug
// flags |= (UInt32)1 << kTimePrec_Win;
// flags |= (UInt32)1 << kTimePrec_1ns;
}
}
else
{
// if (is_for_MethodChanging) return;
}
SetItemText(IDT_COMPRESS_TIME_INFO, s);
}
m_Prec.ResetContent();
_auto_Prec = defaultPrec;
unsigned selectedPrec = defaultPrec;
{
// if (TimePrec >= kTimePrec_Win && TimePrec <= kTimePrec_DOS)
if ((Int32)TimePrec >= 0)
selectedPrec = TimePrec;
}
int curSel = -1;
int defaultPrecIndex = -1;
for (unsigned prec = 0;
// prec <= k_PropVar_TimePrec_HighPrec;
prec <= k_PropVar_TimePrec_1ns;
prec++)
{
if (((flags >> prec) & 1) == 0)
continue;
const bool isDefault = (defaultPrec == prec);
const int index = AddPrec(prec, isDefault);
if (isDefault)
defaultPrecIndex = index;
if (selectedPrec == prec)
curSel = index;
}
if (curSel < 0 && selectedPrec > kTimePrec_DOS)
curSel = AddPrec(selectedPrec, false); // isDefault
if (curSel < 0)
curSel = defaultPrecIndex;
if (curSel >= 0)
m_Prec.SetCurSel(curSel);
{
const bool isSet = IsSet_TimePrec();
const int count = m_Prec.GetCount();
const bool showPrec = (count != 0);
ShowItem_Bool(IDC_COMPRESS_TIME_PREC, showPrec);
ShowItem_Bool(IDT_COMPRESS_TIME_PREC, showPrec);
EnableItem(IDC_COMPRESS_TIME_PREC, isSet && (count > 1));
CheckButton(IDX_COMPRESS_PREC_SET, isSet);
const bool setIsSupported = isSet || (count > 1);
EnableItem(IDX_COMPRESS_PREC_SET, setIsSupported);
ShowItem_Bool(IDX_COMPRESS_PREC_SET, setIsSupported);
}
SetTimeMAC();
}
void COptionsDialog::SetTimeMAC()
{
const CArcInfoEx &ai = cd->Get_ArcInfoEx();
const
bool m_allow = ai.Flags_MTime();
bool c_allow = ai.Flags_CTime();
bool a_allow = ai.Flags_ATime();
if (ai.Is_Tar())
{
const int methodID = cd->GetMethodID();
c_allow = false;
a_allow = false;
if (methodID == kPosix)
{
// c_allow = true; // do we need it as change time ?
a_allow = true;
}
}
if (ai.Is_Zip())
{
// const int methodID = GetMethodID();
UInt32 prec = GetPrec();
if (prec == (UInt32)(Int32)-1)
prec = _auto_Prec;
if (prec != kTimePrec_Win)
{
c_allow = false;
a_allow = false;
}
}
/*
MTime.DefaultVal = true;
CTime.DefaultVal = false;
ATime.DefaultVal = false;
*/
MTime.DefaultVal = ai.Flags_MTime_Default();
CTime.DefaultVal = ai.Flags_CTime_Default();
ATime.DefaultVal = ai.Flags_ATime_Default();
ZTime.DefaultVal = false;
const NCompression::CFormatOptions &fo = cd->Get_FormatOptions();
CheckButton_BoolBox (m_allow, fo.MTime, MTime );
CheckButton_BoolBox (c_allow, fo.CTime, CTime );
CheckButton_BoolBox (a_allow, fo.ATime, ATime );
CheckButton_BoolBox (true, fo.SetArcMTime, ZTime);
if (m_allow && !fo.MTime.Def)
{
const bool isSingleFile = ai.Flags_KeepName();
if (!isSingleFile)
{
// we can hide changing checkboxes for MTime here:
ShowItem_Bool (MTime.Set_Id, false);
EnableItem (MTime.Id, false);
}
}
// On_CheckBoxSet_Prec_Clicked();
// const bool isSingleFile = ai.Flags_KeepName();
// mtime for Gz can be
}
void COptionsDialog::On_CheckBoxSet_Prec_Clicked()
{
const bool isSet = IsButtonCheckedBool(IDX_COMPRESS_PREC_SET);
if (!isSet)
{
// We save current MAC boxes to memory before SetPrec()
Store_TimeBoxes();
Reset_TimePrec();
SetPrec();
}
EnableItem(IDC_COMPRESS_TIME_PREC, isSet);
}
void COptionsDialog::On_CheckBoxSet_Clicked(const CBoolBox &bb)
{
const bool isSet = IsButtonCheckedBool(bb.Set_Id);
if (!isSet)
CheckButton(bb.Id, bb.DefaultVal);
EnableItem(bb.Id, isSet);
}
#ifdef LANG
static const UInt32 kLangIDs_Options[] =
{
IDX_COMPRESS_NT_SYM_LINKS,
IDX_COMPRESS_NT_HARD_LINKS,
IDX_COMPRESS_NT_ALT_STREAMS,
IDX_COMPRESS_NT_SECUR,
IDG_COMPRESS_TIME,
IDT_COMPRESS_TIME_PREC,
IDX_COMPRESS_MTIME,
IDX_COMPRESS_CTIME,
IDX_COMPRESS_ATIME,
IDX_COMPRESS_ZTIME,
IDX_COMPRESS_PRESERVE_ATIME
};
#endif
bool COptionsDialog::OnInit()
{
#ifdef LANG
LangSetWindowText(*this, IDB_COMPRESS_OPTIONS); // IDS_OPTIONS
LangSetDlgItems(*this, kLangIDs_Options, ARRAY_SIZE(kLangIDs_Options));
// LangSetDlgItemText(*this, IDB_COMPRESS_TIME_DEFAULT, IDB_COMPRESS_TIME_DEFAULT);
// LangSetDlgItemText(*this, IDX_COMPRESS_TIME_DEFAULT, IDX_COMPRESS_TIME_DEFAULT);
#endif
LangString(IDS_COMPRESS_SEC, SecString);
if (SecString.IsEmpty())
SecString = "sec";
LangString(IDS_COMPRESS_NS, NsString);
if (NsString.IsEmpty())
NsString = "ns";
{
// const CArcInfoEx &ai = cd->Get_ArcInfoEx();
ShowItem_Bool ( IDX_COMPRESS_NT_SYM_LINKS, cd->SymLinks.Supported);
ShowItem_Bool ( IDX_COMPRESS_NT_HARD_LINKS, cd->HardLinks.Supported);
ShowItem_Bool ( IDX_COMPRESS_NT_ALT_STREAMS, cd->AltStreams.Supported);
ShowItem_Bool ( IDX_COMPRESS_NT_SECUR, cd->NtSecurity.Supported);
ShowItem_Bool ( IDG_COMPRESS_NTFS,
cd->SymLinks.Supported
|| cd->HardLinks.Supported
|| cd->AltStreams.Supported
|| cd->NtSecurity.Supported);
}
/* we read property from two sources:
1) command line : (Info)
2) registry : (m_RegistryInfo)
(Info) has priority, if both are no defined */
CheckButton_Bool1 ( IDX_COMPRESS_NT_SYM_LINKS, cd->SymLinks);
CheckButton_Bool1 ( IDX_COMPRESS_NT_HARD_LINKS, cd->HardLinks);
CheckButton_Bool1 ( IDX_COMPRESS_NT_ALT_STREAMS, cd->AltStreams);
CheckButton_Bool1 ( IDX_COMPRESS_NT_SECUR, cd->NtSecurity);
CheckButton_Bool1 (IDX_COMPRESS_PRESERVE_ATIME, cd->PreserveATime);
m_Prec.Attach (GetItem(IDC_COMPRESS_TIME_PREC));
MTime.SetIDs ( IDX_COMPRESS_MTIME, IDX_COMPRESS_MTIME_SET);
CTime.SetIDs ( IDX_COMPRESS_CTIME, IDX_COMPRESS_CTIME_SET);
ATime.SetIDs ( IDX_COMPRESS_ATIME, IDX_COMPRESS_ATIME_SET);
ZTime.SetIDs ( IDX_COMPRESS_ZTIME, IDX_COMPRESS_ZTIME_SET);
{
const NCompression::CFormatOptions &fo = cd->Get_FormatOptions();
TimePrec = fo.TimePrec;
MTime.BoolPair = fo.MTime;
CTime.BoolPair = fo.CTime;
ATime.BoolPair = fo.ATime;
ZTime.BoolPair = fo.SetArcMTime;
}
SetPrec();
NormalizePosition();
return CModalDialog::OnInit();
}
bool COptionsDialog::OnCommand(int code, int itemID, LPARAM lParam)
{
if (code == CBN_SELCHANGE)
{
switch (itemID)
{
case IDC_COMPRESS_TIME_PREC:
{
Store_TimeBoxes();
SetTimeMAC(); // for zip/tar
return true;
}
}
}
return CModalDialog::OnCommand(code, itemID, lParam);
}
bool COptionsDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
{
switch (buttonID)
{
case IDX_COMPRESS_PREC_SET: { On_CheckBoxSet_Prec_Clicked(); return true; }
case IDX_COMPRESS_MTIME_SET: { On_CheckBoxSet_Clicked (MTime); return true; }
case IDX_COMPRESS_CTIME_SET: { On_CheckBoxSet_Clicked (CTime); return true; }
case IDX_COMPRESS_ATIME_SET: { On_CheckBoxSet_Clicked (ATime); return true; }
case IDX_COMPRESS_ZTIME_SET: { On_CheckBoxSet_Clicked (ZTime); return true; }
}
return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
}
void COptionsDialog::OnOK()
{
GetButton_Bool1 (IDX_COMPRESS_NT_SYM_LINKS, cd->SymLinks);
GetButton_Bool1 (IDX_COMPRESS_NT_HARD_LINKS, cd->HardLinks);
GetButton_Bool1 (IDX_COMPRESS_NT_ALT_STREAMS, cd->AltStreams);
GetButton_Bool1 (IDX_COMPRESS_NT_SECUR, cd->NtSecurity);
GetButton_Bool1 (IDX_COMPRESS_PRESERVE_ATIME, cd->PreserveATime);
Store_TimeBoxes();
{
NCompression::CFormatOptions &fo = cd->Get_FormatOptions();
fo.TimePrec = TimePrec;
fo.MTime = MTime.BoolPair;
fo.CTime = CTime.BoolPair;
fo.ATime = ATime.BoolPair;
fo.SetArcMTime = ZTime.BoolPair;
}
CModalDialog::OnOK();
}
void COptionsDialog::OnHelp()
{
ShowHelpWindow(kHelpTopic);
}

View File

@@ -60,6 +60,14 @@ namespace NCompressDialog
CBoolPair HardLinks;
CBoolPair AltStreams;
CBoolPair NtSecurity;
CBoolPair PreserveATime;
UInt32 TimePrec;
CBoolPair MTime;
CBoolPair CTime;
CBoolPair ATime;
CBoolPair SetArcMTime;
UString ArcPath; // in: Relative or abs ; out: Relative or abs
@@ -91,11 +99,46 @@ namespace NCompressDialog
Options.Empty();
SplitVolume.Empty();
EncryptionMethod.Empty();
TimePrec = (UInt32)(Int32)(-1);
}
};
}
struct CBool1
{
bool Val;
bool Supported;
CBool1(): Val(false), Supported(false) {}
void Init()
{
Val = false;
Supported = false;
}
void SetTrueTrue()
{
Val = true;
Supported = true;
}
void SetVal_as_Supported(bool val)
{
Val = val;
Supported = true;
}
/*
bool IsVal_True_and_Defined() const
{
return Def && Val;
}
*/
};
class CCompressDialog: public NWindows::NControl::CModalDialog
{
NWindows::NControl::CComboBox m_ArchivePath;
@@ -128,8 +171,6 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
int _default_encryptionMethod_Index;
NCompression::CInfo m_RegistryInfo;
int m_PrevFormat;
UString DirPrefix;
UString StartDirPrefix;
@@ -139,23 +180,25 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
UInt64 _ramSize_Reduced; // full for 64-bit and reduced for 32-bit
UInt64 _ramUsage_Auto;
void CheckButton_TwoBools(UINT id, const CBoolPair &b1, const CBoolPair &b2);
void GetButton_Bools(UINT id, CBoolPair &b1, CBoolPair &b2);
public:
NCompression::CInfo m_RegistryInfo;
CBool1 SymLinks;
CBool1 HardLinks;
CBool1 AltStreams;
CBool1 NtSecurity;
CBool1 PreserveATime;
void SetArchiveName(const UString &name);
int FindRegistryFormat(const UString &name);
int FindRegistryFormatAlways(const UString &name);
unsigned FindRegistryFormat_Always(const UString &name);
const CArcInfoEx &Get_ArcInfoEx()
{
return (*ArcFormats)[GetFormatIndex()];
}
NCompression::CFormatOptions &Get_FormatOptions()
{
const CArcInfoEx &ai = Get_ArcInfoEx();
return m_RegistryInfo.Formats[ FindRegistryFormatAlways(ai.Name) ];
}
NCompression::CFormatOptions &Get_FormatOptions();
void CheckSFXNameChange();
void SetArchiveName2(bool prevWasSFX);
@@ -239,6 +282,12 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
UInt32 GetBlockSizeSpec() { return GetComboValue(m_Solid, 1); }
/*
UInt32 GetPrecSpec() { return GetComboValue(m_Prec, 1); }
UInt32 GetPrec() { return GetComboValue(m_Prec, 0); }
*/
int AddOrder(UInt32 size);
int AddOrder_Auto();
@@ -273,6 +322,7 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
void PrintMemUsage(UINT res, UInt64 value);
void SetMemoryUsage();
void SetParams();
void SaveOptionsInMem();
void UpdatePasswordControl();
@@ -285,7 +335,7 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
void CheckSFXControlsEnable();
// void CheckVolumeEnable();
void EnableMultiCombo(unsigned id);
void FormatChanged();
void FormatChanged(bool isChanged);
void OnButtonSetArchive();
bool IsSFX();
@@ -302,6 +352,8 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
MessageBoxW(*this, message, L"7-Zip", MB_ICONERROR);
}
void ShowOptionsString();
public:
const CObjectVector<CArcInfoEx> *ArcFormats;
CUIntVector ArcIndices; // can not be empty, must contain Info.FormatIndex, if Info.FormatIndex >= 0
@@ -315,11 +367,103 @@ public:
INT_PTR Create(HWND wndParent = 0)
{
BIG_DIALOG_SIZE(400, 304);
BIG_DIALOG_SIZE(400, 320);
return CModalDialog::Create(SIZED_DIALOG(IDD_COMPRESS), wndParent);
}
CCompressDialog(): CurrentDirWasChanged(false) {};
};
class COptionsDialog: public NWindows::NControl::CModalDialog
{
struct CBoolBox
{
bool IsSupported;
bool DefaultVal;
CBoolPair BoolPair;
int Id;
int Set_Id;
void SetIDs(int id, int set_Id)
{
Id = id;
Set_Id = set_Id;
}
CBoolBox():
IsSupported(false),
DefaultVal(false)
{}
};
CCompressDialog *cd;
NWindows::NControl::CComboBox m_Prec;
UInt32 _auto_Prec;
UInt32 TimePrec;
void Reset_TimePrec() { TimePrec = (UInt32)(Int32)-1; }
bool IsSet_TimePrec() const { return TimePrec != (UInt32)(Int32)-1; }
CBoolBox MTime;
CBoolBox CTime;
CBoolBox ATime;
CBoolBox ZTime;
UString SecString;
UString NsString;
void CheckButton_Bool1(UINT id, const CBool1 &b1);
void GetButton_Bool1(UINT id, CBool1 &b1);
void CheckButton_BoolBox(bool supported, const CBoolPair &b2, CBoolBox &bb);
void GetButton_BoolBox(CBoolBox &bb);
void Store_TimeBoxes();
UInt32 GetComboValue(NWindows::NControl::CComboBox &c, int defMax = 0);
UInt32 GetPrecSpec()
{
UInt32 prec = GetComboValue(m_Prec, 1);
if (prec == _auto_Prec)
prec = (UInt32)(Int32)-1;
return prec;
}
UInt32 GetPrec() { return GetComboValue(m_Prec, 0); }
// void OnButton_TimeDefault();
int AddPrec(unsigned prec, bool isDefault);
void SetPrec();
void SetTimeMAC();
void On_CheckBoxSet_Prec_Clicked();
void On_CheckBoxSet_Clicked(const CBoolBox &bb);
virtual bool OnInit();
virtual bool OnCommand(int code, int itemID, LPARAM lParam);
virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
virtual void OnOK();
virtual void OnHelp();
public:
INT_PTR Create(HWND wndParent = 0)
{
BIG_DIALOG_SIZE(240, 232);
return CModalDialog::Create(SIZED_DIALOG(IDD_COMPRESS_OPTIONS), wndParent);
}
COptionsDialog(CCompressDialog *cdLoc):
cd(cdLoc)
// , TimePrec(0)
{
Reset_TimePrec();
};
};
#endif

View File

@@ -2,7 +2,7 @@
#include "../../GuiCommon.rc"
#define xc 400
#define yc 354
#define yc 320
#undef gSize
#undef gSpace
@@ -20,10 +20,6 @@
#define gSize 192
#define gSpace 24
#define ntSize2 168
#define ntSizeX (ntSize2 - m - m)
#define ntPosX m + m
#define ntPosY 292
#define g1xs 88
#define g0xs (gSize - g1xs)
@@ -99,18 +95,9 @@ BEGIN
LTEXT "Parameters:", IDT_COMPRESS_PARAMETERS, m, 256, gSize, 8
EDITTEXT IDE_COMPRESS_PARAMETERS, m, 268, gSize, 14, ES_AUTOHSCROLL
GROUPBOX "NTFS", IDG_COMPRESS_NTFS, m, ntPosY, ntSize2, 68
CONTROL "Store symbolic links", IDX_COMPRESS_NT_SYM_LINKS, MY_CHECKBOX,
ntPosX, ntPosY + 12, ntSizeX, 10
CONTROL "Store hard links", IDX_COMPRESS_NT_HARD_LINKS, MY_CHECKBOX,
ntPosX, ntPosY + 26, ntSizeX, 10
CONTROL "Store alternate data streams", IDX_COMPRESS_NT_ALT_STREAMS, MY_CHECKBOX,
ntPosX, ntPosY + 40, ntSizeX, 10
CONTROL "Store file security", IDX_COMPRESS_NT_SECUR, MY_CHECKBOX,
ntPosX, ntPosY + 54, ntSizeX, 10
PUSHBUTTON "Options", IDB_COMPRESS_OPTIONS, m, 292, bxs, bys
LTEXT "", IDT_COMPRESS_OPTIONS, m + bxs + m, 294, gSize - bxs - m, 16, SS_NOPREFIX
LTEXT "&Update mode:", IDT_COMPRESS_UPDATE_MODE, g4x, 41, 80, 8
COMBOBOX IDC_COMPRESS_UPDATE_MODE, g4x + 84, 39, g4xs - 84, 80, MY_COMBO
@@ -225,4 +212,10 @@ BEGIN
IDS_COMPRESS_SOLID "Solid"
IDS_SPLIT_CONFIRM "Specified volume size: {0} bytes.\nAre you sure you want to split archive into such volumes?"
IDS_COMPRESS_SEC "sec"
IDS_COMPRESS_NS "ns"
END
#include "CompressOptionsDialog.rc"

View File

@@ -1,5 +1,6 @@
#define IDD_COMPRESS 4000
#define IDD_COMPRESS_2 14000
#define IDD_COMPRESS_OPTIONS 14001
#define IDC_COMPRESS_ARCHIVE 100
#define IDB_COMPRESS_SET_ARCHIVE 101
@@ -28,6 +29,10 @@
#define IDT_COMPRESS_ARCHIVE_FOLDER 130
// #define IDB_COMPRESS_OPTIONS 140
#define IDB_COMPRESS_OPTIONS 2100
#define IDT_COMPRESS_OPTIONS 141
#define IDT_COMPRESS_PATH_MODE 3410
#define IDT_PASSWORD_ENTER 3801
@@ -86,3 +91,31 @@
#define IDT_SPLIT_TO_VOLUMES 7302
#define IDS_INCORRECT_VOLUME_SIZE 7307
#define IDS_SPLIT_CONFIRM 7308
// Options Dialog
#define IDG_COMPRESS_TIME 4080
#define IDT_COMPRESS_TIME_PREC 4081
#define IDX_COMPRESS_MTIME 4082
#define IDX_COMPRESS_CTIME 4083
#define IDX_COMPRESS_ATIME 4084
#define IDX_COMPRESS_ZTIME 4085
#define IDX_COMPRESS_PRESERVE_ATIME 4086
#define IDS_COMPRESS_SEC 4090
#define IDS_COMPRESS_NS 4091
#define IDC_COMPRESS_TIME_PREC 190
#define IDT_COMPRESS_TIME_INFO 191
#define IDX_COMPRESS_PREC_SET 201
#define IDX_COMPRESS_MTIME_SET 202
#define IDX_COMPRESS_CTIME_SET 203
#define IDX_COMPRESS_ATIME_SET 204
#define IDX_COMPRESS_ZTIME_SET 205
// #define IDX_COMPRESS_NT_SYM_LINKS_SET 210
// #define IDX_COMPRESS_NT_HARD_LINKS_SET 211
// #define IDX_COMPRESS_NT_ALT_STREAMS_SET 212
// #define IDX_COMPRESS_NT_SECUR_SET 213

View File

@@ -0,0 +1,76 @@
#include "CompressDialogRes.h"
#include "../../GuiCommon.rc"
#define xc 240
#define yc 232
#define g5x m
#define g5x2 (g5x + m)
#define g5xs (xc)
#define g5xs2 (g5xs - m - m)
#define ntPosX g5x2
#define ntPosY m
#define ntSizeX g5xs2
#define precSizeX 76
#define ntSizeY 72
#define timePosY (ntPosY + ntSizeY + 20)
#define ceSize 18
#define ceString ":"
IDD_COMPRESS_OPTIONS DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT
CAPTION "Options"
BEGIN
GROUPBOX "NTFS", IDG_COMPRESS_NTFS, g5x, ntPosY, g5xs, ntSizeY
CONTROL "Store symbolic links", IDX_COMPRESS_NT_SYM_LINKS, MY_CHECKBOX,
ntPosX, ntPosY + 12, ntSizeX, 10
CONTROL "Store hard links", IDX_COMPRESS_NT_HARD_LINKS, MY_CHECKBOX,
ntPosX, ntPosY + 26, ntSizeX, 10
CONTROL "Store alternate data streams", IDX_COMPRESS_NT_ALT_STREAMS, MY_CHECKBOX,
ntPosX, ntPosY + 40, ntSizeX, 10
CONTROL "Store file security", IDX_COMPRESS_NT_SECUR, MY_CHECKBOX,
ntPosX, ntPosY + 54, ntSizeX, 10
LTEXT "", IDT_COMPRESS_TIME_INFO, g5x, timePosY - 14, g5xs, 8
GROUPBOX "Time", IDG_COMPRESS_TIME, g5x, timePosY, g5xs, 112
// CONTROL "Default", IDX_COMPRESS_TIME_DEFAULT, MY_CHECKBOX,
// ntPosX, timePosY + 10, ntSizeX, 16
CONTROL ceString, IDX_COMPRESS_PREC_SET, MY_CHECKBOX, ntPosX, timePosY + 14, ceSize, 10
LTEXT "Timestamp precision:", IDT_COMPRESS_TIME_PREC,
ntPosX + ceSize, timePosY + 14, ntSizeX - precSizeX - ceSize, 8
COMBOBOX IDC_COMPRESS_TIME_PREC, ntPosX + ntSizeX - precSizeX, timePosY + 12, precSizeX, 70, MY_COMBO
// PUSHBUTTON "Default", IDB_COMPRESS_TIME_DEFAULT, ntPosX + ntSizeX - bxs, timePosY + 22, bxs, bys, WS_GROUP
CONTROL ceString, IDX_COMPRESS_MTIME_SET, MY_CHECKBOX, ntPosX, timePosY + 28, ceSize, 10
CONTROL "Store modification time", IDX_COMPRESS_MTIME, MY_CHECKBOX,
ntPosX + ceSize, timePosY + 28, ntSizeX - ceSize, 10
CONTROL ceString, IDX_COMPRESS_CTIME_SET, MY_CHECKBOX, ntPosX, timePosY + 42, ceSize, 10
CONTROL "Store creation time", IDX_COMPRESS_CTIME, MY_CHECKBOX,
ntPosX + ceSize, timePosY + 42, ntSizeX - ceSize, 10
CONTROL ceString, IDX_COMPRESS_ATIME_SET, MY_CHECKBOX, ntPosX, timePosY + 56, ceSize, 10
CONTROL "Store last access time", IDX_COMPRESS_ATIME, MY_CHECKBOX,
ntPosX + ceSize, timePosY + 56, ntSizeX - ceSize, 10
CONTROL ceString, IDX_COMPRESS_ZTIME_SET, MY_CHECKBOX | BS_MULTILINE, ntPosX, timePosY + 72, ceSize, 16
CONTROL "Set archive time to latest file time", IDX_COMPRESS_ZTIME, MY_CHECKBOX | BS_MULTILINE,
ntPosX + ceSize, timePosY + 72, ntSizeX - ceSize, 16
CONTROL "Do not change source files last access time", IDX_COMPRESS_PRESERVE_ATIME, MY_CHECKBOX | BS_MULTILINE,
ntPosX, timePosY + 92, ntSizeX, 16
DEFPUSHBUTTON "OK", IDOK, bx3, by, bxs, bys, WS_GROUP
PUSHBUTTON "Cancel", IDCANCEL, bx2, by, bxs, bys
PUSHBUTTON "Help", IDHELP, bx1, by, bxs, bys
END

View File

@@ -75,6 +75,8 @@ extern
bool g_LVN_ITEMACTIVATE_Support;
bool g_LVN_ITEMACTIVATE_Support = true;
DECLARE_AND_SET_CLIENT_VERSION_VAR
static void ErrorMessage(LPCWSTR message)
{
MessageBoxW(NULL, message, L"7-Zip ZS", MB_ICONERROR | MB_OK);
@@ -135,7 +137,7 @@ static int Main2()
CREATE_CODECS_OBJECT
codecs->CaseSensitiveChange = options.CaseSensitiveChange;
codecs->CaseSensitive_Change = options.CaseSensitive_Change;
codecs->CaseSensitive = options.CaseSensitive;
ThrowException_if_Error(codecs->Load());
Codecs_AddHashArcHandler(codecs);

View File

@@ -773,6 +773,10 @@ SOURCE=..\..\..\..\C\7zCrcOpt.c
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\7zTypes.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Alloc.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
@@ -1211,5 +1215,17 @@ SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp
SOURCE=..\..\Archive\Common\OutStreamWithCRC.h
# End Source File
# End Group
# Begin Group "7-Zip"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\Archive\IArchive.h
# End Source File
# Begin Source File
SOURCE=..\..\ICoder.h
# End Source File
# End Group
# End Target
# End Project

View File

@@ -61,6 +61,53 @@ HRESULT CThreadUpdating::ProcessVirt()
return HRESULT_FROM_WIN32(ei.SystemError);
}
// parse command line properties
static bool ParseProp_Time_BoolPair(const CProperty &prop, const char *name, CBoolPair &bp)
{
if (!prop.Name.IsPrefixedBy_Ascii_NoCase(name))
return false;
const UString rem = prop.Name.Ptr((unsigned)strlen(name));
UString val = prop.Value;
if (!rem.IsEmpty())
{
if (!val.IsEmpty())
return true;
val = rem;
}
bool res;
if (StringToBool(val, res))
{
bp.Val = res;
bp.Def = true;
}
return true;
}
static void ParseProp(
const CProperty &prop,
NCompressDialog::CInfo &di)
{
if (ParseProp_Time_BoolPair(prop, "tm", di.MTime)) return;
if (ParseProp_Time_BoolPair(prop, "tc", di.CTime)) return;
if (ParseProp_Time_BoolPair(prop, "ta", di.ATime)) return;
}
static void ParseProperties(
const CObjectVector<CProperty> &properties,
NCompressDialog::CInfo &di)
{
FOR_VECTOR (i, properties)
{
ParseProp(properties[i], di);
}
}
static void AddProp_UString(CObjectVector<CProperty> &properties, const char *name, const UString &value)
{
CProperty prop;
@@ -81,10 +128,31 @@ static void AddProp_bool(CObjectVector<CProperty> &properties, const char *name,
AddProp_UString(properties, name, UString(value ? "on": "off"));
}
static bool IsThereMethodOverride(bool is7z, const UString &propertiesString)
static void AddProp_BoolPair(CObjectVector<CProperty> &properties,
const char *name, const CBoolPair &bp)
{
if (bp.Def)
AddProp_bool(properties, name, bp.Val);
}
static void SplitOptionsToStrings(const UString &src, UStringVector &strings)
{
SplitString(src, strings);
FOR_VECTOR (i, strings)
{
UString &s = strings[i];
if (s.Len() > 2
&& s[0] == '-'
&& MyCharLower_Ascii(s[1]) == 'm')
s.DeleteFrontal(2);
}
}
static bool IsThereMethodOverride(bool is7z, const UStringVector &strings)
{
UStringVector strings;
SplitString(propertiesString, strings);
FOR_VECTOR (i, strings)
{
const UString &s = strings[i];
@@ -106,17 +174,11 @@ static bool IsThereMethodOverride(bool is7z, const UString &propertiesString)
}
static void ParseAndAddPropertires(CObjectVector<CProperty> &properties,
const UString &propertiesString)
const UStringVector &strings)
{
UStringVector strings;
SplitString(propertiesString, strings);
FOR_VECTOR (i, strings)
{
UString s = strings[i];
if (s.Len() > 2
&& s[0] == '-'
&& MyCharLower_Ascii(s[1]) == 'm')
s.DeleteFrontal(2);
const UString &s = strings[i];
CProperty property;
const int index = s.Find(L'=');
if (index < 0)
@@ -142,58 +204,49 @@ static void AddProp_Size(CObjectVector<CProperty> &properties, const char *name,
static void SetOutProperties(
CObjectVector<CProperty> &properties,
const NCompressDialog::CInfo &di,
bool is7z,
UInt32 level,
bool setMethod,
const UString &method,
UInt64 dict64,
bool orderMode,
UInt32 order,
bool solidIsSpecified, UInt64 solidBlockSize,
// bool multiThreadIsAllowed,
UInt32 numThreads,
const UString &encryptionMethod,
bool encryptHeadersIsAllowed, bool encryptHeaders,
const NCompression::CMemUse &memUse,
bool /* sfxMode */)
bool setMethod)
{
if (level != (UInt32)(Int32)-1)
AddProp_UInt32(properties, "x", (UInt32)level);
if (di.Level != (UInt32)(Int32)-1)
AddProp_UInt32(properties, "x", (UInt32)di.Level);
if (setMethod)
{
if (!method.IsEmpty())
AddProp_UString(properties, is7z ? "0": "m", method);
if (dict64 != (UInt64)(Int64)-1)
if (!di.Method.IsEmpty())
AddProp_UString(properties, is7z ? "0": "m", di.Method);
if (di.Dict64 != (UInt64)(Int64)-1)
{
AString name;
if (is7z)
name = "0";
name += (orderMode ? "mem" : "d");
AddProp_Size(properties, name, dict64);
name += (di.OrderMode ? "mem" : "d");
AddProp_Size(properties, name, di.Dict64);
}
if (order != (UInt32)(Int32)-1)
if (di.Order != (UInt32)(Int32)-1)
{
AString name;
if (is7z)
name = "0";
name += (orderMode ? "o" : "fb");
AddProp_UInt32(properties, name, (UInt32)order);
name += (di.OrderMode ? "o" : "fb");
AddProp_UInt32(properties, name, (UInt32)di.Order);
}
}
if (!encryptionMethod.IsEmpty())
AddProp_UString(properties, "em", encryptionMethod);
if (!di.EncryptionMethod.IsEmpty())
AddProp_UString(properties, "em", di.EncryptionMethod);
if (encryptHeadersIsAllowed)
AddProp_bool(properties, "he", encryptHeaders);
if (solidIsSpecified)
AddProp_Size(properties, "s", solidBlockSize);
if (di.EncryptHeadersIsAllowed)
AddProp_bool(properties, "he", di.EncryptHeaders);
if (di.SolidIsSpecified)
AddProp_Size(properties, "s", di.SolidBlockSize);
if (
// multiThreadIsAllowed &&
numThreads != (UInt32)(Int32)-1)
AddProp_UInt32(properties, "mt", numThreads);
// di.MultiThreadIsAllowed &&
di.NumThreads != (UInt32)(Int32)-1)
AddProp_UInt32(properties, "mt", di.NumThreads);
const NCompression::CMemUse &memUse = di.MemUsage;
if (memUse.IsDefined)
{
const char *kMemUse = "memuse";
@@ -208,8 +261,16 @@ static void SetOutProperties(
else
AddProp_Size(properties, kMemUse, memUse.Val);
}
AddProp_BoolPair(properties, "tm", di.MTime);
AddProp_BoolPair(properties, "tc", di.CTime);
AddProp_BoolPair(properties, "ta", di.ATime);
if (di.TimePrec != (UInt32)(Int32)-1)
AddProp_UInt32(properties, "tp", di.TimePrec);
}
struct C_UpdateMode_ToAction_Pair
{
NCompressDialog::NUpdateMode::EEnum UpdateMode;
@@ -358,6 +419,10 @@ static HRESULT ShowDialog(
di.HardLinks = options.HardLinks;
di.AltStreams = options.AltStreams;
di.NtSecurity = options.NtSecurity;
if (options.SetArcMTime)
di.SetArcMTime.SetTrueTrue();
if (options.PreserveATime)
di.PreserveATime.SetTrueTrue();
if (callback->PasswordIsDefined)
di.Password = callback->Password;
@@ -373,6 +438,8 @@ static HRESULT ShowDialog(
di.UpdateMode = g_UpdateMode_Pairs[(unsigned)index].UpdateMode;
}
ParseProperties(options.MethodMode.Properties, di);
if (dialog.Create(hwndParent) != IDOK)
return E_ABORT;
@@ -382,6 +449,9 @@ static HRESULT ShowDialog(
options.HardLinks = di.HardLinks;
options.AltStreams = di.AltStreams;
options.NtSecurity = di.NtSecurity;
options.SetArcMTime = di.SetArcMTime.Val;
if (di.PreserveATime.Def)
options.PreserveATime = di.PreserveATime.Val;
#if defined(_WIN32) && !defined(UNDER_CE)
curDirRestorer.NeedRestore = dialog.CurrentDirWasChanged;
@@ -411,29 +481,21 @@ static HRESULT ShowDialog(
if (callback->PasswordIsDefined)
callback->Password = di.Password;
// we clear command line options, and fill options form Dialog
options.MethodMode.Properties.Clear();
bool is7z = archiverInfo.Name.IsEqualTo_Ascii_NoCase("7z");
bool methodOverride = IsThereMethodOverride(is7z, di.Options);
const bool is7z = archiverInfo.Is_7z();
SetOutProperties(
options.MethodMode.Properties,
UStringVector optionStrings;
SplitOptionsToStrings(di.Options, optionStrings);
const bool methodOverride = IsThereMethodOverride(is7z, optionStrings);
SetOutProperties(options.MethodMode.Properties, di,
is7z,
di.Level,
!methodOverride,
di.Method,
di.Dict64,
di.OrderMode, di.Order,
di.SolidIsSpecified, di.SolidBlockSize,
// di.MultiThreadIsAllowed,
di.NumThreads,
di.EncryptionMethod,
di.EncryptHeadersIsAllowed, di.EncryptHeaders,
di.MemUsage,
di.SFXMode);
!methodOverride); // setMethod
options.OpenShareForWrite = di.OpenShareForWrite;
ParseAndAddPropertires(options.MethodMode.Properties, di.Options);
ParseAndAddPropertires(options.MethodMode.Properties, optionStrings);
if (di.SFXMode)
options.SfxMode = true;