mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-09 22:07:05 -06:00
Update to 7-Zip Version 22.00
See: https://sourceforge.net/p/sevenzip/discussion/45797/thread/9c2d9061ce/
This commit is contained in:
@@ -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!!!
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(¤tItemIndex));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -334,7 +334,7 @@ static void ExtractGroupCommand(const UStringVector &arcPaths, UString ¶ms,
|
||||
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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
@@ -29,6 +29,16 @@ namespace NOverwriteMode
|
||||
};
|
||||
}
|
||||
|
||||
namespace NZoneIdMode
|
||||
{
|
||||
enum EEnum
|
||||
{
|
||||
kNone,
|
||||
kAll,
|
||||
kOffice
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
{}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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); }
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -112,6 +112,9 @@ struct CUpdateOptions
|
||||
CBoolPair HardLinks;
|
||||
CBoolPair SymLinks;
|
||||
|
||||
CBoolPair StoreOwnerId;
|
||||
CBoolPair StoreOwnerName;
|
||||
|
||||
bool DeleteAfterCompressing;
|
||||
|
||||
bool SetArcMTime;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -63,6 +63,8 @@ void UpdateProduce(
|
||||
break;
|
||||
}
|
||||
|
||||
up2.IsSameTime = ((unsigned)pair.State == NUpdateArchive::NPairState::kSameFiles);
|
||||
|
||||
operationChain.Add(up2);
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 << ' ';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -138,6 +138,7 @@ private:
|
||||
|
||||
HBITMAP _bitmap;
|
||||
CBoolPair _elimDup;
|
||||
UInt32 _writeZone;
|
||||
|
||||
bool IsSeparator;
|
||||
bool IsRoot;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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:
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
{}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ®)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
76
CPP/7zip/UI/GUI/CompressOptionsDialog.rc
Normal file
76
CPP/7zip/UI/GUI/CompressOptionsDialog.rc
Normal 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
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user