mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-07 11:14:58 -06:00
9.34
This commit is contained in:
committed by
Kornel Lesiński
parent
83f8ddcc5b
commit
f08f4dcc3c
1188
CPP/7zip/UI/Agent/Agent.cpp
Executable file → Normal file
1188
CPP/7zip/UI/Agent/Agent.cpp
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
109
CPP/7zip/UI/Agent/Agent.h
Executable file → Normal file
109
CPP/7zip/UI/Agent/Agent.h
Executable file → Normal file
@@ -3,9 +3,9 @@
|
||||
#ifndef __AGENT_AGENT_H
|
||||
#define __AGENT_AGENT_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "../../../Windows/PropVariant.h"
|
||||
|
||||
#include "../Common/OpenArchive.h"
|
||||
#include "../Common/UpdateAction.h"
|
||||
@@ -27,8 +27,8 @@ DECL_INTERFACE(IArchiveFolderInternal, 0x01, 0xC)
|
||||
|
||||
struct CProxyItem
|
||||
{
|
||||
const CProxyFolder *Folder;
|
||||
UInt32 Index;
|
||||
unsigned ProxyFolderIndex;
|
||||
unsigned Index;
|
||||
};
|
||||
|
||||
class CAgent;
|
||||
@@ -45,25 +45,33 @@ enum AGENT_OP
|
||||
class CAgentFolder:
|
||||
public IFolderFolder,
|
||||
public IFolderProperties,
|
||||
public IArchiveGetRawProps,
|
||||
public IGetFolderArcProps,
|
||||
public IFolderCompare,
|
||||
public IFolderGetItemName,
|
||||
public IArchiveFolder,
|
||||
public IArchiveFolderInternal,
|
||||
public IInArchiveGetStream,
|
||||
// public IFolderSetReplaceAltStreamCharsMode,
|
||||
#ifdef NEW_FOLDER_INTERFACE
|
||||
public IFolderOperations,
|
||||
public IFolderSetFlatMode,
|
||||
#endif
|
||||
public CMyUnknownImp
|
||||
{
|
||||
void LoadFolder(const CProxyFolder *folder);
|
||||
void LoadFolder(unsigned proxyFolderIndex);
|
||||
public:
|
||||
|
||||
MY_QUERYINTERFACE_BEGIN2(IFolderFolder)
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderProperties)
|
||||
MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps)
|
||||
MY_QUERYINTERFACE_ENTRY(IGetFolderArcProps)
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderCompare)
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderGetItemName)
|
||||
MY_QUERYINTERFACE_ENTRY(IArchiveFolder)
|
||||
MY_QUERYINTERFACE_ENTRY(IArchiveFolderInternal)
|
||||
MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream)
|
||||
// MY_QUERYINTERFACE_ENTRY(IFolderSetReplaceAltStreamCharsMode)
|
||||
#ifdef NEW_FOLDER_INTERFACE
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderOperations)
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderSetFlatMode)
|
||||
@@ -71,21 +79,24 @@ public:
|
||||
MY_QUERYINTERFACE_END
|
||||
MY_ADDREF_RELEASE
|
||||
|
||||
HRESULT BindToFolder(const CProxyFolder *folder, IFolderFolder **resultFolder);
|
||||
void GetRealIndices(const UINT32 *indices, UINT32 numItems, CUIntVector &realIndices) const;
|
||||
HRESULT BindToFolder_Internal(unsigned proxyFolderIndex, IFolderFolder **resultFolder);
|
||||
int GetRealIndex(unsigned index) const;
|
||||
void GetRealIndices(const UInt32 *indices, UInt32 numItems,
|
||||
bool includeAltStreams, bool includeFolderSubItemsInFlatMode, CUIntVector &realIndices) const;
|
||||
|
||||
// INTERFACE_FolderSetReplaceAltStreamCharsMode(;)
|
||||
|
||||
INTERFACE_FolderFolder(;)
|
||||
INTERFACE_FolderProperties(;)
|
||||
INTERFACE_IArchiveGetRawProps(;)
|
||||
INTERFACE_IFolderGetItemName(;)
|
||||
|
||||
STDMETHOD(GetFolderArcProps)(IFolderArcProps **object);
|
||||
STDMETHOD_(Int32, CompareItems)(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw);
|
||||
int CompareItems2(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw);
|
||||
|
||||
// IArchiveFolder
|
||||
STDMETHOD(Extract)(const UINT32 *indices, UINT32 numItems,
|
||||
NExtract::NPathMode::EEnum pathMode,
|
||||
NExtract::NOverwriteMode::EEnum overwriteMode,
|
||||
const wchar_t *path,
|
||||
Int32 testMode,
|
||||
IFolderArchiveExtractCallback *extractCallback);
|
||||
INTERFACE_IArchiveFolder(;)
|
||||
|
||||
STDMETHOD(GetAgentFolder)(CAgentFolder **agentFolder);
|
||||
|
||||
@@ -97,14 +108,15 @@ public:
|
||||
STDMETHOD(SetFlatMode)(Int32 flatMode);
|
||||
#endif
|
||||
|
||||
CAgentFolder(): _proxyFolderItem(NULL), _flatMode(0) {}
|
||||
CAgentFolder(): _proxyFolderItem(0), _flatMode(0) /* , _replaceAltStreamCharsMode(0) */ {}
|
||||
|
||||
void Init(const CProxyArchive *proxyHandler,
|
||||
const CProxyFolder *proxyFolderItem,
|
||||
void Init(const CProxyArchive *proxyArc, const CProxyArchive2 *proxyArc2,
|
||||
unsigned proxyFolderItem,
|
||||
IFolderFolder *parentFolder,
|
||||
CAgent *agent)
|
||||
{
|
||||
_proxyArchive = proxyHandler;
|
||||
_proxyArchive = proxyArc;
|
||||
_proxyArchive2 = proxyArc2;
|
||||
_proxyFolderItem = proxyFolderItem;
|
||||
_parentFolder = parentFolder;
|
||||
_agent = (IInFolderArchive *)agent;
|
||||
@@ -114,25 +126,29 @@ public:
|
||||
void GetPathParts(UStringVector &pathParts);
|
||||
HRESULT CommonUpdateOperation(
|
||||
AGENT_OP operation,
|
||||
bool moveMode,
|
||||
const wchar_t *newItemName,
|
||||
const NUpdateArchive::CActionSet *actionSet,
|
||||
const UINT32 *indices, UINT32 numItems,
|
||||
const UInt32 *indices, UInt32 numItems,
|
||||
IFolderArchiveUpdateCallback *updateCallback100);
|
||||
|
||||
|
||||
UString GetPrefix(UInt32 index) const;
|
||||
void GetPrefix(UInt32 index, UString &prefix) const;
|
||||
UString GetName(UInt32 index) const;
|
||||
UString GetFullPathPrefixPlusPrefix(UInt32 index) const;
|
||||
|
||||
public:
|
||||
const CProxyArchive *_proxyArchive;
|
||||
const CProxyFolder *_proxyFolderItem;
|
||||
const CProxyArchive2 *_proxyArchive2;
|
||||
// const CProxyFolder *_proxyFolderItem;
|
||||
unsigned _proxyFolderItem;
|
||||
CMyComPtr<IFolderFolder> _parentFolder;
|
||||
CMyComPtr<IInFolderArchive> _agent;
|
||||
CAgent *_agentSpec;
|
||||
|
||||
CRecordVector<CProxyItem> _items;
|
||||
bool _flatMode;
|
||||
// Int32 _replaceAltStreamCharsMode;
|
||||
private:
|
||||
};
|
||||
|
||||
@@ -163,7 +179,7 @@ public:
|
||||
INTERFACE_IOutFolderArchive(;)
|
||||
|
||||
HRESULT CommonUpdate(ISequentialOutStream *outArchiveStream,
|
||||
int numUpdateItems, IArchiveUpdateCallback *updateCallback);
|
||||
unsigned numUpdateItems, IArchiveUpdateCallback *updateCallback);
|
||||
|
||||
HRESULT CreateFolder(ISequentialOutStream *outArchiveStream,
|
||||
const wchar_t *folderName, IFolderArchiveUpdateCallback *updateCallback100);
|
||||
@@ -177,7 +193,7 @@ public:
|
||||
IFolderArchiveUpdateCallback *updateCallback100);
|
||||
|
||||
// ISetProperties
|
||||
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
|
||||
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, UInt32 numProps);
|
||||
#endif
|
||||
|
||||
CCodecs *_codecs;
|
||||
@@ -189,8 +205,10 @@ private:
|
||||
HRESULT ReadItems();
|
||||
public:
|
||||
CProxyArchive *_proxyArchive;
|
||||
CProxyArchive2 *_proxyArchive2;
|
||||
CArchiveLink _archiveLink;
|
||||
|
||||
bool ThereIsPathProp;
|
||||
|
||||
UString ArchiveType;
|
||||
|
||||
@@ -201,6 +219,7 @@ public:
|
||||
CAgentFolder *_agentFolder;
|
||||
|
||||
UString _archiveFilePath;
|
||||
bool _isDeviceFile;
|
||||
|
||||
#ifndef EXTRACT_ONLY
|
||||
CObjectVector<UString> m_PropNames;
|
||||
@@ -209,28 +228,50 @@ public:
|
||||
|
||||
const CArc &GetArc() const { return _archiveLink.Arcs.Back(); }
|
||||
IInArchive *GetArchive() const { if ( _archiveLink.Arcs.IsEmpty()) return 0; return GetArc().Archive; }
|
||||
bool CanUpdate() const { return _archiveLink.Arcs.Size() <= 1; }
|
||||
bool CanUpdate() const;
|
||||
|
||||
UString GetTypeOfArc(const CArc &arc) const
|
||||
{
|
||||
if (arc.FormatIndex < 0)
|
||||
return L"Parser";
|
||||
return _codecs->GetFormatNamePtr(arc.FormatIndex);
|
||||
}
|
||||
|
||||
UString GetTypeOfArc(const CArc &arc) const { return _codecs->Formats[arc.FormatIndex].Name; }
|
||||
UString GetErrorMessage() const
|
||||
{
|
||||
UString s;
|
||||
for (int i = _archiveLink.Arcs.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
const CArc &arc = _archiveLink.Arcs[i];
|
||||
if (arc.ErrorMessage.IsEmpty())
|
||||
continue;
|
||||
if (!s.IsEmpty())
|
||||
s += L"--------------------\n";
|
||||
s += arc.ErrorMessage;
|
||||
s += L"\n\n[";
|
||||
s += GetTypeOfArc(arc);
|
||||
s += L"] ";
|
||||
s += arc.Path;
|
||||
s += L"\n";
|
||||
|
||||
UString s2;
|
||||
if (arc.ErrorInfo.ErrorFormatIndex >= 0)
|
||||
s2 = L"Can not open the file as [" + _codecs->Formats[arc.ErrorInfo.ErrorFormatIndex].Name + L"] archive";
|
||||
|
||||
if (!arc.ErrorInfo.ErrorMessage.IsEmpty())
|
||||
{
|
||||
if (!s2.IsEmpty())
|
||||
s2 += L"\n";
|
||||
s2 += L"\n[";
|
||||
s2 += GetTypeOfArc(arc);
|
||||
s2 += L"]: ";
|
||||
s2 += arc.ErrorInfo.ErrorMessage;
|
||||
}
|
||||
if (!s2.IsEmpty())
|
||||
{
|
||||
if (!s.IsEmpty())
|
||||
s += L"--------------------\n";
|
||||
s += arc.Path;
|
||||
s += L"\n";
|
||||
s += s2;
|
||||
s += L"\n";
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void KeepModeForNextOpen() { _archiveLink.KeepModeForNextOpen(); }
|
||||
|
||||
};
|
||||
|
||||
#ifdef NEW_FOLDER_INTERFACE
|
||||
|
||||
207
CPP/7zip/UI/Agent/AgentOut.cpp
Executable file → Normal file
207
CPP/7zip/UI/Agent/AgentOut.cpp
Executable file → Normal file
@@ -2,9 +2,9 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Windows/FileDir.h"
|
||||
#include "Windows/FileName.h"
|
||||
#include "Windows/Time.h"
|
||||
#include "../../../Windows/FileDir.h"
|
||||
#include "../../../Windows/FileName.h"
|
||||
#include "../../../Windows/TimeUtils.h"
|
||||
|
||||
#include "../../Compress/CopyCoder.h"
|
||||
|
||||
@@ -32,7 +32,10 @@ STDMETHODIMP CAgent::SetFolder(IFolderFolder *folder)
|
||||
RINOK(archiveFolderInternal->GetAgentFolder(&_agentFolder));
|
||||
}
|
||||
|
||||
_archiveNamePrefix = _agentFolder->_proxyFolderItem->GetFullPathPrefix();
|
||||
if (_proxyArchive2)
|
||||
_archiveNamePrefix = _proxyArchive2->GetFullPathPrefix(_agentFolder->_proxyFolderItem);
|
||||
else
|
||||
_archiveNamePrefix = _proxyArchive->GetFullPathPrefix(_agentFolder->_proxyFolderItem);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -40,10 +43,9 @@ STDMETHODIMP CAgent::SetFiles(const wchar_t *folderPrefix,
|
||||
const wchar_t **names, UInt32 numNames)
|
||||
{
|
||||
_folderPrefix = us2fs(folderPrefix);
|
||||
_names.Clear();
|
||||
_names.Reserve(numNames);
|
||||
_names.ClearAndReserve(numNames);
|
||||
for (UInt32 i = 0; i < numNames; i++)
|
||||
_names.Add(us2fs(names[i]));
|
||||
_names.AddInReserved(us2fs(names[i]));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -52,7 +54,7 @@ static HRESULT EnumerateArchiveItems(CAgent *agent,
|
||||
const UString &prefix,
|
||||
CObjectVector<CArcItem> &arcItems)
|
||||
{
|
||||
int i;
|
||||
unsigned i;
|
||||
for (i = 0; i < item.Files.Size(); i++)
|
||||
{
|
||||
const CProxyFile &fileItem = item.Files[i];
|
||||
@@ -67,7 +69,7 @@ static HRESULT EnumerateArchiveItems(CAgent *agent,
|
||||
}
|
||||
for (i = 0; i < item.Folders.Size(); i++)
|
||||
{
|
||||
const CProxyFolder &dirItem = item.Folders[i];
|
||||
const CProxyFolder &dirItem = agent->_proxyArchive->Folders[item.Folders[i]];
|
||||
UString fullName = prefix + dirItem.Name;
|
||||
if (dirItem.IsLeaf)
|
||||
{
|
||||
@@ -85,6 +87,38 @@ static HRESULT EnumerateArchiveItems(CAgent *agent,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT EnumerateArchiveItems2(const CAgent *agent,
|
||||
const CProxyArchive2 *proxyArchive2,
|
||||
unsigned folderIndex,
|
||||
const UString &prefix,
|
||||
CObjectVector<CArcItem> &arcItems)
|
||||
{
|
||||
const CProxyFolder2 &folder = proxyArchive2->Folders[folderIndex];
|
||||
FOR_VECTOR (i, folder.SubFiles)
|
||||
{
|
||||
unsigned arcIndex = folder.SubFiles[i];
|
||||
const CProxyFile2 &file = proxyArchive2->Files[arcIndex];
|
||||
CArcItem ai;
|
||||
ai.IndexInServer = arcIndex;
|
||||
ai.Name = prefix + file.Name;
|
||||
ai.Censored = true; // test it
|
||||
RINOK(agent->GetArc().GetItemMTime(arcIndex, ai.MTime, ai.MTimeDefined));
|
||||
ai.IsDir = file.IsDir();
|
||||
ai.SizeDefined = false;
|
||||
if (!ai.IsDir)
|
||||
{
|
||||
RINOK(agent->GetArc().GetItemSize(arcIndex, ai.Size, ai.SizeDefined));
|
||||
ai.IsDir = false;
|
||||
}
|
||||
arcItems.Add(ai);
|
||||
if (ai.IsDir)
|
||||
{
|
||||
RINOK(EnumerateArchiveItems2(agent, proxyArchive2, file.FolderIndex, ai.Name + UString(WCHAR_PATH_SEPARATOR), arcItems));
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
struct CAgUpCallbackImp: public IUpdateProduceCallback
|
||||
{
|
||||
const CObjectVector<CArcItem> *_arcItems;
|
||||
@@ -100,7 +134,20 @@ HRESULT CAgUpCallbackImp::ShowDeleteFile(int arcIndex)
|
||||
return _callback->DeleteOperation((*_arcItems)[arcIndex].Name);
|
||||
}
|
||||
|
||||
|
||||
static void SetInArchiveInterfaces(CAgent *agent, CArchiveUpdateCallback *upd)
|
||||
{
|
||||
if (agent->_archiveLink.Arcs.IsEmpty())
|
||||
return;
|
||||
const CArc &arc = agent->GetArc();
|
||||
upd->Archive = arc.Archive;
|
||||
upd->GetRawProps = arc.GetRawProps;
|
||||
upd->GetRootProps = arc.GetRootProps;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgent::DoOperation(
|
||||
FStringVector *requestedPaths,
|
||||
FStringVector *processedPaths,
|
||||
CCodecs *codecs,
|
||||
int formatIndex,
|
||||
ISequentialOutStream *outArchiveStream,
|
||||
@@ -111,7 +158,7 @@ STDMETHODIMP CAgent::DoOperation(
|
||||
if (!CanUpdate())
|
||||
return E_NOTIMPL;
|
||||
NUpdateArchive::CActionSet actionSet;
|
||||
int i;
|
||||
unsigned i;
|
||||
for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
|
||||
actionSet.StateActions[i] = (NUpdateArchive::NPairAction::EEnum)stateActions[i];
|
||||
|
||||
@@ -120,11 +167,9 @@ STDMETHODIMP CAgent::DoOperation(
|
||||
{
|
||||
FString folderPrefix = _folderPrefix;
|
||||
NFile::NName::NormalizeDirPathPrefix(folderPrefix);
|
||||
FStringVector errorPaths;
|
||||
CRecordVector<DWORD> errorCodes;
|
||||
dirItems.EnumerateDirItems2(folderPrefix, _archiveNamePrefix, _names, errorPaths, errorCodes);
|
||||
if (errorCodes.Size() > 0)
|
||||
return errorCodes.Front();
|
||||
dirItems.EnumerateItems2(folderPrefix, _archiveNamePrefix, _names, requestedPaths);
|
||||
if (dirItems.ErrorCodes.Size() > 0)
|
||||
return dirItems.ErrorCodes.Front();
|
||||
}
|
||||
|
||||
CMyComPtr<IOutArchive> outArchive;
|
||||
@@ -170,7 +215,14 @@ STDMETHODIMP CAgent::DoOperation(
|
||||
if (GetArchive())
|
||||
{
|
||||
RINOK(ReadItems());
|
||||
EnumerateArchiveItems(this, _proxyArchive->RootFolder, L"", arcItems);
|
||||
if (_proxyArchive2)
|
||||
{
|
||||
RINOK(EnumerateArchiveItems2(this, _proxyArchive2, 0, L"", arcItems));
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(EnumerateArchiveItems(this, _proxyArchive->Folders[0], L"", arcItems));
|
||||
}
|
||||
}
|
||||
|
||||
CRecordVector<CUpdatePair2> updatePairs2;
|
||||
@@ -200,9 +252,21 @@ STDMETHODIMP CAgent::DoOperation(
|
||||
updateCallbackSpec->DirItems = &dirItems;
|
||||
updateCallbackSpec->ArcItems = &arcItems;
|
||||
updateCallbackSpec->UpdatePairs = &updatePairs2;
|
||||
updateCallbackSpec->Archive = GetArchive();
|
||||
|
||||
SetInArchiveInterfaces(this, updateCallbackSpec);
|
||||
|
||||
updateCallbackSpec->Callback = &updateCallbackAgent;
|
||||
|
||||
CByteBuffer processedItems;
|
||||
if (processedPaths)
|
||||
{
|
||||
unsigned num = dirItems.Items.Size();
|
||||
processedItems.Alloc(num);
|
||||
for (i = 0; i < num; i++)
|
||||
processedItems[i] = 0;
|
||||
updateCallbackSpec->ProcessedItemsStatuses = processedItems;
|
||||
}
|
||||
|
||||
CMyComPtr<ISetProperties> setProperties;
|
||||
if (outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties) == S_OK)
|
||||
{
|
||||
@@ -219,7 +283,7 @@ STDMETHODIMP CAgent::DoOperation(
|
||||
CPropVariant *propValues = new CPropVariant[m_PropValues.Size()];
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < m_PropValues.Size(); i++)
|
||||
FOR_VECTOR (i, m_PropValues)
|
||||
propValues[i] = m_PropValues[i];
|
||||
RINOK(setProperties->SetProperties(&names.Front(), propValues, names.Size()));
|
||||
}
|
||||
@@ -244,17 +308,27 @@ STDMETHODIMP CAgent::DoOperation(
|
||||
RINOK(NCompress::CopyStream(sfxStream, outArchiveStream, NULL));
|
||||
}
|
||||
|
||||
return outArchive->UpdateItems(outArchiveStream, updatePairs2.Size(),updateCallback);
|
||||
HRESULT res = outArchive->UpdateItems(outArchiveStream, updatePairs2.Size(), updateCallback);
|
||||
if (res == S_OK && processedPaths)
|
||||
{
|
||||
for (i = 0; i < dirItems.Items.Size(); i++)
|
||||
if (processedItems[i] != 0)
|
||||
processedPaths->Add(us2fs(dirItems.GetPhyPath(i)));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgent::DoOperation2(ISequentialOutStream *outArchiveStream,
|
||||
STDMETHODIMP CAgent::DoOperation2(
|
||||
FStringVector *requestedPaths,
|
||||
FStringVector *processedPaths,
|
||||
ISequentialOutStream *outArchiveStream,
|
||||
const Byte *stateActions, const wchar_t *sfxModule, IFolderArchiveUpdateCallback *updateCallback100)
|
||||
{
|
||||
return DoOperation(_codecs, -1, outArchiveStream, stateActions, sfxModule, updateCallback100);
|
||||
return DoOperation(requestedPaths, processedPaths, _codecs, -1, outArchiveStream, stateActions, sfxModule, updateCallback100);
|
||||
}
|
||||
|
||||
HRESULT CAgent::CommonUpdate(ISequentialOutStream *outArchiveStream,
|
||||
int numUpdateItems, IArchiveUpdateCallback *updateCallback)
|
||||
unsigned numUpdateItems, IArchiveUpdateCallback *updateCallback)
|
||||
{
|
||||
if (!CanUpdate())
|
||||
return E_NOTIMPL;
|
||||
@@ -276,8 +350,11 @@ STDMETHODIMP CAgent::DeleteItems(ISequentialOutStream *outArchiveStream,
|
||||
CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);
|
||||
|
||||
CUIntVector realIndices;
|
||||
_agentFolder->GetRealIndices(indices, numItems, realIndices);
|
||||
int curIndex = 0;
|
||||
_agentFolder->GetRealIndices(indices, numItems,
|
||||
true, // includeAltStreams
|
||||
false, // includeFolderSubItemsInFlatMode, we don't want to delete subItems in Flat Mode
|
||||
realIndices);
|
||||
unsigned curIndex = 0;
|
||||
UInt32 numItemsInArchive;
|
||||
RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive));
|
||||
for (UInt32 i = 0; i < numItemsInArchive; i++)
|
||||
@@ -289,13 +366,13 @@ STDMETHODIMP CAgent::DeleteItems(ISequentialOutStream *outArchiveStream,
|
||||
continue;
|
||||
}
|
||||
CUpdatePair2 up2;
|
||||
up2.NewData = up2.NewProps = false;
|
||||
up2.IsAnti = false; // check it. Maybe it can be undefined
|
||||
up2.ArcIndex = i;
|
||||
up2.SetAs_NoChangeArcItem(i);
|
||||
updatePairs.Add(up2);
|
||||
}
|
||||
updateCallbackSpec->UpdatePairs = &updatePairs;
|
||||
updateCallbackSpec->Archive = GetArchive();
|
||||
|
||||
SetInArchiveInterfaces(this, updateCallbackSpec);
|
||||
|
||||
updateCallbackSpec->Callback = &updateCallbackAgent;
|
||||
return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback);
|
||||
}
|
||||
@@ -317,14 +394,12 @@ HRESULT CAgent::CreateFolder(ISequentialOutStream *outArchiveStream,
|
||||
for (UInt32 i = 0; i < numItemsInArchive; i++)
|
||||
{
|
||||
CUpdatePair2 up2;
|
||||
up2.NewData = up2.NewProps = false;
|
||||
up2.IsAnti = false; // check it.
|
||||
up2.ArcIndex = i;
|
||||
up2.SetAs_NoChangeArcItem(i);
|
||||
updatePairs.Add(up2);
|
||||
}
|
||||
CUpdatePair2 up2;
|
||||
up2.NewData = up2.NewProps = true;
|
||||
up2.IsAnti = false;
|
||||
up2.UseArcProps = false;
|
||||
up2.DirIndex = 0;
|
||||
|
||||
updatePairs.Add(up2);
|
||||
@@ -335,7 +410,10 @@ HRESULT CAgent::CreateFolder(ISequentialOutStream *outArchiveStream,
|
||||
|
||||
di.Attrib = FILE_ATTRIBUTE_DIRECTORY;
|
||||
di.Size = 0;
|
||||
di.Name = _agentFolder->_proxyFolderItem->GetFullPathPrefix() + folderName;
|
||||
if (_proxyArchive2)
|
||||
di.Name = _proxyArchive2->GetFullPathPrefix(_agentFolder->_proxyFolderItem) + folderName;
|
||||
else
|
||||
di.Name = _proxyArchive->GetFullPathPrefix(_agentFolder->_proxyFolderItem) + folderName;
|
||||
|
||||
FILETIME ft;
|
||||
NTime::GetCurUtcFileTime(ft);
|
||||
@@ -346,7 +424,9 @@ HRESULT CAgent::CreateFolder(ISequentialOutStream *outArchiveStream,
|
||||
updateCallbackSpec->Callback = &updateCallbackAgent;
|
||||
updateCallbackSpec->DirItems = &dirItems;
|
||||
updateCallbackSpec->UpdatePairs = &updatePairs;
|
||||
updateCallbackSpec->Archive = GetArchive();
|
||||
|
||||
SetInArchiveInterfaces(this, updateCallbackSpec);
|
||||
|
||||
return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback);
|
||||
}
|
||||
|
||||
@@ -359,6 +439,8 @@ HRESULT CAgent::RenameItem(ISequentialOutStream *outArchiveStream,
|
||||
return E_NOTIMPL;
|
||||
if (numItems != 1)
|
||||
return E_INVALIDARG;
|
||||
if (!_archiveLink.IsOpen)
|
||||
return E_FAIL;
|
||||
CRecordVector<CUpdatePair2> updatePairs;
|
||||
CUpdateCallbackAgent updateCallbackAgent;
|
||||
updateCallbackAgent.SetCallback(updateCallback100);
|
||||
@@ -366,7 +448,12 @@ HRESULT CAgent::RenameItem(ISequentialOutStream *outArchiveStream,
|
||||
CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);
|
||||
|
||||
CUIntVector realIndices;
|
||||
_agentFolder->GetRealIndices(indices, numItems, realIndices);
|
||||
_agentFolder->GetRealIndices(indices, numItems,
|
||||
true, // includeAltStreams
|
||||
true, // includeFolderSubItemsInFlatMode
|
||||
realIndices);
|
||||
|
||||
int mainRealIndex = _agentFolder->GetRealIndex(indices[0]);
|
||||
|
||||
UString fullPrefix = _agentFolder->GetFullPathPrefixPlusPrefix(indices[0]);
|
||||
UString oldItemPath = fullPrefix + _agentFolder->GetName(indices[0]);
|
||||
@@ -374,41 +461,37 @@ HRESULT CAgent::RenameItem(ISequentialOutStream *outArchiveStream,
|
||||
|
||||
UStringVector newNames;
|
||||
|
||||
int curIndex = 0;
|
||||
unsigned curIndex = 0;
|
||||
UInt32 numItemsInArchive;
|
||||
RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive));
|
||||
for (UInt32 i = 0; i < numItemsInArchive; i++)
|
||||
{
|
||||
CUpdatePair2 up2;
|
||||
up2.SetAs_NoChangeArcItem(i);
|
||||
if (curIndex < realIndices.Size())
|
||||
if (realIndices[curIndex] == i)
|
||||
{
|
||||
CUpdatePair2 up2;
|
||||
up2.NewData = false;
|
||||
up2.NewProps = true;
|
||||
RINOK(GetArc().IsItemAnti(i, up2.IsAnti));
|
||||
up2.ArcIndex = i;
|
||||
RINOK(GetArc().IsItemAnti(i, up2.IsAnti)); // it must work without that line too.
|
||||
|
||||
UString oldFullPath;
|
||||
RINOK(GetArc().GetItemPath(i, oldFullPath));
|
||||
RINOK(GetArc().GetItemPath2(i, oldFullPath));
|
||||
|
||||
if (oldItemPath.CompareNoCase(oldFullPath.Left(oldItemPath.Length())) != 0)
|
||||
if (MyStringCompareNoCase_N(oldFullPath, oldItemPath, oldItemPath.Len()) != 0)
|
||||
return E_INVALIDARG;
|
||||
|
||||
up2.NewNameIndex = newNames.Add(newItemPath + oldFullPath.Mid(oldItemPath.Length()));
|
||||
updatePairs.Add(up2);
|
||||
up2.NewNameIndex = newNames.Add(newItemPath + oldFullPath.Ptr(oldItemPath.Len()));
|
||||
up2.IsMainRenameItem = (mainRealIndex == (int)i);
|
||||
curIndex++;
|
||||
continue;
|
||||
}
|
||||
CUpdatePair2 up2;
|
||||
up2.NewData = up2.NewProps = false;
|
||||
up2.IsAnti = false;
|
||||
up2.ArcIndex = i;
|
||||
updatePairs.Add(up2);
|
||||
}
|
||||
updateCallbackSpec->Callback = &updateCallbackAgent;
|
||||
updateCallbackSpec->UpdatePairs = &updatePairs;
|
||||
updateCallbackSpec->NewNames = &newNames;
|
||||
updateCallbackSpec->Archive = GetArchive();
|
||||
|
||||
SetInArchiveInterfaces(this, updateCallbackSpec);
|
||||
|
||||
return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback);
|
||||
}
|
||||
|
||||
@@ -428,7 +511,10 @@ HRESULT CAgent::UpdateOneFile(ISequentialOutStream *outArchiveStream,
|
||||
UInt32 realIndex;
|
||||
{
|
||||
CUIntVector realIndices;
|
||||
_agentFolder->GetRealIndices(indices, numItems, realIndices);
|
||||
_agentFolder->GetRealIndices(indices, numItems,
|
||||
false, // includeAltStreams // we update only main stream of file
|
||||
false, // includeFolderSubItemsInFlatMode
|
||||
realIndices);
|
||||
if (realIndices.Size() != 1)
|
||||
return E_FAIL;
|
||||
realIndex = realIndices[0];
|
||||
@@ -437,9 +523,7 @@ HRESULT CAgent::UpdateOneFile(ISequentialOutStream *outArchiveStream,
|
||||
{
|
||||
FStringVector filePaths;
|
||||
filePaths.Add(us2fs(diskFilePath));
|
||||
FStringVector errorPaths;
|
||||
CRecordVector<DWORD> errorCodes;
|
||||
dirItems.EnumerateDirItems2(FString(), UString(), filePaths, errorPaths, errorCodes);
|
||||
dirItems.EnumerateItems2(FString(), UString(), filePaths, NULL);
|
||||
if (dirItems.Items.Size() != 1)
|
||||
return E_FAIL;
|
||||
}
|
||||
@@ -449,32 +533,31 @@ HRESULT CAgent::UpdateOneFile(ISequentialOutStream *outArchiveStream,
|
||||
for (UInt32 i = 0; i < numItemsInArchive; i++)
|
||||
{
|
||||
CUpdatePair2 up2;
|
||||
up2.ArcIndex = i;
|
||||
up2.IsAnti = false;
|
||||
up2.NewData = false;
|
||||
up2.NewProps = false;
|
||||
up2.SetAs_NoChangeArcItem(i);
|
||||
if (realIndex == i)
|
||||
{
|
||||
up2.DirIndex = 0;
|
||||
up2.NewData = true;
|
||||
up2.NewProps = true;
|
||||
up2.UseArcProps = false;
|
||||
}
|
||||
updatePairs.Add(up2);
|
||||
}
|
||||
updateCallbackSpec->DirItems = &dirItems;
|
||||
updateCallbackSpec->Callback = &updateCallbackAgent;
|
||||
updateCallbackSpec->UpdatePairs = &updatePairs;
|
||||
updateCallbackSpec->Archive = GetArchive();
|
||||
|
||||
SetInArchiveInterfaces(this, updateCallbackSpec);
|
||||
|
||||
updateCallbackSpec->KeepOriginalItemNames = true;
|
||||
return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback);
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgent::SetProperties(const wchar_t **names,
|
||||
const PROPVARIANT *values, Int32 numProperties)
|
||||
STDMETHODIMP CAgent::SetProperties(const wchar_t **names, const PROPVARIANT *values, UInt32 numProps)
|
||||
{
|
||||
m_PropNames.Clear();
|
||||
m_PropValues.Clear();
|
||||
for (int i = 0; i < numProperties; i++)
|
||||
for (UInt32 i = 0; i < numProps; i++)
|
||||
{
|
||||
m_PropNames.Add(names[i]);
|
||||
m_PropValues.Add(values[i]);
|
||||
|
||||
565
CPP/7zip/UI/Agent/AgentProxy.cpp
Executable file → Normal file
565
CPP/7zip/UI/Agent/AgentProxy.cpp
Executable file → Normal file
@@ -3,17 +3,21 @@
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../../C/Sort.h"
|
||||
#include "../../../../C/CpuArch.h"
|
||||
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "Windows/PropVariantConversions.h"
|
||||
#include "../../../Common/Wildcard.h"
|
||||
|
||||
#include "../../../Windows/PropVariant.h"
|
||||
#include "../../../Windows/PropVariantConv.h"
|
||||
|
||||
#include "AgentProxy.h"
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
int CProxyFolder::FindDirSubItemIndex(const UString &name, int &insertPos) const
|
||||
int CProxyArchive::FindDirSubItemIndex(unsigned folderIndex, const UString &name, unsigned &insertPos) const
|
||||
{
|
||||
int left = 0, right = Folders.Size();
|
||||
const CRecordVector<unsigned> &subFolders = Folders[folderIndex].Folders;
|
||||
unsigned left = 0, right = subFolders.Size();
|
||||
for (;;)
|
||||
{
|
||||
if (left == right)
|
||||
@@ -21,10 +25,11 @@ int CProxyFolder::FindDirSubItemIndex(const UString &name, int &insertPos) const
|
||||
insertPos = left;
|
||||
return -1;
|
||||
}
|
||||
int mid = (left + right) / 2;
|
||||
int compare = name.CompareNoCase(Folders[mid].Name);
|
||||
unsigned mid = (left + right) / 2;
|
||||
unsigned folderIndex = subFolders[mid];
|
||||
int compare = CompareFileNames(name, Folders[folderIndex].Name);
|
||||
if (compare == 0)
|
||||
return mid;
|
||||
return folderIndex;
|
||||
if (compare < 0)
|
||||
right = mid;
|
||||
else
|
||||
@@ -32,40 +37,41 @@ int CProxyFolder::FindDirSubItemIndex(const UString &name, int &insertPos) const
|
||||
}
|
||||
}
|
||||
|
||||
int CProxyFolder::FindDirSubItemIndex(const UString &name) const
|
||||
int CProxyArchive::FindDirSubItemIndex(unsigned folderIndex, const UString &name) const
|
||||
{
|
||||
int insertPos;
|
||||
return FindDirSubItemIndex(name, insertPos);
|
||||
unsigned insertPos;
|
||||
return FindDirSubItemIndex(folderIndex, name, insertPos);
|
||||
}
|
||||
|
||||
void CProxyFolder::AddFileSubItem(UInt32 index, const UString &name)
|
||||
{
|
||||
Files.Add(CProxyFile());
|
||||
Files.Back().Name = name;
|
||||
Files.Back().Index = index;
|
||||
CProxyFile &f = Files.AddNew();
|
||||
f.Index = index;
|
||||
f.Name = name;
|
||||
}
|
||||
|
||||
CProxyFolder* CProxyFolder::AddDirSubItem(UInt32 index, bool leaf, const UString &name)
|
||||
unsigned CProxyArchive::AddDirSubItem(unsigned folderIndex, UInt32 index, bool leaf, const UString &name)
|
||||
{
|
||||
int insertPos;
|
||||
int folderIndex = FindDirSubItemIndex(name, insertPos);
|
||||
if (folderIndex >= 0)
|
||||
unsigned insertPos;
|
||||
int subFolderIndex = FindDirSubItemIndex(folderIndex, name, insertPos);
|
||||
if (subFolderIndex >= 0)
|
||||
{
|
||||
CProxyFolder *item = &Folders[folderIndex];
|
||||
CProxyFolder &item = Folders[subFolderIndex];
|
||||
if (leaf)
|
||||
{
|
||||
item->Index = index;
|
||||
item->IsLeaf = true;
|
||||
item.Index = index;
|
||||
item.IsLeaf = true;
|
||||
}
|
||||
return item;
|
||||
return subFolderIndex;
|
||||
}
|
||||
Folders.Insert(insertPos, CProxyFolder());
|
||||
CProxyFolder *item = &Folders[insertPos];
|
||||
item->Name = name;
|
||||
item->Index = index;
|
||||
item->Parent = this;
|
||||
item->IsLeaf = leaf;
|
||||
return item;
|
||||
subFolderIndex = Folders.Size();
|
||||
Folders[folderIndex].Folders.Insert(insertPos, subFolderIndex);
|
||||
CProxyFolder &item = Folders.AddNew();
|
||||
item.Name = name;
|
||||
item.Index = index;
|
||||
item.Parent = folderIndex;
|
||||
item.IsLeaf = leaf;
|
||||
return subFolderIndex;
|
||||
}
|
||||
|
||||
void CProxyFolder::Clear()
|
||||
@@ -74,51 +80,71 @@ void CProxyFolder::Clear()
|
||||
Files.Clear();
|
||||
}
|
||||
|
||||
void CProxyFolder::GetPathParts(UStringVector &pathParts) const
|
||||
void CProxyArchive::GetPathParts(int folderIndex, UStringVector &pathParts) const
|
||||
{
|
||||
pathParts.Clear();
|
||||
const CProxyFolder *current = this;
|
||||
while (current->Parent != NULL)
|
||||
while (folderIndex >= 0)
|
||||
{
|
||||
pathParts.Insert(0, current->Name);
|
||||
current = current->Parent;
|
||||
const CProxyFolder &folder = Folders[folderIndex];
|
||||
folderIndex = folder.Parent;
|
||||
if (folderIndex < 0)
|
||||
break;
|
||||
pathParts.Insert(0, folder.Name);
|
||||
}
|
||||
}
|
||||
|
||||
UString CProxyFolder::GetFullPathPrefix() const
|
||||
UString CProxyArchive::GetFullPathPrefix(int folderIndex) const
|
||||
{
|
||||
UString result;
|
||||
const CProxyFolder *current = this;
|
||||
while (current->Parent != NULL)
|
||||
while (folderIndex >= 0)
|
||||
{
|
||||
result = current->Name + UString(WCHAR_PATH_SEPARATOR) + result;
|
||||
current = current->Parent;
|
||||
const CProxyFolder &folder = Folders[folderIndex];
|
||||
folderIndex = folder.Parent;
|
||||
if (folderIndex < 0)
|
||||
break;
|
||||
result = folder.Name + UString(WCHAR_PATH_SEPARATOR) + result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void CProxyFolder::AddRealIndices(CUIntVector &realIndices) const
|
||||
void CProxyArchive::AddRealIndices(unsigned folderIndex, CUIntVector &realIndices) const
|
||||
{
|
||||
if (IsLeaf)
|
||||
realIndices.Add(Index);
|
||||
int i;
|
||||
for (i = 0; i < Folders.Size(); i++)
|
||||
Folders[i].AddRealIndices(realIndices);
|
||||
for (i = 0; i < Files.Size(); i++)
|
||||
realIndices.Add(Files[i].Index);
|
||||
const CProxyFolder &folder = Folders[folderIndex];
|
||||
if (folder.IsLeaf)
|
||||
realIndices.Add(folder.Index);
|
||||
unsigned i;
|
||||
for (i = 0; i < folder.Folders.Size(); i++)
|
||||
AddRealIndices(folder.Folders[i], realIndices);
|
||||
for (i = 0; i < folder.Files.Size(); i++)
|
||||
realIndices.Add(folder.Files[i].Index);
|
||||
}
|
||||
|
||||
void CProxyFolder::GetRealIndices(const UInt32 *indices, UInt32 numItems, CUIntVector &realIndices) const
|
||||
int CProxyArchive::GetRealIndex(unsigned folderIndex, unsigned index) const
|
||||
{
|
||||
const CProxyFolder &folder = Folders[folderIndex];
|
||||
unsigned numDirItems = folder.Folders.Size();
|
||||
if (index < numDirItems)
|
||||
{
|
||||
const CProxyFolder &f = Folders[folder.Folders[index]];
|
||||
if (f.IsLeaf)
|
||||
return f.Index;
|
||||
return -1;
|
||||
}
|
||||
return folder.Files[index - numDirItems].Index;
|
||||
}
|
||||
|
||||
void CProxyArchive::GetRealIndices(unsigned folderIndex, const UInt32 *indices, UInt32 numItems, CUIntVector &realIndices) const
|
||||
{
|
||||
const CProxyFolder &folder = Folders[folderIndex];
|
||||
realIndices.Clear();
|
||||
for (UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
int index = indices[i];
|
||||
int numDirItems = Folders.Size();
|
||||
UInt32 index = indices[i];
|
||||
unsigned numDirItems = folder.Folders.Size();
|
||||
if (index < numDirItems)
|
||||
Folders[index].AddRealIndices(realIndices);
|
||||
AddRealIndices(folder.Folders[index], realIndices);
|
||||
else
|
||||
realIndices.Add(Files[index - numDirItems].Index);
|
||||
realIndices.Add(folder.Files[index - numDirItems].Index);
|
||||
}
|
||||
HeapSort(&realIndices.Front(), realIndices.Size());
|
||||
}
|
||||
@@ -126,111 +152,426 @@ void CProxyFolder::GetRealIndices(const UInt32 *indices, UInt32 numItems, CUIntV
|
||||
///////////////////////////////////////////////
|
||||
// CProxyArchive
|
||||
|
||||
static UInt64 GetSize(IInArchive *archive, UInt32 index, PROPID propID)
|
||||
static bool GetSize(IInArchive *archive, UInt32 index, PROPID propID, UInt64 &size)
|
||||
{
|
||||
size = 0;
|
||||
NCOM::CPropVariant prop;
|
||||
if (archive->GetProperty(index, propID, &prop) == S_OK)
|
||||
if (prop.vt != VT_EMPTY)
|
||||
return ConvertPropVariantToUInt64(prop);
|
||||
return 0;
|
||||
if (archive->GetProperty(index, propID, &prop) != S_OK)
|
||||
throw 20120228;
|
||||
return ConvertPropVariantToUInt64(prop, size);
|
||||
}
|
||||
|
||||
void CProxyFolder::CalculateSizes(IInArchive *archive)
|
||||
void CProxyArchive::CalculateSizes(unsigned folderIndex, IInArchive *archive)
|
||||
{
|
||||
Size = PackSize = 0;
|
||||
NumSubFolders = Folders.Size();
|
||||
NumSubFiles = Files.Size();
|
||||
CrcIsDefined = true;
|
||||
Crc = 0;
|
||||
int i;
|
||||
for (i = 0; i < Files.Size(); i++)
|
||||
CProxyFolder &folder = Folders[folderIndex];
|
||||
folder.Size = folder.PackSize = 0;
|
||||
folder.NumSubFolders = folder.Folders.Size();
|
||||
folder.NumSubFiles = folder.Files.Size();
|
||||
folder.CrcIsDefined = true;
|
||||
folder.Crc = 0;
|
||||
unsigned i;
|
||||
for (i = 0; i < folder.Files.Size(); i++)
|
||||
{
|
||||
UInt32 index = Files[i].Index;
|
||||
Size += GetSize(archive, index, kpidSize);
|
||||
PackSize += GetSize(archive, index, kpidPackSize);
|
||||
UInt32 index = folder.Files[i].Index;
|
||||
UInt64 size, packSize;
|
||||
bool sizeDefined = GetSize(archive, index, kpidSize, size);
|
||||
folder.Size += size;
|
||||
GetSize(archive, index, kpidPackSize, packSize);
|
||||
folder.PackSize += packSize;
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
if (archive->GetProperty(index, kpidCRC, &prop) == S_OK && prop.vt == VT_UI4)
|
||||
Crc += prop.ulVal;
|
||||
if (archive->GetProperty(index, kpidCRC, &prop) == S_OK)
|
||||
{
|
||||
if (prop.vt == VT_UI4)
|
||||
folder.Crc += prop.ulVal;
|
||||
else if (prop.vt != VT_EMPTY || size != 0 || !sizeDefined)
|
||||
folder.CrcIsDefined = false;
|
||||
}
|
||||
else
|
||||
CrcIsDefined = false;
|
||||
folder.CrcIsDefined = false;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < Folders.Size(); i++)
|
||||
for (i = 0; i < folder.Folders.Size(); i++)
|
||||
{
|
||||
CProxyFolder &f = Folders[i];
|
||||
f.CalculateSizes(archive);
|
||||
Size += f.Size;
|
||||
PackSize += f.PackSize;
|
||||
NumSubFiles += f.NumSubFiles;
|
||||
NumSubFolders += f.NumSubFolders;
|
||||
Crc += f.Crc;
|
||||
unsigned subFolderIndex = folder.Folders[i];
|
||||
CProxyFolder &f = Folders[subFolderIndex];
|
||||
CalculateSizes(subFolderIndex, archive);
|
||||
folder.Size += f.Size;
|
||||
folder.PackSize += f.PackSize;
|
||||
folder.NumSubFiles += f.NumSubFiles;
|
||||
folder.NumSubFolders += f.NumSubFolders;
|
||||
folder.Crc += f.Crc;
|
||||
if (!f.CrcIsDefined)
|
||||
CrcIsDefined = false;
|
||||
folder.CrcIsDefined = false;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CProxyArchive::Load(const CArc &arc, IProgress *progress)
|
||||
{
|
||||
RootFolder.Clear();
|
||||
/*
|
||||
DWORD tickCount = GetTickCount();
|
||||
for (int ttt = 0; ttt < 1000; ttt++) {
|
||||
*/
|
||||
|
||||
Folders.Clear();
|
||||
Folders.AddNew();
|
||||
IInArchive *archive = arc.Archive;
|
||||
{
|
||||
ThereIsPathProp = false;
|
||||
UInt32 numProps;
|
||||
archive->GetNumberOfProperties(&numProps);
|
||||
for (UInt32 i = 0; i < numProps; i++)
|
||||
{
|
||||
CMyComBSTR name;
|
||||
PROPID propID;
|
||||
VARTYPE varType;
|
||||
RINOK(archive->GetPropertyInfo(i, &name, &propID, &varType));
|
||||
if (propID == kpidPath)
|
||||
{
|
||||
ThereIsPathProp = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 numItems;
|
||||
RINOK(archive->GetNumberOfItems(&numItems));
|
||||
if (progress != NULL)
|
||||
{
|
||||
UInt64 totalItems = numItems;
|
||||
RINOK(progress->SetTotal(totalItems));
|
||||
}
|
||||
if (progress)
|
||||
RINOK(progress->SetTotal(numItems));
|
||||
UString filePath;
|
||||
UString fileName;
|
||||
for (UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
if (progress != NULL && (i & 0xFFFFF) == 0)
|
||||
if (progress && (i & 0xFFFFF) == 0)
|
||||
{
|
||||
UInt64 currentItemIndex = i;
|
||||
RINOK(progress->SetCompleted(¤tItemIndex));
|
||||
}
|
||||
UString filePath;
|
||||
RINOK(arc.GetItemPath(i, filePath));
|
||||
CProxyFolder *curItem = &RootFolder;
|
||||
int len = filePath.Length();
|
||||
unsigned curItem = 0;
|
||||
unsigned len = filePath.Len();
|
||||
fileName.Empty();
|
||||
for (int j = 0; j < len; j++)
|
||||
|
||||
/*
|
||||
if (arc.Ask_Deleted)
|
||||
{
|
||||
bool isDeleted = false;
|
||||
RINOK(Archive_IsItem_Deleted(archive, i, isDeleted));
|
||||
if (isDeleted)
|
||||
curItem = AddDirSubItem(curItem, (UInt32)(Int32)-1, false, L"[DELETED]");
|
||||
}
|
||||
*/
|
||||
|
||||
for (unsigned j = 0; j < len; j++)
|
||||
{
|
||||
wchar_t c = filePath[j];
|
||||
if (c == WCHAR_PATH_SEPARATOR || c == L'/')
|
||||
{
|
||||
curItem = curItem->AddDirSubItem((UInt32)(Int32)-1, false, fileName);
|
||||
curItem = AddDirSubItem(curItem, (UInt32)(Int32)-1, false, fileName);
|
||||
fileName.Empty();
|
||||
}
|
||||
else
|
||||
fileName += c;
|
||||
}
|
||||
|
||||
/*
|
||||
that code must be implemeted to hide alt streams in list.
|
||||
if (arc.Ask_AltStreams)
|
||||
{
|
||||
bool isAltStream;
|
||||
RINOK(Archive_IsItem_AltStream(archive, i, isAltStream));
|
||||
if (isAltStream)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
bool isFolder;
|
||||
RINOK(IsArchiveItemFolder(archive, i, isFolder));
|
||||
RINOK(Archive_IsItem_Folder(archive, i, isFolder));
|
||||
if (isFolder)
|
||||
curItem->AddDirSubItem(i, true, fileName);
|
||||
AddDirSubItem(curItem, i, true, fileName);
|
||||
else
|
||||
curItem->AddFileSubItem(i, fileName);
|
||||
Folders[curItem].AddFileSubItem(i, fileName);
|
||||
}
|
||||
RootFolder.CalculateSizes(archive);
|
||||
CalculateSizes(0, archive);
|
||||
|
||||
/*
|
||||
}
|
||||
char s[128];
|
||||
sprintf(s, "load archive %7d ms", GetTickCount() - tickCount);
|
||||
OutputDebugStringA(s);
|
||||
*/
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ---------- for Tree-mode archive ----------
|
||||
|
||||
void CProxyArchive2::GetPathParts(int folderIndex, UStringVector &pathParts) const
|
||||
{
|
||||
pathParts.Clear();
|
||||
while (folderIndex > 0)
|
||||
{
|
||||
const CProxyFolder2 &folder = Folders[folderIndex];
|
||||
const CProxyFile2 &file = Files[folder.ArcIndex];
|
||||
pathParts.Insert(0, file.Name);
|
||||
int par = file.Parent;
|
||||
if (par < 0)
|
||||
break;
|
||||
folderIndex = Files[par].FolderIndex;
|
||||
}
|
||||
}
|
||||
|
||||
UString CProxyArchive2::GetFullPathPrefix(unsigned folderIndex) const
|
||||
{
|
||||
return Folders[folderIndex].PathPrefix;
|
||||
/*
|
||||
UString result;
|
||||
while (folderIndex > 0)
|
||||
{
|
||||
const CProxyFile2 &file = Files[Folders[folderIndex].ArcIndex];
|
||||
result = (UString)(file.Name) + (UString)WCHAR_PATH_SEPARATOR + result;
|
||||
if (file.Parent < 0)
|
||||
break;
|
||||
folderIndex = Files[file.Parent].FolderIndex;
|
||||
}
|
||||
return result;
|
||||
*/
|
||||
}
|
||||
|
||||
void CProxyArchive2::AddRealIndices_of_ArcItem(unsigned arcIndex, bool includeAltStreams, CUIntVector &realIndices) const
|
||||
{
|
||||
realIndices.Add(arcIndex);
|
||||
const CProxyFile2 &file = Files[arcIndex];
|
||||
if (file.FolderIndex >= 0)
|
||||
AddRealIndices_of_Folder(file.FolderIndex, includeAltStreams, realIndices);
|
||||
if (includeAltStreams && file.AltStreamsFolderIndex >= 0)
|
||||
AddRealIndices_of_Folder(file.AltStreamsFolderIndex, includeAltStreams, realIndices);
|
||||
}
|
||||
|
||||
void CProxyArchive2::AddRealIndices_of_Folder(unsigned folderIndex, bool includeAltStreams, CUIntVector &realIndices) const
|
||||
{
|
||||
const CRecordVector<unsigned> &subFiles = Folders[folderIndex].SubFiles;
|
||||
FOR_VECTOR (i, subFiles)
|
||||
{
|
||||
AddRealIndices_of_ArcItem(subFiles[i], includeAltStreams, realIndices);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned CProxyArchive2::GetRealIndex(unsigned folderIndex, unsigned index) const
|
||||
{
|
||||
return Folders[folderIndex].SubFiles[index];
|
||||
}
|
||||
|
||||
void CProxyArchive2::GetRealIndices(unsigned folderIndex, const UInt32 *indices, UInt32 numItems, bool includeAltStreams, CUIntVector &realIndices) const
|
||||
{
|
||||
const CProxyFolder2 &folder = Folders[folderIndex];
|
||||
realIndices.Clear();
|
||||
for (UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
AddRealIndices_of_ArcItem(folder.SubFiles[indices[i]], includeAltStreams, realIndices);
|
||||
}
|
||||
HeapSort(&realIndices.Front(), realIndices.Size());
|
||||
}
|
||||
|
||||
void CProxyArchive2::CalculateSizes(unsigned folderIndex, IInArchive *archive)
|
||||
{
|
||||
CProxyFolder2 &folder = Folders[folderIndex];
|
||||
folder.Size = folder.PackSize = 0;
|
||||
folder.NumSubFolders = 0; // folder.Folders.Size();
|
||||
folder.NumSubFiles = 0; // folder.Files.Size();
|
||||
folder.CrcIsDefined = true;
|
||||
folder.Crc = 0;
|
||||
FOR_VECTOR (i, folder.SubFiles)
|
||||
{
|
||||
UInt32 index = folder.SubFiles[i];
|
||||
UInt64 size, packSize;
|
||||
bool sizeDefined = GetSize(archive, index, kpidSize, size);
|
||||
folder.Size += size;
|
||||
GetSize(archive, index, kpidPackSize, packSize);
|
||||
folder.PackSize += packSize;
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
if (archive->GetProperty(index, kpidCRC, &prop) == S_OK)
|
||||
{
|
||||
if (prop.vt == VT_UI4)
|
||||
folder.Crc += prop.ulVal;
|
||||
else if (prop.vt != VT_EMPTY || size != 0 || !sizeDefined)
|
||||
folder.CrcIsDefined = false;
|
||||
}
|
||||
else
|
||||
folder.CrcIsDefined = false;
|
||||
}
|
||||
|
||||
const CProxyFile2 &subFile = Files[index];
|
||||
if (subFile.FolderIndex < 0)
|
||||
{
|
||||
folder.NumSubFiles++;
|
||||
}
|
||||
else
|
||||
{
|
||||
folder.NumSubFolders++;
|
||||
CProxyFolder2 &f = Folders[subFile.FolderIndex];
|
||||
f.PathPrefix = folder.PathPrefix + subFile.Name + WCHAR_PATH_SEPARATOR;
|
||||
CalculateSizes(subFile.FolderIndex, archive);
|
||||
folder.Size += f.Size;
|
||||
folder.PackSize += f.PackSize;
|
||||
folder.NumSubFiles += f.NumSubFiles;
|
||||
folder.NumSubFolders += f.NumSubFolders;
|
||||
folder.Crc += f.Crc;
|
||||
if (!f.CrcIsDefined)
|
||||
folder.CrcIsDefined = false;
|
||||
}
|
||||
|
||||
if (subFile.AltStreamsFolderIndex < 0)
|
||||
{
|
||||
// folder.NumSubFiles++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// folder.NumSubFolders++;
|
||||
CProxyFolder2 &f = Folders[subFile.AltStreamsFolderIndex];
|
||||
f.PathPrefix = folder.PathPrefix + subFile.Name + L":";
|
||||
CalculateSizes(subFile.AltStreamsFolderIndex, archive);
|
||||
/*
|
||||
folder.Size += f.Size;
|
||||
folder.PackSize += f.PackSize;
|
||||
folder.NumSubFiles += f.NumSubFiles;
|
||||
folder.NumSubFolders += f.NumSubFolders;
|
||||
folder.Crc += f.Crc;
|
||||
if (!f.CrcIsDefined)
|
||||
folder.CrcIsDefined = false;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CProxyArchive2::IsThere_SubDir(unsigned folderIndex, const UString &name) const
|
||||
{
|
||||
const CRecordVector<unsigned> &subFiles = Folders[folderIndex].SubFiles;
|
||||
FOR_VECTOR (i, subFiles)
|
||||
{
|
||||
const CProxyFile2 &file = Files[subFiles[i]];
|
||||
if (file.IsDir())
|
||||
if (CompareFileNames(name, file.Name) == 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
HRESULT CProxyArchive2::Load(const CArc &arc, IProgress *progress)
|
||||
{
|
||||
if (!arc.GetRawProps)
|
||||
return E_FAIL;
|
||||
|
||||
// DWORD tickCount = GetTickCount();
|
||||
|
||||
Folders.Clear();
|
||||
|
||||
IInArchive *archive = arc.Archive;
|
||||
|
||||
UInt32 numItems;
|
||||
RINOK(archive->GetNumberOfItems(&numItems));
|
||||
if (progress)
|
||||
RINOK(progress->SetTotal(numItems));
|
||||
UString fileName;
|
||||
{
|
||||
CProxyFolder2 &folder = Folders.AddNew();
|
||||
folder.ArcIndex = -1;
|
||||
}
|
||||
|
||||
Files.Alloc(numItems);
|
||||
|
||||
UInt32 i;
|
||||
for (i = 0; i < numItems; i++)
|
||||
{
|
||||
if (progress && (i & 0xFFFFF) == 0)
|
||||
{
|
||||
UInt64 currentItemIndex = i;
|
||||
RINOK(progress->SetCompleted(¤tItemIndex));
|
||||
}
|
||||
|
||||
CProxyFile2 &file = Files[i];
|
||||
|
||||
#ifdef MY_CPU_LE
|
||||
const void *p;
|
||||
UInt32 size;
|
||||
UInt32 propType;
|
||||
RINOK(arc.GetRawProps->GetRawProp(i, kpidName, &p, &size, &propType));
|
||||
|
||||
if (p && propType == PROP_DATA_TYPE_wchar_t_PTR_Z_LE)
|
||||
{
|
||||
file.Name = (const wchar_t *)p;
|
||||
file.NameSize = 0;
|
||||
if (size >= 2)
|
||||
file.NameSize = size / 2 - 1;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(arc.Archive->GetProperty(i, kpidName, &prop));
|
||||
const wchar_t *s;
|
||||
if (prop.vt == VT_BSTR)
|
||||
s = prop.bstrVal;
|
||||
else if (prop.vt == VT_EMPTY)
|
||||
s = L"[Content]";
|
||||
else
|
||||
return E_FAIL;
|
||||
file.NameSize = MyStringLen(s);
|
||||
file.Name = new wchar_t[file.NameSize + 1];
|
||||
file.NeedDeleteName = true;
|
||||
MyStringCopy((wchar_t *)file.Name, s);
|
||||
}
|
||||
UInt32 parent = (UInt32)(Int32)-1;
|
||||
UInt32 parentType = 0;
|
||||
RINOK(arc.GetRawProps->GetParent(i, &parent, &parentType));
|
||||
file.Parent = (Int32)parent;
|
||||
|
||||
if (arc.Ask_Deleted)
|
||||
{
|
||||
bool isDeleted = false;
|
||||
RINOK(Archive_IsItem_Deleted(archive, i, isDeleted));
|
||||
if (isDeleted)
|
||||
{
|
||||
// continue;
|
||||
// curItem = AddDirSubItem(curItem, (UInt32)(Int32)-1, false, L"[DELETED]");
|
||||
}
|
||||
}
|
||||
|
||||
bool isFolder;
|
||||
RINOK(Archive_IsItem_Folder(archive, i, isFolder));
|
||||
|
||||
if (isFolder)
|
||||
{
|
||||
file.FolderIndex = Folders.Size();
|
||||
CProxyFolder2 &folder = Folders.AddNew();
|
||||
folder.ArcIndex = i;
|
||||
}
|
||||
if (arc.Ask_AltStream)
|
||||
RINOK(Archive_IsItem_AltStream(archive, i, file.IsAltStream));
|
||||
}
|
||||
|
||||
for (i = 0; i < numItems; i++)
|
||||
{
|
||||
CProxyFile2 &file = Files[i];
|
||||
if (file.IsAltStream)
|
||||
{
|
||||
if (file.Parent >= 0)
|
||||
{
|
||||
int &folderIndex = Files[file.Parent].AltStreamsFolderIndex;
|
||||
if (folderIndex < 0)
|
||||
{
|
||||
folderIndex = Folders.Size();
|
||||
CProxyFolder2 &folder = Folders.AddNew();
|
||||
folder.ArcIndex = file.Parent; // do we need it ???
|
||||
}
|
||||
Folders[folderIndex].SubFiles.Add(i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int folderIndex = GetParentFolderOfFile(i);
|
||||
if (folderIndex < 0)
|
||||
return E_FAIL;
|
||||
Folders[folderIndex].SubFiles.Add(i);
|
||||
}
|
||||
}
|
||||
CalculateSizes(0, archive);
|
||||
|
||||
/*
|
||||
char s[128];
|
||||
sprintf(s, "load archive %7d ms", GetTickCount() - tickCount);
|
||||
OutputDebugStringA(s);
|
||||
*/
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
113
CPP/7zip/UI/Agent/AgentProxy.h
Executable file → Normal file
113
CPP/7zip/UI/Agent/AgentProxy.h
Executable file → Normal file
@@ -13,39 +13,116 @@ struct CProxyFile
|
||||
|
||||
class CProxyFolder: public CProxyFile
|
||||
{
|
||||
int FindDirSubItemIndex(const UString &name, int &insertPos) const;
|
||||
void AddRealIndices(CUIntVector &realIndices) const;
|
||||
public:
|
||||
CProxyFolder *Parent;
|
||||
CObjectVector<CProxyFolder> Folders;
|
||||
int Parent;
|
||||
CRecordVector<unsigned> Folders;
|
||||
CObjectVector<CProxyFile> Files;
|
||||
bool IsLeaf;
|
||||
|
||||
bool CrcIsDefined;
|
||||
UInt64 Size;
|
||||
UInt64 PackSize;
|
||||
UInt32 Crc;
|
||||
UInt32 NumSubFolders;
|
||||
UInt32 NumSubFiles;
|
||||
bool IsLeaf;
|
||||
bool CrcIsDefined;
|
||||
|
||||
CProxyFolder(): Parent(NULL) {};
|
||||
int FindDirSubItemIndex(const UString &name) const;
|
||||
CProxyFolder* AddDirSubItem(UInt32 index, bool leaf, const UString &name);
|
||||
CProxyFolder(): Parent(-1) {};
|
||||
void AddFileSubItem(UInt32 index, const UString &name);
|
||||
void Clear();
|
||||
|
||||
void GetPathParts(UStringVector &pathParts) const;
|
||||
UString GetFullPathPrefix() const;
|
||||
void GetRealIndices(const UInt32 *indices, UInt32 numItems, CUIntVector &realIndices) const;
|
||||
void CalculateSizes(IInArchive *archive);
|
||||
};
|
||||
|
||||
struct CProxyArchive
|
||||
class CProxyArchive
|
||||
{
|
||||
CProxyFolder RootFolder;
|
||||
bool ThereIsPathProp;
|
||||
int FindDirSubItemIndex(unsigned folderIndex, const UString &name, unsigned &insertPos) const;
|
||||
|
||||
void CalculateSizes(unsigned folderIndex, IInArchive *archive);
|
||||
unsigned AddDirSubItem(unsigned folderIndex, UInt32 index, bool leaf, const UString &name);
|
||||
public:
|
||||
CObjectVector<CProxyFolder> Folders; // Folders[0] - isRoot
|
||||
|
||||
int FindDirSubItemIndex(unsigned folderIndex, const UString &name) const;
|
||||
void GetPathParts(int folderIndex, UStringVector &pathParts) const;
|
||||
UString GetFullPathPrefix(int folderIndex) const;
|
||||
|
||||
// AddRealIndices DOES ADD also item represented by folderIndex (if it's Leaf)
|
||||
void AddRealIndices(unsigned folderIndex, CUIntVector &realIndices) const;
|
||||
int GetRealIndex(unsigned folderIndex, unsigned index) const;
|
||||
void GetRealIndices(unsigned folderIndex, const UInt32 *indices, UInt32 numItems, CUIntVector &realIndices) const;
|
||||
|
||||
HRESULT Load(const CArc &arc, IProgress *progress);
|
||||
};
|
||||
|
||||
|
||||
// ---------- for Tree-mode archive ----------
|
||||
|
||||
struct CProxyFile2
|
||||
{
|
||||
int FolderIndex; // >= 0 for dir. (index in ProxyArchive2->Folders)
|
||||
int AltStreamsFolderIndex; // >= 0 if there are alt streams. (index in ProxyArchive2->Folders)
|
||||
int Parent; // >= 0 if there is parent. (index in archive and in ProxyArchive2->Files)
|
||||
const wchar_t *Name;
|
||||
unsigned NameSize;
|
||||
bool Ignore;
|
||||
bool IsAltStream;
|
||||
bool NeedDeleteName;
|
||||
|
||||
int GetFolderIndex(bool forAltStreams) const { return forAltStreams ? AltStreamsFolderIndex : FolderIndex; }
|
||||
|
||||
bool IsDir() const { return FolderIndex >= 0; }
|
||||
CProxyFile2(): FolderIndex(-1), AltStreamsFolderIndex(-1), Name(NULL), Ignore(false), IsAltStream(false), NeedDeleteName(false) {}
|
||||
~CProxyFile2()
|
||||
{
|
||||
if (NeedDeleteName)
|
||||
delete [](wchar_t *)Name;
|
||||
}
|
||||
};
|
||||
|
||||
class CProxyFolder2
|
||||
{
|
||||
public:
|
||||
Int32 ArcIndex; // = -1 for Root folder
|
||||
CRecordVector<unsigned> SubFiles;
|
||||
UString PathPrefix;
|
||||
UInt64 Size;
|
||||
UInt64 PackSize;
|
||||
bool CrcIsDefined;
|
||||
UInt32 Crc;
|
||||
UInt32 NumSubFolders;
|
||||
UInt32 NumSubFiles;
|
||||
|
||||
CProxyFolder2(): ArcIndex(-1) {};
|
||||
void AddFileSubItem(UInt32 index, const UString &name);
|
||||
void Clear();
|
||||
|
||||
};
|
||||
|
||||
class CProxyArchive2
|
||||
{
|
||||
void CalculateSizes(unsigned folderIndex, IInArchive *archive);
|
||||
// AddRealIndices_of_Folder DOES NOT ADD item itself represented by folderIndex
|
||||
void AddRealIndices_of_Folder(unsigned folderIndex, bool includeAltStreams, CUIntVector &realIndices) const;
|
||||
public:
|
||||
CObjectVector<CProxyFolder2> Folders; // Folders[0] - is root folder
|
||||
CObjArray<CProxyFile2> Files; // all aitems from archive in same order
|
||||
|
||||
bool IsThere_SubDir(unsigned folderIndex, const UString &name) const;
|
||||
|
||||
void GetPathParts(int folderIndex, UStringVector &pathParts) const;
|
||||
UString GetFullPathPrefix(unsigned folderIndex) const;
|
||||
|
||||
// AddRealIndices_of_ArcItem DOES ADD item and subItems
|
||||
void AddRealIndices_of_ArcItem(unsigned arcIndex, bool includeAltStreams, CUIntVector &realIndices) const;
|
||||
unsigned GetRealIndex(unsigned folderIndex, unsigned index) const;
|
||||
void GetRealIndices(unsigned folderIndex, const UInt32 *indices, UInt32 numItems, bool includeAltStreams, CUIntVector &realIndices) const;
|
||||
|
||||
HRESULT Load(const CArc &arc, IProgress *progress);
|
||||
|
||||
int GetParentFolderOfFile(UInt32 indexInArc) const
|
||||
{
|
||||
const CProxyFile2 &file = Files[indexInArc];
|
||||
if (file.Parent < 0)
|
||||
return 0;
|
||||
return Files[file.Parent].FolderIndex;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
29
CPP/7zip/UI/Agent/ArchiveFolder.cpp
Executable file → Normal file
29
CPP/7zip/UI/Agent/ArchiveFolder.cpp
Executable file → Normal file
@@ -2,15 +2,26 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/ComTry.h"
|
||||
#include "../../../Common/ComTry.h"
|
||||
|
||||
#include "../Common/ArchiveExtractCallback.h"
|
||||
|
||||
#include "Agent.h"
|
||||
|
||||
STDMETHODIMP CAgentFolder::CopyTo(const UInt32 *indices, UInt32 numItems,
|
||||
/*
|
||||
STDMETHODIMP CAgentFolder::SetReplaceAltStreamCharsMode(Int32 replaceAltStreamCharsMode)
|
||||
{
|
||||
_replaceAltStreamCharsMode = replaceAltStreamCharsMode;
|
||||
return S_OK;
|
||||
}
|
||||
*/
|
||||
|
||||
STDMETHODIMP CAgentFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 numItems,
|
||||
Int32 includeAltStreams, Int32 replaceAltStreamCharsMode,
|
||||
const wchar_t *path, IFolderOperationsExtractCallback *callback)
|
||||
{
|
||||
if (moveMode)
|
||||
return E_NOTIMPL;
|
||||
COM_TRY_BEGIN
|
||||
CMyComPtr<IFolderArchiveExtractCallback> extractCallback2;
|
||||
{
|
||||
@@ -18,15 +29,11 @@ STDMETHODIMP CAgentFolder::CopyTo(const UInt32 *indices, UInt32 numItems,
|
||||
RINOK(callbackWrap.QueryInterface(IID_IFolderArchiveExtractCallback, &extractCallback2));
|
||||
}
|
||||
NExtract::NPathMode::EEnum pathMode = _flatMode ?
|
||||
NExtract::NPathMode::kNoPathnames :
|
||||
NExtract::NPathMode::kCurrentPathnames;
|
||||
return Extract(indices,numItems, pathMode, NExtract::NOverwriteMode::kAskBefore,
|
||||
NExtract::NPathMode::kNoPaths :
|
||||
NExtract::NPathMode::kCurPaths;
|
||||
return Extract(indices, numItems,
|
||||
includeAltStreams, replaceAltStreamCharsMode,
|
||||
pathMode, NExtract::NOverwriteMode::kAsk,
|
||||
path, BoolToInt(false), extractCallback2);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgentFolder::MoveTo(const UInt32 * /* indices */, UInt32 /* numItems */,
|
||||
const wchar_t * /* path */, IFolderOperationsExtractCallback * /* callback */)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
14
CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp
Executable file → Normal file
14
CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp
Executable file → Normal file
@@ -15,8 +15,8 @@ void CArchiveFolderManager::LoadFormats()
|
||||
|
||||
int CArchiveFolderManager::FindFormat(const UString &type)
|
||||
{
|
||||
for (int i = 0; i < _codecs->Formats.Size(); i++)
|
||||
if (type.CompareNoCase(_codecs->Formats[i].Name) == 0)
|
||||
FOR_VECTOR (i, _codecs->Formats)
|
||||
if (type.IsEqualToNoCase(_codecs->Formats[i].Name))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
@@ -60,11 +60,11 @@ STDMETHODIMP CArchiveFolderManager::GetExtensions(const wchar_t *type, BSTR *ext
|
||||
|
||||
static void AddIconExt(const CCodecIcons &lib, UString &dest)
|
||||
{
|
||||
for (int j = 0; j < lib.IconPairs.Size(); j++)
|
||||
FOR_VECTOR (i, lib.IconPairs)
|
||||
{
|
||||
if (!dest.IsEmpty())
|
||||
dest += L' ';
|
||||
dest += lib.IconPairs[j].Ext;
|
||||
dest += lib.IconPairs[i].Ext;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ STDMETHODIMP CArchiveFolderManager::GetExtensions(BSTR *extensions)
|
||||
LoadFormats();
|
||||
*extensions = 0;
|
||||
UString res;
|
||||
for (int i = 0; i < _codecs->Libs.Size(); i++)
|
||||
FOR_VECTOR (i, _codecs->Libs)
|
||||
AddIconExt(_codecs->Libs[i], res);
|
||||
AddIconExt(_codecs->InternalIcons, res);
|
||||
return StringToBstr(res, extensions);
|
||||
@@ -84,7 +84,7 @@ STDMETHODIMP CArchiveFolderManager::GetIconPath(const wchar_t *ext, BSTR *iconPa
|
||||
LoadFormats();
|
||||
*iconPath = 0;
|
||||
*iconIndex = 0;
|
||||
for (int i = 0; i < _codecs->Libs.Size(); i++)
|
||||
FOR_VECTOR (i, _codecs->Libs)
|
||||
{
|
||||
const CCodecLib &lib = _codecs->Libs[i];
|
||||
int ii;
|
||||
@@ -112,7 +112,7 @@ STDMETHODIMP CArchiveFolderManager::GetTypes(BSTR *types)
|
||||
{
|
||||
LoadFormats();
|
||||
UString typesStrings;
|
||||
for(int i = 0; i < _codecs.Formats.Size(); i++)
|
||||
FOR_VECTOR(i, _codecs.Formats)
|
||||
{
|
||||
const CArcInfoEx &ai = _codecs.Formats[i];
|
||||
if (ai.AssociateExts.Size() == 0)
|
||||
|
||||
205
CPP/7zip/UI/Agent/ArchiveFolderOut.cpp
Executable file → Normal file
205
CPP/7zip/UI/Agent/ArchiveFolderOut.cpp
Executable file → Normal file
@@ -2,79 +2,157 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/ComTry.h"
|
||||
#include "../../../Common/ComTry.h"
|
||||
|
||||
#include "Windows/FileDir.h"
|
||||
#include "../../../Windows/FileDir.h"
|
||||
|
||||
#include "../../Common/FileStreams.h"
|
||||
#include "../../Common/LimitedStreams.h"
|
||||
|
||||
#include "../../Compress/CopyCoder.h"
|
||||
|
||||
#include "../Common/WorkDir.h"
|
||||
|
||||
#include "Agent.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
using namespace NDirectory;
|
||||
using namespace NDir;
|
||||
|
||||
void CAgentFolder::GetPathParts(UStringVector &pathParts)
|
||||
{
|
||||
_proxyFolderItem->GetPathParts(pathParts);
|
||||
if (_proxyArchive2)
|
||||
_proxyArchive2->GetPathParts(_proxyFolderItem, pathParts);
|
||||
else
|
||||
_proxyArchive->GetPathParts(_proxyFolderItem, pathParts);
|
||||
}
|
||||
|
||||
static bool DeleteEmptyFolderAndEmptySubFolders(const FString &path)
|
||||
{
|
||||
NFind::CFileInfo fileInfo;
|
||||
FString pathPrefix = path + FCHAR_PATH_SEPARATOR;
|
||||
{
|
||||
NFind::CEnumerator enumerator(pathPrefix + FCHAR_ANY_MASK);
|
||||
while (enumerator.Next(fileInfo))
|
||||
{
|
||||
if (fileInfo.IsDir())
|
||||
if (!DeleteEmptyFolderAndEmptySubFolders(pathPrefix + fileInfo.Name))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/*
|
||||
// we don't need clear readonly for folders
|
||||
if (!SetFileAttrib(path, 0))
|
||||
return false;
|
||||
*/
|
||||
return RemoveDir(path);
|
||||
}
|
||||
|
||||
|
||||
HRESULT CAgentFolder::CommonUpdateOperation(
|
||||
AGENT_OP operation,
|
||||
bool moveMode,
|
||||
const wchar_t *newItemName,
|
||||
const NUpdateArchive::CActionSet *actionSet,
|
||||
const UINT32 *indices, UINT32 numItems,
|
||||
const UInt32 *indices, UInt32 numItems,
|
||||
IFolderArchiveUpdateCallback *updateCallback100)
|
||||
{
|
||||
CWorkDirTempFile tempFile;
|
||||
RINOK(tempFile.CreateTempFile(us2fs(_agentSpec->_archiveFilePath)));
|
||||
if (!_agentSpec->CanUpdate())
|
||||
return E_NOTIMPL;
|
||||
|
||||
/*
|
||||
if (SetOutProperties(anOutArchive, aCompressionInfo.Method) != S_OK)
|
||||
return NFileOperationReturnCode::kError;
|
||||
*/
|
||||
|
||||
////////////////////////////
|
||||
// Save FolderItem;
|
||||
|
||||
UStringVector pathParts;
|
||||
GetPathParts(pathParts);
|
||||
|
||||
HRESULT result;
|
||||
switch (operation)
|
||||
{
|
||||
case AGENT_OP_Delete:
|
||||
result = _agentSpec->DeleteItems(tempFile.OutStream, indices, numItems, updateCallback100);
|
||||
break;
|
||||
case AGENT_OP_CreateFolder:
|
||||
result = _agentSpec->CreateFolder(tempFile.OutStream, newItemName, updateCallback100);
|
||||
break;
|
||||
case AGENT_OP_Rename:
|
||||
result = _agentSpec->RenameItem(tempFile.OutStream, indices, numItems, newItemName, updateCallback100);
|
||||
break;
|
||||
case AGENT_OP_CopyFromFile:
|
||||
result = _agentSpec->UpdateOneFile(tempFile.OutStream, indices, numItems, newItemName, updateCallback100);
|
||||
break;
|
||||
case AGENT_OP_Uni:
|
||||
{
|
||||
Byte actionSetByte[NUpdateArchive::NPairState::kNumValues];
|
||||
for (int i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
|
||||
actionSetByte[i] = (Byte)actionSet->StateActions[i];
|
||||
result = _agentSpec->DoOperation2(tempFile.OutStream, actionSetByte, NULL, updateCallback100);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
RINOK(result);
|
||||
FStringVector requestedPaths;
|
||||
FStringVector processedPaths;
|
||||
|
||||
CWorkDirTempFile tempFile;
|
||||
RINOK(tempFile.CreateTempFile(us2fs(_agentSpec->_archiveFilePath)));
|
||||
{
|
||||
CMyComPtr<IOutStream> tailStream;
|
||||
const CArc &arc = *_agentSpec->_archiveLink.GetArc();
|
||||
|
||||
if (arc.ArcStreamOffset == 0)
|
||||
tailStream = tempFile.OutStream;
|
||||
else
|
||||
{
|
||||
if (arc.Offset < 0)
|
||||
return E_NOTIMPL;
|
||||
RINOK(arc.InStream->Seek(0, STREAM_SEEK_SET, NULL));
|
||||
RINOK(NCompress::CopyStream_ExactSize(arc.InStream, tempFile.OutStream, arc.ArcStreamOffset, NULL));
|
||||
CTailOutStream *tailStreamSpec = new CTailOutStream;
|
||||
tailStream = tailStreamSpec;
|
||||
tailStreamSpec->Stream = tempFile.OutStream;
|
||||
tailStreamSpec->Offset = arc.ArcStreamOffset;
|
||||
tailStreamSpec->Init();
|
||||
}
|
||||
|
||||
HRESULT result;
|
||||
|
||||
switch (operation)
|
||||
{
|
||||
case AGENT_OP_Delete:
|
||||
result = _agentSpec->DeleteItems(tailStream, indices, numItems, updateCallback100);
|
||||
break;
|
||||
case AGENT_OP_CreateFolder:
|
||||
result = _agentSpec->CreateFolder(tailStream, newItemName, updateCallback100);
|
||||
break;
|
||||
case AGENT_OP_Rename:
|
||||
result = _agentSpec->RenameItem(tailStream, indices, numItems, newItemName, updateCallback100);
|
||||
break;
|
||||
case AGENT_OP_CopyFromFile:
|
||||
result = _agentSpec->UpdateOneFile(tailStream, indices, numItems, newItemName, updateCallback100);
|
||||
break;
|
||||
case AGENT_OP_Uni:
|
||||
{
|
||||
Byte actionSetByte[NUpdateArchive::NPairState::kNumValues];
|
||||
for (int i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
|
||||
actionSetByte[i] = (Byte)actionSet->StateActions[i];
|
||||
result = _agentSpec->DoOperation2(
|
||||
moveMode ? &requestedPaths : NULL,
|
||||
moveMode ? &processedPaths : NULL,
|
||||
tailStream, actionSetByte, NULL, updateCallback100);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
RINOK(result);
|
||||
}
|
||||
|
||||
_agentSpec->KeepModeForNextOpen();
|
||||
_agentSpec->Close();
|
||||
|
||||
// before 9.26: if there was error for MoveToOriginal archive was closed.
|
||||
// now: we reopen archive after close
|
||||
|
||||
// m_FolderItem = NULL;
|
||||
|
||||
RINOK(tempFile.MoveToOriginal(true));
|
||||
HRESULT res = tempFile.MoveToOriginal(true);
|
||||
|
||||
// RINOK(res);
|
||||
if (res == S_OK)
|
||||
{
|
||||
if (moveMode)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < processedPaths.Size(); i++)
|
||||
{
|
||||
DeleteFileAlways(processedPaths[i]);
|
||||
}
|
||||
for (i = 0; i < requestedPaths.Size(); i++)
|
||||
{
|
||||
const FString &fs = requestedPaths[i];
|
||||
if (NFind::DoesDirExist(fs))
|
||||
DeleteEmptyFolderAndEmptySubFolders(fs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
CMyComPtr<IArchiveOpenCallback> openCallback;
|
||||
@@ -85,12 +163,11 @@ HRESULT CAgentFolder::CommonUpdateOperation(
|
||||
RINOK(_agentSpec->ReOpen(openCallback));
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
// Restore FolderItem;
|
||||
|
||||
CMyComPtr<IFolderFolder> archiveFolder;
|
||||
RINOK(_agentSpec->BindToRootFolder(&archiveFolder));
|
||||
for (int i = 0; i < pathParts.Size(); i++)
|
||||
FOR_VECTOR (i, pathParts)
|
||||
{
|
||||
CMyComPtr<IFolderFolder> newFolder;
|
||||
archiveFolder->BindToFolder(pathParts[i], &newFolder);
|
||||
@@ -105,15 +182,16 @@ HRESULT CAgentFolder::CommonUpdateOperation(
|
||||
RINOK(archiveFolderInternal->GetAgentFolder(&agentFolder));
|
||||
_proxyFolderItem = agentFolder->_proxyFolderItem;
|
||||
_proxyArchive = agentFolder->_proxyArchive;
|
||||
_proxyArchive2 = agentFolder->_proxyArchive2;
|
||||
_parentFolder = agentFolder->_parentFolder;
|
||||
|
||||
return S_OK;
|
||||
return res;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgentFolder::CopyFrom(
|
||||
STDMETHODIMP CAgentFolder::CopyFrom(Int32 moveMode,
|
||||
const wchar_t *fromFolderPath, // test it
|
||||
const wchar_t **itemsPaths,
|
||||
UINT32 numItems,
|
||||
UInt32 numItems,
|
||||
IProgress *progress)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
@@ -126,8 +204,9 @@ STDMETHODIMP CAgentFolder::CopyFrom(
|
||||
{
|
||||
RINOK(_agentSpec->SetFiles(fromFolderPath, itemsPaths, numItems));
|
||||
RINOK(_agentSpec->SetFolder(this));
|
||||
return CommonUpdateOperation(AGENT_OP_Uni, NULL,
|
||||
&NUpdateArchive::kAddActionSet, 0, 0, updateCallback100);
|
||||
return CommonUpdateOperation(AGENT_OP_Uni, (moveMode != 0), NULL,
|
||||
&NUpdateArchive::k_ActionSet_Add,
|
||||
0, 0, updateCallback100);
|
||||
}
|
||||
catch(const UString &s)
|
||||
{
|
||||
@@ -150,8 +229,8 @@ STDMETHODIMP CAgentFolder::CopyFromFile(UInt32 destIndex, const wchar_t *itemPat
|
||||
try
|
||||
{
|
||||
RINOK(_agentSpec->SetFolder(this));
|
||||
return CommonUpdateOperation(AGENT_OP_CopyFromFile, itemPath,
|
||||
&NUpdateArchive::kAddActionSet,
|
||||
return CommonUpdateOperation(AGENT_OP_CopyFromFile, false, itemPath,
|
||||
&NUpdateArchive::k_ActionSet_Add,
|
||||
&indices.Front(), indices.Size(), updateCallback100);
|
||||
}
|
||||
catch(const UString &s)
|
||||
@@ -162,7 +241,7 @@ STDMETHODIMP CAgentFolder::CopyFromFile(UInt32 destIndex, const wchar_t *itemPat
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgentFolder::Delete(const UINT32 *indices, UINT32 numItems, IProgress *progress)
|
||||
STDMETHODIMP CAgentFolder::Delete(const UInt32 *indices, UInt32 numItems, IProgress *progress)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
RINOK(_agentSpec->SetFolder(this));
|
||||
@@ -173,16 +252,24 @@ STDMETHODIMP CAgentFolder::Delete(const UINT32 *indices, UINT32 numItems, IProgr
|
||||
RINOK(progressWrapper.QueryInterface(
|
||||
IID_IFolderArchiveUpdateCallback, &updateCallback100));
|
||||
}
|
||||
return CommonUpdateOperation(AGENT_OP_Delete, NULL,
|
||||
&NUpdateArchive::kDeleteActionSet, indices, numItems, updateCallback100);
|
||||
return CommonUpdateOperation(AGENT_OP_Delete, false, NULL,
|
||||
&NUpdateArchive::k_ActionSet_Delete, indices, numItems, updateCallback100);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgentFolder::CreateFolder(const wchar_t *name, IProgress *progress)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
if (_proxyFolderItem->FindDirSubItemIndex(name) >= 0)
|
||||
return ERROR_ALREADY_EXISTS;
|
||||
if (_proxyArchive2)
|
||||
{
|
||||
if (_proxyArchive2->IsThere_SubDir(_proxyFolderItem, name))
|
||||
return ERROR_ALREADY_EXISTS;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_proxyArchive->FindDirSubItemIndex(_proxyFolderItem, name) >= 0)
|
||||
return ERROR_ALREADY_EXISTS;
|
||||
}
|
||||
RINOK(_agentSpec->SetFolder(this));
|
||||
CMyComPtr<IFolderArchiveUpdateCallback> updateCallback100;
|
||||
if (progress)
|
||||
@@ -190,11 +277,11 @@ STDMETHODIMP CAgentFolder::CreateFolder(const wchar_t *name, IProgress *progress
|
||||
CMyComPtr<IProgress> progressWrapper = progress;
|
||||
RINOK(progressWrapper.QueryInterface(IID_IFolderArchiveUpdateCallback, &updateCallback100));
|
||||
}
|
||||
return CommonUpdateOperation(AGENT_OP_CreateFolder, name, NULL, NULL, 0, updateCallback100);
|
||||
return CommonUpdateOperation(AGENT_OP_CreateFolder, false, name, NULL, NULL, 0, updateCallback100);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgentFolder::Rename(UINT32 index, const wchar_t *newName, IProgress *progress)
|
||||
STDMETHODIMP CAgentFolder::Rename(UInt32 index, const wchar_t *newName, IProgress *progress)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
CUIntVector indices;
|
||||
@@ -206,7 +293,7 @@ STDMETHODIMP CAgentFolder::Rename(UINT32 index, const wchar_t *newName, IProgres
|
||||
CMyComPtr<IProgress> progressWrapper = progress;
|
||||
RINOK(progressWrapper.QueryInterface(IID_IFolderArchiveUpdateCallback, &updateCallback100));
|
||||
}
|
||||
return CommonUpdateOperation(AGENT_OP_Rename, newName, NULL, &indices.Front(),
|
||||
return CommonUpdateOperation(AGENT_OP_Rename, false, newName, NULL, &indices.Front(),
|
||||
indices.Size(), updateCallback100);
|
||||
COM_TRY_END
|
||||
}
|
||||
@@ -216,7 +303,7 @@ STDMETHODIMP CAgentFolder::CreateFile(const wchar_t * /* name */, IProgress * /*
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgentFolder::SetProperty(UINT32 /* index */, PROPID /* propID */,
|
||||
STDMETHODIMP CAgentFolder::SetProperty(UInt32 /* index */, PROPID /* propID */,
|
||||
const PROPVARIANT * /* value */, IProgress * /* progress */)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
|
||||
15
CPP/7zip/UI/Agent/IFolderArchive.h
Executable file → Normal file
15
CPP/7zip/UI/Agent/IFolderArchive.h
Executable file → Normal file
@@ -3,6 +3,8 @@
|
||||
#ifndef __IFOLDER_ARCHIVE_H
|
||||
#define __IFOLDER_ARCHIVE_H
|
||||
|
||||
#include "../../../Common/MyString.h"
|
||||
|
||||
#include "../../Archive/IArchive.h"
|
||||
#include "../../UI/Common/LoadCodecs.h"
|
||||
#include "../../UI/FileManager/IFolder.h"
|
||||
@@ -15,12 +17,14 @@
|
||||
|
||||
#define INTERFACE_IArchiveFolder(x) \
|
||||
STDMETHOD(Extract)(const UInt32 *indices, UInt32 numItems, \
|
||||
Int32 includeAltStreams, \
|
||||
Int32 replaceAltStreamCharsMode, \
|
||||
NExtract::NPathMode::EEnum pathMode, \
|
||||
NExtract::NOverwriteMode::EEnum overwriteMode, \
|
||||
const wchar_t *path, Int32 testMode, \
|
||||
IFolderArchiveExtractCallback *extractCallback2) x; \
|
||||
|
||||
FOLDER_ARCHIVE_INTERFACE(IArchiveFolder, 0x05)
|
||||
FOLDER_ARCHIVE_INTERFACE(IArchiveFolder, 0x0D)
|
||||
{
|
||||
INTERFACE_IArchiveFolder(PURE)
|
||||
};
|
||||
@@ -58,14 +62,19 @@ FOLDER_ARCHIVE_INTERFACE_SUB(IFolderArchiveUpdateCallback, IProgress, 0x0B)
|
||||
STDMETHOD(SetFiles)(const wchar_t *folderPrefix, const wchar_t **names, UInt32 numNames) x; \
|
||||
STDMETHOD(DeleteItems)(ISequentialOutStream *outArchiveStream, \
|
||||
const UInt32 *indices, UInt32 numItems, IFolderArchiveUpdateCallback *updateCallback) x; \
|
||||
STDMETHOD(DoOperation)(CCodecs *codecs, int index, \
|
||||
STDMETHOD(DoOperation)( \
|
||||
FStringVector *requestedPaths, \
|
||||
FStringVector *processedPaths, \
|
||||
CCodecs *codecs, int index, \
|
||||
ISequentialOutStream *outArchiveStream, const Byte *stateActions, const wchar_t *sfxModule, \
|
||||
IFolderArchiveUpdateCallback *updateCallback) x; \
|
||||
STDMETHOD(DoOperation2)( \
|
||||
FStringVector *requestedPaths, \
|
||||
FStringVector *processedPaths, \
|
||||
ISequentialOutStream *outArchiveStream, const Byte *stateActions, const wchar_t *sfxModule, \
|
||||
IFolderArchiveUpdateCallback *updateCallback) x; \
|
||||
|
||||
FOLDER_ARCHIVE_INTERFACE(IOutFolderArchive, 0x0A)
|
||||
FOLDER_ARCHIVE_INTERFACE(IOutFolderArchive, 0x0F)
|
||||
{
|
||||
INTERFACE_IOutFolderArchive(PURE)
|
||||
};
|
||||
|
||||
15
CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp
Executable file → Normal file
15
CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp
Executable file → Normal file
@@ -2,8 +2,9 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Windows/Error.h"
|
||||
#include "Common/IntToString.h"
|
||||
#include "../../../Common/IntToString.h"
|
||||
|
||||
#include "../../../Windows/ErrorMsg.h"
|
||||
|
||||
#include "UpdateCallbackAgent.h"
|
||||
|
||||
@@ -62,11 +63,11 @@ HRESULT CUpdateCallbackAgent::OpenFileError(const wchar_t *name, DWORD systemErr
|
||||
{
|
||||
if (Callback)
|
||||
{
|
||||
RINOK(Callback->UpdateErrorMessage(
|
||||
UString(L"WARNING: ") +
|
||||
NError::MyFormatMessageW(systemError) +
|
||||
UString(L": ") +
|
||||
name));
|
||||
UString s = L"WARNING: ";
|
||||
s += NError::MyFormatMessage(systemError);
|
||||
s += L": ";
|
||||
s += name;
|
||||
RINOK(Callback->UpdateErrorMessage(s));
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
5
CPP/7zip/UI/Agent/UpdateCallbackAgent.h
Executable file → Normal file
5
CPP/7zip/UI/Agent/UpdateCallbackAgent.h
Executable file → Normal file
@@ -1,9 +1,10 @@
|
||||
// UpdateCallbackAgent.h
|
||||
|
||||
#ifndef __UPDATECALLBACKAGENT_H
|
||||
#define __UPDATECALLBACKAGENT_H
|
||||
#ifndef __UPDATE_CALLBACK_AGENT_H
|
||||
#define __UPDATE_CALLBACK_AGENT_H
|
||||
|
||||
#include "../Common/UpdateCallback.h"
|
||||
|
||||
#include "IFolderArchive.h"
|
||||
|
||||
class CUpdateCallbackAgent: public IUpdateCallbackUI
|
||||
|
||||
172
CPP/7zip/UI/Client7z/Client7z.cpp
Executable file → Normal file
172
CPP/7zip/UI/Client7z/Client7z.cpp
Executable file → Normal file
@@ -2,39 +2,46 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/IntToString.h"
|
||||
#include "Common/MyInitGuid.h"
|
||||
#include "Common/StringConvert.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "Windows/DLL.h"
|
||||
#include "Windows/FileDir.h"
|
||||
#include "Windows/FileFind.h"
|
||||
#include "Windows/FileName.h"
|
||||
#include "Windows/NtCheck.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "Windows/PropVariantConversions.h"
|
||||
#include "../../../Common/Defs.h"
|
||||
#include "../../../Common/MyInitGuid.h"
|
||||
|
||||
#include "../../../Common/IntToString.h"
|
||||
#include "../../../Common/StringConvert.h"
|
||||
|
||||
#include "../../../Windows/DLL.h"
|
||||
#include "../../../Windows/FileDir.h"
|
||||
#include "../../../Windows/FileFind.h"
|
||||
#include "../../../Windows/FileName.h"
|
||||
#include "../../../Windows/NtCheck.h"
|
||||
#include "../../../Windows/PropVariant.h"
|
||||
#include "../../../Windows/PropVariantConv.h"
|
||||
|
||||
#include "../../Common/FileStreams.h"
|
||||
|
||||
#include "../../Archive/IArchive.h"
|
||||
|
||||
#include "../../IPassword.h"
|
||||
#include "../../MyVersion.h"
|
||||
#include "../../../../C/7zVersion.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
HINSTANCE g_hInstance = 0;
|
||||
#endif
|
||||
|
||||
// Tou 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}
|
||||
DEFINE_GUID(CLSID_CFormat7z,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00);
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
using namespace NDir;
|
||||
|
||||
#define kDllName "7z.dll"
|
||||
|
||||
static const char *kCopyrightString = "\n" MY_7ZIP_VERSION
|
||||
static const char *kCopyrightString = "\n7-Zip " MY_VERSION
|
||||
" (" kDllName " client) "
|
||||
MY_COPYRIGHT " " MY_DATE "\n";
|
||||
|
||||
@@ -46,12 +53,6 @@ static const char *kHelpString =
|
||||
" Client7z.exe x archive.7z : eXtract files from archive.7z\n";
|
||||
|
||||
|
||||
typedef UINT32 (WINAPI * CreateObjectFunc)(
|
||||
const GUID *clsID,
|
||||
const GUID *interfaceID,
|
||||
void **outObject);
|
||||
|
||||
|
||||
static AString FStringToConsoleString(const FString &s)
|
||||
{
|
||||
return GetOemString(fs2us(s));
|
||||
@@ -177,7 +178,11 @@ static const char *kSkippingString = "Skipping ";
|
||||
static const char *kUnsupportedMethod = "Unsupported Method";
|
||||
static const char *kCRCFailed = "CRC Failed";
|
||||
static const char *kDataError = "Data Error";
|
||||
static const char *kUnknownError = "Unknown Error";
|
||||
static const char *kUnavailableData = "Unavailable data";
|
||||
static const char *kUnexpectedEnd = "Unexpected end of data";
|
||||
static const char *kDataAfterEnd = "There are some data after the end of the payload data";
|
||||
static const char *kIsNotArc = "Is not archive";
|
||||
static const char *kHeadersError = "Headers Error";
|
||||
|
||||
class CArchiveExtractCallback:
|
||||
public IArchiveExtractCallback,
|
||||
@@ -232,7 +237,7 @@ void CArchiveExtractCallback::Init(IInArchive *archiveHandler, const FString &di
|
||||
NumErrors = 0;
|
||||
_archiveHandler = archiveHandler;
|
||||
_directoryPath = directoryPath;
|
||||
NFile::NName::NormalizeDirPathPrefix(_directoryPath);
|
||||
NName::NormalizeDirPathPrefix(_directoryPath);
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 /* size */)
|
||||
@@ -314,10 +319,8 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index,
|
||||
// Get Size
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(_archiveHandler->GetProperty(index, kpidSize, &prop));
|
||||
bool newFileSizeDefined = (prop.vt != VT_EMPTY);
|
||||
UInt64 newFileSize;
|
||||
if (newFileSizeDefined)
|
||||
newFileSize = ConvertPropVariantToUInt64(prop);
|
||||
/* bool newFileSizeDefined = */ ConvertPropVariantToUInt64(prop, newFileSize);
|
||||
}
|
||||
|
||||
|
||||
@@ -325,7 +328,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index,
|
||||
// Create folders for file
|
||||
int slashPos = _filePath.ReverseFind(WCHAR_PATH_SEPARATOR);
|
||||
if (slashPos >= 0)
|
||||
NFile::NDirectory::CreateComplexDirectory(_directoryPath + us2fs(_filePath.Left(slashPos)));
|
||||
CreateComplexDir(_directoryPath + us2fs(_filePath.Left(slashPos)));
|
||||
}
|
||||
|
||||
FString fullProcessedPath = _directoryPath + us2fs(_filePath);
|
||||
@@ -333,14 +336,14 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index,
|
||||
|
||||
if (_processedFileInfo.isDir)
|
||||
{
|
||||
NFile::NDirectory::CreateComplexDirectory(fullProcessedPath);
|
||||
CreateComplexDir(fullProcessedPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
NFile::NFind::CFileInfo fi;
|
||||
NFind::CFileInfo fi;
|
||||
if (fi.Find(fullProcessedPath))
|
||||
{
|
||||
if (!NFile::NDirectory::DeleteFileAlways(fullProcessedPath))
|
||||
if (!DeleteFileAlways(fullProcessedPath))
|
||||
{
|
||||
PrintError("Can not delete output file", fullProcessedPath);
|
||||
return E_ABORT;
|
||||
@@ -379,27 +382,53 @@ STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)
|
||||
|
||||
STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
|
||||
{
|
||||
switch(operationResult)
|
||||
switch (operationResult)
|
||||
{
|
||||
case NArchive::NExtract::NOperationResult::kOK:
|
||||
break;
|
||||
default:
|
||||
{
|
||||
NumErrors++;
|
||||
PrintString(" ");
|
||||
switch(operationResult)
|
||||
PrintString(" : ");
|
||||
const char *s = NULL;
|
||||
switch (operationResult)
|
||||
{
|
||||
case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
|
||||
PrintString(kUnsupportedMethod);
|
||||
case NArchive::NExtract::NOperationResult::kUnsupportedMethod:
|
||||
s = kUnsupportedMethod;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kCRCError:
|
||||
PrintString(kCRCFailed);
|
||||
s = kCRCFailed;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kDataError:
|
||||
PrintString(kDataError);
|
||||
s = kDataError;
|
||||
break;
|
||||
default:
|
||||
PrintString(kUnknownError);
|
||||
case NArchive::NExtract::NOperationResult::kUnavailable:
|
||||
s = kUnavailableData;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kUnexpectedEnd:
|
||||
s = kUnexpectedEnd;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kDataAfterEnd:
|
||||
s = kDataAfterEnd;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kIsNotArc:
|
||||
s = kIsNotArc;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kHeadersError:
|
||||
s = kHeadersError;
|
||||
break;
|
||||
}
|
||||
if (s)
|
||||
{
|
||||
PrintString("Error : ");
|
||||
PrintString(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
char temp[16];
|
||||
ConvertUInt32ToString(operationResult, temp);
|
||||
PrintString("Error #");
|
||||
PrintString(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -412,7 +441,7 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
|
||||
}
|
||||
_outFileStream.Release();
|
||||
if (_extractMode && _processedFileInfo.AttribDefined)
|
||||
NFile::NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attrib);
|
||||
SetFileAttrib(_diskFilePath, _processedFileInfo.Attrib);
|
||||
PrintNewLine();
|
||||
return S_OK;
|
||||
}
|
||||
@@ -528,7 +557,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 /* index */,
|
||||
if (newProperties != NULL)
|
||||
*newProperties = BoolToInt(true);
|
||||
if (indexInArchive != NULL)
|
||||
*indexInArchive = (UInt32)-1;
|
||||
*indexInArchive = (UInt32)(Int32)-1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -632,7 +661,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOu
|
||||
wchar_t temp[16];
|
||||
ConvertUInt32ToString(index + 1, temp);
|
||||
UString res = temp;
|
||||
while (res.Length() < 2)
|
||||
while (res.Len() < 2)
|
||||
res = UString(L'0') + res;
|
||||
UString fileName = VolName;
|
||||
fileName += L'.';
|
||||
@@ -685,8 +714,8 @@ int MY_CDECL main(int numArgs, const char *args[])
|
||||
PrintError("Can not load 7-zip library");
|
||||
return 1;
|
||||
}
|
||||
CreateObjectFunc createObjectFunc = (CreateObjectFunc)lib.GetProc("CreateObject");
|
||||
if (createObjectFunc == 0)
|
||||
Func_CreateObject createObjectFunc = (Func_CreateObject)lib.GetProc("CreateObject");
|
||||
if (!createObjectFunc)
|
||||
{
|
||||
PrintError("Can not get CreateObject");
|
||||
return 1;
|
||||
@@ -695,15 +724,15 @@ int MY_CDECL main(int numArgs, const char *args[])
|
||||
char c;
|
||||
{
|
||||
AString command = args[1];
|
||||
if (command.Length() != 1)
|
||||
if (command.Len() != 1)
|
||||
{
|
||||
PrintError("incorrect command");
|
||||
return 1;
|
||||
}
|
||||
c = (char)MyCharUpper(command[0]);
|
||||
c = (char)MyCharLower_Ascii(command[0]);
|
||||
}
|
||||
FString archiveName = CmdStringToFString(args[2]);
|
||||
if (c == 'A')
|
||||
if (c == 'a')
|
||||
{
|
||||
// create archive command
|
||||
if (numArgs < 4)
|
||||
@@ -712,27 +741,29 @@ int MY_CDECL main(int numArgs, const char *args[])
|
||||
return 1;
|
||||
}
|
||||
CObjectVector<CDirItem> dirItems;
|
||||
int i;
|
||||
for (i = 3; i < numArgs; i++)
|
||||
{
|
||||
CDirItem di;
|
||||
FString name = CmdStringToFString(args[i]);
|
||||
|
||||
NFile::NFind::CFileInfo fi;
|
||||
if (!fi.Find(name))
|
||||
int i;
|
||||
for (i = 3; i < numArgs; i++)
|
||||
{
|
||||
PrintError("Can't find file", name);
|
||||
return 1;
|
||||
CDirItem di;
|
||||
FString name = CmdStringToFString(args[i]);
|
||||
|
||||
NFind::CFileInfo fi;
|
||||
if (!fi.Find(name))
|
||||
{
|
||||
PrintError("Can't find file", name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
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.FullPath = name;
|
||||
dirItems.Add(di);
|
||||
}
|
||||
|
||||
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.FullPath = name;
|
||||
dirItems.Add(di);
|
||||
}
|
||||
COutFileStream *outFileStreamSpec = new COutFileStream;
|
||||
CMyComPtr<IOutStream> outFileStream = outFileStreamSpec;
|
||||
@@ -762,7 +793,7 @@ int MY_CDECL main(int numArgs, const char *args[])
|
||||
L"s",
|
||||
L"x"
|
||||
};
|
||||
const int kNumProps = sizeof(names) / sizeof(names[0]);
|
||||
const unsigned kNumProps = ARRAY_SIZE(names);
|
||||
NCOM::CPropVariant values[kNumProps] =
|
||||
{
|
||||
false, // solid mode OFF
|
||||
@@ -786,7 +817,7 @@ int MY_CDECL main(int numArgs, const char *args[])
|
||||
PrintError("Update Error");
|
||||
return 1;
|
||||
}
|
||||
for (i = 0; i < updateCallbackSpec->FailedFiles.Size(); i++)
|
||||
FOR_VECTOR (i, updateCallbackSpec->FailedFiles)
|
||||
{
|
||||
PrintNewLine();
|
||||
PrintError("Error for file", updateCallbackSpec->FailedFiles[i]);
|
||||
@@ -803,9 +834,9 @@ int MY_CDECL main(int numArgs, const char *args[])
|
||||
}
|
||||
|
||||
bool listCommand;
|
||||
if (c == 'L')
|
||||
if (c == 'l')
|
||||
listCommand = true;
|
||||
else if (c == 'X')
|
||||
else if (c == 'x')
|
||||
listCommand = false;
|
||||
else
|
||||
{
|
||||
@@ -854,7 +885,8 @@ int MY_CDECL main(int numArgs, const char *args[])
|
||||
// Get uncompressed size of file
|
||||
NCOM::CPropVariant prop;
|
||||
archive->GetProperty(i, kpidSize, &prop);
|
||||
UString s = ConvertPropVariantToString(prop);
|
||||
char s[32];
|
||||
ConvertPropVariantToShortString(prop, s);
|
||||
PrintString(s);
|
||||
PrintString(" ");
|
||||
}
|
||||
@@ -862,8 +894,10 @@ int MY_CDECL main(int numArgs, const char *args[])
|
||||
// Get name of file
|
||||
NCOM::CPropVariant prop;
|
||||
archive->GetProperty(i, kpidPath, &prop);
|
||||
UString s = ConvertPropVariantToString(prop);
|
||||
PrintString(s);
|
||||
if (prop.vt == VT_BSTR)
|
||||
PrintString(prop.bstrVal);
|
||||
else if (prop.vt != VT_EMPTY)
|
||||
PrintString("ERROR!");
|
||||
}
|
||||
PrintNewLine();
|
||||
}
|
||||
|
||||
21
CPP/7zip/UI/Client7z/Client7z.dsp
Executable file → Normal file
21
CPP/7zip/UI/Client7z/Client7z.dsp
Executable file → Normal file
@@ -39,9 +39,10 @@ RSC=rc.exe
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
|
||||
# ADD CPP /nologo /MD /W4 /WX /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
# ADD RSC /l 0x419 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -49,7 +50,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"Release/7zcl.exe"
|
||||
|
||||
!ELSEIF "$(CFG)" == "Client7z - Win32 Debug"
|
||||
|
||||
@@ -65,7 +66,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /W4 /WX /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
# ADD RSC /l 0x419 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -73,7 +74,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/7zcl.exe" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
@@ -86,6 +87,10 @@ LINK32=link.exe
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.cpp
|
||||
# ADD CPP /Yc"stdafx.h"
|
||||
# End Source File
|
||||
@@ -147,11 +152,11 @@ SOURCE=..\..\..\Windows\PropVariant.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\PropVariantConversions.cpp
|
||||
SOURCE=..\..\..\Windows\PropVariantConv.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\PropVariantConversions.h
|
||||
SOURCE=..\..\..\Windows\PropVariantConv.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Common"
|
||||
@@ -222,5 +227,9 @@ SOURCE=..\..\Common\FileStreams.h
|
||||
|
||||
SOURCE=.\Client7z.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Sort.h
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
|
||||
0
CPP/7zip/UI/Client7z/Client7z.dsw
Executable file → Normal file
0
CPP/7zip/UI/Client7z/Client7z.dsw
Executable file → Normal file
0
CPP/7zip/UI/Client7z/StdAfx.cpp
Executable file → Normal file
0
CPP/7zip/UI/Client7z/StdAfx.cpp
Executable file → Normal file
3
CPP/7zip/UI/Client7z/StdAfx.h
Executable file → Normal file
3
CPP/7zip/UI/Client7z/StdAfx.h
Executable file → Normal file
@@ -3,7 +3,6 @@
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include "../../../Common/Common.h"
|
||||
|
||||
#endif
|
||||
|
||||
25
CPP/7zip/UI/Client7z/makefile
Executable file → Normal file
25
CPP/7zip/UI/Client7z/makefile
Executable file → Normal file
@@ -1,8 +1,7 @@
|
||||
PROG = 7z.exe
|
||||
PROG = 7zcl.exe
|
||||
MY_CONSOLE = 1
|
||||
CFLAGS = $(CFLAGS) -I ../../../
|
||||
|
||||
CONSOLE_OBJS = \
|
||||
CURRENT_OBJS = \
|
||||
$O\Client7z.obj \
|
||||
|
||||
COMMON_OBJS = \
|
||||
@@ -21,25 +20,9 @@ WIN_OBJS = \
|
||||
$O\FileIO.obj \
|
||||
$O\FileName.obj \
|
||||
$O\PropVariant.obj \
|
||||
$O\PropVariantConversions.obj \
|
||||
$O\PropVariantConv.obj \
|
||||
|
||||
7ZIP_COMMON_OBJS = \
|
||||
$O\FileStreams.obj \
|
||||
|
||||
OBJS = \
|
||||
$O\StdAfx.obj \
|
||||
$(CONSOLE_OBJS) \
|
||||
$(COMMON_OBJS) \
|
||||
$(WIN_OBJS) \
|
||||
$(7ZIP_COMMON_OBJS) \
|
||||
|
||||
!include "../../../Build.mak"
|
||||
|
||||
$(CONSOLE_OBJS): $(*B).cpp
|
||||
$(COMPL)
|
||||
$(COMMON_OBJS): ../../../Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(WIN_OBJS): ../../../Windows/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
!include "../../7zip.mak"
|
||||
|
||||
3
CPP/7zip/UI/Client7z/resource.rc
Normal file
3
CPP/7zip/UI/Client7z/resource.rc
Normal file
@@ -0,0 +1,3 @@
|
||||
#include "../../MyVersionInfo.rc"
|
||||
|
||||
MY_VERSION_INFO_APP("7-Zip client", "7zcl")
|
||||
1061
CPP/7zip/UI/Common/ArchiveCommandLine.cpp
Executable file → Normal file
1061
CPP/7zip/UI/Common/ArchiveCommandLine.cpp
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
73
CPP/7zip/UI/Common/ArchiveCommandLine.h
Executable file → Normal file
73
CPP/7zip/UI/Common/ArchiveCommandLine.h
Executable file → Normal file
@@ -3,15 +3,16 @@
|
||||
#ifndef __ARCHIVE_COMMAND_LINE_H
|
||||
#define __ARCHIVE_COMMAND_LINE_H
|
||||
|
||||
#include "Common/CommandLineParser.h"
|
||||
#include "Common/Wildcard.h"
|
||||
#include "../../../Common/CommandLineParser.h"
|
||||
#include "../../../Common/Wildcard.h"
|
||||
|
||||
#include "Extract.h"
|
||||
#include "HashCalc.h"
|
||||
#include "Update.h"
|
||||
|
||||
struct CArchiveCommandLineException: public AString
|
||||
struct CArcCmdLineException: public UString
|
||||
{
|
||||
CArchiveCommandLineException(const char *errorMessage): AString(errorMessage) {}
|
||||
CArcCmdLineException(const char *a, const wchar_t *u = NULL);
|
||||
};
|
||||
|
||||
namespace NCommandType { enum EEnum
|
||||
@@ -21,35 +22,33 @@ namespace NCommandType { enum EEnum
|
||||
kDelete,
|
||||
kTest,
|
||||
kExtract,
|
||||
kFullExtract,
|
||||
kExtractFull,
|
||||
kList,
|
||||
kBenchmark,
|
||||
kInfo
|
||||
kInfo,
|
||||
kHash,
|
||||
kRename
|
||||
};}
|
||||
|
||||
namespace NRecursedType { enum EEnum
|
||||
{
|
||||
kRecursed,
|
||||
kWildCardOnlyRecursed,
|
||||
kNonRecursed
|
||||
};}
|
||||
|
||||
struct CArchiveCommand
|
||||
struct CArcCommand
|
||||
{
|
||||
NCommandType::EEnum CommandType;
|
||||
|
||||
bool IsFromExtractGroup() const;
|
||||
bool IsFromUpdateGroup() const;
|
||||
bool IsTestMode() const { return CommandType == NCommandType::kTest; }
|
||||
bool IsTestCommand() const { return CommandType == NCommandType::kTest; }
|
||||
NExtract::NPathMode::EEnum GetPathMode() const;
|
||||
};
|
||||
|
||||
struct CArchiveCommandLineOptions
|
||||
struct CArcCmdLineOptions
|
||||
{
|
||||
bool HelpMode;
|
||||
|
||||
#ifdef _WIN32
|
||||
bool LargePages;
|
||||
#endif
|
||||
bool CaseSensitiveChange;
|
||||
bool CaseSensitive;
|
||||
|
||||
bool IsInTerminal;
|
||||
bool IsStdOutTerminal;
|
||||
@@ -60,10 +59,9 @@ struct CArchiveCommandLineOptions
|
||||
|
||||
bool YesToAll;
|
||||
bool ShowDialog;
|
||||
// NWildcard::CCensor ArchiveWildcardCensor;
|
||||
NWildcard::CCensor WildcardCensor;
|
||||
NWildcard::CCensor Censor;
|
||||
|
||||
CArchiveCommand Command;
|
||||
CArcCommand Command;
|
||||
UString ArchiveName;
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
@@ -72,35 +70,52 @@ struct CArchiveCommandLineOptions
|
||||
#endif
|
||||
|
||||
bool TechMode;
|
||||
// Extract
|
||||
bool CalcCrc;
|
||||
|
||||
UStringVector HashMethods;
|
||||
|
||||
bool AppendName;
|
||||
FString OutputDir;
|
||||
NExtract::NOverwriteMode::EEnum OverwriteMode;
|
||||
UStringVector ArchivePathsSorted;
|
||||
UStringVector ArchivePathsFullSorted;
|
||||
CObjectVector<CProperty> Properties;
|
||||
|
||||
CExtractOptionsBase ExtractOptions;
|
||||
|
||||
CBoolPair NtSecurity;
|
||||
CBoolPair AltStreams;
|
||||
CBoolPair HardLinks;
|
||||
CBoolPair SymLinks;
|
||||
|
||||
CUpdateOptions UpdateOptions;
|
||||
CHashOptions HashOptions;
|
||||
UString ArcType;
|
||||
UStringVector ExcludedArcTypes;
|
||||
bool EnablePercents;
|
||||
|
||||
// Benchmark
|
||||
UInt32 NumIterations;
|
||||
|
||||
CArchiveCommandLineOptions(): StdInMode(false), StdOutMode(false) {};
|
||||
CArcCmdLineOptions():
|
||||
StdInMode(false),
|
||||
StdOutMode(false),
|
||||
CaseSensitiveChange(false),
|
||||
CaseSensitive(false)
|
||||
{};
|
||||
};
|
||||
|
||||
class CArchiveCommandLineParser
|
||||
class CArcCmdLineParser
|
||||
{
|
||||
NCommandLineParser::CParser parser;
|
||||
public:
|
||||
CArchiveCommandLineParser();
|
||||
void Parse1(const UStringVector &commandStrings, CArchiveCommandLineOptions &options);
|
||||
void Parse2(CArchiveCommandLineOptions &options);
|
||||
CArcCmdLineParser();
|
||||
void Parse1(const UStringVector &commandStrings, CArcCmdLineOptions &options);
|
||||
void Parse2(CArcCmdLineOptions &options);
|
||||
};
|
||||
|
||||
void EnumerateDirItemsAndSort(NWildcard::CCensor &wildcardCensor,
|
||||
void EnumerateDirItemsAndSort(
|
||||
bool storeAltStreams,
|
||||
NWildcard::CCensor &censor,
|
||||
NWildcard::ECensorPathMode pathMode,
|
||||
const UString &addPathPrefix,
|
||||
UStringVector &sortedPaths,
|
||||
UStringVector &sortedFullPaths);
|
||||
|
||||
|
||||
987
CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
Executable file → Normal file
987
CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
194
CPP/7zip/UI/Common/ArchiveExtractCallback.h
Executable file → Normal file
194
CPP/7zip/UI/Common/ArchiveExtractCallback.h
Executable file → Normal file
@@ -3,8 +3,8 @@
|
||||
#ifndef __ARCHIVE_EXTRACT_CALLBACK_H
|
||||
#define __ARCHIVE_EXTRACT_CALLBACK_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "Common/Wildcard.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../../Common/Wildcard.h"
|
||||
|
||||
#include "../../IPassword.h"
|
||||
|
||||
@@ -13,12 +13,117 @@
|
||||
|
||||
#include "../../Archive/IArchive.h"
|
||||
|
||||
#include "../../Archive/Common/OutStreamWithCRC.h"
|
||||
|
||||
#include "ExtractMode.h"
|
||||
#include "IFileExtractCallback.h"
|
||||
#include "OpenArchive.h"
|
||||
|
||||
#include "HashCalc.h"
|
||||
|
||||
#ifndef _SFX
|
||||
|
||||
class COutStreamWithHash:
|
||||
public ISequentialOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CMyComPtr<ISequentialOutStream> _stream;
|
||||
UInt64 _size;
|
||||
bool _calculate;
|
||||
public:
|
||||
IHashCalc *_hash;
|
||||
|
||||
MY_UNKNOWN_IMP
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
void SetStream(ISequentialOutStream *stream) { _stream = stream; }
|
||||
void ReleaseStream() { _stream.Release(); }
|
||||
void Init(bool calculate = true)
|
||||
{
|
||||
InitCRC();
|
||||
_size = 0;
|
||||
_calculate = calculate;
|
||||
}
|
||||
void EnableCalc(bool calculate) { _calculate = calculate; }
|
||||
void InitCRC() { _hash->InitForNewFile(); }
|
||||
UInt64 GetSize() const { return _size; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
struct CExtractNtOptions
|
||||
{
|
||||
CBoolPair NtSecurity;
|
||||
CBoolPair SymLinks;
|
||||
CBoolPair HardLinks;
|
||||
CBoolPair AltStreams;
|
||||
bool ReplaceColonForAltStream;
|
||||
bool WriteToAltStreamIfColon;
|
||||
|
||||
CExtractNtOptions():
|
||||
ReplaceColonForAltStream(false),
|
||||
WriteToAltStreamIfColon(false)
|
||||
{
|
||||
SymLinks.Val = true;
|
||||
HardLinks.Val = true;
|
||||
AltStreams.Val = true;
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef _SFX
|
||||
|
||||
class CGetProp:
|
||||
public IGetProp,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
const CArc *Arc;
|
||||
UInt32 IndexInArc;
|
||||
UString Name; // relative path
|
||||
|
||||
MY_UNKNOWN_IMP1(IGetProp)
|
||||
INTERFACE_IGetProp(;)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _SFX
|
||||
#ifndef UNDER_CE
|
||||
|
||||
#define SUPPORT_LINKS
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef SUPPORT_LINKS
|
||||
|
||||
struct CHardLinkNode
|
||||
{
|
||||
UInt64 StreamId;
|
||||
UInt64 INode;
|
||||
|
||||
int Compare(const CHardLinkNode &a) const;
|
||||
};
|
||||
|
||||
class CHardLinks
|
||||
{
|
||||
public:
|
||||
CRecordVector<CHardLinkNode> IDs;
|
||||
CObjectVector<FString> Links;
|
||||
|
||||
void Clear()
|
||||
{
|
||||
IDs.Clear();
|
||||
Links.Clear();
|
||||
}
|
||||
|
||||
void PrepareLinks()
|
||||
{
|
||||
while (Links.Size() < IDs.Size())
|
||||
Links.AddNew();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
class CArchiveExtractCallback:
|
||||
public IArchiveExtractCallback,
|
||||
// public IArchiveVolumeExtractCallback,
|
||||
@@ -27,18 +132,30 @@ class CArchiveExtractCallback:
|
||||
public CMyUnknownImp
|
||||
{
|
||||
const CArc *_arc;
|
||||
CExtractNtOptions _ntOptions;
|
||||
|
||||
const NWildcard::CCensorNode *_wildcardCensor;
|
||||
CMyComPtr<IFolderArchiveExtractCallback> _extractCallback2;
|
||||
CMyComPtr<ICompressProgressInfo> _compressProgress;
|
||||
CMyComPtr<ICryptoGetTextPassword> _cryptoGetTextPassword;
|
||||
FString _directoryPath;
|
||||
FString _directoryPathFull;
|
||||
NExtract::NPathMode::EEnum _pathMode;
|
||||
NExtract::NOverwriteMode::EEnum _overwriteMode;
|
||||
|
||||
#ifndef _SFX
|
||||
|
||||
CMyComPtr<IFolderExtractToStreamCallback> ExtractToStreamCallback;
|
||||
CGetProp *GetProp_Spec;
|
||||
CMyComPtr<IGetProp> GetProp;
|
||||
|
||||
#endif
|
||||
|
||||
FString _diskFilePath;
|
||||
UString _filePath;
|
||||
UInt64 _position;
|
||||
bool _isSplit;
|
||||
bool _isAltStream;
|
||||
|
||||
bool _extractMode;
|
||||
|
||||
@@ -69,25 +186,39 @@ class CArchiveExtractCallback:
|
||||
COutFileStream *_outFileStreamSpec;
|
||||
CMyComPtr<ISequentialOutStream> _outFileStream;
|
||||
|
||||
COutStreamWithCRC *_crcStreamSpec;
|
||||
CMyComPtr<ISequentialOutStream> _crcStream;
|
||||
#ifndef _SFX
|
||||
|
||||
COutStreamWithHash *_hashStreamSpec;
|
||||
CMyComPtr<ISequentialOutStream> _hashStream;
|
||||
bool _hashStreamWasUsed;
|
||||
|
||||
#endif
|
||||
|
||||
UStringVector _removePathParts;
|
||||
bool _use_baseParentFolder_mode;
|
||||
UInt32 _baseParentFolder;
|
||||
|
||||
bool _stdOutMode;
|
||||
bool _testMode;
|
||||
bool _crcMode;
|
||||
bool _multiArchives;
|
||||
|
||||
CMyComPtr<ICompressProgressInfo> _localProgress;
|
||||
UInt64 _packTotal;
|
||||
UInt64 _unpTotal;
|
||||
|
||||
FStringVector _extractedFolderPaths;
|
||||
CRecordVector<UInt32> _extractedFolderIndices;
|
||||
|
||||
#if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX)
|
||||
bool _saclEnabled;
|
||||
#endif
|
||||
|
||||
void CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath);
|
||||
HRESULT GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined);
|
||||
HRESULT GetUnpackSize();
|
||||
|
||||
HRESULT SendMessageError(const char *message, const FString &path);
|
||||
HRESULT SendMessageError2(const char *message, const FString &path1, const FString &path2);
|
||||
|
||||
public:
|
||||
|
||||
@@ -95,8 +226,9 @@ public:
|
||||
|
||||
UInt64 NumFolders;
|
||||
UInt64 NumFiles;
|
||||
UInt64 NumAltStreams;
|
||||
UInt64 UnpackSize;
|
||||
UInt32 CrcSum;
|
||||
UInt64 AltStreams_UnpackSize;
|
||||
|
||||
MY_UNKNOWN_IMP2(ICryptoGetTextPassword, ICompressProgressInfo)
|
||||
// COM_INTERFACE_ENTRY(IArchiveVolumeExtractCallback)
|
||||
@@ -110,15 +242,7 @@ public:
|
||||
|
||||
STDMETHOD(CryptoGetTextPassword)(BSTR *password);
|
||||
|
||||
CArchiveExtractCallback():
|
||||
WriteCTime(true),
|
||||
WriteATime(true),
|
||||
WriteMTime(true),
|
||||
_multiArchives(false)
|
||||
{
|
||||
LocalProgressSpec = new CLocalProgress();
|
||||
_localProgress = LocalProgressSpec;
|
||||
}
|
||||
CArchiveExtractCallback();
|
||||
|
||||
void InitForMulti(bool multiArchives,
|
||||
NExtract::NPathMode::EEnum pathMode,
|
||||
@@ -127,19 +251,49 @@ public:
|
||||
_multiArchives = multiArchives;
|
||||
_pathMode = pathMode;
|
||||
_overwriteMode = overwriteMode;
|
||||
NumFolders = NumFiles = UnpackSize = 0;
|
||||
CrcSum = 0;
|
||||
NumFolders = NumFiles = NumAltStreams = UnpackSize = AltStreams_UnpackSize = 0;
|
||||
}
|
||||
|
||||
#ifndef _SFX
|
||||
|
||||
void SetHashMethods(IHashCalc *hash)
|
||||
{
|
||||
if (!hash)
|
||||
return;
|
||||
_hashStreamSpec = new COutStreamWithHash;
|
||||
_hashStream = _hashStreamSpec;
|
||||
_hashStreamSpec->_hash = hash;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void Init(
|
||||
const CExtractNtOptions &ntOptions,
|
||||
const NWildcard::CCensorNode *wildcardCensor,
|
||||
const CArc *arc,
|
||||
IFolderArchiveExtractCallback *extractCallback2,
|
||||
bool stdOutMode, bool testMode, bool crcMode,
|
||||
bool stdOutMode, bool testMode,
|
||||
const FString &directoryPath,
|
||||
const UStringVector &removePathParts,
|
||||
UInt64 packSize);
|
||||
|
||||
#ifdef SUPPORT_LINKS
|
||||
private:
|
||||
CHardLinks _hardLinks;
|
||||
public:
|
||||
// call PrepareHardLinks() after Init()
|
||||
HRESULT PrepareHardLinks(const CRecordVector<UInt32> *realIndices); // NULL means all items
|
||||
#endif
|
||||
|
||||
// call it after Init()
|
||||
|
||||
void SetBaseParentFolderIndex(UInt32 indexInArc)
|
||||
{
|
||||
_use_baseParentFolder_mode = true;
|
||||
_baseParentFolder = indexInArc;
|
||||
}
|
||||
|
||||
HRESULT SetDirsTimes();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
24
CPP/7zip/UI/Common/ArchiveName.cpp
Executable file → Normal file
24
CPP/7zip/UI/Common/ArchiveName.cpp
Executable file → Normal file
@@ -2,22 +2,38 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Windows/FileDir.h"
|
||||
#include "Windows/FileFind.h"
|
||||
#include "../../../Windows/FileDir.h"
|
||||
|
||||
#include "ExtractingFilePath.h"
|
||||
#include "ArchiveName.h"
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
UString CreateArchiveName(const NFile::NFind::CFileInfo fileInfo, bool keepName)
|
||||
{
|
||||
FString resultName = fileInfo.Name;
|
||||
if (!fileInfo.IsDir() && !keepName)
|
||||
{
|
||||
int dotPos = resultName.ReverseFind(FTEXT('.'));
|
||||
if (dotPos > 0)
|
||||
{
|
||||
FString archiveName2 = resultName.Left(dotPos);
|
||||
if (archiveName2.ReverseFind(FTEXT('.')) < 0)
|
||||
resultName = archiveName2;
|
||||
}
|
||||
}
|
||||
return GetCorrectFsPath(fs2us(resultName));
|
||||
}
|
||||
|
||||
static FString CreateArchiveName2(const FString &srcName, bool fromPrev, bool keepName)
|
||||
{
|
||||
FString resultName = FTEXT("Archive");
|
||||
if (fromPrev)
|
||||
{
|
||||
FString dirPrefix;
|
||||
if (NFile::NDirectory::GetOnlyDirPrefix(srcName, dirPrefix))
|
||||
if (NFile::NDir::GetOnlyDirPrefix(srcName, dirPrefix))
|
||||
{
|
||||
if (dirPrefix.Length() > 0)
|
||||
if (dirPrefix.Len() > 0)
|
||||
if (dirPrefix.Back() == FCHAR_PATH_SEPARATOR)
|
||||
{
|
||||
dirPrefix.DeleteBack();
|
||||
|
||||
9
CPP/7zip/UI/Common/ArchiveName.h
Executable file → Normal file
9
CPP/7zip/UI/Common/ArchiveName.h
Executable file → Normal file
@@ -1,10 +1,13 @@
|
||||
// ArchiveName.h
|
||||
|
||||
#ifndef __ARCHIVENAME_H
|
||||
#define __ARCHIVENAME_H
|
||||
#ifndef __ARCHIVE_NAME_H
|
||||
#define __ARCHIVE_NAME_H
|
||||
|
||||
#include "Common/MyString.h"
|
||||
#include "../../../Common/MyString.h"
|
||||
|
||||
#include "../../../Windows/FileFind.h"
|
||||
|
||||
UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName);
|
||||
UString CreateArchiveName(const NWindows::NFile::NFind::CFileInfo fileInfo, bool keepName);
|
||||
|
||||
#endif
|
||||
|
||||
38
CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
Executable file → Normal file
38
CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
Executable file → Normal file
@@ -2,9 +2,10 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/ComTry.h"
|
||||
#include "../../../Common/ComTry.h"
|
||||
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "../../../Windows/FileName.h"
|
||||
#include "../../../Windows/PropVariant.h"
|
||||
|
||||
#include "../../Common/FileStreams.h"
|
||||
|
||||
@@ -59,41 +60,32 @@ STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
int COpenCallbackImp::FindName(const UString &name)
|
||||
{
|
||||
for (int i = 0; i < FileNames.Size(); i++)
|
||||
if (name.CompareNoCase(FileNames[i]) == 0)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct CInFileStreamVol: public CInFileStream
|
||||
{
|
||||
UString Name;
|
||||
int FileNameIndex;
|
||||
COpenCallbackImp *OpenCallbackImp;
|
||||
CMyComPtr<IArchiveOpenCallback> OpenCallbackRef;
|
||||
|
||||
~CInFileStreamVol()
|
||||
{
|
||||
if (OpenCallbackRef)
|
||||
{
|
||||
int index = OpenCallbackImp->FindName(Name);
|
||||
if (index >= 0)
|
||||
OpenCallbackImp->FileNames.Delete(index);
|
||||
}
|
||||
OpenCallbackImp->FileNames_WasUsed[FileNameIndex] = false;
|
||||
}
|
||||
};
|
||||
|
||||
STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStream)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
*inStream = NULL;
|
||||
if (_subArchiveMode)
|
||||
return S_FALSE;
|
||||
if (Callback)
|
||||
{
|
||||
RINOK(Callback->Open_CheckBreak());
|
||||
}
|
||||
*inStream = NULL;
|
||||
FString fullPath = _folderPrefix + us2fs(name);
|
||||
FString fullPath;
|
||||
if (!NFile::NName::GetFullPath(_folderPrefix, us2fs(name), fullPath))
|
||||
return S_FALSE;
|
||||
if (!_fileInfo.Find(fullPath))
|
||||
return S_FALSE;
|
||||
if (_fileInfo.IsDir())
|
||||
@@ -102,12 +94,14 @@ STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStre
|
||||
CMyComPtr<IInStream> inStreamTemp = inFile;
|
||||
if (!inFile->Open(fullPath))
|
||||
return ::GetLastError();
|
||||
*inStream = inStreamTemp.Detach();
|
||||
inFile->Name = name;
|
||||
|
||||
FileSizes.Add(_fileInfo.Size);
|
||||
FileNames.Add(name);
|
||||
inFile->FileNameIndex = FileNames_WasUsed.Add(true);
|
||||
inFile->OpenCallbackImp = this;
|
||||
inFile->OpenCallbackRef = this;
|
||||
FileNames.Add(name);
|
||||
TotalSize += _fileInfo.Size;
|
||||
// TotalSize += _fileInfo.Size;
|
||||
*inStream = inStreamTemp.Detach();
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
28
CPP/7zip/UI/Common/ArchiveOpenCallback.h
Executable file → Normal file
28
CPP/7zip/UI/Common/ArchiveOpenCallback.h
Executable file → Normal file
@@ -3,10 +3,9 @@
|
||||
#ifndef __ARCHIVE_OPEN_CALLBACK_H
|
||||
#define __ARCHIVE_OPEN_CALLBACK_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "Common/MyString.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
#include "Windows/FileFind.h"
|
||||
#include "../../../Windows/FileFind.h"
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
#include "../../IPassword.h"
|
||||
@@ -21,7 +20,7 @@
|
||||
|
||||
#define INTERFACE_IOpenCallbackUI_Crypto(x) \
|
||||
virtual HRESULT Open_CryptoGetTextPassword(BSTR *password) x; \
|
||||
virtual HRESULT Open_GetPasswordIfAny(UString &password) x; \
|
||||
virtual HRESULT Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password) x; \
|
||||
virtual bool Open_WasPasswordAsked() x; \
|
||||
virtual void Open_ClearPasswordWasAskedFlag() x; \
|
||||
|
||||
@@ -72,8 +71,8 @@ public:
|
||||
{
|
||||
_subArchiveMode = true;
|
||||
_subArchiveName = name;
|
||||
TotalSize = 0;
|
||||
return S_OK;
|
||||
// TotalSize = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -81,23 +80,32 @@ private:
|
||||
NWindows::NFile::NFind::CFileInfo _fileInfo;
|
||||
bool _subArchiveMode;
|
||||
UString _subArchiveName;
|
||||
|
||||
public:
|
||||
UStringVector FileNames;
|
||||
CBoolVector FileNames_WasUsed;
|
||||
CRecordVector<UInt64> FileSizes;
|
||||
|
||||
IOpenCallbackUI *Callback;
|
||||
CMyComPtr<IArchiveOpenCallback> ReOpenCallback;
|
||||
UInt64 TotalSize;
|
||||
// UInt64 TotalSize;
|
||||
|
||||
COpenCallbackImp(): Callback(NULL) {}
|
||||
void Init(const FString &folderPrefix, const FString &fileName)
|
||||
{
|
||||
_folderPrefix = folderPrefix;
|
||||
if (!_fileInfo.Find(_folderPrefix + fileName))
|
||||
throw 1;
|
||||
throw 20121118;
|
||||
FileNames.Clear();
|
||||
FileNames_WasUsed.Clear();
|
||||
FileSizes.Clear();
|
||||
_subArchiveMode = false;
|
||||
TotalSize = 0;
|
||||
// TotalSize = 0;
|
||||
}
|
||||
bool SetSecondFileInfo(CFSTR newName)
|
||||
{
|
||||
return _fileInfo.Find(newName) && !_fileInfo.IsDir();
|
||||
}
|
||||
int FindName(const UString &name);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
1482
CPP/7zip/UI/Common/Bench.cpp
Executable file → Normal file
1482
CPP/7zip/UI/Common/Bench.cpp
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
8
CPP/7zip/UI/Common/Bench.h
Executable file → Normal file
8
CPP/7zip/UI/Common/Bench.h
Executable file → Normal file
@@ -14,21 +14,23 @@ struct CBenchInfo
|
||||
UInt64 UserFreq;
|
||||
UInt64 UnpackSize;
|
||||
UInt64 PackSize;
|
||||
UInt32 NumIterations;
|
||||
UInt64 NumIterations;
|
||||
|
||||
CBenchInfo(): NumIterations(0) {}
|
||||
UInt64 GetUsage() const;
|
||||
UInt64 GetRatingPerUsage(UInt64 rating) const;
|
||||
UInt64 GetSpeed(UInt64 numCommands) const;
|
||||
};
|
||||
|
||||
struct IBenchCallback
|
||||
{
|
||||
virtual HRESULT SetFreq(bool showFreq, UInt64 cpuFreq) = 0;
|
||||
virtual HRESULT SetEncodeResult(const CBenchInfo &info, bool final) = 0;
|
||||
virtual HRESULT SetDecodeResult(const CBenchInfo &info, bool final) = 0;
|
||||
};
|
||||
|
||||
UInt64 GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size);
|
||||
UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt32 numIterations);
|
||||
UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations);
|
||||
|
||||
const int kBenchMinDicLogSize = 18;
|
||||
|
||||
@@ -45,7 +47,7 @@ HRESULT Bench(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
IBenchPrintCallback *printCallback,
|
||||
IBenchCallback *benchCallback,
|
||||
const CObjectVector<CProperty> props,
|
||||
const CObjectVector<CProperty> &props,
|
||||
UInt32 numIterations,
|
||||
bool multiDict
|
||||
);
|
||||
|
||||
109
CPP/7zip/UI/Common/CompressCall.cpp
Executable file → Normal file
109
CPP/7zip/UI/Common/CompressCall.cpp
Executable file → Normal file
@@ -2,17 +2,17 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/IntToString.h"
|
||||
#include "Common/MyCom.h"
|
||||
#include "Common/Random.h"
|
||||
#include "Common/StringConvert.h"
|
||||
#include "../../../Common/IntToString.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../../Common/Random.h"
|
||||
#include "../../../Common/StringConvert.h"
|
||||
|
||||
#include "Windows/DLL.h"
|
||||
#include "Windows/Error.h"
|
||||
#include "Windows/FileDir.h"
|
||||
#include "Windows/FileMapping.h"
|
||||
#include "Windows/Process.h"
|
||||
#include "Windows/Synchronization.h"
|
||||
#include "../../../Windows/DLL.h"
|
||||
#include "../../../Windows/ErrorMsg.h"
|
||||
#include "../../../Windows/FileDir.h"
|
||||
#include "../../../Windows/FileMapping.h"
|
||||
#include "../../../Windows/ProcessUtils.h"
|
||||
#include "../../../Windows/Synchronization.h"
|
||||
|
||||
#include "../FileManager/RegistryUtils.h"
|
||||
|
||||
@@ -23,12 +23,15 @@ using namespace NWindows;
|
||||
#define MY_TRY_BEGIN try {
|
||||
#define MY_TRY_FINISH } \
|
||||
catch(...) { ErrorMessageHRESULT(E_FAIL); return E_FAIL; }
|
||||
#define MY_TRY_FINISH_VOID } \
|
||||
catch(...) { ErrorMessageHRESULT(E_FAIL); }
|
||||
|
||||
static LPCWSTR kShowDialogSwitch = L" -ad";
|
||||
static LPCWSTR kEmailSwitch = L" -seml.";
|
||||
static LPCWSTR kIncludeSwitch = L" -i";
|
||||
static LPCWSTR kArchiveTypeSwitch = L" -t";
|
||||
static LPCWSTR kArcIncludeSwitches = L" -an -ai";
|
||||
static LPCWSTR kHashIncludeSwitches = L" -i";
|
||||
static LPCWSTR kStopSwitchParsing = L" --";
|
||||
static LPCWSTR kLargePagesDisable = L" -slp-";
|
||||
|
||||
@@ -46,7 +49,7 @@ static void ErrorMessage(LPCWSTR message)
|
||||
|
||||
static void ErrorMessageHRESULT(HRESULT res, LPCWSTR s = NULL)
|
||||
{
|
||||
UString s2 = NError::MyFormatMessageW(res);
|
||||
UString s2 = NError::MyFormatMessage(res);
|
||||
if (s)
|
||||
{
|
||||
s2 += L'\n';
|
||||
@@ -56,11 +59,12 @@ static void ErrorMessageHRESULT(HRESULT res, LPCWSTR s = NULL)
|
||||
}
|
||||
|
||||
static HRESULT MyCreateProcess(LPCWSTR imageName, const UString ¶ms,
|
||||
LPCWSTR curDir, bool waitFinish,
|
||||
// LPCWSTR curDir,
|
||||
bool waitFinish,
|
||||
NSynchronization::CBaseEvent *event)
|
||||
{
|
||||
CProcess process;
|
||||
WRes res = process.Create(imageName, params, curDir);
|
||||
WRes res = process.Create(imageName, params, NULL); // curDir);
|
||||
if (res != 0)
|
||||
{
|
||||
ErrorMessageHRESULT(res, imageName);
|
||||
@@ -71,7 +75,7 @@ static HRESULT MyCreateProcess(LPCWSTR imageName, const UString ¶ms,
|
||||
else if (event != NULL)
|
||||
{
|
||||
HANDLE handles[] = { process, *event };
|
||||
::WaitForMultipleObjects(sizeof(handles) / sizeof(handles[0]), handles, FALSE, INFINITE);
|
||||
::WaitForMultipleObjects(ARRAY_SIZE(handles), handles, FALSE, INFINITE);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
@@ -105,8 +109,8 @@ static HRESULT CreateMap(const UStringVector &names,
|
||||
UString ¶ms)
|
||||
{
|
||||
UInt32 totalSize = 1;
|
||||
for (int i = 0; i < names.Size(); i++)
|
||||
totalSize += (names[i].Length() + 1);
|
||||
FOR_VECTOR (i, names)
|
||||
totalSize += (names[i].Len() + 1);
|
||||
totalSize *= sizeof(wchar_t);
|
||||
|
||||
CRandNameGenerator random;
|
||||
@@ -153,10 +157,10 @@ static HRESULT CreateMap(const UStringVector &names,
|
||||
{
|
||||
wchar_t *cur = (wchar_t *)data;
|
||||
*cur++ = 0;
|
||||
for (int i = 0; i < names.Size(); i++)
|
||||
FOR_VECTOR (i, names)
|
||||
{
|
||||
const UString &s = names[i];
|
||||
int len = s.Length() + 1;
|
||||
int len = s.Len() + 1;
|
||||
memcpy(cur, (const wchar_t *)s, len * sizeof(wchar_t));
|
||||
cur += len;
|
||||
}
|
||||
@@ -168,6 +172,7 @@ HRESULT CompressFiles(
|
||||
const UString &arcPathPrefix,
|
||||
const UString &arcName,
|
||||
const UString &arcType,
|
||||
bool addExtension,
|
||||
const UStringVector &names,
|
||||
bool email, bool showDialog, bool waitFinish)
|
||||
{
|
||||
@@ -193,31 +198,46 @@ HRESULT CompressFiles(
|
||||
|
||||
AddLagePagesSwitch(params);
|
||||
|
||||
if (arcName.IsEmpty())
|
||||
params += L" -an";
|
||||
|
||||
if (addExtension)
|
||||
params += L" -saa";
|
||||
else
|
||||
params += L" -sae";
|
||||
|
||||
params += kStopSwitchParsing;
|
||||
params += L' ';
|
||||
|
||||
params += GetQuotedString(
|
||||
#ifdef UNDER_CE
|
||||
arcPathPrefix +
|
||||
#endif
|
||||
if (!arcName.IsEmpty())
|
||||
{
|
||||
params += GetQuotedString(
|
||||
// #ifdef UNDER_CE
|
||||
arcPathPrefix +
|
||||
// #endif
|
||||
arcName);
|
||||
}
|
||||
|
||||
return MyCreateProcess(Get7zGuiPath(), params,
|
||||
(arcPathPrefix.IsEmpty()? 0: (LPCWSTR)arcPathPrefix), waitFinish, &event);
|
||||
// (arcPathPrefix.IsEmpty()? 0: (LPCWSTR)arcPathPrefix),
|
||||
waitFinish, &event);
|
||||
MY_TRY_FINISH
|
||||
}
|
||||
|
||||
static HRESULT ExtractGroupCommand(const UStringVector &arcPaths, UString ¶ms)
|
||||
static void ExtractGroupCommand(const UStringVector &arcPaths, UString ¶ms, bool isHash)
|
||||
{
|
||||
AddLagePagesSwitch(params);
|
||||
params += kArcIncludeSwitches;
|
||||
params += isHash ? kHashIncludeSwitches : kArcIncludeSwitches;
|
||||
CFileMapping fileMapping;
|
||||
NSynchronization::CManualResetEvent event;
|
||||
RINOK(CreateMap(arcPaths, fileMapping, event, params));
|
||||
return MyCreateProcess(Get7zGuiPath(), params, 0, false, &event);
|
||||
HRESULT result = CreateMap(arcPaths, fileMapping, event, params);
|
||||
if (result == S_OK)
|
||||
result = MyCreateProcess(Get7zGuiPath(), params, false, &event);
|
||||
if (result != S_OK)
|
||||
ErrorMessageHRESULT(result);
|
||||
}
|
||||
|
||||
HRESULT ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog)
|
||||
void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog, bool elimDup)
|
||||
{
|
||||
MY_TRY_BEGIN
|
||||
UString params = L'x';
|
||||
@@ -226,23 +246,40 @@ HRESULT ExtractArchives(const UStringVector &arcPaths, const UString &outFolder,
|
||||
params += L" -o";
|
||||
params += GetQuotedString(outFolder);
|
||||
}
|
||||
if (elimDup)
|
||||
params += L" -spe";
|
||||
if (showDialog)
|
||||
params += kShowDialogSwitch;
|
||||
return ExtractGroupCommand(arcPaths, params);
|
||||
MY_TRY_FINISH
|
||||
ExtractGroupCommand(arcPaths, params, false);
|
||||
MY_TRY_FINISH_VOID
|
||||
}
|
||||
|
||||
HRESULT TestArchives(const UStringVector &arcPaths)
|
||||
void TestArchives(const UStringVector &arcPaths)
|
||||
{
|
||||
MY_TRY_BEGIN
|
||||
UString params = L't';
|
||||
return ExtractGroupCommand(arcPaths, params);
|
||||
MY_TRY_FINISH
|
||||
ExtractGroupCommand(arcPaths, params, false);
|
||||
MY_TRY_FINISH_VOID
|
||||
}
|
||||
|
||||
HRESULT Benchmark(bool totalMode)
|
||||
void CalcChecksum(const UStringVector &paths, const UString &methodName)
|
||||
{
|
||||
MY_TRY_BEGIN
|
||||
return MyCreateProcess(Get7zGuiPath(), totalMode ? L"b -mm=*" : L"b", 0, false, NULL);
|
||||
MY_TRY_FINISH
|
||||
UString params = L'h';
|
||||
if (!methodName.IsEmpty())
|
||||
{
|
||||
params += L" -scrc";
|
||||
params += methodName;
|
||||
}
|
||||
ExtractGroupCommand(paths, params, true);
|
||||
MY_TRY_FINISH_VOID
|
||||
}
|
||||
|
||||
void Benchmark(bool totalMode)
|
||||
{
|
||||
MY_TRY_BEGIN
|
||||
HRESULT result = MyCreateProcess(Get7zGuiPath(), totalMode ? L"b -mm=*" : L"b", false, NULL);
|
||||
if (result != S_OK)
|
||||
ErrorMessageHRESULT(result);
|
||||
MY_TRY_FINISH_VOID
|
||||
}
|
||||
|
||||
10
CPP/7zip/UI/Common/CompressCall.h
Executable file → Normal file
10
CPP/7zip/UI/Common/CompressCall.h
Executable file → Normal file
@@ -3,7 +3,7 @@
|
||||
#ifndef __COMPRESS_CALL_H
|
||||
#define __COMPRESS_CALL_H
|
||||
|
||||
#include "Common/MyString.h"
|
||||
#include "../../../Common/MyString.h"
|
||||
|
||||
UString GetQuotedString(const UString &s);
|
||||
|
||||
@@ -11,11 +11,13 @@ HRESULT CompressFiles(
|
||||
const UString &arcPathPrefix,
|
||||
const UString &arcName,
|
||||
const UString &arcType,
|
||||
bool addExtension,
|
||||
const UStringVector &names,
|
||||
bool email, bool showDialog, bool waitFinish);
|
||||
|
||||
HRESULT ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog);
|
||||
HRESULT TestArchives(const UStringVector &arcPaths);
|
||||
HRESULT Benchmark(bool totalMode);
|
||||
void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog, bool elimDup);
|
||||
void TestArchives(const UStringVector &arcPaths);
|
||||
void CalcChecksum(const UStringVector &paths, const UString &methodName);
|
||||
void Benchmark(bool totalMode);
|
||||
|
||||
#endif
|
||||
|
||||
150
CPP/7zip/UI/Common/CompressCall2.cpp
Executable file → Normal file
150
CPP/7zip/UI/Common/CompressCall2.cpp
Executable file → Normal file
@@ -2,13 +2,14 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/MyException.h"
|
||||
#include "../../../Common/MyException.h"
|
||||
|
||||
#include "../../UI/common/ArchiveCommandLine.h"
|
||||
|
||||
#include "../../UI/GUI/BenchmarkDialog.h"
|
||||
#include "../../UI/GUI/ExtractGUI.h"
|
||||
#include "../../UI/GUI/UpdateGUI.h"
|
||||
#include "../../UI/GUI/HashGUI.h"
|
||||
|
||||
#include "../../UI/GUI/ExtractRes.h"
|
||||
|
||||
@@ -16,20 +17,38 @@
|
||||
|
||||
extern HWND g_HWND;
|
||||
|
||||
#define MY_TRY_BEGIN try {
|
||||
#define MY_TRY_BEGIN HRESULT result; try {
|
||||
#define MY_TRY_FINISH } \
|
||||
catch(CSystemException &e) { result = e.ErrorCode; } \
|
||||
catch(...) { result = E_FAIL; } \
|
||||
if (result != S_OK && result != E_ABORT) \
|
||||
ErrorMessageHRESULT(result);
|
||||
|
||||
static void ThrowException_if_Error(HRESULT res)
|
||||
{
|
||||
if (res != S_OK)
|
||||
throw CSystemException(res);
|
||||
}
|
||||
|
||||
#define CREATE_CODECS \
|
||||
CCodecs *codecs = new CCodecs; \
|
||||
CMyComPtr<IUnknown> compressCodecsInfo = codecs; \
|
||||
result = codecs->Load(); \
|
||||
if (result != S_OK) \
|
||||
throw CSystemException(result);
|
||||
CMyComPtr<ICompressCodecsInfo> compressCodecsInfo = codecs; \
|
||||
ThrowException_if_Error(codecs->Load());
|
||||
|
||||
#ifdef EXTERNAL_CODECS
|
||||
|
||||
#define LOAD_EXTERNAL_CODECS \
|
||||
CExternalCodecs __externalCodecs; \
|
||||
__externalCodecs.GetCodecs = codecs; \
|
||||
__externalCodecs.GetHashers = codecs; \
|
||||
ThrowException_if_Error(__externalCodecs.LoadCodecs());
|
||||
|
||||
#else
|
||||
|
||||
LOAD_EXTERNAL_CODECS
|
||||
|
||||
#endif
|
||||
|
||||
UString GetQuotedString(const UString &s)
|
||||
{
|
||||
return UString(L'\"') + s + UString(L'\"');
|
||||
@@ -45,19 +64,19 @@ static void ErrorMessageHRESULT(HRESULT res)
|
||||
ErrorMessage(HResultToMessage(res));
|
||||
}
|
||||
|
||||
static void ErrorLangMessage(UINT resourceID, UInt32 langID)
|
||||
static void ErrorLangMessage(UINT resourceID)
|
||||
{
|
||||
ErrorMessage(LangString(resourceID, langID));
|
||||
ErrorMessage(LangString(resourceID));
|
||||
}
|
||||
|
||||
HRESULT CompressFiles(
|
||||
const UString &arcPathPrefix,
|
||||
const UString &arcName,
|
||||
const UString &arcType,
|
||||
bool addExtension,
|
||||
const UStringVector &names,
|
||||
bool email, bool showDialog, bool /* waitFinish */)
|
||||
{
|
||||
HRESULT result;
|
||||
MY_TRY_BEGIN
|
||||
CREATE_CODECS
|
||||
|
||||
@@ -67,26 +86,35 @@ HRESULT CompressFiles(
|
||||
|
||||
CUpdateOptions uo;
|
||||
uo.EMailMode = email;
|
||||
uo.SetAddActionCommand();
|
||||
uo.SetActionCommand_Add();
|
||||
|
||||
CIntVector formatIndices;
|
||||
if (!codecs->FindFormatForArchiveType(arcType, formatIndices))
|
||||
uo.ArcNameMode = (addExtension ? k_ArcNameMode_Add : k_ArcNameMode_Exact);
|
||||
|
||||
CObjectVector<COpenType> formatIndices;
|
||||
if (!ParseOpenTypes(*codecs, arcType, formatIndices))
|
||||
{
|
||||
ErrorLangMessage(IDS_UNSUPPORTED_ARCHIVE_TYPE, 0x0200060D);
|
||||
ErrorLangMessage(IDS_UNSUPPORTED_ARCHIVE_TYPE);
|
||||
return E_FAIL;
|
||||
}
|
||||
if (!uo.Init(codecs, formatIndices, arcPathPrefix + arcName))
|
||||
const UString arcPath = arcPathPrefix + arcName;
|
||||
if (!uo.InitFormatIndex(codecs, formatIndices, arcPath) ||
|
||||
!uo.SetArcPath(codecs, arcPath))
|
||||
{
|
||||
ErrorLangMessage(IDS_UPDATE_NOT_SUPPORTED, 0x02000601);
|
||||
ErrorLangMessage(IDS_UPDATE_NOT_SUPPORTED);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
NWildcard::CCensor censor;
|
||||
for (int i = 0; i < names.Size(); i++)
|
||||
censor.AddItem(true, names[i], false);
|
||||
FOR_VECTOR (i, names)
|
||||
{
|
||||
censor.AddPreItem(names[i]);
|
||||
}
|
||||
|
||||
bool messageWasDisplayed = false;
|
||||
result = UpdateGUI(codecs, censor, uo, showDialog, messageWasDisplayed, &callback, g_HWND);
|
||||
|
||||
result = UpdateGUI(codecs,
|
||||
formatIndices, arcPath,
|
||||
censor, uo, showDialog, messageWasDisplayed, &callback, g_HWND);
|
||||
|
||||
if (result != S_OK)
|
||||
{
|
||||
@@ -105,15 +133,16 @@ HRESULT CompressFiles(
|
||||
}
|
||||
|
||||
static HRESULT ExtractGroupCommand(const UStringVector &arcPaths,
|
||||
bool showDialog, const UString &outFolder, bool testMode)
|
||||
bool showDialog, const UString &outFolder, bool testMode, bool elimDup = false)
|
||||
{
|
||||
HRESULT result;
|
||||
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;
|
||||
@@ -125,20 +154,29 @@ static HRESULT ExtractGroupCommand(const UStringVector &arcPaths,
|
||||
UStringVector arcPathsSorted;
|
||||
UStringVector arcFullPathsSorted;
|
||||
{
|
||||
NWildcard::CCensor acrCensor;
|
||||
for (int i = 0; i < arcPaths.Size(); i++)
|
||||
acrCensor.AddItem(true, arcPaths[i], false);
|
||||
EnumerateDirItemsAndSort(acrCensor, arcPathsSorted, arcFullPathsSorted);
|
||||
NWildcard::CCensor arcCensor;
|
||||
FOR_VECTOR (i, arcPaths)
|
||||
{
|
||||
arcCensor.AddPreItem(arcPaths[i]);
|
||||
}
|
||||
arcCensor.AddPathsToCensor(NWildcard::k_RelatPath);
|
||||
EnumerateDirItemsAndSort(false, arcCensor, NWildcard::k_RelatPath, UString(), arcPathsSorted, arcFullPathsSorted);
|
||||
}
|
||||
|
||||
CIntVector formatIndices;
|
||||
|
||||
NWildcard::CCensor censor;
|
||||
censor.AddItem(true, L"*", false);
|
||||
CObjectVector<COpenType> formatIndices;
|
||||
|
||||
NWildcard::CCensor censor;
|
||||
{
|
||||
censor.AddPreItem_Wildcard();
|
||||
}
|
||||
|
||||
censor.AddPathsToCensor(NWildcard::k_RelatPath);
|
||||
|
||||
bool messageWasDisplayed = false;
|
||||
result = ExtractGUI(codecs, formatIndices, arcPathsSorted, arcFullPathsSorted,
|
||||
censor.Pairs.Front().Head, eo, showDialog, messageWasDisplayed, ecs, g_HWND);
|
||||
result = ExtractGUI(codecs,
|
||||
formatIndices, CIntVector(),
|
||||
arcPathsSorted, arcFullPathsSorted,
|
||||
censor.Pairs.Front().Head, eo, NULL, showDialog, messageWasDisplayed, ecs, g_HWND);
|
||||
if (result != S_OK)
|
||||
{
|
||||
if (result != E_ABORT && messageWasDisplayed)
|
||||
@@ -150,26 +188,51 @@ static HRESULT ExtractGroupCommand(const UStringVector &arcPaths,
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog)
|
||||
void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog, bool elimDup)
|
||||
{
|
||||
return ExtractGroupCommand(arcPaths, showDialog, outFolder, false);
|
||||
ExtractGroupCommand(arcPaths, showDialog, outFolder, false, elimDup);
|
||||
}
|
||||
|
||||
HRESULT TestArchives(const UStringVector &arcPaths)
|
||||
void TestArchives(const UStringVector &arcPaths)
|
||||
{
|
||||
return ExtractGroupCommand(arcPaths, true, UString(), true);
|
||||
ExtractGroupCommand(arcPaths, true, UString(), true);
|
||||
}
|
||||
|
||||
HRESULT Benchmark(bool totalMode)
|
||||
void CalcChecksum(const UStringVector &paths, const UString &methodName)
|
||||
{
|
||||
HRESULT result;
|
||||
MY_TRY_BEGIN
|
||||
CREATE_CODECS
|
||||
LOAD_EXTERNAL_CODECS
|
||||
|
||||
#ifdef EXTERNAL_CODECS
|
||||
CObjectVector<CCodecInfoEx> externalCodecs;
|
||||
RINOK(LoadExternalCodecs(codecs, externalCodecs));
|
||||
#endif
|
||||
NWildcard::CCensor censor;
|
||||
FOR_VECTOR (i, paths)
|
||||
{
|
||||
censor.AddPreItem(paths[i]);
|
||||
}
|
||||
|
||||
censor.AddPathsToCensor(NWildcard::k_RelatPath);
|
||||
bool messageWasDisplayed = false;
|
||||
|
||||
CHashOptions options;
|
||||
options.Methods.Add(methodName);
|
||||
|
||||
result = HashCalcGUI(EXTERNAL_CODECS_VARS censor, options, messageWasDisplayed);
|
||||
if (result != S_OK)
|
||||
{
|
||||
if (result != E_ABORT && messageWasDisplayed)
|
||||
return; // E_FAIL;
|
||||
throw CSystemException(result);
|
||||
}
|
||||
MY_TRY_FINISH
|
||||
return; // result;
|
||||
}
|
||||
|
||||
void Benchmark(bool totalMode)
|
||||
{
|
||||
MY_TRY_BEGIN
|
||||
CREATE_CODECS
|
||||
LOAD_EXTERNAL_CODECS
|
||||
|
||||
CObjectVector<CProperty> props;
|
||||
if (totalMode)
|
||||
{
|
||||
@@ -178,11 +241,6 @@ HRESULT Benchmark(bool totalMode)
|
||||
prop.Value = L"*";
|
||||
props.Add(prop);
|
||||
}
|
||||
result = Benchmark(
|
||||
#ifdef EXTERNAL_CODECS
|
||||
codecs, &externalCodecs,
|
||||
#endif
|
||||
props, g_HWND);
|
||||
result = Benchmark(EXTERNAL_CODECS_VARS props, g_HWND);
|
||||
MY_TRY_FINISH
|
||||
return result;
|
||||
}
|
||||
|
||||
6
CPP/7zip/UI/Common/DefaultName.cpp
Executable file → Normal file
6
CPP/7zip/UI/Common/DefaultName.cpp
Executable file → Normal file
@@ -7,13 +7,13 @@
|
||||
static UString GetDefaultName3(const UString &fileName,
|
||||
const UString &extension, const UString &addSubExtension)
|
||||
{
|
||||
int extLength = extension.Length();
|
||||
int fileNameLength = fileName.Length();
|
||||
int extLength = extension.Len();
|
||||
int fileNameLength = fileName.Len();
|
||||
if (fileNameLength > extLength + 1)
|
||||
{
|
||||
int dotPos = fileNameLength - (extLength + 1);
|
||||
if (fileName[dotPos] == '.')
|
||||
if (extension.CompareNoCase(fileName.Mid(dotPos + 1)) == 0)
|
||||
if (extension.IsEqualToNoCase(fileName.Ptr(dotPos + 1)))
|
||||
return fileName.Left(dotPos) + addSubExtension;
|
||||
}
|
||||
int dotPos = fileName.ReverseFind(L'.');
|
||||
|
||||
6
CPP/7zip/UI/Common/DefaultName.h
Executable file → Normal file
6
CPP/7zip/UI/Common/DefaultName.h
Executable file → Normal file
@@ -1,9 +1,9 @@
|
||||
// DefaultName.h
|
||||
|
||||
#ifndef __DEFAULTNAME_H
|
||||
#define __DEFAULTNAME_H
|
||||
#ifndef __DEFAULT_NAME_H
|
||||
#define __DEFAULT_NAME_H
|
||||
|
||||
#include "Common/MyString.h"
|
||||
#include "../../../Common/MyString.h"
|
||||
|
||||
UString GetDefaultName2(const UString &fileName,
|
||||
const UString &extension, const UString &addSubExtension);
|
||||
|
||||
83
CPP/7zip/UI/Common/DirItem.h
Executable file → Normal file
83
CPP/7zip/UI/Common/DirItem.h
Executable file → Normal file
@@ -3,8 +3,12 @@
|
||||
#ifndef __DIR_ITEM_H
|
||||
#define __DIR_ITEM_H
|
||||
|
||||
#include "Common/MyString.h"
|
||||
#include "Common/Types.h"
|
||||
#include "../../../Common/MyString.h"
|
||||
|
||||
#include "../../../Windows/FileFind.h"
|
||||
|
||||
#include "../../Common/UniqBlocks.h"
|
||||
|
||||
#include "../../Archive/IArchive.h"
|
||||
|
||||
struct CDirItem
|
||||
@@ -14,11 +18,23 @@ struct CDirItem
|
||||
FILETIME ATime;
|
||||
FILETIME MTime;
|
||||
UString Name;
|
||||
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
// UString ShortName;
|
||||
CByteBuffer ReparseData;
|
||||
CByteBuffer ReparseData2; // fixed (reduced) absolute links
|
||||
|
||||
bool AreReparseData() const { return ReparseData.Size() != 0 || !ReparseData2.Size() != 0; }
|
||||
#endif
|
||||
|
||||
UInt32 Attrib;
|
||||
int PhyParent;
|
||||
int LogParent;
|
||||
int SecureIndex;
|
||||
|
||||
bool IsAltStream;
|
||||
|
||||
CDirItem(): PhyParent(-1), LogParent(-1) {}
|
||||
CDirItem(): PhyParent(-1), LogParent(-1), SecureIndex(-1), IsAltStream(false) {}
|
||||
bool IsDir() const { return (Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0 ; }
|
||||
};
|
||||
|
||||
@@ -29,24 +45,64 @@ class CDirItems
|
||||
CIntVector LogParents;
|
||||
|
||||
UString GetPrefixesPath(const CIntVector &parents, int index, const UString &name) const;
|
||||
|
||||
void EnumerateDir(int phyParent, int logParent, const FString &phyPrefix);
|
||||
|
||||
public:
|
||||
CObjectVector<CDirItem> Items;
|
||||
|
||||
bool SymLinks;
|
||||
|
||||
bool ScanAltStreams;
|
||||
FStringVector ErrorPaths;
|
||||
CRecordVector<DWORD> ErrorCodes;
|
||||
UInt64 TotalSize;
|
||||
|
||||
|
||||
#ifndef UNDER_CE
|
||||
void SetLinkInfo(CDirItem &dirItem, const NWindows::NFile::NFind::CFileInfo &fi,
|
||||
const FString &phyPrefix);
|
||||
#endif
|
||||
|
||||
void AddError(const FString &path, DWORD errorCode)
|
||||
{
|
||||
ErrorCodes.Add(errorCode);
|
||||
ErrorPaths.Add(path);
|
||||
}
|
||||
|
||||
void AddError(const FString &path)
|
||||
{
|
||||
AddError(path, ::GetLastError());
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
|
||||
CUniqBlocks SecureBlocks;
|
||||
CByteBuffer TempSecureBuf;
|
||||
bool _saclEnabled;
|
||||
bool ReadSecure;
|
||||
|
||||
void AddSecurityItem(const FString &path, int &secureIndex);
|
||||
|
||||
#endif
|
||||
|
||||
CDirItems();
|
||||
|
||||
int GetNumFolders() const { return Prefixes.Size(); }
|
||||
UString GetPhyPath(int index) const;
|
||||
UString GetLogPath(int index) const;
|
||||
UString GetPhyPath(unsigned index) const;
|
||||
UString GetLogPath(unsigned index) const;
|
||||
|
||||
int AddPrefix(int phyParent, int logParent, const UString &prefix);
|
||||
unsigned AddPrefix(int phyParent, int logParent, const UString &prefix);
|
||||
void DeleteLastPrefix();
|
||||
|
||||
void EnumerateDirectory(int phyParent, int logParent, const FString &phyPrefix,
|
||||
FStringVector &errorPaths, CRecordVector<DWORD> &errorCodes);
|
||||
|
||||
void EnumerateDirItems2(
|
||||
void EnumerateItems2(
|
||||
const FString &phyPrefix,
|
||||
const UString &logPrefix,
|
||||
const FStringVector &filePaths,
|
||||
FStringVector &errorPaths, CRecordVector<DWORD> &errorCodes);
|
||||
FStringVector *requestedPaths);
|
||||
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
void FillFixedReparse();
|
||||
#endif
|
||||
|
||||
void ReserveDown();
|
||||
};
|
||||
@@ -57,13 +113,14 @@ struct CArcItem
|
||||
FILETIME MTime;
|
||||
UString Name;
|
||||
bool IsDir;
|
||||
bool IsAltStream;
|
||||
bool SizeDefined;
|
||||
bool MTimeDefined;
|
||||
bool Censored;
|
||||
UInt32 IndexInServer;
|
||||
int TimeType;
|
||||
|
||||
CArcItem(): IsDir(false), SizeDefined(false), MTimeDefined(false), Censored(false), TimeType(-1) {}
|
||||
CArcItem(): IsDir(false), IsAltStream(false), SizeDefined(false), MTimeDefined(false), Censored(false), TimeType(-1) {}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
624
CPP/7zip/UI/Common/EnumDirItems.cpp
Executable file → Normal file
624
CPP/7zip/UI/Common/EnumDirItems.cpp
Executable file → Normal file
@@ -2,7 +2,16 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Windows/FileName.h"
|
||||
#include "../../../Common/Wildcard.h"
|
||||
|
||||
#include "../../../Windows/FileDir.h"
|
||||
#include "../../../Windows/FileIO.h"
|
||||
#include "../../../Windows/FileName.h"
|
||||
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
#define _USE_SECURITY_CODE
|
||||
#include "../../../Windows/SecurityUtils.h"
|
||||
#endif
|
||||
|
||||
#include "EnumDirItems.h"
|
||||
|
||||
@@ -10,7 +19,7 @@ using namespace NWindows;
|
||||
using namespace NFile;
|
||||
using namespace NName;
|
||||
|
||||
void AddDirFileInfo(int phyParent, int logParent,
|
||||
void AddDirFileInfo(int phyParent, int logParent, int secureIndex,
|
||||
const NFind::CFileInfo &fi, CObjectVector<CDirItem> &dirItems)
|
||||
{
|
||||
CDirItem di;
|
||||
@@ -19,41 +28,46 @@ void AddDirFileInfo(int phyParent, int logParent,
|
||||
di.ATime = fi.ATime;
|
||||
di.MTime = fi.MTime;
|
||||
di.Attrib = fi.Attrib;
|
||||
di.IsAltStream = fi.IsAltStream;
|
||||
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
|
||||
dirItems.Add(di);
|
||||
}
|
||||
|
||||
UString CDirItems::GetPrefixesPath(const CIntVector &parents, int index, const UString &name) const
|
||||
{
|
||||
UString path;
|
||||
int len = name.Length();
|
||||
unsigned len = name.Len();
|
||||
int i;
|
||||
for (i = index; i >= 0; i = parents[i])
|
||||
len += Prefixes[i].Length();
|
||||
int totalLen = len;
|
||||
len += Prefixes[i].Len();
|
||||
unsigned totalLen = len;
|
||||
wchar_t *p = path.GetBuffer(len);
|
||||
p[len] = 0;
|
||||
len -= name.Length();
|
||||
memcpy(p + len, (const wchar_t *)name, name.Length() * sizeof(wchar_t));
|
||||
len -= name.Len();
|
||||
memcpy(p + len, (const wchar_t *)name, name.Len() * sizeof(wchar_t));
|
||||
for (i = index; i >= 0; i = parents[i])
|
||||
{
|
||||
const UString &s = Prefixes[i];
|
||||
len -= s.Length();
|
||||
memcpy(p + len, (const wchar_t *)s, s.Length() * sizeof(wchar_t));
|
||||
len -= s.Len();
|
||||
memcpy(p + len, (const wchar_t *)s, s.Len() * sizeof(wchar_t));
|
||||
}
|
||||
path.ReleaseBuffer(totalLen);
|
||||
return path;
|
||||
}
|
||||
|
||||
UString CDirItems::GetPhyPath(int index) const
|
||||
UString CDirItems::GetPhyPath(unsigned index) const
|
||||
{
|
||||
const CDirItem &di = Items[index];
|
||||
return GetPrefixesPath(PhyParents, di.PhyParent, di.Name);
|
||||
}
|
||||
|
||||
UString CDirItems::GetLogPath(int index) const
|
||||
UString CDirItems::GetLogPath(unsigned index) const
|
||||
{
|
||||
const CDirItem &di = Items[index];
|
||||
return GetPrefixesPath(LogParents, di.LogParent, di.Name);
|
||||
@@ -67,7 +81,7 @@ void CDirItems::ReserveDown()
|
||||
Items.ReserveDown();
|
||||
}
|
||||
|
||||
int CDirItems::AddPrefix(int phyParent, int logParent, const UString &prefix)
|
||||
unsigned CDirItems::AddPrefix(int phyParent, int logParent, const UString &prefix)
|
||||
{
|
||||
PhyParents.Add(phyParent);
|
||||
LogParents.Add(logParent);
|
||||
@@ -81,8 +95,77 @@ void CDirItems::DeleteLastPrefix()
|
||||
Prefixes.DeleteBack();
|
||||
}
|
||||
|
||||
void CDirItems::EnumerateDirectory(int phyParent, int logParent, const FString &phyPrefix,
|
||||
FStringVector &errorPaths, CRecordVector<DWORD> &errorCodes)
|
||||
bool InitLocalPrivileges();
|
||||
|
||||
CDirItems::CDirItems():
|
||||
SymLinks(false),
|
||||
TotalSize(0)
|
||||
#ifdef _USE_SECURITY_CODE
|
||||
, ReadSecure(false)
|
||||
#endif
|
||||
{
|
||||
#ifdef _USE_SECURITY_CODE
|
||||
_saclEnabled = InitLocalPrivileges();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _USE_SECURITY_CODE
|
||||
|
||||
void CDirItems::AddSecurityItem(const FString &path, int &secureIndex)
|
||||
{
|
||||
secureIndex = -1;
|
||||
|
||||
SECURITY_INFORMATION securInfo =
|
||||
DACL_SECURITY_INFORMATION |
|
||||
GROUP_SECURITY_INFORMATION |
|
||||
OWNER_SECURITY_INFORMATION;
|
||||
if (_saclEnabled)
|
||||
securInfo |= SACL_SECURITY_INFORMATION;
|
||||
|
||||
DWORD errorCode = 0;
|
||||
DWORD secureSize;
|
||||
BOOL res = ::GetFileSecurityW(fs2us(path), securInfo, TempSecureBuf, (DWORD)TempSecureBuf.Size(), &secureSize);
|
||||
if (res)
|
||||
{
|
||||
if (secureSize == 0)
|
||||
return;
|
||||
if (secureSize > TempSecureBuf.Size())
|
||||
errorCode = ERROR_INVALID_FUNCTION;
|
||||
}
|
||||
else
|
||||
{
|
||||
errorCode = GetLastError();
|
||||
if (errorCode == ERROR_INSUFFICIENT_BUFFER)
|
||||
{
|
||||
if (secureSize <= TempSecureBuf.Size())
|
||||
errorCode = ERROR_INVALID_FUNCTION;
|
||||
else
|
||||
{
|
||||
TempSecureBuf.Alloc(secureSize);
|
||||
res = ::GetFileSecurityW(fs2us(path), securInfo, TempSecureBuf, (DWORD)TempSecureBuf.Size(), &secureSize);
|
||||
if (res)
|
||||
{
|
||||
if (secureSize != TempSecureBuf.Size())
|
||||
errorCode = ERROR_INVALID_FUNCTION;;
|
||||
}
|
||||
else
|
||||
errorCode = GetLastError();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (res)
|
||||
{
|
||||
secureIndex = SecureBlocks.AddUniq(TempSecureBuf, secureSize);
|
||||
return;
|
||||
}
|
||||
if (errorCode == 0)
|
||||
errorCode = ERROR_INVALID_FUNCTION;
|
||||
AddError(path, errorCode);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void CDirItems::EnumerateDir(int phyParent, int logParent, const FString &phyPrefix)
|
||||
{
|
||||
NFind::CEnumerator enumerator(phyPrefix + FCHAR_ANY_MASK);
|
||||
for (;;)
|
||||
@@ -91,140 +174,320 @@ void CDirItems::EnumerateDirectory(int phyParent, int logParent, const FString &
|
||||
bool found;
|
||||
if (!enumerator.Next(fi, found))
|
||||
{
|
||||
errorCodes.Add(::GetLastError());
|
||||
errorPaths.Add(phyPrefix);
|
||||
AddError(phyPrefix);
|
||||
return;
|
||||
}
|
||||
if (!found)
|
||||
break;
|
||||
AddDirFileInfo(phyParent, logParent, fi, Items);
|
||||
|
||||
int secureIndex = -1;
|
||||
#ifdef _USE_SECURITY_CODE
|
||||
if (ReadSecure)
|
||||
AddSecurityItem(phyPrefix + fi.Name, secureIndex);
|
||||
#endif
|
||||
|
||||
AddDirFileInfo(phyParent, logParent, secureIndex, fi, Items);
|
||||
|
||||
if (fi.IsDir())
|
||||
{
|
||||
const FString name2 = fi.Name + FCHAR_PATH_SEPARATOR;
|
||||
int parent = AddPrefix(phyParent, logParent, fs2us(name2));
|
||||
EnumerateDirectory(parent, parent, phyPrefix + name2, errorPaths, errorCodes);
|
||||
unsigned parent = AddPrefix(phyParent, logParent, fs2us(name2));
|
||||
EnumerateDir(parent, parent, phyPrefix + name2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CDirItems::EnumerateDirItems2(const FString &phyPrefix, const UString &logPrefix,
|
||||
const FStringVector &filePaths, FStringVector &errorPaths, CRecordVector<DWORD> &errorCodes)
|
||||
void CDirItems::EnumerateItems2(
|
||||
const FString &phyPrefix,
|
||||
const UString &logPrefix,
|
||||
const FStringVector &filePaths,
|
||||
FStringVector *requestedPaths)
|
||||
{
|
||||
int phyParent = phyPrefix.IsEmpty() ? -1 : AddPrefix(-1, -1, fs2us(phyPrefix));
|
||||
int logParent = logPrefix.IsEmpty() ? -1 : AddPrefix(-1, -1, logPrefix);
|
||||
|
||||
for (int i = 0; i < filePaths.Size(); i++)
|
||||
FOR_VECTOR (i, filePaths)
|
||||
{
|
||||
const FString &filePath = filePaths[i];
|
||||
NFind::CFileInfo fi;
|
||||
const FString phyPath = phyPrefix + filePath;
|
||||
if (!fi.Find(phyPath))
|
||||
{
|
||||
errorCodes.Add(::GetLastError());
|
||||
errorPaths.Add(phyPath);
|
||||
AddError(phyPath);
|
||||
continue;
|
||||
}
|
||||
if (requestedPaths)
|
||||
requestedPaths->Add(phyPath);
|
||||
|
||||
int delimiter = filePath.ReverseFind(FCHAR_PATH_SEPARATOR);
|
||||
FString phyPrefixCur;
|
||||
int phyParentCur = phyParent;
|
||||
if (delimiter >= 0)
|
||||
{
|
||||
phyPrefixCur = filePath.Left(delimiter + 1);
|
||||
phyPrefixCur.SetFrom(filePath, delimiter + 1);
|
||||
phyParentCur = AddPrefix(phyParent, logParent, fs2us(phyPrefixCur));
|
||||
}
|
||||
AddDirFileInfo(phyParentCur, logParent, fi, Items);
|
||||
|
||||
int secureIndex = -1;
|
||||
#ifdef _USE_SECURITY_CODE
|
||||
if (ReadSecure)
|
||||
AddSecurityItem(phyPath, secureIndex);
|
||||
#endif
|
||||
|
||||
AddDirFileInfo(phyParentCur, logParent, secureIndex, fi, Items);
|
||||
|
||||
if (fi.IsDir())
|
||||
{
|
||||
const FString name2 = fi.Name + FCHAR_PATH_SEPARATOR;
|
||||
int parent = AddPrefix(phyParentCur, logParent, fs2us(name2));
|
||||
EnumerateDirectory(parent, parent, phyPrefix + phyPrefixCur + name2, errorPaths, errorCodes);
|
||||
unsigned parent = AddPrefix(phyParentCur, logParent, fs2us(name2));
|
||||
EnumerateDir(parent, parent, phyPrefix + phyPrefixCur + name2);
|
||||
}
|
||||
}
|
||||
ReserveDown();
|
||||
}
|
||||
|
||||
static HRESULT EnumerateDirItems(const NWildcard::CCensorNode &curNode,
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static HRESULT EnumerateDirItems(
|
||||
const NWildcard::CCensorNode &curNode,
|
||||
int phyParent, int logParent, const FString &phyPrefix,
|
||||
const UStringVector &addArchivePrefix,
|
||||
CDirItems &dirItems,
|
||||
bool enterToSubFolders,
|
||||
IEnumDirItemCallback *callback,
|
||||
FStringVector &errorPaths,
|
||||
CRecordVector<DWORD> &errorCodes);
|
||||
IEnumDirItemCallback *callback);
|
||||
|
||||
static HRESULT EnumerateDirItems_Spec(const NWildcard::CCensorNode &curNode,
|
||||
static HRESULT EnumerateDirItems_Spec(
|
||||
const NWildcard::CCensorNode &curNode,
|
||||
int phyParent, int logParent, const FString &curFolderName,
|
||||
const FString &phyPrefix,
|
||||
const UStringVector &addArchivePrefix,
|
||||
CDirItems &dirItems,
|
||||
bool enterToSubFolders,
|
||||
IEnumDirItemCallback *callback,
|
||||
FStringVector &errorPaths,
|
||||
CRecordVector<DWORD> &errorCodes)
|
||||
|
||||
IEnumDirItemCallback *callback)
|
||||
{
|
||||
const FString name2 = curFolderName + FCHAR_PATH_SEPARATOR;
|
||||
int parent = dirItems.AddPrefix(phyParent, logParent, fs2us(name2));
|
||||
int numItems = dirItems.Items.Size();
|
||||
HRESULT res = EnumerateDirItems(curNode, parent, parent, phyPrefix + name2,
|
||||
addArchivePrefix, dirItems, enterToSubFolders, callback, errorPaths, errorCodes);
|
||||
unsigned parent = dirItems.AddPrefix(phyParent, logParent, fs2us(name2));
|
||||
unsigned numItems = dirItems.Items.Size();
|
||||
HRESULT res = EnumerateDirItems(
|
||||
curNode, parent, parent, phyPrefix + name2,
|
||||
addArchivePrefix, dirItems, enterToSubFolders, callback);
|
||||
if (numItems == dirItems.Items.Size())
|
||||
dirItems.DeleteLastPrefix();
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifndef UNDER_CE
|
||||
|
||||
static HRESULT EnumerateDirItems(const NWildcard::CCensorNode &curNode,
|
||||
static void EnumerateAltStreams(
|
||||
const NFind::CFileInfo &fi,
|
||||
const NWildcard::CCensorNode &curNode,
|
||||
int phyParent, int logParent, const FString &phyPrefix,
|
||||
const UStringVector &addArchivePrefix, // prefix from curNode
|
||||
CDirItems &dirItems)
|
||||
{
|
||||
const FString fullPath = phyPrefix + fi.Name;
|
||||
NFind::CStreamEnumerator enumerator(fullPath);
|
||||
for (;;)
|
||||
{
|
||||
NFind::CStreamInfo si;
|
||||
bool found;
|
||||
if (!enumerator.Next(si, found))
|
||||
{
|
||||
dirItems.AddError(fullPath + FTEXT(":*"), (DWORD)E_FAIL);
|
||||
break;
|
||||
}
|
||||
if (!found)
|
||||
break;
|
||||
if (si.IsMainStream())
|
||||
continue;
|
||||
UStringVector addArchivePrefixNew = addArchivePrefix;
|
||||
UString reducedName = si.GetReducedName();
|
||||
addArchivePrefixNew.Back() += reducedName;
|
||||
if (curNode.CheckPathToRoot(false, addArchivePrefixNew, true))
|
||||
continue;
|
||||
NFind::CFileInfo fi2 = fi;
|
||||
fi2.Name += us2fs(reducedName);
|
||||
fi2.Size = si.Size;
|
||||
fi2.Attrib &= ~FILE_ATTRIBUTE_DIRECTORY;
|
||||
fi2.IsAltStream = true;
|
||||
AddDirFileInfo(phyParent, logParent, -1, fi2, dirItems.Items);
|
||||
dirItems.TotalSize += fi2.Size;
|
||||
}
|
||||
}
|
||||
|
||||
void CDirItems::SetLinkInfo(CDirItem &dirItem, const NFind::CFileInfo &fi,
|
||||
const FString &phyPrefix)
|
||||
{
|
||||
if (!SymLinks || !fi.HasReparsePoint())
|
||||
return;
|
||||
const FString path = phyPrefix + fi.Name;
|
||||
CByteBuffer &buf = dirItem.ReparseData;
|
||||
if (NIO::GetReparseData(path, buf))
|
||||
{
|
||||
CReparseAttr attr;
|
||||
if (attr.Parse(buf, buf.Size()))
|
||||
return;
|
||||
}
|
||||
AddError(path);
|
||||
buf.Free();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static HRESULT EnumerateForItem(
|
||||
NFind::CFileInfo &fi,
|
||||
const NWildcard::CCensorNode &curNode,
|
||||
int phyParent, int logParent, const FString &phyPrefix,
|
||||
const UStringVector &addArchivePrefix, // prefix from curNode
|
||||
CDirItems &dirItems,
|
||||
bool enterToSubFolders,
|
||||
IEnumDirItemCallback *callback,
|
||||
FStringVector &errorPaths,
|
||||
CRecordVector<DWORD> &errorCodes)
|
||||
IEnumDirItemCallback *callback)
|
||||
{
|
||||
const UString name = fs2us(fi.Name);
|
||||
bool enterToSubFolders2 = enterToSubFolders;
|
||||
UStringVector addArchivePrefixNew = addArchivePrefix;
|
||||
addArchivePrefixNew.Add(name);
|
||||
{
|
||||
UStringVector addArchivePrefixNewTemp(addArchivePrefixNew);
|
||||
if (curNode.CheckPathToRoot(false, addArchivePrefixNewTemp, !fi.IsDir()))
|
||||
return S_OK;
|
||||
}
|
||||
int dirItemIndex = -1;
|
||||
|
||||
if (curNode.CheckPathToRoot(true, addArchivePrefixNew, !fi.IsDir()))
|
||||
{
|
||||
int secureIndex = -1;
|
||||
#ifdef _USE_SECURITY_CODE
|
||||
if (dirItems.ReadSecure)
|
||||
dirItems.AddSecurityItem(phyPrefix + fi.Name, secureIndex);
|
||||
#endif
|
||||
|
||||
dirItemIndex = dirItems.Items.Size();
|
||||
AddDirFileInfo(phyParent, logParent, secureIndex, fi, dirItems.Items);
|
||||
dirItems.TotalSize += fi.Size;
|
||||
if (fi.IsDir())
|
||||
enterToSubFolders2 = true;
|
||||
}
|
||||
|
||||
#ifndef UNDER_CE
|
||||
if (dirItems.ScanAltStreams)
|
||||
{
|
||||
EnumerateAltStreams(fi, curNode, phyParent, logParent, phyPrefix,
|
||||
addArchivePrefixNew, dirItems);
|
||||
}
|
||||
|
||||
if (dirItemIndex >= 0)
|
||||
{
|
||||
CDirItem &dirItem = dirItems.Items[dirItemIndex];
|
||||
dirItems.SetLinkInfo(dirItem, fi, phyPrefix);
|
||||
if (dirItem.ReparseData.Size() != 0)
|
||||
return S_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!fi.IsDir())
|
||||
return S_OK;
|
||||
|
||||
const NWildcard::CCensorNode *nextNode = 0;
|
||||
if (addArchivePrefix.IsEmpty())
|
||||
{
|
||||
int index = curNode.FindSubNode(name);
|
||||
if (index >= 0)
|
||||
nextNode = &curNode.SubNodes[index];
|
||||
}
|
||||
if (!enterToSubFolders2 && nextNode == 0)
|
||||
return S_OK;
|
||||
|
||||
addArchivePrefixNew = addArchivePrefix;
|
||||
if (nextNode == 0)
|
||||
{
|
||||
nextNode = &curNode;
|
||||
addArchivePrefixNew.Add(name);
|
||||
}
|
||||
|
||||
return EnumerateDirItems_Spec(
|
||||
*nextNode, phyParent, logParent, fi.Name, phyPrefix,
|
||||
addArchivePrefixNew,
|
||||
dirItems,
|
||||
enterToSubFolders2, callback);
|
||||
}
|
||||
|
||||
|
||||
static bool CanUseFsDirect(const NWildcard::CCensorNode &curNode)
|
||||
{
|
||||
FOR_VECTOR (i, curNode.IncludeItems)
|
||||
{
|
||||
const NWildcard::CItem &item = curNode.IncludeItems[i];
|
||||
if (item.Recursive || item.PathParts.Size() != 1)
|
||||
return false;
|
||||
const UString &name = item.PathParts.Front();
|
||||
if (name.IsEmpty())
|
||||
return false;
|
||||
|
||||
/* Windows doesn't support file name with wildcard.
|
||||
but if another system supports file name with wildcard,
|
||||
and wildcard mode is disabled, we can ignore wildcard in name */
|
||||
/*
|
||||
if (!item.WildcardParsing)
|
||||
continue;
|
||||
*/
|
||||
if (DoesNameContainWildcard(name))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static HRESULT EnumerateDirItems(
|
||||
const NWildcard::CCensorNode &curNode,
|
||||
int phyParent, int logParent, const FString &phyPrefix,
|
||||
const UStringVector &addArchivePrefix, // prefix from curNode
|
||||
CDirItems &dirItems,
|
||||
bool enterToSubFolders,
|
||||
IEnumDirItemCallback *callback)
|
||||
{
|
||||
if (!enterToSubFolders)
|
||||
if (curNode.NeedCheckSubDirs())
|
||||
enterToSubFolders = true;
|
||||
if (callback)
|
||||
RINOK(callback->ScanProgress(dirItems.GetNumFolders(), dirItems.Items.Size(), fs2us(phyPrefix)));
|
||||
RINOK(callback->ScanProgress(dirItems.GetNumFolders(), dirItems.Items.Size(), dirItems.TotalSize, fs2us(phyPrefix), true));
|
||||
|
||||
// try direct_names case at first
|
||||
if (addArchivePrefix.IsEmpty() && !enterToSubFolders)
|
||||
{
|
||||
// check that all names are direct
|
||||
int i;
|
||||
for (i = 0; i < curNode.IncludeItems.Size(); i++)
|
||||
{
|
||||
const NWildcard::CItem &item = curNode.IncludeItems[i];
|
||||
if (item.Recursive || item.PathParts.Size() != 1)
|
||||
break;
|
||||
const UString &name = item.PathParts.Front();
|
||||
if (name.IsEmpty() || DoesNameContainWildCard(name))
|
||||
break;
|
||||
}
|
||||
if (i == curNode.IncludeItems.Size())
|
||||
if (CanUseFsDirect(curNode))
|
||||
{
|
||||
// all names are direct (no wildcards)
|
||||
// so we don't need file_system's dir enumerator
|
||||
CRecordVector<bool> needEnterVector;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < curNode.IncludeItems.Size(); i++)
|
||||
{
|
||||
const NWildcard::CItem &item = curNode.IncludeItems[i];
|
||||
const UString &name = item.PathParts.Front();
|
||||
const FString fullPath = phyPrefix + us2fs(name);
|
||||
NFind::CFileInfo fi;
|
||||
#ifdef _WIN32
|
||||
if (phyPrefix.IsEmpty() && item.IsDriveItem())
|
||||
{
|
||||
fi.SetAsDir();
|
||||
fi.Name = fullPath;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (!fi.Find(fullPath))
|
||||
{
|
||||
errorCodes.Add(::GetLastError());
|
||||
errorPaths.Add(fullPath);
|
||||
dirItems.AddError(fullPath);
|
||||
continue;
|
||||
}
|
||||
bool isDir = fi.IsDir();
|
||||
if (isDir && !item.ForDir || !isDir && !item.ForFile)
|
||||
{
|
||||
errorCodes.Add((DWORD)E_FAIL);
|
||||
errorPaths.Add(fullPath);
|
||||
dirItems.AddError(fullPath, (DWORD)E_FAIL);
|
||||
continue;
|
||||
}
|
||||
{
|
||||
@@ -233,7 +496,36 @@ static HRESULT EnumerateDirItems(const NWildcard::CCensorNode &curNode,
|
||||
if (curNode.CheckPathToRoot(false, pathParts, !isDir))
|
||||
continue;
|
||||
}
|
||||
AddDirFileInfo(phyParent, logParent, fi, dirItems.Items);
|
||||
|
||||
int secureIndex = -1;
|
||||
#ifdef _USE_SECURITY_CODE
|
||||
if (dirItems.ReadSecure)
|
||||
dirItems.AddSecurityItem(fullPath, secureIndex);
|
||||
#endif
|
||||
|
||||
AddDirFileInfo(phyParent, logParent, secureIndex, fi, dirItems.Items);
|
||||
|
||||
#ifndef UNDER_CE
|
||||
{
|
||||
CDirItem &dirItem = dirItems.Items.Back();
|
||||
dirItems.SetLinkInfo(dirItem, fi, phyPrefix);
|
||||
if (dirItem.ReparseData.Size() != 0)
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
dirItems.TotalSize += fi.Size;
|
||||
|
||||
#ifndef UNDER_CE
|
||||
if (dirItems.ScanAltStreams)
|
||||
{
|
||||
UStringVector pathParts;
|
||||
pathParts.Add(fs2us(fi.Name));
|
||||
EnumerateAltStreams(fi, curNode, phyParent, logParent, phyPrefix,
|
||||
pathParts, dirItems);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!isDir)
|
||||
continue;
|
||||
|
||||
@@ -254,8 +546,9 @@ static HRESULT EnumerateDirItems(const NWildcard::CCensorNode &curNode,
|
||||
}
|
||||
|
||||
RINOK(EnumerateDirItems_Spec(*nextNode, phyParent, logParent, fi.Name, phyPrefix,
|
||||
addArchivePrefixNew, dirItems, true, callback, errorPaths, errorCodes));
|
||||
addArchivePrefixNew, dirItems, true, callback));
|
||||
}
|
||||
|
||||
for (i = 0; i < curNode.SubNodes.Size(); i++)
|
||||
{
|
||||
if (i < needEnterVector.Size())
|
||||
@@ -264,100 +557,201 @@ static HRESULT EnumerateDirItems(const NWildcard::CCensorNode &curNode,
|
||||
const NWildcard::CCensorNode &nextNode = curNode.SubNodes[i];
|
||||
const FString fullPath = phyPrefix + us2fs(nextNode.Name);
|
||||
NFind::CFileInfo fi;
|
||||
#ifdef _WIN32
|
||||
if (phyPrefix.IsEmpty() && NWildcard::IsDriveColonName(nextNode.Name))
|
||||
{
|
||||
fi.SetAsDir();
|
||||
fi.Name = fullPath;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (!fi.Find(fullPath))
|
||||
{
|
||||
if (!nextNode.AreThereIncludeItems())
|
||||
continue;
|
||||
errorCodes.Add(::GetLastError());
|
||||
errorPaths.Add(fullPath);
|
||||
dirItems.AddError(fullPath);
|
||||
continue;
|
||||
}
|
||||
if (!fi.IsDir())
|
||||
{
|
||||
errorCodes.Add((DWORD)E_FAIL);
|
||||
errorPaths.Add(fullPath);
|
||||
dirItems.AddError(fullPath, (DWORD)E_FAIL);
|
||||
continue;
|
||||
}
|
||||
|
||||
RINOK(EnumerateDirItems_Spec(nextNode, phyParent, logParent, fi.Name, phyPrefix,
|
||||
UStringVector(), dirItems, false, callback, errorPaths, errorCodes));
|
||||
UStringVector(), dirItems, false, callback));
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef UNDER_CE
|
||||
|
||||
// scan drives, if wildcard is "*:\"
|
||||
|
||||
if (phyPrefix.IsEmpty() && curNode.IncludeItems.Size() > 0)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < curNode.IncludeItems.Size(); i++)
|
||||
{
|
||||
const NWildcard::CItem &item = curNode.IncludeItems[i];
|
||||
if (item.PathParts.Size() < 1)
|
||||
break;
|
||||
const UString &name = item.PathParts.Front();
|
||||
if (name.Len() != 2 || name[1] != ':')
|
||||
break;
|
||||
if (item.PathParts.Size() == 1)
|
||||
if (item.ForFile || !item.ForDir)
|
||||
break;
|
||||
if (NWildcard::IsDriveColonName(name))
|
||||
continue;
|
||||
if (name[0] != '*' && name[0] != '?')
|
||||
break;
|
||||
}
|
||||
if (i == curNode.IncludeItems.Size())
|
||||
{
|
||||
FStringVector driveStrings;
|
||||
NFind::MyGetLogicalDriveStrings(driveStrings);
|
||||
for (i = 0; i < driveStrings.Size(); i++)
|
||||
{
|
||||
FString driveName = driveStrings[i];
|
||||
if (driveName.Len() < 3 || driveName.Back() != '\\')
|
||||
return E_FAIL;
|
||||
driveName.DeleteBack();
|
||||
NFind::CFileInfo fi;
|
||||
fi.SetAsDir();
|
||||
fi.Name = driveName;
|
||||
|
||||
RINOK(EnumerateForItem(fi, curNode, phyParent, logParent, phyPrefix,
|
||||
addArchivePrefix, dirItems, enterToSubFolders, callback));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
NFind::CEnumerator enumerator(phyPrefix + FCHAR_ANY_MASK);
|
||||
for (int ttt = 0; ; ttt++)
|
||||
for (unsigned ttt = 0; ; ttt++)
|
||||
{
|
||||
NFind::CFileInfo fi;
|
||||
bool found;
|
||||
if (!enumerator.Next(fi, found))
|
||||
{
|
||||
errorCodes.Add(::GetLastError());
|
||||
errorPaths.Add(phyPrefix);
|
||||
dirItems.AddError(phyPrefix);
|
||||
break;
|
||||
}
|
||||
if (!found)
|
||||
break;
|
||||
|
||||
if (callback && (ttt & 0xFF) == 0xFF)
|
||||
RINOK(callback->ScanProgress(dirItems.GetNumFolders(), dirItems.Items.Size(), fs2us(phyPrefix)));
|
||||
const UString &name = fs2us(fi.Name);
|
||||
bool enterToSubFolders2 = enterToSubFolders;
|
||||
UStringVector addArchivePrefixNew = addArchivePrefix;
|
||||
addArchivePrefixNew.Add(name);
|
||||
{
|
||||
UStringVector addArchivePrefixNewTemp(addArchivePrefixNew);
|
||||
if (curNode.CheckPathToRoot(false, addArchivePrefixNewTemp, !fi.IsDir()))
|
||||
continue;
|
||||
}
|
||||
if (curNode.CheckPathToRoot(true, addArchivePrefixNew, !fi.IsDir()))
|
||||
{
|
||||
AddDirFileInfo(phyParent, logParent, fi, dirItems.Items);
|
||||
if (fi.IsDir())
|
||||
enterToSubFolders2 = true;
|
||||
}
|
||||
if (!fi.IsDir())
|
||||
continue;
|
||||
RINOK(callback->ScanProgress(dirItems.GetNumFolders(), dirItems.Items.Size(), dirItems.TotalSize, fs2us(phyPrefix), true));
|
||||
|
||||
const NWildcard::CCensorNode *nextNode = 0;
|
||||
if (addArchivePrefix.IsEmpty())
|
||||
{
|
||||
int index = curNode.FindSubNode(name);
|
||||
if (index >= 0)
|
||||
nextNode = &curNode.SubNodes[index];
|
||||
}
|
||||
if (!enterToSubFolders2 && nextNode == 0)
|
||||
continue;
|
||||
|
||||
addArchivePrefixNew = addArchivePrefix;
|
||||
if (nextNode == 0)
|
||||
{
|
||||
nextNode = &curNode;
|
||||
addArchivePrefixNew.Add(name);
|
||||
}
|
||||
|
||||
RINOK(EnumerateDirItems_Spec(*nextNode, phyParent, logParent, fi.Name, phyPrefix,
|
||||
addArchivePrefixNew, dirItems, enterToSubFolders2, callback, errorPaths, errorCodes));
|
||||
RINOK(EnumerateForItem(fi, curNode, phyParent, logParent, phyPrefix,
|
||||
addArchivePrefix, dirItems, enterToSubFolders, callback));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT EnumerateItems(
|
||||
const NWildcard::CCensor &censor,
|
||||
const NWildcard::ECensorPathMode pathMode,
|
||||
const UString &addPathPrefix,
|
||||
CDirItems &dirItems,
|
||||
IEnumDirItemCallback *callback,
|
||||
FStringVector &errorPaths,
|
||||
CRecordVector<DWORD> &errorCodes)
|
||||
IEnumDirItemCallback *callback)
|
||||
{
|
||||
for (int i = 0; i < censor.Pairs.Size(); i++)
|
||||
FOR_VECTOR (i, censor.Pairs)
|
||||
{
|
||||
const NWildcard::CPair &pair = censor.Pairs[i];
|
||||
int phyParent = pair.Prefix.IsEmpty() ? -1 : dirItems.AddPrefix(-1, -1, pair.Prefix);
|
||||
RINOK(EnumerateDirItems(pair.Head, phyParent, -1, us2fs(pair.Prefix), UStringVector(), dirItems, false,
|
||||
callback, errorPaths, errorCodes));
|
||||
int logParent = -1;
|
||||
|
||||
if (pathMode == NWildcard::k_AbsPath)
|
||||
logParent = phyParent;
|
||||
else
|
||||
{
|
||||
if (!addPathPrefix.IsEmpty())
|
||||
logParent = dirItems.AddPrefix(-1, -1, addPathPrefix);
|
||||
}
|
||||
|
||||
RINOK(EnumerateDirItems(pair.Head, phyParent, logParent, us2fs(pair.Prefix), UStringVector(),
|
||||
dirItems,
|
||||
false, // enterToSubFolders
|
||||
callback));
|
||||
}
|
||||
dirItems.ReserveDown();
|
||||
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
dirItems.FillFixedReparse();
|
||||
#endif
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
|
||||
void CDirItems::FillFixedReparse()
|
||||
{
|
||||
/* imagex/WIM reduces absolute pathes in links (raparse data),
|
||||
if we archive non root folder. We do same thing here */
|
||||
|
||||
if (!SymLinks)
|
||||
return;
|
||||
|
||||
FOR_VECTOR(i, Items)
|
||||
{
|
||||
CDirItem &item = Items[i];
|
||||
if (item.ReparseData.Size() == 0)
|
||||
continue;
|
||||
|
||||
CReparseAttr attr;
|
||||
if (!attr.Parse(item.ReparseData, item.ReparseData.Size()))
|
||||
continue;
|
||||
if (attr.IsRelative())
|
||||
continue;
|
||||
|
||||
const UString &link = attr.GetPath();
|
||||
if (!IsDrivePath(link))
|
||||
continue;
|
||||
// maybe we need to support networks paths also ?
|
||||
|
||||
FString fullPathF;
|
||||
if (!NDir::MyGetFullPathName(us2fs(GetPhyPath(i)), fullPathF))
|
||||
continue;
|
||||
UString fullPath = fs2us(fullPathF);
|
||||
const UString logPath = GetLogPath(i);
|
||||
if (logPath.Len() >= fullPath.Len())
|
||||
continue;
|
||||
if (CompareFileNames(logPath, fullPath.RightPtr(logPath.Len())) != 0)
|
||||
continue;
|
||||
|
||||
const UString prefix = fullPath.Left(fullPath.Len() - logPath.Len());
|
||||
if (prefix.Back() != WCHAR_PATH_SEPARATOR)
|
||||
continue;
|
||||
|
||||
unsigned rootPrefixSize = GetRootPrefixSize(prefix);
|
||||
if (rootPrefixSize == 0)
|
||||
continue;
|
||||
if (rootPrefixSize == prefix.Len())
|
||||
continue; // simple case: paths are from root
|
||||
|
||||
if (link.Len() <= prefix.Len())
|
||||
continue;
|
||||
|
||||
if (CompareFileNames(link.Left(prefix.Len()), prefix) != 0)
|
||||
continue;
|
||||
|
||||
UString newLink = prefix.Left(rootPrefixSize);
|
||||
newLink += link.Ptr(prefix.Len());
|
||||
|
||||
CByteBuffer data;
|
||||
if (!FillLinkData(data, newLink, attr.IsSymLink()))
|
||||
continue;
|
||||
item.ReparseData2 = data;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
16
CPP/7zip/UI/Common/EnumDirItems.h
Executable file → Normal file
16
CPP/7zip/UI/Common/EnumDirItems.h
Executable file → Normal file
@@ -3,23 +3,25 @@
|
||||
#ifndef __ENUM_DIR_ITEMS_H
|
||||
#define __ENUM_DIR_ITEMS_H
|
||||
|
||||
#include "Common/Wildcard.h"
|
||||
#include "Windows/FileFind.h"
|
||||
#include "../../../Common/Wildcard.h"
|
||||
|
||||
#include "../../../Windows/FileFind.h"
|
||||
|
||||
#include "DirItem.h"
|
||||
|
||||
void AddDirFileInfo(int phyParent, int logParent,
|
||||
void AddDirFileInfo(int phyParent, int logParent, int secureIndex,
|
||||
const NWindows::NFile::NFind::CFileInfo &fi, CObjectVector<CDirItem> &dirItems);
|
||||
|
||||
struct IEnumDirItemCallback
|
||||
{
|
||||
virtual HRESULT ScanProgress(UInt64 numFolders, UInt64 numFiles, const wchar_t *path) = 0;
|
||||
virtual HRESULT ScanProgress(UInt64 numFolders, UInt64 numFiles, UInt64 totalSize, const wchar_t *path, bool isDir) = 0;
|
||||
};
|
||||
|
||||
HRESULT EnumerateItems(
|
||||
const NWildcard::CCensor &censor,
|
||||
NWildcard::ECensorPathMode pathMode,
|
||||
const UString &addPathPrefix,
|
||||
CDirItems &dirItems,
|
||||
IEnumDirItemCallback *callback,
|
||||
FStringVector &errorPaths,
|
||||
CRecordVector<DWORD> &errorCodes);
|
||||
IEnumDirItemCallback *callback);
|
||||
|
||||
#endif
|
||||
|
||||
0
CPP/7zip/UI/Common/ExitCode.h
Executable file → Normal file
0
CPP/7zip/UI/Common/ExitCode.h
Executable file → Normal file
366
CPP/7zip/UI/Common/Extract.cpp
Executable file → Normal file
366
CPP/7zip/UI/Common/Extract.cpp
Executable file → Normal file
@@ -2,11 +2,13 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "../../../../C/Sort.h"
|
||||
|
||||
#include "Windows/FileDir.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "Windows/PropVariantConversions.h"
|
||||
#include "../../../Common/StringConvert.h"
|
||||
|
||||
#include "../../../Windows/FileDir.h"
|
||||
#include "../../../Windows/PropVariant.h"
|
||||
#include "../../../Windows/PropVariantConv.h"
|
||||
|
||||
#include "../Common/ExtractingFilePath.h"
|
||||
|
||||
@@ -14,54 +16,117 @@
|
||||
#include "SetProperties.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
using namespace NDir;
|
||||
|
||||
static HRESULT DecompressArchive(
|
||||
const CArc &arc,
|
||||
CCodecs *codecs,
|
||||
const CArchiveLink &arcLink,
|
||||
UInt64 packSize,
|
||||
const NWildcard::CCensorNode &wildcardCensor,
|
||||
const CExtractOptions &options,
|
||||
bool calcCrc,
|
||||
IExtractCallbackUI *callback,
|
||||
CArchiveExtractCallback *extractCallbackSpec,
|
||||
CArchiveExtractCallback *ecs,
|
||||
UString &errorMessage,
|
||||
UInt64 &stdInProcessed)
|
||||
{
|
||||
const CArc &arc = arcLink.Arcs.Back();
|
||||
stdInProcessed = 0;
|
||||
IInArchive *archive = arc.Archive;
|
||||
CRecordVector<UInt32> realIndices;
|
||||
|
||||
UStringVector removePathParts;
|
||||
|
||||
FString outDir = options.OutputDir;
|
||||
UString replaceName = arc.DefaultName;
|
||||
|
||||
if (arcLink.Arcs.Size() > 1)
|
||||
{
|
||||
// Most "pe" archives have same name of archive subfile "[0]" or ".rsrc_1".
|
||||
// So it extracts different archives to one folder.
|
||||
// We will use top level archive name
|
||||
const CArc &arc0 = arcLink.Arcs[0];
|
||||
if (StringsAreEqualNoCase_Ascii(codecs->Formats[arc0.FormatIndex].Name, "pe"))
|
||||
replaceName = arc0.DefaultName;
|
||||
}
|
||||
|
||||
outDir.Replace(FSTRING_ANY_MASK, us2fs(GetCorrectFsPath(replaceName)));
|
||||
|
||||
bool elimIsPossible = false;
|
||||
UString elimPrefix; // only pure name without dir delimiter
|
||||
FString outDirReduced = outDir;
|
||||
|
||||
if (options.ElimDup.Val)
|
||||
{
|
||||
UString dirPrefix;
|
||||
SplitPathToParts_Smart(fs2us(outDir), dirPrefix, elimPrefix);
|
||||
if (!elimPrefix.IsEmpty())
|
||||
{
|
||||
if (IsCharDirLimiter(elimPrefix.Back()))
|
||||
elimPrefix.DeleteBack();
|
||||
if (!elimPrefix.IsEmpty())
|
||||
{
|
||||
outDirReduced = us2fs(dirPrefix);
|
||||
elimIsPossible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!options.StdInMode)
|
||||
{
|
||||
UInt32 numItems;
|
||||
RINOK(archive->GetNumberOfItems(&numItems));
|
||||
|
||||
UString filePath;
|
||||
|
||||
for (UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
UString filePath;
|
||||
RINOK(arc.GetItemPath(i, filePath));
|
||||
|
||||
if (elimIsPossible && options.ElimDup.Val)
|
||||
{
|
||||
if (!IsPath1PrefixedByPath2(filePath, elimPrefix))
|
||||
elimIsPossible = false;
|
||||
else
|
||||
{
|
||||
wchar_t c = filePath[elimPrefix.Len()];
|
||||
if (c != 0 && !IsCharDirLimiter(c))
|
||||
elimIsPossible = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool isFolder;
|
||||
RINOK(IsArchiveItemFolder(archive, i, isFolder));
|
||||
if (!wildcardCensor.CheckPath(filePath, !isFolder))
|
||||
RINOK(Archive_IsItem_Folder(archive, i, isFolder));
|
||||
bool isAltStream;
|
||||
RINOK(Archive_IsItem_AltStream(archive, i, isAltStream));
|
||||
if (!options.NtOptions.AltStreams.Val && isAltStream)
|
||||
continue;
|
||||
if (!wildcardCensor.CheckPath(isAltStream, filePath, !isFolder))
|
||||
continue;
|
||||
realIndices.Add(i);
|
||||
}
|
||||
|
||||
if (realIndices.Size() == 0)
|
||||
{
|
||||
callback->ThereAreNoFiles();
|
||||
return S_OK;
|
||||
return callback->ExtractResult(S_OK);
|
||||
}
|
||||
}
|
||||
|
||||
UStringVector removePathParts;
|
||||
if (elimIsPossible)
|
||||
outDir = outDirReduced;
|
||||
|
||||
FString outDir = options.OutputDir;
|
||||
outDir.Replace(FSTRING_ANY_MASK, us2fs(GetCorrectFsPath(arc.DefaultName)));
|
||||
#ifdef _WIN32
|
||||
// GetCorrectFullFsPath doesn't like "..".
|
||||
// outDir.TrimRight();
|
||||
// outDir = GetCorrectFullFsPath(outDir);
|
||||
#endif
|
||||
|
||||
if (!outDir.IsEmpty())
|
||||
if (!NFile::NDirectory::CreateComplexDirectory(outDir))
|
||||
if (outDir.IsEmpty())
|
||||
outDir = FString(FTEXT(".")) + FString(FSTRING_PATH_SEPARATOR);
|
||||
else
|
||||
if (!CreateComplexDir(outDir))
|
||||
{
|
||||
HRESULT res = ::GetLastError();
|
||||
if (res == S_OK)
|
||||
@@ -70,55 +135,92 @@ static HRESULT DecompressArchive(
|
||||
return res;
|
||||
}
|
||||
|
||||
extractCallbackSpec->Init(
|
||||
ecs->Init(
|
||||
options.NtOptions,
|
||||
options.StdInMode ? &wildcardCensor : NULL,
|
||||
&arc,
|
||||
callback,
|
||||
options.StdOutMode, options.TestMode, options.CalcCrc,
|
||||
options.StdOutMode, options.TestMode,
|
||||
outDir,
|
||||
removePathParts,
|
||||
packSize);
|
||||
|
||||
#if !defined(_7ZIP_ST) && !defined(_SFX)
|
||||
RINOK(SetProperties(archive, options.Properties));
|
||||
|
||||
#ifdef SUPPORT_LINKS
|
||||
|
||||
if (!options.StdInMode &&
|
||||
!options.TestMode &&
|
||||
options.NtOptions.HardLinks.Val)
|
||||
{
|
||||
RINOK(ecs->PrepareHardLinks(&realIndices));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
HRESULT result;
|
||||
Int32 testMode = (options.TestMode && !options.CalcCrc) ? 1: 0;
|
||||
Int32 testMode = (options.TestMode && !calcCrc) ? 1: 0;
|
||||
if (options.StdInMode)
|
||||
{
|
||||
result = archive->Extract(NULL, (UInt32)(Int32)-1, testMode, extractCallbackSpec);
|
||||
result = archive->Extract(NULL, (UInt32)(Int32)-1, testMode, ecs);
|
||||
NCOM::CPropVariant prop;
|
||||
if (archive->GetArchiveProperty(kpidPhySize, &prop) == S_OK)
|
||||
if (prop.vt == VT_UI8 || prop.vt == VT_UI4)
|
||||
stdInProcessed = ConvertPropVariantToUInt64(prop);
|
||||
ConvertPropVariantToUInt64(prop, stdInProcessed);
|
||||
}
|
||||
else
|
||||
result = archive->Extract(&realIndices.Front(), realIndices.Size(), testMode, extractCallbackSpec);
|
||||
|
||||
result = archive->Extract(&realIndices.Front(), realIndices.Size(), testMode, ecs);
|
||||
if (result == S_OK)
|
||||
result = ecs->SetDirsTimes();
|
||||
return callback->ExtractResult(result);
|
||||
}
|
||||
|
||||
HRESULT DecompressArchives(
|
||||
CCodecs *codecs, const CIntVector &formatIndices,
|
||||
/* v9.31: BUG was fixed:
|
||||
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)
|
||||
{
|
||||
unsigned left = 0, right = fileName.Size();
|
||||
while (left != right)
|
||||
{
|
||||
unsigned mid = (left + right) / 2;
|
||||
const UString &midValue = fileName[mid];
|
||||
int compare = CompareFileNames(name, midValue);
|
||||
if (compare == 0)
|
||||
return mid;
|
||||
if (compare < 0)
|
||||
right = mid;
|
||||
else
|
||||
left = mid + 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
HRESULT Extract(
|
||||
CCodecs *codecs,
|
||||
const CObjectVector<COpenType> &types,
|
||||
const CIntVector &excludedFormats,
|
||||
UStringVector &arcPaths, UStringVector &arcPathsFull,
|
||||
const NWildcard::CCensorNode &wildcardCensor,
|
||||
const CExtractOptions &options,
|
||||
IOpenCallbackUI *openCallback,
|
||||
IExtractCallbackUI *extractCallback,
|
||||
#ifndef _SFX
|
||||
IHashCalc *hash,
|
||||
#endif
|
||||
UString &errorMessage,
|
||||
CDecompressStat &stat)
|
||||
{
|
||||
stat.Clear();
|
||||
int i;
|
||||
UInt64 totalPackSize = 0;
|
||||
CRecordVector<UInt64> archiveSizes;
|
||||
CRecordVector<UInt64> arcSizes;
|
||||
|
||||
int numArcs = options.StdInMode ? 1 : arcPaths.Size();
|
||||
unsigned numArcs = options.StdInMode ? 1 : arcPaths.Size();
|
||||
|
||||
unsigned i;
|
||||
for (i = 0; i < numArcs; i++)
|
||||
{
|
||||
NFile::NFind::CFileInfo fi;
|
||||
NFind::CFileInfo fi;
|
||||
fi.Size = 0;
|
||||
if (!options.StdInMode)
|
||||
{
|
||||
@@ -128,21 +230,37 @@ HRESULT DecompressArchives(
|
||||
if (fi.IsDir())
|
||||
throw "can't decompress folder";
|
||||
}
|
||||
archiveSizes.Add(fi.Size);
|
||||
arcSizes.Add(fi.Size);
|
||||
totalPackSize += fi.Size;
|
||||
}
|
||||
CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
|
||||
CMyComPtr<IArchiveExtractCallback> ec(extractCallbackSpec);
|
||||
|
||||
CBoolArr skipArcs(numArcs);
|
||||
for (i = 0; i < numArcs; i++)
|
||||
skipArcs[i] = false;
|
||||
|
||||
CArchiveExtractCallback *ecs = new CArchiveExtractCallback;
|
||||
CMyComPtr<IArchiveExtractCallback> ec(ecs);
|
||||
bool multi = (numArcs > 1);
|
||||
extractCallbackSpec->InitForMulti(multi, options.PathMode, options.OverwriteMode);
|
||||
ecs->InitForMulti(multi, options.PathMode, options.OverwriteMode);
|
||||
#ifndef _SFX
|
||||
ecs->SetHashMethods(hash);
|
||||
#endif
|
||||
|
||||
if (multi)
|
||||
{
|
||||
RINOK(extractCallback->SetTotal(totalPackSize));
|
||||
}
|
||||
|
||||
UInt64 totalPackProcessed = 0;
|
||||
bool thereAreNotOpenArcs = false;
|
||||
|
||||
for (i = 0; i < numArcs; i++)
|
||||
{
|
||||
if (skipArcs[i])
|
||||
continue;
|
||||
|
||||
const UString &arcPath = arcPaths[i];
|
||||
NFile::NFind::CFileInfo fi;
|
||||
NFind::CFileInfo fi;
|
||||
if (options.StdInMode)
|
||||
{
|
||||
fi.Size = 0;
|
||||
@@ -159,16 +277,17 @@ HRESULT DecompressArchives(
|
||||
#endif
|
||||
|
||||
RINOK(extractCallback->BeforeOpen(arcPath));
|
||||
CArchiveLink archiveLink;
|
||||
CArchiveLink arcLink;
|
||||
|
||||
CIntVector formatIndices2 = formatIndices;
|
||||
CObjectVector<COpenType> types2 = types;
|
||||
/*
|
||||
#ifndef _SFX
|
||||
if (formatIndices.IsEmpty())
|
||||
if (types.IsEmpty())
|
||||
{
|
||||
int pos = arcPath.ReverseFind(L'.');
|
||||
if (pos >= 0)
|
||||
{
|
||||
UString s = arcPath.Mid(pos + 1);
|
||||
UString s = arcPath.Ptr(pos + 1);
|
||||
int index = codecs->FindFormatForExtension(s);
|
||||
if (index >= 0 && s == L"001")
|
||||
{
|
||||
@@ -176,18 +295,31 @@ HRESULT DecompressArchives(
|
||||
pos = s.ReverseFind(L'.');
|
||||
if (pos >= 0)
|
||||
{
|
||||
int index2 = codecs->FindFormatForExtension(s.Mid(pos + 1));
|
||||
if (index2 >= 0 && s.CompareNoCase(L"rar") != 0)
|
||||
int index2 = codecs->FindFormatForExtension(s.Ptr(pos + 1));
|
||||
if (index2 >= 0) // && s.CompareNoCase(L"rar") != 0
|
||||
{
|
||||
formatIndices2.Add(index2);
|
||||
formatIndices2.Add(index);
|
||||
types2.Add(index2);
|
||||
types2.Add(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
HRESULT result = archiveLink.Open2(codecs, formatIndices2, options.StdInMode, NULL, arcPath, openCallback);
|
||||
*/
|
||||
|
||||
COpenOptions op;
|
||||
#ifndef _SFX
|
||||
op.props = &options.Properties;
|
||||
#endif
|
||||
op.codecs = codecs;
|
||||
op.types = &types2;
|
||||
op.excludedFormats = &excludedFormats;
|
||||
op.stdInMode = options.StdInMode;
|
||||
op.stream = NULL;
|
||||
op.filePath = arcPath;
|
||||
HRESULT result = arcLink.Open2(op, openCallback);
|
||||
|
||||
if (result == E_ABORT)
|
||||
return result;
|
||||
|
||||
@@ -196,68 +328,148 @@ HRESULT DecompressArchives(
|
||||
crypted = openCallback->Open_WasPasswordAsked();
|
||||
#endif
|
||||
|
||||
RINOK(extractCallback->OpenResult(arcPath, result, crypted));
|
||||
if (result != S_OK)
|
||||
continue;
|
||||
if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0)
|
||||
result = S_FALSE;
|
||||
|
||||
// arcLink.Set_ErrorsText();
|
||||
RINOK(extractCallback->OpenResult(arcPath, result, crypted));
|
||||
|
||||
|
||||
if (!options.StdInMode)
|
||||
for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)
|
||||
{
|
||||
int index = arcPathsFull.FindInSorted(archiveLink.VolumePaths[v]);
|
||||
if (index >= 0 && index > i)
|
||||
FOR_VECTOR (r, arcLink.Arcs)
|
||||
{
|
||||
arcPaths.Delete(index);
|
||||
arcPathsFull.Delete(index);
|
||||
totalPackSize -= archiveSizes[index];
|
||||
archiveSizes.Delete(index);
|
||||
numArcs = arcPaths.Size();
|
||||
const CArc &arc = arcLink.Arcs[r];
|
||||
const CArcErrorInfo &er = arc.ErrorInfo;
|
||||
if (er.IsThereErrorOrWarning())
|
||||
{
|
||||
RINOK(extractCallback->SetError(r, arc.Path,
|
||||
er.GetErrorFlags(), er.ErrorMessage,
|
||||
er.GetWarningFlags(), er.WarningMessage));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (archiveLink.VolumePaths.Size() != 0)
|
||||
|
||||
if (result != S_OK)
|
||||
{
|
||||
totalPackSize += archiveLink.VolumesSize;
|
||||
RINOK(extractCallback->SetTotal(totalPackSize));
|
||||
thereAreNotOpenArcs = true;
|
||||
if (!options.StdInMode)
|
||||
{
|
||||
NFind::CFileInfo fi;
|
||||
if (fi.Find(us2fs(arcPath)))
|
||||
if (!fi.IsDir())
|
||||
totalPackProcessed += fi.Size;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!options.StdInMode)
|
||||
{
|
||||
// numVolumes += arcLink.VolumePaths.Size();
|
||||
// arcLink.VolumesSize;
|
||||
|
||||
// totalPackSize -= DeleteUsedFileNamesFromList(arcLink, i + 1, arcPaths, arcPathsFull, &arcSizes);
|
||||
// numArcs = arcPaths.Size();
|
||||
if (arcLink.VolumePaths.Size() != 0)
|
||||
{
|
||||
Int64 correctionSize = arcLink.VolumesSize;
|
||||
FOR_VECTOR (v, arcLink.VolumePaths)
|
||||
{
|
||||
int index = Find_FileName_InSortedVector(arcPathsFull, arcLink.VolumePaths[v]);
|
||||
if (index >= 0)
|
||||
{
|
||||
if ((unsigned)index > i)
|
||||
{
|
||||
skipArcs[index] = true;
|
||||
correctionSize -= arcSizes[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (correctionSize != 0)
|
||||
{
|
||||
Int64 newPackSize = (Int64)totalPackSize + correctionSize;
|
||||
if (newPackSize < 0)
|
||||
newPackSize = 0;
|
||||
totalPackSize = newPackSize;
|
||||
RINOK(extractCallback->SetTotal(totalPackSize));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
bool passwordIsDefined;
|
||||
UString password;
|
||||
RINOK(openCallback->Open_GetPasswordIfAny(password));
|
||||
if (!password.IsEmpty())
|
||||
RINOK(openCallback->Open_GetPasswordIfAny(passwordIsDefined, password));
|
||||
if (passwordIsDefined)
|
||||
{
|
||||
RINOK(extractCallback->SetPassword(password));
|
||||
}
|
||||
#endif
|
||||
|
||||
for (int v = 0; v < archiveLink.Arcs.Size(); v++)
|
||||
FOR_VECTOR (k, arcLink.Arcs)
|
||||
{
|
||||
const UString &s = archiveLink.Arcs[v].ErrorMessage;
|
||||
if (!s.IsEmpty())
|
||||
const CArc &arc = arcLink.Arcs[k];
|
||||
const CArcErrorInfo &er = arc.ErrorInfo;
|
||||
|
||||
if (er.ErrorFormatIndex >= 0)
|
||||
{
|
||||
RINOK(extractCallback->OpenTypeWarning(arc.Path,
|
||||
codecs->GetFormatNamePtr(arc.FormatIndex),
|
||||
codecs->GetFormatNamePtr(er.ErrorFormatIndex)))
|
||||
/*
|
||||
UString s = L"Can not open the file as [" + codecs->Formats[arc.ErrorFormatIndex].Name + L"] archive\n";
|
||||
s += L"The file is open as [" + codecs->Formats[arc.FormatIndex].Name + L"] archive";
|
||||
RINOK(extractCallback->MessageError(s));
|
||||
*/
|
||||
}
|
||||
{
|
||||
const UString &s = er.ErrorMessage;
|
||||
if (!s.IsEmpty())
|
||||
{
|
||||
RINOK(extractCallback->MessageError(s));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CArc &arc = archiveLink.Arcs.Back();
|
||||
CArc &arc = arcLink.Arcs.Back();
|
||||
arc.MTimeDefined = (!options.StdInMode && !fi.IsDevice);
|
||||
arc.MTime = fi.MTime;
|
||||
|
||||
UInt64 packProcessed;
|
||||
RINOK(DecompressArchive(arc,
|
||||
fi.Size + archiveLink.VolumesSize,
|
||||
wildcardCensor, options, extractCallback, extractCallbackSpec, errorMessage, packProcessed));
|
||||
bool calcCrc =
|
||||
#ifndef _SFX
|
||||
(hash != NULL);
|
||||
#else
|
||||
false;
|
||||
#endif
|
||||
|
||||
RINOK(DecompressArchive(
|
||||
codecs,
|
||||
arcLink,
|
||||
fi.Size + arcLink.VolumesSize,
|
||||
wildcardCensor,
|
||||
options,
|
||||
calcCrc,
|
||||
extractCallback, ecs, errorMessage, packProcessed));
|
||||
if (!options.StdInMode)
|
||||
packProcessed = fi.Size + archiveLink.VolumesSize;
|
||||
extractCallbackSpec->LocalProgressSpec->InSize += packProcessed;
|
||||
extractCallbackSpec->LocalProgressSpec->OutSize = extractCallbackSpec->UnpackSize;
|
||||
packProcessed = fi.Size + arcLink.VolumesSize;
|
||||
totalPackProcessed += packProcessed;
|
||||
ecs->LocalProgressSpec->InSize += packProcessed;
|
||||
ecs->LocalProgressSpec->OutSize = ecs->UnpackSize;
|
||||
if (!errorMessage.IsEmpty())
|
||||
return E_FAIL;
|
||||
}
|
||||
stat.NumFolders = extractCallbackSpec->NumFolders;
|
||||
stat.NumFiles = extractCallbackSpec->NumFiles;
|
||||
stat.UnpackSize = extractCallbackSpec->UnpackSize;
|
||||
stat.CrcSum = extractCallbackSpec->CrcSum;
|
||||
|
||||
if (multi || thereAreNotOpenArcs)
|
||||
{
|
||||
RINOK(extractCallback->SetTotal(totalPackSize));
|
||||
RINOK(extractCallback->SetCompleted(&totalPackProcessed));
|
||||
}
|
||||
stat.NumFolders = ecs->NumFolders;
|
||||
stat.NumFiles = ecs->NumFiles;
|
||||
stat.NumAltStreams = ecs->NumAltStreams;
|
||||
stat.UnpackSize = ecs->UnpackSize;
|
||||
stat.AltStreams_UnpackSize = ecs->AltStreams_UnpackSize;
|
||||
stat.NumArchives = arcPaths.Size();
|
||||
stat.PackSize = extractCallbackSpec->LocalProgressSpec->InSize;
|
||||
stat.PackSize = ecs->LocalProgressSpec->InSize;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
52
CPP/7zip/UI/Common/Extract.h
Executable file → Normal file
52
CPP/7zip/UI/Common/Extract.h
Executable file → Normal file
@@ -3,7 +3,7 @@
|
||||
#ifndef __EXTRACT_H
|
||||
#define __EXTRACT_H
|
||||
|
||||
#include "Windows/FileFind.h"
|
||||
#include "../../../Windows/FileFind.h"
|
||||
|
||||
#include "../../Archive/IArchive.h"
|
||||
|
||||
@@ -14,21 +14,37 @@
|
||||
|
||||
#include "../Common/LoadCodecs.h"
|
||||
|
||||
struct CExtractOptions
|
||||
struct CExtractOptionsBase
|
||||
{
|
||||
CBoolPair ElimDup;
|
||||
|
||||
bool PathMode_Force;
|
||||
bool OverwriteMode_Force;
|
||||
NExtract::NPathMode::EEnum PathMode;
|
||||
NExtract::NOverwriteMode::EEnum OverwriteMode;
|
||||
|
||||
FString OutputDir;
|
||||
CExtractNtOptions NtOptions;
|
||||
|
||||
CExtractOptionsBase():
|
||||
PathMode_Force(false),
|
||||
OverwriteMode_Force(false),
|
||||
PathMode(NExtract::NPathMode::kFullPaths),
|
||||
OverwriteMode(NExtract::NOverwriteMode::kAsk)
|
||||
{}
|
||||
};
|
||||
|
||||
struct CExtractOptions: public CExtractOptionsBase
|
||||
{
|
||||
bool StdInMode;
|
||||
bool StdOutMode;
|
||||
bool YesToAll;
|
||||
bool TestMode;
|
||||
bool CalcCrc;
|
||||
NExtract::NPathMode::EEnum PathMode;
|
||||
NExtract::NOverwriteMode::EEnum OverwriteMode;
|
||||
FString OutputDir;
|
||||
|
||||
// bool ShowDialog;
|
||||
// bool PasswordEnabled;
|
||||
// UString Password;
|
||||
#if !defined(_7ZIP_ST) && !defined(_SFX)
|
||||
#ifndef _SFX
|
||||
CObjectVector<CProperty> Properties;
|
||||
#endif
|
||||
|
||||
@@ -37,13 +53,10 @@ struct CExtractOptions
|
||||
#endif
|
||||
|
||||
CExtractOptions():
|
||||
TestMode(false),
|
||||
StdInMode(false),
|
||||
StdOutMode(false),
|
||||
YesToAll(false),
|
||||
TestMode(false),
|
||||
CalcCrc(false),
|
||||
PathMode(NExtract::NPathMode::kFullPathnames),
|
||||
OverwriteMode(NExtract::NOverwriteMode::kAskBefore)
|
||||
YesToAll(false)
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -51,25 +64,30 @@ struct CDecompressStat
|
||||
{
|
||||
UInt64 NumArchives;
|
||||
UInt64 UnpackSize;
|
||||
UInt64 AltStreams_UnpackSize;
|
||||
UInt64 PackSize;
|
||||
UInt64 NumFolders;
|
||||
UInt64 NumFiles;
|
||||
UInt32 CrcSum;
|
||||
UInt64 NumAltStreams;
|
||||
|
||||
void Clear()
|
||||
{
|
||||
NumArchives = UnpackSize = PackSize = NumFolders = NumFiles = 0;
|
||||
CrcSum = 0;
|
||||
NumArchives = UnpackSize = AltStreams_UnpackSize = PackSize = NumFolders = NumFiles = NumAltStreams = 0;
|
||||
}
|
||||
};
|
||||
|
||||
HRESULT DecompressArchives(
|
||||
CCodecs *codecs, const CIntVector &formatIndices,
|
||||
HRESULT Extract(
|
||||
CCodecs *codecs,
|
||||
const CObjectVector<COpenType> &types,
|
||||
const CIntVector &excludedFormats,
|
||||
UStringVector &archivePaths, UStringVector &archivePathsFull,
|
||||
const NWildcard::CCensorNode &wildcardCensor,
|
||||
const CExtractOptions &options,
|
||||
IOpenCallbackUI *openCallback,
|
||||
IExtractCallbackUI *extractCallback,
|
||||
#ifndef _SFX
|
||||
IHashCalc *hash,
|
||||
#endif
|
||||
UString &errorMessage,
|
||||
CDecompressStat &stat);
|
||||
|
||||
|
||||
40
CPP/7zip/UI/Common/ExtractMode.h
Executable file → Normal file
40
CPP/7zip/UI/Common/ExtractMode.h
Executable file → Normal file
@@ -5,27 +5,29 @@
|
||||
|
||||
namespace NExtract {
|
||||
|
||||
namespace NPathMode
|
||||
namespace NPathMode
|
||||
{
|
||||
enum EEnum
|
||||
{
|
||||
enum EEnum
|
||||
{
|
||||
kFullPathnames,
|
||||
kCurrentPathnames,
|
||||
kNoPathnames
|
||||
};
|
||||
}
|
||||
|
||||
namespace NOverwriteMode
|
||||
kFullPaths,
|
||||
kCurPaths,
|
||||
kNoPaths,
|
||||
kAbsPaths
|
||||
};
|
||||
}
|
||||
|
||||
namespace NOverwriteMode
|
||||
{
|
||||
enum EEnum
|
||||
{
|
||||
enum EEnum
|
||||
{
|
||||
kAskBefore,
|
||||
kWithoutPrompt,
|
||||
kSkipExisting,
|
||||
kAutoRename,
|
||||
kAutoRenameExisting
|
||||
};
|
||||
}
|
||||
kAsk,
|
||||
kOverwrite,
|
||||
kSkip,
|
||||
kRename,
|
||||
kRenameExisting
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
110
CPP/7zip/UI/Common/ExtractingFilePath.cpp
Executable file → Normal file
110
CPP/7zip/UI/Common/ExtractingFilePath.cpp
Executable file → Normal file
@@ -2,26 +2,44 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../../C/Types.h"
|
||||
#include "../../../Common/Wildcard.h"
|
||||
|
||||
#include "Common/Wildcard.h"
|
||||
#include "../../../Windows/FileName.h"
|
||||
|
||||
#include "ExtractingFilePath.h"
|
||||
|
||||
static UString ReplaceIncorrectChars(const UString &s)
|
||||
static UString ReplaceIncorrectChars(const UString &s, bool repaceColon)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
UString res;
|
||||
for (int i = 0; i < s.Length(); i++)
|
||||
bool beforeColon = true;
|
||||
{
|
||||
wchar_t c = s[i];
|
||||
if (c < 0x20 || c == '*' || c == '?' || c == '<' || c == '>' || c == '|' || c == ':' || c == '"')
|
||||
c = '_';
|
||||
res += c;
|
||||
for (unsigned i = 0; i < s.Len(); i++)
|
||||
{
|
||||
wchar_t c = s[i];
|
||||
if (beforeColon)
|
||||
if (c == '*' || c == '?' || c < 0x20 || c == '<' || c == '>' || c == '|' || c == '"')
|
||||
c = '_';
|
||||
if (c == ':')
|
||||
{
|
||||
if (repaceColon)
|
||||
c = '_';
|
||||
else
|
||||
beforeColon = false;
|
||||
}
|
||||
res += c;
|
||||
}
|
||||
}
|
||||
if (beforeColon)
|
||||
{
|
||||
for (int i = res.Len() - 1; i >= 0; i--)
|
||||
{
|
||||
wchar_t c = res[i];
|
||||
if (c != '.' && c != ' ')
|
||||
break;
|
||||
res.ReplaceOneCharAtPos(i, '_');
|
||||
}
|
||||
}
|
||||
res.TrimRight();
|
||||
while (!res.IsEmpty() && res.Back() == '.')
|
||||
res.DeleteBack();
|
||||
return res;
|
||||
#else
|
||||
return s;
|
||||
@@ -29,27 +47,28 @@ static UString ReplaceIncorrectChars(const UString &s)
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
static const wchar_t *g_ReservedNames[] =
|
||||
{
|
||||
L"CON", L"PRN", L"AUX", L"NUL"
|
||||
};
|
||||
|
||||
static bool CheckTail(const UString &name, int len)
|
||||
static bool CheckTail(const UString &name, unsigned len)
|
||||
{
|
||||
int dotPos = name.Find(L'.');
|
||||
if (dotPos < 0)
|
||||
dotPos = name.Length();
|
||||
dotPos = name.Len();
|
||||
UString s = name.Left(dotPos);
|
||||
s.TrimRight();
|
||||
return (s.Length() != len);
|
||||
return s.Len() != len;
|
||||
}
|
||||
|
||||
static bool CheckNameNum(const UString &name, const wchar_t *reservedName)
|
||||
{
|
||||
int len = MyStringLen(reservedName);
|
||||
if (name.Length() <= len)
|
||||
unsigned len = MyStringLen(reservedName);
|
||||
if (name.Len() <= len)
|
||||
return true;
|
||||
if (name.Left(len).CompareNoCase(reservedName) != 0)
|
||||
if (MyStringCompareNoCase_N(name, reservedName, len) != 0)
|
||||
return true;
|
||||
wchar_t c = name[len];
|
||||
if (c < L'0' || c > L'9')
|
||||
@@ -59,13 +78,13 @@ static bool CheckNameNum(const UString &name, const wchar_t *reservedName)
|
||||
|
||||
static bool IsSupportedName(const UString &name)
|
||||
{
|
||||
for (int i = 0; i < sizeof(g_ReservedNames) / sizeof(g_ReservedNames[0]); i++)
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(g_ReservedNames); i++)
|
||||
{
|
||||
const wchar_t *reservedName = g_ReservedNames[i];
|
||||
int len = MyStringLen(reservedName);
|
||||
if (name.Length() < len)
|
||||
unsigned len = MyStringLen(reservedName);
|
||||
if (name.Len() < len)
|
||||
continue;
|
||||
if (name.Left(len).CompareNoCase(reservedName) != 0)
|
||||
if (MyStringCompareNoCase_N(name, reservedName, len) != 0)
|
||||
continue;
|
||||
if (!CheckTail(name, len))
|
||||
return false;
|
||||
@@ -74,21 +93,34 @@ static bool IsSupportedName(const UString &name)
|
||||
return false;
|
||||
return CheckNameNum(name, L"LPT");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static UString GetCorrectFileName(const UString &path)
|
||||
static UString GetCorrectFileName(const UString &path, bool repaceColon)
|
||||
{
|
||||
if (path == L".." || path == L".")
|
||||
return UString();
|
||||
return ReplaceIncorrectChars(path);
|
||||
return ReplaceIncorrectChars(path, repaceColon);
|
||||
}
|
||||
|
||||
void MakeCorrectPath(UStringVector &pathParts)
|
||||
void MakeCorrectPath(bool isPathFromRoot, UStringVector &pathParts, bool replaceAltStreamColon)
|
||||
{
|
||||
for (int i = 0; i < pathParts.Size();)
|
||||
for (unsigned i = 0; i < pathParts.Size();)
|
||||
{
|
||||
UString &s = pathParts[i];
|
||||
s = GetCorrectFileName(s);
|
||||
#ifdef _WIN32
|
||||
bool needReplaceColon = (replaceAltStreamColon || i != pathParts.Size() - 1);
|
||||
if (i == 0 && isPathFromRoot && NWindows::NFile::NName::IsDrivePath(s))
|
||||
{
|
||||
UString s2 = s[0];
|
||||
s2 += L'_';
|
||||
s2 += GetCorrectFileName(s.Ptr(2), needReplaceColon);
|
||||
s = s2;
|
||||
}
|
||||
else
|
||||
s = GetCorrectFileName(s, needReplaceColon);
|
||||
#endif
|
||||
|
||||
if (s.IsEmpty())
|
||||
pathParts.Delete(i);
|
||||
else
|
||||
@@ -105,7 +137,7 @@ void MakeCorrectPath(UStringVector &pathParts)
|
||||
UString MakePathNameFromParts(const UStringVector &parts)
|
||||
{
|
||||
UString result;
|
||||
for (int i = 0; i < parts.Size(); i++)
|
||||
FOR_VECTOR (i, parts)
|
||||
{
|
||||
if (i != 0)
|
||||
result += WCHAR_PATH_SEPARATOR;
|
||||
@@ -114,13 +146,29 @@ UString MakePathNameFromParts(const UStringVector &parts)
|
||||
return result;
|
||||
}
|
||||
|
||||
static const wchar_t *k_EmptyReplaceName = L"[]";
|
||||
|
||||
void Correct_IfEmptyLastPart(UStringVector &parts)
|
||||
{
|
||||
if (parts.IsEmpty())
|
||||
parts.Add(k_EmptyReplaceName);
|
||||
else
|
||||
{
|
||||
UString &s = parts.Back();
|
||||
if (s.IsEmpty())
|
||||
s = k_EmptyReplaceName;
|
||||
}
|
||||
}
|
||||
|
||||
UString GetCorrectFsPath(const UString &path)
|
||||
{
|
||||
UString res = GetCorrectFileName(path);
|
||||
UString res = GetCorrectFileName(path, true);
|
||||
#ifdef _WIN32
|
||||
if (!IsSupportedName(res))
|
||||
res = (UString)L"_" + res;
|
||||
#endif
|
||||
if (res.IsEmpty())
|
||||
res = k_EmptyReplaceName;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -128,14 +176,14 @@ UString GetCorrectFullFsPath(const UString &path)
|
||||
{
|
||||
UStringVector parts;
|
||||
SplitPathToParts(path, parts);
|
||||
for (int i = 0; i < parts.Size(); i++)
|
||||
FOR_VECTOR (i, parts)
|
||||
{
|
||||
UString &s = parts[i];
|
||||
#ifdef _WIN32
|
||||
while (!s.IsEmpty() && s.Back() == '.')
|
||||
while (!s.IsEmpty() && (s.Back() == '.' || s.Back() == ' '))
|
||||
s.DeleteBack();
|
||||
if (!IsSupportedName(s))
|
||||
s = (UString)L"_" + s;
|
||||
s.InsertAtFront(L'_');
|
||||
#endif
|
||||
}
|
||||
return MakePathNameFromParts(parts);
|
||||
|
||||
12
CPP/7zip/UI/Common/ExtractingFilePath.h
Executable file → Normal file
12
CPP/7zip/UI/Common/ExtractingFilePath.h
Executable file → Normal file
@@ -3,11 +3,19 @@
|
||||
#ifndef __EXTRACTING_FILE_PATH_H
|
||||
#define __EXTRACTING_FILE_PATH_H
|
||||
|
||||
#include "Common/MyString.h"
|
||||
#include "../../../Common/MyString.h"
|
||||
|
||||
UString MakePathNameFromParts(const UStringVector &parts);
|
||||
void MakeCorrectPath(UStringVector &pathParts);
|
||||
|
||||
/* for WIN32:
|
||||
if (isRoot == true), and pathParts[0] contains path like "c:name",
|
||||
it thinks that "c:" is drive prefix (it's not ":name alt stream) and
|
||||
the function changes part to c_name */
|
||||
void MakeCorrectPath(bool isPathFromRoot, UStringVector &pathParts, bool replaceAltStreamColon);
|
||||
|
||||
UString GetCorrectFsPath(const UString &path);
|
||||
UString GetCorrectFullFsPath(const UString &path);
|
||||
|
||||
void Correct_IfEmptyLastPart(UStringVector &parts);
|
||||
|
||||
#endif
|
||||
|
||||
361
CPP/7zip/UI/Common/HashCalc.cpp
Normal file
361
CPP/7zip/UI/Common/HashCalc.cpp
Normal file
@@ -0,0 +1,361 @@
|
||||
// HashCalc.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../../C/Alloc.h"
|
||||
|
||||
#include "../../../Common/StringToInt.h"
|
||||
|
||||
#include "../../Common/FileStreams.h"
|
||||
#include "../../Common/StreamUtils.h"
|
||||
|
||||
#include "EnumDirItems.h"
|
||||
#include "HashCalc.h"
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
class CHashMidBuf
|
||||
{
|
||||
void *_data;
|
||||
public:
|
||||
CHashMidBuf(): _data(0) {}
|
||||
operator void *() { return _data; }
|
||||
bool Alloc(size_t size)
|
||||
{
|
||||
if (_data != 0)
|
||||
return false;
|
||||
_data = ::MidAlloc(size);
|
||||
return _data != 0;
|
||||
}
|
||||
~CHashMidBuf() { ::MidFree(_data); }
|
||||
};
|
||||
|
||||
struct CEnumDirItemCallback_Hash: public IEnumDirItemCallback
|
||||
{
|
||||
IHashCallbackUI *Callback;
|
||||
|
||||
HRESULT ScanProgress(UInt64 numFolders, UInt64 numFiles, UInt64 totalSize, const wchar_t *path, bool isDir)
|
||||
{
|
||||
return Callback->ScanProgress(numFolders, numFiles, totalSize, path, isDir);
|
||||
}
|
||||
};
|
||||
|
||||
static const wchar_t *k_DefaultHashMethod = L"CRC32";
|
||||
|
||||
HRESULT CHashBundle::SetMethods(DECL_EXTERNAL_CODECS_LOC_VARS const UStringVector &hashMethods)
|
||||
{
|
||||
UStringVector names = hashMethods;
|
||||
if (names.IsEmpty())
|
||||
names.Add(k_DefaultHashMethod);
|
||||
|
||||
CRecordVector<CMethodId> ids;
|
||||
CObjectVector<COneMethodInfo> methods;
|
||||
|
||||
unsigned i;
|
||||
for (i = 0; i < names.Size(); i++)
|
||||
{
|
||||
COneMethodInfo m;
|
||||
RINOK(m.ParseMethodFromString(names[i]));
|
||||
|
||||
if (m.MethodName.IsEmpty())
|
||||
m.MethodName = k_DefaultHashMethod;
|
||||
|
||||
if (m.MethodName == L"*")
|
||||
{
|
||||
CRecordVector<CMethodId> tempMethods;
|
||||
GetHashMethods(EXTERNAL_CODECS_LOC_VARS tempMethods);
|
||||
methods.Clear();
|
||||
ids.Clear();
|
||||
FOR_VECTOR (t, tempMethods)
|
||||
{
|
||||
int index = ids.AddToUniqueSorted(tempMethods[t]);
|
||||
if (ids.Size() != methods.Size())
|
||||
methods.Insert(index, m);
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// m.MethodName.RemoveChar(L'-');
|
||||
CMethodId id;
|
||||
if (!FindHashMethod(EXTERNAL_CODECS_LOC_VARS m.MethodName, id))
|
||||
return E_NOTIMPL;
|
||||
int index = ids.AddToUniqueSorted(id);
|
||||
if (ids.Size() != methods.Size())
|
||||
methods.Insert(index, m);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ids.Size(); i++)
|
||||
{
|
||||
CMyComPtr<IHasher> hasher;
|
||||
UString name;
|
||||
RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS ids[i], name, hasher));
|
||||
if (!hasher)
|
||||
throw "Can't create hasher";
|
||||
const COneMethodInfo &m = methods[i];
|
||||
{
|
||||
CMyComPtr<ICompressSetCoderProperties> scp;
|
||||
hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp);
|
||||
if (scp)
|
||||
{
|
||||
RINOK(m.SetCoderProps(scp, NULL));
|
||||
}
|
||||
}
|
||||
UInt32 digestSize = hasher->GetDigestSize();
|
||||
if (digestSize > k_HashCalc_DigestSize_Max)
|
||||
return E_NOTIMPL;
|
||||
CHasherState &h = Hashers.AddNew();
|
||||
h.Hasher = hasher;
|
||||
h.Name = name;
|
||||
h.DigestSize = digestSize;
|
||||
for (int i = 0; i < k_HashCalc_NumGroups; i++)
|
||||
memset(h.Digests[i], 0, digestSize);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CHashBundle::InitForNewFile()
|
||||
{
|
||||
CurSize = 0;
|
||||
FOR_VECTOR (i, Hashers)
|
||||
{
|
||||
CHasherState &h = Hashers[i];
|
||||
h.Hasher->Init();
|
||||
memset(h.Digests[k_HashCalc_Index_Current], 0, h.DigestSize);
|
||||
}
|
||||
}
|
||||
|
||||
void CHashBundle::Update(const void *data, UInt32 size)
|
||||
{
|
||||
CurSize += size;
|
||||
FOR_VECTOR (i, Hashers)
|
||||
Hashers[i].Hasher->Update(data, size);
|
||||
}
|
||||
|
||||
void CHashBundle::SetSize(UInt64 size)
|
||||
{
|
||||
CurSize = size;
|
||||
}
|
||||
|
||||
static void AddDigests(Byte *dest, const Byte *src, UInt32 size)
|
||||
{
|
||||
unsigned next = 0;
|
||||
for (UInt32 i = 0; i < size; i++)
|
||||
{
|
||||
next += (unsigned)dest[i] + (unsigned)src[i];
|
||||
dest[i] = (Byte)next;
|
||||
next >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
void CHashBundle::Final(bool isDir, bool isAltStream, const UString &path)
|
||||
{
|
||||
if (isDir)
|
||||
NumDirs++;
|
||||
else if (isAltStream)
|
||||
{
|
||||
NumAltStreams++;
|
||||
AltStreamsSize += CurSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
NumFiles++;
|
||||
FilesSize += CurSize;
|
||||
}
|
||||
|
||||
Byte pre[16];
|
||||
memset(pre, 0, sizeof(pre));
|
||||
if (isDir)
|
||||
pre[0] = 1;
|
||||
|
||||
FOR_VECTOR (i, Hashers)
|
||||
{
|
||||
CHasherState &h = Hashers[i];
|
||||
if (!isDir)
|
||||
{
|
||||
h.Hasher->Final(h.Digests[0]);
|
||||
if (!isAltStream)
|
||||
AddDigests(h.Digests[k_HashCalc_Index_DataSum], h.Digests[0], h.DigestSize);
|
||||
}
|
||||
|
||||
h.Hasher->Init();
|
||||
h.Hasher->Update(pre, sizeof(pre));
|
||||
h.Hasher->Update(h.Digests[0], h.DigestSize);
|
||||
|
||||
for (unsigned k = 0; k < path.Len(); k++)
|
||||
{
|
||||
wchar_t c = path[k];
|
||||
Byte temp[2] = { (Byte)(c & 0xFF), (Byte)((c >> 8) & 0xFF) };
|
||||
h.Hasher->Update(temp, 2);
|
||||
}
|
||||
|
||||
Byte tempDigest[k_HashCalc_DigestSize_Max];
|
||||
h.Hasher->Final(tempDigest);
|
||||
if (!isAltStream)
|
||||
AddDigests(h.Digests[k_HashCalc_Index_NamesSum], tempDigest, h.DigestSize);
|
||||
AddDigests(h.Digests[k_HashCalc_Index_StreamsSum], tempDigest, h.DigestSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HRESULT HashCalc(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
const NWildcard::CCensor &censor,
|
||||
const CHashOptions &options,
|
||||
UString &errorInfo,
|
||||
IHashCallbackUI *callback)
|
||||
{
|
||||
CDirItems dirItems;
|
||||
|
||||
UInt64 numErrors = 0;
|
||||
UInt64 totalBytes = 0;
|
||||
if (options.StdInMode)
|
||||
{
|
||||
CDirItem di;
|
||||
di.Size = (UInt64)(Int64)-1;
|
||||
di.Attrib = 0;
|
||||
di.MTime.dwLowDateTime = 0;
|
||||
di.MTime.dwHighDateTime = 0;
|
||||
di.CTime = di.ATime = di.MTime;
|
||||
dirItems.Items.Add(di);
|
||||
}
|
||||
else
|
||||
{
|
||||
CEnumDirItemCallback_Hash enumCallback;
|
||||
enumCallback.Callback = callback;
|
||||
RINOK(callback->StartScanning());
|
||||
dirItems.ScanAltStreams = options.AltStreamsMode;
|
||||
HRESULT res = EnumerateItems(censor,
|
||||
options.PathMode,
|
||||
UString(),
|
||||
dirItems, &enumCallback);
|
||||
totalBytes = dirItems.TotalSize;
|
||||
FOR_VECTOR (i, dirItems.ErrorPaths)
|
||||
{
|
||||
RINOK(callback->CanNotFindError(fs2us(dirItems.ErrorPaths[i]), dirItems.ErrorCodes[i]));
|
||||
}
|
||||
numErrors = dirItems.ErrorPaths.Size();
|
||||
if (res != S_OK)
|
||||
{
|
||||
if (res != E_ABORT)
|
||||
errorInfo = L"Scanning error";
|
||||
return res;
|
||||
}
|
||||
RINOK(callback->FinishScanning());
|
||||
}
|
||||
|
||||
unsigned i;
|
||||
CHashBundle hb;
|
||||
RINOK(hb.SetMethods(EXTERNAL_CODECS_LOC_VARS options.Methods));
|
||||
hb.Init();
|
||||
hb.NumErrors = numErrors;
|
||||
|
||||
if (options.StdInMode)
|
||||
{
|
||||
RINOK(callback->SetNumFiles(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(callback->SetTotal(totalBytes));
|
||||
}
|
||||
|
||||
const UInt32 kBufSize = 1 << 15;
|
||||
CHashMidBuf buf;
|
||||
if (!buf.Alloc(kBufSize))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
UInt64 completeValue = 0;
|
||||
|
||||
RINOK(callback->BeforeFirstFile(hb));
|
||||
|
||||
for (i = 0; i < dirItems.Items.Size(); i++)
|
||||
{
|
||||
CMyComPtr<ISequentialInStream> inStream;
|
||||
UString path;
|
||||
bool isDir = false;
|
||||
bool isAltStream = false;
|
||||
if (options.StdInMode)
|
||||
{
|
||||
inStream = new CStdInFileStream;
|
||||
}
|
||||
else
|
||||
{
|
||||
CInFileStream *inStreamSpec = new CInFileStream;
|
||||
inStream = inStreamSpec;
|
||||
const CDirItem &dirItem = dirItems.Items[i];
|
||||
isDir = dirItem.IsDir();
|
||||
isAltStream = dirItem.IsAltStream;
|
||||
path = dirItems.GetLogPath(i);
|
||||
if (!isDir)
|
||||
{
|
||||
UString phyPath = dirItems.GetPhyPath(i);
|
||||
if (!inStreamSpec->OpenShared(us2fs(phyPath), options.OpenShareForWrite))
|
||||
{
|
||||
HRESULT res = callback->OpenFileError(phyPath, ::GetLastError());
|
||||
hb.NumErrors++;
|
||||
if (res != S_FALSE)
|
||||
return res;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
RINOK(callback->GetStream(path, isDir));
|
||||
UInt64 fileSize = 0;
|
||||
|
||||
hb.InitForNewFile();
|
||||
if (!isDir)
|
||||
{
|
||||
for (UInt32 step = 0;; step++)
|
||||
{
|
||||
if ((step & 0xFF) == 0)
|
||||
RINOK(callback->SetCompleted(&completeValue));
|
||||
UInt32 size;
|
||||
RINOK(inStream->Read(buf, kBufSize, &size));
|
||||
if (size == 0)
|
||||
break;
|
||||
hb.Update(buf, size);
|
||||
fileSize += size;
|
||||
completeValue += size;
|
||||
}
|
||||
}
|
||||
hb.Final(isDir, isAltStream, path);
|
||||
RINOK(callback->SetOperationResult(fileSize, hb, !isDir));
|
||||
RINOK(callback->SetCompleted(&completeValue));
|
||||
}
|
||||
return callback->AfterLastFile(hb);
|
||||
}
|
||||
|
||||
|
||||
static inline char GetHex(Byte value)
|
||||
{
|
||||
return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
|
||||
}
|
||||
|
||||
void AddHashHexToString(char *dest, const Byte *data, UInt32 size)
|
||||
{
|
||||
dest[size * 2] = 0;
|
||||
if (!data)
|
||||
{
|
||||
for (UInt32 i = 0; i < size; i++)
|
||||
{
|
||||
dest[0] = ' ';
|
||||
dest[1] = ' ';
|
||||
dest += 2;
|
||||
}
|
||||
return;
|
||||
}
|
||||
int step = 2;
|
||||
if (size <= 8)
|
||||
{
|
||||
step = -2;
|
||||
dest += size * 2 - 2;
|
||||
}
|
||||
for (UInt32 i = 0; i < size; i++)
|
||||
{
|
||||
Byte b = data[i];
|
||||
dest[0] = GetHex((Byte)((b >> 4) & 0xF));
|
||||
dest[1] = GetHex((Byte)(b & 0xF));
|
||||
dest += step;
|
||||
}
|
||||
}
|
||||
107
CPP/7zip/UI/Common/HashCalc.h
Normal file
107
CPP/7zip/UI/Common/HashCalc.h
Normal file
@@ -0,0 +1,107 @@
|
||||
// HashCalc.h
|
||||
|
||||
#ifndef __HASH_CALC_H
|
||||
#define __HASH_CALC_H
|
||||
|
||||
#include "../../../Common/Wildcard.h"
|
||||
|
||||
#include "../../Common/CreateCoder.h"
|
||||
#include "../../Common/MethodProps.h"
|
||||
|
||||
#include "Property.h"
|
||||
|
||||
const unsigned k_HashCalc_DigestSize_Max = 64;
|
||||
|
||||
const unsigned k_HashCalc_NumGroups = 4;
|
||||
|
||||
enum
|
||||
{
|
||||
k_HashCalc_Index_Current,
|
||||
k_HashCalc_Index_DataSum,
|
||||
k_HashCalc_Index_NamesSum,
|
||||
k_HashCalc_Index_StreamsSum
|
||||
};
|
||||
|
||||
struct CHasherState
|
||||
{
|
||||
CMyComPtr<IHasher> Hasher;
|
||||
UString Name;
|
||||
UInt32 DigestSize;
|
||||
Byte Digests[k_HashCalc_NumGroups][k_HashCalc_DigestSize_Max];
|
||||
};
|
||||
|
||||
struct IHashCalc
|
||||
{
|
||||
virtual void InitForNewFile() = 0;
|
||||
virtual void Update(const void *data, UInt32 size) = 0;
|
||||
virtual void SetSize(UInt64 size) = 0;
|
||||
virtual void Final(bool isDir, bool isAltStream, const UString &path) = 0;
|
||||
};
|
||||
|
||||
struct CHashBundle: public IHashCalc
|
||||
{
|
||||
CObjectVector<CHasherState> Hashers;
|
||||
|
||||
UInt64 NumFiles;
|
||||
UInt64 NumDirs;
|
||||
UInt64 NumAltStreams;
|
||||
UInt64 FilesSize;
|
||||
UInt64 AltStreamsSize;
|
||||
UInt64 NumErrors;
|
||||
|
||||
UInt64 CurSize;
|
||||
|
||||
HRESULT SetMethods(DECL_EXTERNAL_CODECS_LOC_VARS const UStringVector &methods);
|
||||
|
||||
void Init()
|
||||
{
|
||||
NumFiles = NumDirs = NumAltStreams = FilesSize = AltStreamsSize = NumErrors = 0;
|
||||
}
|
||||
|
||||
void InitForNewFile();
|
||||
void Update(const void *data, UInt32 size);
|
||||
void SetSize(UInt64 size);
|
||||
void Final(bool isDir, bool isAltStream, const UString &path);
|
||||
};
|
||||
|
||||
#define INTERFACE_IHashCallbackUI(x) \
|
||||
virtual HRESULT StartScanning() x; \
|
||||
virtual HRESULT ScanProgress(UInt64 numFolders, UInt64 numFiles, UInt64 totalSize, const wchar_t *path, bool isDir) x; \
|
||||
virtual HRESULT CanNotFindError(const wchar_t *name, DWORD systemError) x; \
|
||||
virtual HRESULT FinishScanning() x; \
|
||||
virtual HRESULT SetNumFiles(UInt64 numFiles) x; \
|
||||
virtual HRESULT SetTotal(UInt64 size) x; \
|
||||
virtual HRESULT SetCompleted(const UInt64 *completeValue) x; \
|
||||
virtual HRESULT CheckBreak() x; \
|
||||
virtual HRESULT BeforeFirstFile(const CHashBundle &hb) x; \
|
||||
virtual HRESULT GetStream(const wchar_t *name, bool isFolder) x; \
|
||||
virtual HRESULT OpenFileError(const wchar_t *name, DWORD systemError) x; \
|
||||
virtual HRESULT SetOperationResult(UInt64 fileSize, const CHashBundle &hb, bool showHash) x; \
|
||||
virtual HRESULT AfterLastFile(const CHashBundle &hb) x; \
|
||||
|
||||
struct IHashCallbackUI
|
||||
{
|
||||
INTERFACE_IHashCallbackUI(=0)
|
||||
};
|
||||
|
||||
struct CHashOptions
|
||||
{
|
||||
UStringVector Methods;
|
||||
bool OpenShareForWrite;
|
||||
bool StdInMode;
|
||||
bool AltStreamsMode;
|
||||
NWildcard::ECensorPathMode PathMode;
|
||||
|
||||
CHashOptions(): StdInMode(false), OpenShareForWrite(false), AltStreamsMode(false), PathMode(NWildcard::k_RelatPath) {};
|
||||
};
|
||||
|
||||
HRESULT HashCalc(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
const NWildcard::CCensor &censor,
|
||||
const CHashOptions &options,
|
||||
UString &errorInfo,
|
||||
IHashCallbackUI *callback);
|
||||
|
||||
void AddHashHexToString(char *dest, const Byte *data, UInt32 size);
|
||||
|
||||
#endif
|
||||
32
CPP/7zip/UI/Common/IFileExtractCallback.h
Executable file → Normal file
32
CPP/7zip/UI/Common/IFileExtractCallback.h
Executable file → Normal file
@@ -1,9 +1,10 @@
|
||||
// IFileExtractCallback.h
|
||||
|
||||
#ifndef __IFILEEXTRACTCALLBACK_H
|
||||
#define __IFILEEXTRACTCALLBACK_H
|
||||
#ifndef __I_FILE_EXTRACT_CALLBACK_H
|
||||
#define __I_FILE_EXTRACT_CALLBACK_H
|
||||
|
||||
#include "../../../Common/MyString.h"
|
||||
|
||||
#include "Common/MyString.h"
|
||||
#include "../../IDecl.h"
|
||||
|
||||
namespace NOverwriteAnswer
|
||||
@@ -35,12 +36,37 @@ struct IExtractCallbackUI: IFolderArchiveExtractCallback
|
||||
{
|
||||
virtual HRESULT BeforeOpen(const wchar_t *name) = 0;
|
||||
virtual HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted) = 0;
|
||||
virtual HRESULT SetError(int level, const wchar_t *name,
|
||||
UInt32 errorFlags, const wchar_t *errors,
|
||||
UInt32 warningFlags, const wchar_t *warnings) = 0;
|
||||
virtual HRESULT ThereAreNoFiles() = 0;
|
||||
virtual HRESULT ExtractResult(HRESULT result) = 0;
|
||||
virtual HRESULT OpenTypeWarning(const wchar_t *name, const wchar_t *okType, const wchar_t *errorType) = 0;
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
virtual HRESULT SetPassword(const UString &password) = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#define INTERFACE_IGetProp(x) \
|
||||
STDMETHOD(GetProp)(PROPID propID, PROPVARIANT *value) x; \
|
||||
|
||||
DECL_INTERFACE_SUB(IGetProp, IUnknown, 0x01, 0x20)
|
||||
{
|
||||
INTERFACE_IGetProp(PURE)
|
||||
};
|
||||
|
||||
#define INTERFACE_IFolderExtractToStreamCallback(x) \
|
||||
STDMETHOD(UseExtractToStream)(Int32 *res) x; \
|
||||
STDMETHOD(GetStream7)(const wchar_t *name, Int32 isDir, ISequentialOutStream **outStream, Int32 askExtractMode, IGetProp *getProp) x; \
|
||||
STDMETHOD(PrepareOperation7)(Int32 askExtractMode) x; \
|
||||
STDMETHOD(SetOperationResult7)(Int32 resultEOperationResult, bool encrypted) x; \
|
||||
|
||||
DECL_INTERFACE_SUB(IFolderExtractToStreamCallback, IUnknown, 0x01, 0x30)
|
||||
{
|
||||
INTERFACE_IFolderExtractToStreamCallback(PURE)
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
762
CPP/7zip/UI/Common/LoadCodecs.cpp
Executable file → Normal file
762
CPP/7zip/UI/Common/LoadCodecs.cpp
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
167
CPP/7zip/UI/Common/LoadCodecs.h
Executable file → Normal file
167
CPP/7zip/UI/Common/LoadCodecs.h
Executable file → Normal file
@@ -3,9 +3,11 @@
|
||||
#ifndef __LOAD_CODECS_H
|
||||
#define __LOAD_CODECS_H
|
||||
|
||||
#include "../../../Common/MyBuffer.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../../Common/MyString.h"
|
||||
#include "../../../Common/Buffer.h"
|
||||
#include "../../../Common/ComTry.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
|
||||
#ifdef EXTERNAL_CODECS
|
||||
@@ -22,15 +24,19 @@ struct CDllCodecInfo
|
||||
UInt32 CodecIndex;
|
||||
};
|
||||
|
||||
#include "../../Archive/IArchive.h"
|
||||
struct CDllHasherInfo
|
||||
{
|
||||
int LibIndex;
|
||||
UInt32 HasherIndex;
|
||||
};
|
||||
|
||||
typedef IInArchive * (*CreateInArchiveP)();
|
||||
typedef IOutArchive * (*CreateOutArchiveP)();
|
||||
#include "../../Archive/IArchive.h"
|
||||
|
||||
struct CArcExtInfo
|
||||
{
|
||||
UString Ext;
|
||||
UString AddExt;
|
||||
|
||||
CArcExtInfo() {}
|
||||
CArcExtInfo(const UString &ext): Ext(ext) {}
|
||||
CArcExtInfo(const UString &ext, const UString &addExt): Ext(ext), AddExt(addExt) {}
|
||||
@@ -39,24 +45,45 @@ struct CArcExtInfo
|
||||
|
||||
struct CArcInfoEx
|
||||
{
|
||||
#ifdef EXTERNAL_CODECS
|
||||
int LibIndex;
|
||||
UInt32 FormatIndex;
|
||||
CLSID ClassID;
|
||||
#endif
|
||||
bool UpdateEnabled;
|
||||
CreateInArchiveP CreateInArchive;
|
||||
CreateOutArchiveP CreateOutArchive;
|
||||
UInt32 Flags;
|
||||
|
||||
Func_CreateInArchive CreateInArchive;
|
||||
Func_IsArc IsArcFunc;
|
||||
|
||||
UString Name;
|
||||
CObjectVector<CArcExtInfo> Exts;
|
||||
|
||||
#ifndef _SFX
|
||||
CByteBuffer StartSignature;
|
||||
// CByteBuffer FinishSignature;
|
||||
#ifdef NEW_FOLDER_INTERFACE
|
||||
UStringVector AssociateExts;
|
||||
Func_CreateOutArchive CreateOutArchive;
|
||||
bool UpdateEnabled;
|
||||
bool NewInterface;
|
||||
// UInt32 Version;
|
||||
UInt32 SignatureOffset;
|
||||
CObjectVector<CByteBuffer> Signatures;
|
||||
#ifdef NEW_FOLDER_INTERFACE
|
||||
UStringVector AssociateExts;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef EXTERNAL_CODECS
|
||||
int LibIndex;
|
||||
UInt32 FormatIndex;
|
||||
CLSID ClassID;
|
||||
#endif
|
||||
bool KeepName;
|
||||
|
||||
bool Flags_KeepName() const { return (Flags & NArcInfoFlags::kKeepName) != 0; }
|
||||
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_SymLinks() const { return (Flags & NArcInfoFlags::kSymLinks) != 0; }
|
||||
bool Flags_HardLinks() const { return (Flags & NArcInfoFlags::kHardLinks) != 0; }
|
||||
|
||||
bool Flags_UseGlobalOffset() const { return (Flags & NArcInfoFlags::kUseGlobalOffset) != 0; }
|
||||
bool Flags_StartOpen() const { return (Flags & NArcInfoFlags::kStartOpen) != 0; }
|
||||
bool Flags_BackwardOpen() const { return (Flags & NArcInfoFlags::kBackwardOpen) != 0; }
|
||||
bool Flags_PreArc() const { return (Flags & NArcInfoFlags::kPreArc) != 0; }
|
||||
bool Flags_PureStartOpen() const { return (Flags & NArcInfoFlags::kPureStartOpen) != 0; }
|
||||
|
||||
UString GetMainExt() const
|
||||
{
|
||||
@@ -80,24 +107,29 @@ struct CArcInfoEx
|
||||
}
|
||||
*/
|
||||
|
||||
void AddExts(const wchar_t* ext, const wchar_t* addExt);
|
||||
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():
|
||||
#ifdef EXTERNAL_CODECS
|
||||
LibIndex(-1),
|
||||
#endif
|
||||
UpdateEnabled(false),
|
||||
CreateInArchive(0), CreateOutArchive(0),
|
||||
KeepName(false)
|
||||
#ifndef _SFX
|
||||
#endif
|
||||
Flags(0),
|
||||
CreateInArchive(NULL),
|
||||
IsArcFunc(NULL)
|
||||
#ifndef _SFX
|
||||
, CreateOutArchive(NULL)
|
||||
, UpdateEnabled(false)
|
||||
, NewInterface(false)
|
||||
// , Version(0)
|
||||
, SignatureOffset(0)
|
||||
#endif
|
||||
#ifdef EXTERNAL_CODECS
|
||||
, LibIndex(-1)
|
||||
#endif
|
||||
{}
|
||||
};
|
||||
|
||||
#ifdef EXTERNAL_CODECS
|
||||
typedef UInt32 (WINAPI *GetMethodPropertyFunc)(UInt32 index, PROPID propID, PROPVARIANT *value);
|
||||
typedef UInt32 (WINAPI *CreateObjectFunc)(const GUID *clsID, const GUID *interfaceID, void **outObject);
|
||||
|
||||
|
||||
#ifdef NEW_FOLDER_INTERFACE
|
||||
struct CCodecIcons
|
||||
@@ -114,24 +146,28 @@ struct CCodecIcons
|
||||
#endif
|
||||
|
||||
struct CCodecLib
|
||||
#ifdef NEW_FOLDER_INTERFACE
|
||||
: public CCodecIcons
|
||||
#endif
|
||||
#ifdef NEW_FOLDER_INTERFACE
|
||||
: public CCodecIcons
|
||||
#endif
|
||||
{
|
||||
NWindows::NDLL::CLibrary Lib;
|
||||
GetMethodPropertyFunc GetMethodProperty;
|
||||
CreateObjectFunc CreateObject;
|
||||
#ifdef NEW_FOLDER_INTERFACE
|
||||
FString Path;
|
||||
Func_GetMethodProperty GetMethodProperty;
|
||||
Func_CreateObject CreateObject;
|
||||
CMyComPtr<IHashers> Hashers;
|
||||
|
||||
#ifdef NEW_FOLDER_INTERFACE
|
||||
void LoadIcons() { CCodecIcons::LoadIcons((HMODULE)Lib); }
|
||||
#endif
|
||||
CCodecLib(): GetMethodProperty(0) {}
|
||||
|
||||
CCodecLib(): GetMethodProperty(NULL) {}
|
||||
};
|
||||
#endif
|
||||
|
||||
class CCodecs:
|
||||
#ifdef EXTERNAL_CODECS
|
||||
public ICompressCodecsInfo,
|
||||
public IHashers,
|
||||
#else
|
||||
public IUnknown,
|
||||
#endif
|
||||
@@ -140,7 +176,8 @@ class CCodecs:
|
||||
public:
|
||||
#ifdef EXTERNAL_CODECS
|
||||
CObjectVector<CCodecLib> Libs;
|
||||
CObjectVector<CDllCodecInfo> Codecs;
|
||||
CRecordVector<CDllCodecInfo> Codecs;
|
||||
CRecordVector<CDllHasherInfo> Hashers;
|
||||
|
||||
#ifdef NEW_FOLDER_INTERFACE
|
||||
CCodecIcons InternalIcons;
|
||||
@@ -159,6 +196,16 @@ public:
|
||||
|
||||
public:
|
||||
CObjectVector<CArcInfoEx> Formats;
|
||||
bool CaseSensitiveChange;
|
||||
bool CaseSensitive;
|
||||
|
||||
CCodecs(): CaseSensitiveChange(false), CaseSensitive(false) {}
|
||||
|
||||
const wchar_t *GetFormatNamePtr(int formatIndex)
|
||||
{
|
||||
return formatIndex < 0 ? L"#" : (const wchar_t *)Formats[formatIndex].Name;
|
||||
}
|
||||
|
||||
HRESULT Load();
|
||||
|
||||
#ifndef _SFX
|
||||
@@ -168,65 +215,89 @@ public:
|
||||
bool FindFormatForArchiveType(const UString &arcType, CIntVector &formatIndices) const;
|
||||
#endif
|
||||
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
#ifdef EXTERNAL_CODECS
|
||||
|
||||
MY_UNKNOWN_IMP2(ICompressCodecsInfo, IHashers)
|
||||
|
||||
STDMETHOD(GetNumberOfMethods)(UInt32 *numMethods);
|
||||
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
|
||||
STDMETHOD(CreateDecoder)(UInt32 index, const GUID *interfaceID, void **coder);
|
||||
STDMETHOD(CreateEncoder)(UInt32 index, const GUID *interfaceID, void **coder);
|
||||
#endif
|
||||
|
||||
STDMETHOD_(UInt32, GetNumHashers)();
|
||||
STDMETHOD(GetHasherProp)(UInt32 index, PROPID propID, PROPVARIANT *value);
|
||||
STDMETHOD(CreateHasher)(UInt32 index, IHasher **hasher);
|
||||
|
||||
#else
|
||||
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
#endif // EXTERNAL_CODECS
|
||||
|
||||
#ifdef EXTERNAL_CODECS
|
||||
|
||||
int GetCodecLibIndex(UInt32 index);
|
||||
bool GetCodecEncoderIsAssigned(UInt32 index);
|
||||
HRESULT GetCodecId(UInt32 index, UInt64 &id);
|
||||
UString GetCodecName(UInt32 index);
|
||||
|
||||
HRESULT CreateInArchive(int formatIndex, CMyComPtr<IInArchive> &archive) const
|
||||
int GetHasherLibIndex(UInt32 index);
|
||||
UInt64 GetHasherId(UInt32 index);
|
||||
UString GetHasherName(UInt32 index);
|
||||
UInt32 GetHasherDigestSize(UInt32 index);
|
||||
|
||||
#endif
|
||||
|
||||
HRESULT CreateInArchive(unsigned formatIndex, CMyComPtr<IInArchive> &archive) const
|
||||
{
|
||||
const CArcInfoEx &ai = Formats[formatIndex];
|
||||
#ifdef EXTERNAL_CODECS
|
||||
if (ai.LibIndex < 0)
|
||||
#endif
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
archive = ai.CreateInArchive();
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
#ifdef EXTERNAL_CODECS
|
||||
return CreateArchiveHandler(ai, (void **)&archive, false);
|
||||
#endif
|
||||
}
|
||||
HRESULT CreateOutArchive(int formatIndex, CMyComPtr<IOutArchive> &archive) const
|
||||
|
||||
#ifndef _SFX
|
||||
|
||||
HRESULT CreateOutArchive(unsigned formatIndex, CMyComPtr<IOutArchive> &archive) const
|
||||
{
|
||||
const CArcInfoEx &ai = Formats[formatIndex];
|
||||
#ifdef EXTERNAL_CODECS
|
||||
if (ai.LibIndex < 0)
|
||||
#endif
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
archive = ai.CreateOutArchive();
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
#ifdef EXTERNAL_CODECS
|
||||
return CreateArchiveHandler(ai, (void **)&archive, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
int FindOutFormatFromName(const UString &name) const
|
||||
{
|
||||
for (int i = 0; i < Formats.Size(); i++)
|
||||
FOR_VECTOR (i, Formats)
|
||||
{
|
||||
const CArcInfoEx &arc = Formats[i];
|
||||
if (!arc.UpdateEnabled)
|
||||
continue;
|
||||
if (arc.Name.CompareNoCase(name) == 0)
|
||||
if (arc.Name.IsEqualToNoCase(name))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef EXTERNAL_CODECS
|
||||
HRESULT CreateCoder(const UString &name, bool encode, CMyComPtr<ICompressCoder> &coder) const;
|
||||
#endif
|
||||
|
||||
#endif // _SFX
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
3146
CPP/7zip/UI/Common/OpenArchive.cpp
Executable file → Normal file
3146
CPP/7zip/UI/Common/OpenArchive.cpp
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
346
CPP/7zip/UI/Common/OpenArchive.h
Executable file → Normal file
346
CPP/7zip/UI/Common/OpenArchive.h
Executable file → Normal file
@@ -3,50 +3,309 @@
|
||||
#ifndef __OPEN_ARCHIVE_H
|
||||
#define __OPEN_ARCHIVE_H
|
||||
|
||||
#include "Common/MyString.h"
|
||||
|
||||
#include "Windows/FileFind.h"
|
||||
|
||||
#include "../../Archive/IArchive.h"
|
||||
#include "../../../Windows/PropVariant.h"
|
||||
|
||||
#include "ArchiveOpenCallback.h"
|
||||
#include "LoadCodecs.h"
|
||||
#include "Property.h"
|
||||
|
||||
HRESULT GetArchiveItemBoolProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result);
|
||||
HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result);
|
||||
HRESULT Archive_GetItemBoolProp(IInArchive *arc, UInt32 index, PROPID propID, bool &result) throw();
|
||||
HRESULT Archive_IsItem_Folder(IInArchive *arc, UInt32 index, bool &result) throw();
|
||||
HRESULT Archive_IsItem_Aux(IInArchive *arc, UInt32 index, bool &result) throw();
|
||||
HRESULT Archive_IsItem_AltStream(IInArchive *arc, UInt32 index, bool &result) throw();
|
||||
HRESULT Archive_IsItem_Deleted(IInArchive *arc, UInt32 index, bool &deleted) throw();
|
||||
|
||||
struct CArc
|
||||
/*
|
||||
struct COptionalOpenProperties
|
||||
{
|
||||
UString FormatName;
|
||||
CObjectVector<CProperty> Props;
|
||||
};
|
||||
*/
|
||||
|
||||
#ifdef _SFX
|
||||
#define OPEN_PROPS_DECL
|
||||
#else
|
||||
#define OPEN_PROPS_DECL const CObjectVector<CProperty> *props;
|
||||
// #define OPEN_PROPS_DECL , const CObjectVector<COptionalOpenProperties> *props
|
||||
#endif
|
||||
|
||||
struct COpenSpecFlags
|
||||
{
|
||||
// bool CanReturnFull;
|
||||
bool CanReturnFrontal;
|
||||
bool CanReturnTail;
|
||||
bool CanReturnMid;
|
||||
|
||||
bool CanReturn_NonStart() const { return CanReturnTail || CanReturnMid; }
|
||||
|
||||
COpenSpecFlags():
|
||||
// CanReturnFull(true),
|
||||
CanReturnFrontal(false),
|
||||
CanReturnTail(false),
|
||||
CanReturnMid(false)
|
||||
{}
|
||||
};
|
||||
|
||||
struct COpenType
|
||||
{
|
||||
CMyComPtr<IInArchive> Archive;
|
||||
UString Path;
|
||||
UString DefaultName;
|
||||
int FormatIndex;
|
||||
|
||||
COpenSpecFlags SpecForcedType;
|
||||
COpenSpecFlags SpecMainType;
|
||||
COpenSpecFlags SpecWrongExt;
|
||||
COpenSpecFlags SpecUnknownExt;
|
||||
|
||||
bool Recursive;
|
||||
|
||||
bool CanReturnArc;
|
||||
bool CanReturnParser;
|
||||
bool EachPos;
|
||||
|
||||
// bool SkipSfxStub;
|
||||
// bool ExeAsUnknown;
|
||||
|
||||
bool ZerosTailIsAllowed;
|
||||
|
||||
bool MaxStartOffset_Defined;
|
||||
UInt64 MaxStartOffset;
|
||||
|
||||
const COpenSpecFlags &GetSpec(bool isForced, bool isMain, bool isUnknown) const
|
||||
{
|
||||
return isForced ? SpecForcedType : (isMain ? SpecMainType : (isUnknown ? SpecUnknownExt : SpecWrongExt));
|
||||
}
|
||||
|
||||
COpenType():
|
||||
FormatIndex(-1),
|
||||
Recursive(true),
|
||||
EachPos(false),
|
||||
CanReturnArc(true),
|
||||
CanReturnParser(false),
|
||||
// SkipSfxStub(true),
|
||||
// ExeAsUnknown(true),
|
||||
ZerosTailIsAllowed(false),
|
||||
MaxStartOffset_Defined(false),
|
||||
MaxStartOffset(0)
|
||||
{
|
||||
SpecForcedType.CanReturnFrontal = true;
|
||||
SpecForcedType.CanReturnTail = true;
|
||||
SpecForcedType.CanReturnMid = true;
|
||||
|
||||
SpecMainType.CanReturnFrontal = true;
|
||||
|
||||
SpecUnknownExt.CanReturnTail = true; // for sfx
|
||||
SpecUnknownExt.CanReturnMid = true;
|
||||
SpecUnknownExt.CanReturnFrontal = true; // for alt streams of sfx with pad
|
||||
|
||||
// ZerosTailIsAllowed = true;
|
||||
}
|
||||
};
|
||||
|
||||
struct COpenOptions
|
||||
{
|
||||
CCodecs *codecs;
|
||||
COpenType openType;
|
||||
const CObjectVector<COpenType> *types;
|
||||
const CIntVector *excludedFormats;
|
||||
|
||||
IInStream *stream;
|
||||
ISequentialInStream *seqStream;
|
||||
IArchiveOpenCallback *callback;
|
||||
COpenCallbackImp *callbackSpec;
|
||||
OPEN_PROPS_DECL
|
||||
// bool openOnlySpecifiedByExtension,
|
||||
|
||||
bool stdInMode;
|
||||
UString filePath;
|
||||
|
||||
COpenOptions():
|
||||
codecs(NULL),
|
||||
types(NULL),
|
||||
excludedFormats(NULL),
|
||||
stream(NULL),
|
||||
seqStream(NULL),
|
||||
callback(NULL),
|
||||
callbackSpec(NULL),
|
||||
stdInMode(false)
|
||||
{}
|
||||
|
||||
};
|
||||
|
||||
UInt32 GetOpenArcErrorFlags(const NWindows::NCOM::CPropVariant &prop, bool *isDefinedProp = NULL);
|
||||
|
||||
struct CArcErrorInfo
|
||||
{
|
||||
bool ThereIsTail;
|
||||
bool UnexpecedEnd;
|
||||
bool IgnoreTail; // all are zeros
|
||||
// bool NonZerosTail;
|
||||
bool ErrorFlags_Defined;
|
||||
UInt32 ErrorFlags;
|
||||
UInt32 WarningFlags;
|
||||
int ErrorFormatIndex; // - 1 means no Error.
|
||||
// if FormatIndex == ErrorFormatIndex, the archive is open with offset
|
||||
UInt64 TailSize;
|
||||
|
||||
/* if CArc is Open OK with some format:
|
||||
- ErrorFormatIndex shows error format index, if extension is incorrect
|
||||
- other variables show message and warnings of archive that is open */
|
||||
|
||||
UString ErrorMessage;
|
||||
UString WarningMessage;
|
||||
|
||||
// call IsArc_After_NonOpen only if Open returns S_FALSE
|
||||
bool IsArc_After_NonOpen() const
|
||||
{
|
||||
return (ErrorFlags_Defined && (ErrorFlags & kpv_ErrorFlags_IsNotArc) == 0);
|
||||
}
|
||||
|
||||
|
||||
CArcErrorInfo():
|
||||
ThereIsTail(false),
|
||||
UnexpecedEnd(false),
|
||||
IgnoreTail(false),
|
||||
// NonZerosTail(false),
|
||||
ErrorFlags_Defined(false),
|
||||
ErrorFlags(0),
|
||||
WarningFlags(0),
|
||||
ErrorFormatIndex(-1),
|
||||
TailSize(0)
|
||||
{}
|
||||
|
||||
void ClearErrors();
|
||||
|
||||
void ClearErrors_Full()
|
||||
{
|
||||
ErrorFormatIndex = -1;
|
||||
ClearErrors();
|
||||
}
|
||||
|
||||
bool IsThereErrorOrWarning() const
|
||||
{
|
||||
return ErrorFlags != 0
|
||||
|| WarningFlags != 0
|
||||
|| NeedTailWarning()
|
||||
|| UnexpecedEnd
|
||||
|| !ErrorMessage.IsEmpty()
|
||||
|| !WarningMessage.IsEmpty();
|
||||
}
|
||||
|
||||
bool AreThereErrors() const { return ErrorFlags != 0 || UnexpecedEnd; }
|
||||
bool AreThereWarnings() const { return WarningFlags != 0 || NeedTailWarning(); }
|
||||
|
||||
bool NeedTailWarning() const { return !IgnoreTail && ThereIsTail; }
|
||||
|
||||
UInt32 GetWarningFlags() const
|
||||
{
|
||||
UInt32 a = WarningFlags;
|
||||
if (NeedTailWarning() && (ErrorFlags & kpv_ErrorFlags_DataAfterEnd) == 0)
|
||||
a |= kpv_ErrorFlags_DataAfterEnd;
|
||||
return a;
|
||||
}
|
||||
|
||||
UInt32 GetErrorFlags() const
|
||||
{
|
||||
UInt32 a = ErrorFlags;
|
||||
if (UnexpecedEnd)
|
||||
a |= kpv_ErrorFlags_UnexpectedEnd;
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
class CArc
|
||||
{
|
||||
HRESULT PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyComPtr<IInArchive> &archive);
|
||||
HRESULT CheckZerosTail(const COpenOptions &op, UInt64 offset);
|
||||
HRESULT OpenStream2(const COpenOptions &options);
|
||||
|
||||
public:
|
||||
CMyComPtr<IInArchive> Archive;
|
||||
CMyComPtr<IInStream> InStream;
|
||||
// we use InStream in 2 cases (ArcStreamOffset != 0):
|
||||
// 1) if we use additional cache stream
|
||||
// 2) we reopen sfx archive with CTailInStream
|
||||
|
||||
CMyComPtr<IArchiveGetRawProps> GetRawProps;
|
||||
CMyComPtr<IArchiveGetRootProps> GetRootProps;
|
||||
|
||||
CArcErrorInfo ErrorInfo; // for OK archives
|
||||
CArcErrorInfo NonOpen_ErrorInfo; // ErrorInfo for mainArchive (false OPEN)
|
||||
|
||||
UString Path;
|
||||
UString filePath;
|
||||
UString DefaultName;
|
||||
int FormatIndex; // - 1 means Parser.
|
||||
int SubfileIndex;
|
||||
FILETIME MTime;
|
||||
bool MTimeDefined;
|
||||
UString ErrorMessage;
|
||||
|
||||
Int64 Offset; // it's offset of start of archive inside stream that is open by Archive Handler
|
||||
UInt64 PhySize;
|
||||
// UInt64 OkPhySize;
|
||||
bool PhySizeDefined;
|
||||
// bool OkPhySize_Defined;
|
||||
UInt64 FileSize;
|
||||
UInt64 AvailPhySize; // PhySize, but it's reduced if exceed end of file
|
||||
// bool offsetDefined;
|
||||
|
||||
CArc(): MTimeDefined(false) {}
|
||||
UInt64 ArcStreamOffset; // offset of stream that is open by Archive Handler
|
||||
Int64 GetGlobalOffset() const { return ArcStreamOffset + Offset; } // it's global offset of archive
|
||||
|
||||
// AString ErrorFlagsText;
|
||||
|
||||
bool IsParseArc;
|
||||
|
||||
bool IsTree;
|
||||
|
||||
bool Ask_Deleted;
|
||||
bool Ask_AltStream;
|
||||
bool Ask_Aux;
|
||||
bool Ask_INode;
|
||||
|
||||
bool IgnoreSplit; // don't try split handler
|
||||
|
||||
// void Set_ErrorFlagsText();
|
||||
|
||||
CArc():
|
||||
MTimeDefined(false),
|
||||
IsTree(false),
|
||||
Ask_Deleted(false),
|
||||
Ask_AltStream(false),
|
||||
Ask_Aux(false),
|
||||
Ask_INode(false),
|
||||
IgnoreSplit(false)
|
||||
{}
|
||||
|
||||
HRESULT ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openRes);
|
||||
|
||||
// ~CArc();
|
||||
|
||||
HRESULT Close()
|
||||
{
|
||||
InStream.Release();
|
||||
return Archive->Close();
|
||||
}
|
||||
|
||||
// AltStream's name is concatenated with base file name in one string in parts.Back()
|
||||
HRESULT GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const;
|
||||
|
||||
HRESULT GetItemPath(UInt32 index, UString &result) const;
|
||||
|
||||
// GetItemPath2 adds [DELETED] dir prefix for deleted items.
|
||||
HRESULT GetItemPath2(UInt32 index, UString &result) 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
|
||||
{ return GetArchiveItemBoolProp(Archive, index, kpidIsAnti, result); }
|
||||
{ return Archive_GetItemBoolProp(Archive, index, kpidIsAnti, result); }
|
||||
|
||||
HRESULT OpenStream(
|
||||
CCodecs *codecs,
|
||||
int formatIndex,
|
||||
IInStream *stream,
|
||||
ISequentialInStream *seqStream,
|
||||
IArchiveOpenCallback *callback);
|
||||
|
||||
HRESULT OpenStreamOrFile(
|
||||
CCodecs *codecs,
|
||||
int formatIndex,
|
||||
bool stdInMode,
|
||||
IInStream *stream,
|
||||
IArchiveOpenCallback *callback);
|
||||
HRESULT OpenStream(const COpenOptions &options);
|
||||
HRESULT OpenStreamOrFile(COpenOptions &options);
|
||||
|
||||
HRESULT ReOpen(const COpenOptions &options);
|
||||
|
||||
HRESULT CreateNewTailStream(CMyComPtr<IInStream> &stream);
|
||||
};
|
||||
|
||||
struct CArchiveLink
|
||||
@@ -56,33 +315,32 @@ struct CArchiveLink
|
||||
UInt64 VolumesSize;
|
||||
bool IsOpen;
|
||||
|
||||
// int NonOpenErrorFormatIndex; // - 1 means no Error.
|
||||
UString NonOpen_ArcPath;
|
||||
|
||||
CArcErrorInfo NonOpen_ErrorInfo;
|
||||
|
||||
// UString ErrorsText;
|
||||
// void Set_ErrorsText();
|
||||
|
||||
CArchiveLink(): VolumesSize(0), IsOpen(false) {}
|
||||
void KeepModeForNextOpen();
|
||||
HRESULT Close();
|
||||
void Release();
|
||||
~CArchiveLink() { Release(); }
|
||||
|
||||
const CArc *GetArc() const { return &Arcs.Back(); }
|
||||
IInArchive *GetArchive() const { return Arcs.Back().Archive; }
|
||||
IArchiveGetRawProps *GetArchiveGetRawProps() const { return Arcs.Back().GetRawProps; }
|
||||
IArchiveGetRootProps *GetArchiveGetRootProps() const { return Arcs.Back().GetRootProps; }
|
||||
|
||||
HRESULT Open(
|
||||
CCodecs *codecs,
|
||||
const CIntVector &formatIndices,
|
||||
bool stdInMode,
|
||||
IInStream *stream,
|
||||
const UString &filePath,
|
||||
IArchiveOpenCallback *callback);
|
||||
HRESULT Open(COpenOptions &options);
|
||||
|
||||
HRESULT Open2(
|
||||
CCodecs *codecs,
|
||||
const CIntVector &formatIndices,
|
||||
bool stdInMode,
|
||||
IInStream *stream,
|
||||
const UString &filePath,
|
||||
IOpenCallbackUI *callbackUI);
|
||||
HRESULT Open2(COpenOptions &options, IOpenCallbackUI *callbackUI);
|
||||
|
||||
HRESULT ReOpen(
|
||||
CCodecs *codecs,
|
||||
const UString &filePath,
|
||||
IArchiveOpenCallback *callback);
|
||||
HRESULT ReOpen(COpenOptions &options);
|
||||
};
|
||||
|
||||
bool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector<COpenType> &types);
|
||||
|
||||
#endif
|
||||
|
||||
551
CPP/7zip/UI/Common/PropIDUtils.cpp
Executable file → Normal file
551
CPP/7zip/UI/Common/PropIDUtils.cpp
Executable file → Normal file
@@ -2,33 +2,29 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/IntToString.h"
|
||||
#include "../../../../C/CpuArch.h"
|
||||
|
||||
#include "Windows/FileFind.h"
|
||||
#include "Windows/PropVariantConversions.h"
|
||||
#include "../../../Common/IntToString.h"
|
||||
#include "../../../Common/StringConvert.h"
|
||||
|
||||
#include "../../../Windows/FileFind.h"
|
||||
#include "../../../Windows/FileIO.h"
|
||||
#include "../../../Windows/PropVariantConv.h"
|
||||
|
||||
#include "../../PropID.h"
|
||||
|
||||
#include "PropIDUtils.h"
|
||||
|
||||
#define Get16(x) GetUi16(x)
|
||||
#define Get32(x) GetUi32(x)
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
void ConvertUInt32ToHex(UInt32 value, wchar_t *s)
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
int t = value & 0xF;
|
||||
value >>= 4;
|
||||
s[7 - i] = (wchar_t)((t < 10) ? (L'0' + t) : (L'A' + (t - 10)));
|
||||
}
|
||||
s[8] = L'\0';
|
||||
}
|
||||
|
||||
static const char g_WinAttrib[17] = "RHS8DAdNTsrCOnE_";
|
||||
static const char g_WinAttribChars[16 + 1] = "RHS8DAdNTsLCOnE_";
|
||||
/*
|
||||
0 READONLY
|
||||
1 HIDDEN
|
||||
3 SYSTEM
|
||||
2 SYSTEM
|
||||
|
||||
4 DIRECTORY
|
||||
5 ARCHIVE
|
||||
@@ -45,46 +41,45 @@ static const char g_WinAttrib[17] = "RHS8DAdNTsrCOnE_";
|
||||
16 VIRTUAL
|
||||
*/
|
||||
|
||||
static const char kPosixTypes[16] = { '0', 'p', 'c', '3', 'd', '5', 'b', '7', '-', '9', 'l', 'B', 's', 'D', 'E', 'F' };
|
||||
#define MY_ATTR_CHAR(a, n, c) ((a )& (1 << (n))) ? c : L'-';
|
||||
|
||||
UString ConvertPropertyToString(const PROPVARIANT &prop, PROPID propID, bool full)
|
||||
void ConvertWinAttribToString(char *s, UInt32 wa)
|
||||
{
|
||||
switch(propID)
|
||||
for (int i = 0; i < 16; i++)
|
||||
if ((wa & (1 << i)) && i != 7)
|
||||
*s++ = g_WinAttribChars[i];
|
||||
*s = 0;
|
||||
}
|
||||
|
||||
static const char kPosixTypes[16] = { '0', 'p', 'c', '3', 'd', '5', 'b', '7', '-', '9', 'l', 'B', 's', 'D', 'E', 'F' };
|
||||
#define MY_ATTR_CHAR(a, n, c) ((a) & (1 << (n))) ? c : '-';
|
||||
|
||||
void ConvertPropertyToShortString(char *dest, const PROPVARIANT &prop, PROPID propID, bool full)
|
||||
{
|
||||
*dest = 0;
|
||||
if (prop.vt == VT_FILETIME)
|
||||
{
|
||||
FILETIME localFileTime;
|
||||
if ((prop.filetime.dwHighDateTime == 0 &&
|
||||
prop.filetime.dwLowDateTime == 0) ||
|
||||
!::FileTimeToLocalFileTime(&prop.filetime, &localFileTime))
|
||||
return;
|
||||
ConvertFileTimeToString(localFileTime, dest, true, full);
|
||||
return;
|
||||
}
|
||||
switch (propID)
|
||||
{
|
||||
case kpidCTime:
|
||||
case kpidATime:
|
||||
case kpidMTime:
|
||||
{
|
||||
if (prop.vt != VT_FILETIME)
|
||||
break;
|
||||
FILETIME localFileTime;
|
||||
if ((prop.filetime.dwHighDateTime == 0 &&
|
||||
prop.filetime.dwLowDateTime == 0) ||
|
||||
!::FileTimeToLocalFileTime(&prop.filetime, &localFileTime))
|
||||
return UString();
|
||||
return ConvertFileTimeToString(localFileTime, true, full);
|
||||
}
|
||||
case kpidCRC:
|
||||
{
|
||||
if (prop.vt != VT_UI4)
|
||||
break;
|
||||
wchar_t temp[12];
|
||||
ConvertUInt32ToHex(prop.ulVal, temp);
|
||||
return temp;
|
||||
ConvertUInt32ToHex8Digits(prop.ulVal, dest);
|
||||
return;
|
||||
}
|
||||
case kpidAttrib:
|
||||
{
|
||||
if (prop.vt != VT_UI4)
|
||||
break;
|
||||
UInt32 a = prop.ulVal;
|
||||
wchar_t sz[32];
|
||||
int pos = 0;
|
||||
for (int i = 0; i < 16; i++)
|
||||
if (a & (1 << i) && i != 7)
|
||||
sz[pos++] = g_WinAttrib[i];
|
||||
sz[pos] = '\0';
|
||||
return sz;
|
||||
ConvertWinAttribToString(dest, prop.ulVal);
|
||||
return;
|
||||
}
|
||||
case kpidPosixAttrib:
|
||||
{
|
||||
@@ -92,29 +87,467 @@ UString ConvertPropertyToString(const PROPVARIANT &prop, PROPID propID, bool ful
|
||||
break;
|
||||
UString res;
|
||||
UInt32 a = prop.ulVal;
|
||||
wchar_t temp[16];
|
||||
|
||||
temp[0] = kPosixTypes[(a >> 12) & 0xF];
|
||||
dest[0] = kPosixTypes[(a >> 12) & 0xF];
|
||||
for (int i = 6; i >= 0; i -= 3)
|
||||
{
|
||||
temp[7 - i] = MY_ATTR_CHAR(a, i + 2, L'r');
|
||||
temp[8 - i] = MY_ATTR_CHAR(a, i + 1, L'w');
|
||||
temp[9 - i] = MY_ATTR_CHAR(a, i + 0, L'x');
|
||||
dest[7 - i] = MY_ATTR_CHAR(a, i + 2, 'r');
|
||||
dest[8 - i] = MY_ATTR_CHAR(a, i + 1, 'w');
|
||||
dest[9 - i] = MY_ATTR_CHAR(a, i + 0, 'x');
|
||||
}
|
||||
if ((a & 0x800) != 0) temp[3] = ((a & (1 << 6)) ? 's' : 'S');
|
||||
if ((a & 0x400) != 0) temp[6] = ((a & (1 << 3)) ? 's' : 'S');
|
||||
if ((a & 0x200) != 0) temp[9] = ((a & (1 << 0)) ? 't' : 'T');
|
||||
temp[10] = 0;
|
||||
res = temp;
|
||||
if ((a & 0x800) != 0) dest[3] = ((a & (1 << 6)) ? 's' : 'S');
|
||||
if ((a & 0x400) != 0) dest[6] = ((a & (1 << 3)) ? 's' : 'S');
|
||||
if ((a & 0x200) != 0) dest[9] = ((a & (1 << 0)) ? 't' : 'T');
|
||||
dest[10] = 0;
|
||||
|
||||
a &= ~(UInt32)0xFFFF;
|
||||
if (a != 0)
|
||||
{
|
||||
ConvertUInt32ToHex(a, temp);
|
||||
res = UString(temp) + L' ' + res;
|
||||
dest[10] = ' ';
|
||||
ConvertUInt32ToHex8Digits(a, dest + 11);
|
||||
}
|
||||
return res;
|
||||
return;
|
||||
}
|
||||
case kpidINode:
|
||||
{
|
||||
if (prop.vt != VT_UI8)
|
||||
break;
|
||||
ConvertUInt32ToString((UInt32)(prop.uhVal.QuadPart >> 48), dest);
|
||||
dest += strlen(dest);
|
||||
*dest++ = '-';
|
||||
UInt64 low = prop.uhVal.QuadPart & (((UInt64)1 << 48) - 1);
|
||||
ConvertUInt64ToString(low, dest);
|
||||
return;
|
||||
}
|
||||
case kpidVa:
|
||||
{
|
||||
UInt64 v = 0;
|
||||
if (ConvertPropVariantToUInt64(prop, v))
|
||||
{
|
||||
dest[0] = '0';
|
||||
dest[1] = 'x';
|
||||
ConvertUInt64ToHex(prop.ulVal, dest + 2);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ConvertPropVariantToString(prop);
|
||||
ConvertPropVariantToShortString(prop, dest);
|
||||
}
|
||||
|
||||
void ConvertPropertyToString(UString &dest, const PROPVARIANT &prop, PROPID propID, bool full)
|
||||
{
|
||||
if (prop.vt == VT_BSTR)
|
||||
{
|
||||
dest = prop.bstrVal;
|
||||
return;
|
||||
}
|
||||
char temp[64];
|
||||
ConvertPropertyToShortString(temp, prop, propID, full);
|
||||
int len = MyStringLen(temp);
|
||||
wchar_t *str = dest.GetBuffer(len);
|
||||
for (int i = 0; i < len; i++)
|
||||
str[i] = temp[i];
|
||||
dest.ReleaseBuffer(len);
|
||||
}
|
||||
|
||||
static inline char GetHex(Byte value)
|
||||
{
|
||||
return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
|
||||
}
|
||||
|
||||
#ifndef _SFX
|
||||
|
||||
static inline void AddHexToString(AString &res, Byte value)
|
||||
{
|
||||
res += GetHex((Byte)(value >> 4));
|
||||
res += GetHex((Byte)(value & 0xF));
|
||||
res += ' ';
|
||||
}
|
||||
|
||||
/*
|
||||
static AString Data_To_Hex(const Byte *data, size_t size)
|
||||
{
|
||||
AString s;
|
||||
for (size_t i = 0; i < size; i++)
|
||||
AddHexToString(s, data[i]);
|
||||
return s;
|
||||
}
|
||||
*/
|
||||
|
||||
static const char *sidNames[] =
|
||||
{
|
||||
"0",
|
||||
"Dialup",
|
||||
"Network",
|
||||
"Batch",
|
||||
"Interactive",
|
||||
"Logon", // S-1-5-5-X-Y
|
||||
"Service",
|
||||
"Anonymous",
|
||||
"Proxy",
|
||||
"EnterpriseDC",
|
||||
"Self",
|
||||
"AuthenticatedUsers",
|
||||
"RestrictedCode",
|
||||
"TerminalServer",
|
||||
"RemoteInteractiveLogon",
|
||||
"ThisOrganization",
|
||||
"16",
|
||||
"IUserIIS",
|
||||
"LocalSystem",
|
||||
"LocalService",
|
||||
"NetworkService",
|
||||
"Domains"
|
||||
};
|
||||
|
||||
struct CSecID2Name
|
||||
{
|
||||
UInt32 n;
|
||||
char *sz;
|
||||
};
|
||||
|
||||
const CSecID2Name sid_32_Names[] =
|
||||
{
|
||||
{ 544, "Administrators" },
|
||||
{ 545, "Users" },
|
||||
{ 546, "Guests" },
|
||||
{ 547, "PowerUsers" },
|
||||
{ 548, "AccountOperators" },
|
||||
{ 549, "ServerOperators" },
|
||||
{ 550, "PrintOperators" },
|
||||
{ 551, "BackupOperators" },
|
||||
{ 552, "Replicators" },
|
||||
{ 553, "Backup Operators" },
|
||||
{ 554, "PreWindows2000CompatibleAccess" },
|
||||
{ 555, "RemoteDesktopUsers" },
|
||||
{ 556, "NetworkConfigurationOperators" },
|
||||
{ 557, "IncomingForestTrustBuilders" },
|
||||
{ 558, "PerformanceMonitorUsers" },
|
||||
{ 559, "PerformanceLogUsers" },
|
||||
{ 560, "WindowsAuthorizationAccessGroup" },
|
||||
{ 561, "TerminalServerLicenseServers" },
|
||||
{ 562, "DistributedCOMUsers" },
|
||||
{ 569, "CryptographicOperators" },
|
||||
{ 573, "EventLogReaders" },
|
||||
{ 574, "CertificateServiceDCOMAccess" }
|
||||
};
|
||||
|
||||
static const CSecID2Name sid_21_Names[] =
|
||||
{
|
||||
{ 500, "Administrator" },
|
||||
{ 501, "Guest" },
|
||||
{ 502, "KRBTGT" },
|
||||
{ 512, "DomainAdmins" },
|
||||
{ 513, "DomainUsers" },
|
||||
{ 515, "DomainComputers" },
|
||||
{ 516, "DomainControllers" },
|
||||
{ 517, "CertPublishers" },
|
||||
{ 518, "SchemaAdmins" },
|
||||
{ 519, "EnterpriseAdmins" },
|
||||
{ 520, "GroupPolicyCreatorOwners" },
|
||||
{ 553, "RASandIASServers" },
|
||||
{ 553, "RASandIASServers" },
|
||||
{ 571, "AllowedRODCPasswordReplicationGroup" },
|
||||
{ 572, "DeniedRODCPasswordReplicationGroup" }
|
||||
};
|
||||
|
||||
struct CServicesToName
|
||||
{
|
||||
UInt32 n[5];
|
||||
char *sz;
|
||||
};
|
||||
|
||||
static const CServicesToName services_to_name[] =
|
||||
{
|
||||
{ { 956008885, 3418522649, 1831038044, 1853292631, 2271478464 } , "TrustedInstaller" }
|
||||
};
|
||||
|
||||
static void ParseSid(AString &s, const Byte *p, UInt32 lim, UInt32 &sidSize)
|
||||
{
|
||||
sidSize = 0;
|
||||
if (lim < 8)
|
||||
{
|
||||
s += "ERROR";
|
||||
return;
|
||||
}
|
||||
UInt32 rev = p[0];
|
||||
if (rev != 1)
|
||||
{
|
||||
s += "UNSUPPORTED";
|
||||
return;
|
||||
}
|
||||
UInt32 num = p[1];
|
||||
if (8 + num * 4 > lim)
|
||||
{
|
||||
s += "ERROR";
|
||||
return;
|
||||
}
|
||||
sidSize = 8 + num * 4;
|
||||
UInt32 authority = GetBe32(p + 4);
|
||||
|
||||
if (p[2] == 0 && p[3] == 0 && authority == 5 && num >= 1)
|
||||
{
|
||||
UInt32 v0 = Get32(p + 8);
|
||||
if (v0 < ARRAY_SIZE(sidNames))
|
||||
{
|
||||
s += sidNames[v0];
|
||||
return;
|
||||
}
|
||||
if (v0 == 32 && num == 2)
|
||||
{
|
||||
UInt32 v1 = Get32(p + 12);
|
||||
for (int i = 0; i < ARRAY_SIZE(sid_32_Names); i++)
|
||||
if (sid_32_Names[i].n == v1)
|
||||
{
|
||||
s += sid_32_Names[i].sz;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (v0 == 21 && num == 5)
|
||||
{
|
||||
UInt32 v4 = Get32(p + 8 + 4 * 4);
|
||||
for (int i = 0; i < ARRAY_SIZE(sid_21_Names); i++)
|
||||
if (sid_21_Names[i].n == v4)
|
||||
{
|
||||
s += sid_21_Names[i].sz;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (v0 == 80 && num == 6)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_SIZE(services_to_name); i++)
|
||||
{
|
||||
const CServicesToName &sn = services_to_name[i];
|
||||
int j;
|
||||
for (j = 0; j < 5 && sn.n[j] == Get32(p + 8 + 4 + j * 4); j++);
|
||||
if (j == 5)
|
||||
{
|
||||
s += sn.sz;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char sz[16];
|
||||
s += "S-1-";
|
||||
if (p[2] == 0 && p[3] == 0)
|
||||
{
|
||||
ConvertUInt32ToString(authority, sz);
|
||||
s += sz;
|
||||
}
|
||||
else
|
||||
{
|
||||
s += "0x";
|
||||
for (int i = 2; i < 8; i++)
|
||||
AddHexToString(s, p[i]);
|
||||
}
|
||||
for (UInt32 i = 0; i < num; i++)
|
||||
{
|
||||
s += '-';
|
||||
ConvertUInt32ToString(Get32(p + 8 + i * 4), sz);
|
||||
s += sz;
|
||||
}
|
||||
}
|
||||
|
||||
static void ParseOwner(AString &s, const Byte *p, UInt32 size, UInt32 pos)
|
||||
{
|
||||
if (pos > size)
|
||||
{
|
||||
s += "ERROR";
|
||||
return;
|
||||
}
|
||||
UInt32 sidSize = 0;
|
||||
ParseSid(s, p + pos, size - pos, sidSize);
|
||||
}
|
||||
|
||||
static void AddUInt32ToString(AString &s, UInt32 val)
|
||||
{
|
||||
char sz[16];
|
||||
ConvertUInt32ToString(val, sz);
|
||||
s += sz;
|
||||
}
|
||||
|
||||
static void ParseAcl(AString &s, const Byte *p, UInt32 size, const char *strName, UInt32 flags, UInt32 offset)
|
||||
{
|
||||
UInt32 control = Get16(p + 2);
|
||||
if ((flags & control) == 0)
|
||||
return;
|
||||
UInt32 pos = Get32(p + offset);
|
||||
s += ' ';
|
||||
s += strName;
|
||||
if (pos >= size)
|
||||
return;
|
||||
p += pos;
|
||||
size -= pos;
|
||||
if (size < 8)
|
||||
return;
|
||||
if (Get16(p) != 2) // revision
|
||||
return;
|
||||
// UInt32 aclSize = Get16(p + 2);
|
||||
UInt32 num = Get32(p + 4);
|
||||
AddUInt32ToString(s, num);
|
||||
/*
|
||||
if (num >= (1 << 16))
|
||||
return;
|
||||
if (aclSize > size)
|
||||
return;
|
||||
size = aclSize;
|
||||
size -= 8;
|
||||
p += 8;
|
||||
for (UInt32 i = 0 ; i < num; i++)
|
||||
{
|
||||
if (size <= 8)
|
||||
return;
|
||||
// Byte type = p[0];
|
||||
// Byte flags = p[1];
|
||||
// UInt32 aceSize = Get16(p + 2);
|
||||
// UInt32 mask = Get32(p + 4);
|
||||
p += 8;
|
||||
size -= 8;
|
||||
|
||||
UInt32 sidSize = 0;
|
||||
s += ' ';
|
||||
s += ParseSid(p, size, sidSize);
|
||||
if (sidSize == 0)
|
||||
return;
|
||||
p += sidSize;
|
||||
size -= sidSize;
|
||||
}
|
||||
if (size != 0)
|
||||
s += " ERROR";
|
||||
*/
|
||||
}
|
||||
|
||||
#define MY_SE_OWNER_DEFAULTED (0x0001)
|
||||
#define MY_SE_GROUP_DEFAULTED (0x0002)
|
||||
#define MY_SE_DACL_PRESENT (0x0004)
|
||||
#define MY_SE_DACL_DEFAULTED (0x0008)
|
||||
#define MY_SE_SACL_PRESENT (0x0010)
|
||||
#define MY_SE_SACL_DEFAULTED (0x0020)
|
||||
#define MY_SE_DACL_AUTO_INHERIT_REQ (0x0100)
|
||||
#define MY_SE_SACL_AUTO_INHERIT_REQ (0x0200)
|
||||
#define MY_SE_DACL_AUTO_INHERITED (0x0400)
|
||||
#define MY_SE_SACL_AUTO_INHERITED (0x0800)
|
||||
#define MY_SE_DACL_PROTECTED (0x1000)
|
||||
#define MY_SE_SACL_PROTECTED (0x2000)
|
||||
#define MY_SE_RM_CONTROL_VALID (0x4000)
|
||||
#define MY_SE_SELF_RELATIVE (0x8000)
|
||||
|
||||
void ConvertNtSecureToString(const Byte *data, UInt32 size, AString &s)
|
||||
{
|
||||
s.Empty();
|
||||
if (size < 20 || size > (1 << 18))
|
||||
{
|
||||
s += "ERROR";
|
||||
return;
|
||||
}
|
||||
if (Get16(data) != 1) // revision
|
||||
{
|
||||
s += "UNSUPPORTED";
|
||||
return;
|
||||
}
|
||||
ParseOwner(s, data, size, Get32(data + 4));
|
||||
s += ' ';
|
||||
ParseOwner(s, data, size, Get32(data + 8));
|
||||
ParseAcl(s, data, size, "s:", MY_SE_SACL_PRESENT, 12);
|
||||
ParseAcl(s, data, size, "d:", MY_SE_DACL_PRESENT, 16);
|
||||
s += ' ';
|
||||
AddUInt32ToString(s, size);
|
||||
// s += '\n';
|
||||
// s += Data_To_Hex(data, size);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
static bool CheckSid(const Byte *data, UInt32 size, UInt32 pos)
|
||||
{
|
||||
if (pos >= size)
|
||||
return false;
|
||||
size -= pos;
|
||||
if (size < 8)
|
||||
return false;
|
||||
UInt32 rev = data[pos];
|
||||
if (rev != 1)
|
||||
return false;
|
||||
UInt32 num = data[pos + 1];
|
||||
return (8 + num * 4 <= size);
|
||||
}
|
||||
|
||||
static bool CheckAcl(const Byte *p, UInt32 size, UInt32 flags, UInt32 offset)
|
||||
{
|
||||
UInt32 control = Get16(p + 2);
|
||||
if ((flags & control) == 0)
|
||||
return true;
|
||||
UInt32 pos = Get32(p + offset);
|
||||
if (pos >= size)
|
||||
return false;
|
||||
p += pos;
|
||||
size -= pos;
|
||||
if (size < 8)
|
||||
return false;
|
||||
UInt32 aclSize = Get16(p + 2);
|
||||
return (aclSize <= size);
|
||||
}
|
||||
|
||||
bool CheckNtSecure(const Byte *data, UInt32 size)
|
||||
{
|
||||
if (size < 20)
|
||||
return false;
|
||||
if (Get16(data) != 1) // revision
|
||||
return true; // windows function can handle such error, so we allow it
|
||||
if (size > (1 << 18))
|
||||
return false;
|
||||
if (!CheckSid(data, size, Get32(data + 4))) return false;
|
||||
if (!CheckSid(data, size, Get32(data + 8))) return false;
|
||||
if (!CheckAcl(data, size, MY_SE_SACL_PRESENT, 12)) return false;
|
||||
if (!CheckAcl(data, size, MY_SE_DACL_PRESENT, 16)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s)
|
||||
{
|
||||
s.Empty();
|
||||
NFile::CReparseAttr attr;
|
||||
if (attr.Parse(data, size))
|
||||
{
|
||||
if (!attr.IsSymLink())
|
||||
s += L"Junction: ";
|
||||
s += attr.GetPath();
|
||||
if (!attr.IsOkNamePair())
|
||||
{
|
||||
s += L" : ";
|
||||
s += attr.PrintName;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (size < 8)
|
||||
return false;
|
||||
UInt32 tag = Get32(data);
|
||||
UInt32 len = Get16(data + 4);
|
||||
if (len + 8 > size)
|
||||
return false;
|
||||
if (Get16(data + 6) != 0) // padding
|
||||
return false;
|
||||
|
||||
char hex[16];
|
||||
ConvertUInt32ToHex8Digits(tag, hex);
|
||||
s.AddAsciiStr(hex);
|
||||
s += L' ';
|
||||
|
||||
data += 8;
|
||||
|
||||
for (UInt32 i = 0; i < len; i++)
|
||||
{
|
||||
Byte b = ((const Byte *)data)[i];
|
||||
s += (wchar_t)GetHex((Byte)((b >> 4) & 0xF));
|
||||
s += (wchar_t)GetHex((Byte)(b & 0xF));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
13
CPP/7zip/UI/Common/PropIDUtils.h
Executable file → Normal file
13
CPP/7zip/UI/Common/PropIDUtils.h
Executable file → Normal file
@@ -3,10 +3,15 @@
|
||||
#ifndef __PROPID_UTILS_H
|
||||
#define __PROPID_UTILS_H
|
||||
|
||||
#include "Common/MyString.h"
|
||||
#include "Common/Types.h"
|
||||
#include "../../../Common/MyString.h"
|
||||
|
||||
void ConvertUInt32ToHex(UInt32 value, wchar_t *s);
|
||||
UString ConvertPropertyToString(const PROPVARIANT &propVariant, PROPID propID, bool full = true);
|
||||
// provide at least 64 bytes for buffer including zero-end
|
||||
void ConvertPropertyToShortString(char *dest, const PROPVARIANT &propVariant, PROPID propID, bool full = true) throw();
|
||||
void ConvertPropertyToString(UString &dest, const PROPVARIANT &propVariant, PROPID propID, bool full = true);
|
||||
|
||||
bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s);
|
||||
void ConvertNtSecureToString(const Byte *data, UInt32 size, AString &s);
|
||||
bool CheckNtSecure(const Byte *data, UInt32 size);
|
||||
void ConvertWinAttribToString(char *s, UInt32 wa);
|
||||
|
||||
#endif
|
||||
|
||||
0
CPP/7zip/UI/Common/Property.h
Executable file → Normal file
0
CPP/7zip/UI/Common/Property.h
Executable file → Normal file
25
CPP/7zip/UI/Common/SetProperties.cpp
Executable file → Normal file
25
CPP/7zip/UI/Common/SetProperties.cpp
Executable file → Normal file
@@ -2,25 +2,26 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "SetProperties.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../../Common/MyString.h"
|
||||
#include "../../../Common/StringToInt.h"
|
||||
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "Common/MyString.h"
|
||||
#include "Common/StringToInt.h"
|
||||
#include "Common/MyCom.h"
|
||||
#include "../../../Windows/PropVariant.h"
|
||||
|
||||
#include "../../Archive/IArchive.h"
|
||||
|
||||
#include "SetProperties.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NCOM;
|
||||
|
||||
static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop)
|
||||
{
|
||||
const wchar_t *endPtr;
|
||||
UInt64 result = ConvertStringToUInt64(s, &endPtr);
|
||||
if (endPtr - (const wchar_t *)s != s.Length())
|
||||
const wchar_t *end;
|
||||
UInt64 result = ConvertStringToUInt64(s, &end);
|
||||
if (*end != 0 || s.IsEmpty())
|
||||
prop = s;
|
||||
else if (result <= 0xFFFFFFFF)
|
||||
else if (result <= (UInt32)0xFFFFFFFF)
|
||||
prop = (UInt32)result;
|
||||
else
|
||||
prop = result;
|
||||
@@ -39,8 +40,8 @@ HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &propert
|
||||
CPropVariant *values = new CPropVariant[properties.Size()];
|
||||
try
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < properties.Size(); i++)
|
||||
unsigned i;
|
||||
for (i = 0; i < properties.Size(); i++)
|
||||
{
|
||||
const CProperty &property = properties[i];
|
||||
NCOM::CPropVariant propVariant;
|
||||
@@ -64,7 +65,7 @@ HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &propert
|
||||
values[i] = propVariant;
|
||||
}
|
||||
CRecordVector<const wchar_t *> names;
|
||||
for(i = 0; i < realNames.Size(); i++)
|
||||
for (i = 0; i < realNames.Size(); i++)
|
||||
names.Add((const wchar_t *)realNames[i]);
|
||||
|
||||
RINOK(setProperties->SetProperties(&names.Front(), values, names.Size()));
|
||||
|
||||
0
CPP/7zip/UI/Common/SetProperties.h
Executable file → Normal file
0
CPP/7zip/UI/Common/SetProperties.h
Executable file → Normal file
19
CPP/7zip/UI/Common/SortUtils.cpp
Executable file → Normal file
19
CPP/7zip/UI/Common/SortUtils.cpp
Executable file → Normal file
@@ -2,21 +2,22 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "SortUtils.h"
|
||||
#include "Common/Wildcard.h"
|
||||
#include "../../../Common/Wildcard.h"
|
||||
|
||||
static int CompareStrings(const int *p1, const int *p2, void *param)
|
||||
#include "SortUtils.h"
|
||||
|
||||
static int CompareStrings(const unsigned *p1, const unsigned *p2, void *param)
|
||||
{
|
||||
const UStringVector &strings = *(const UStringVector *)param;
|
||||
return CompareFileNames(strings[*p1], strings[*p2]);
|
||||
}
|
||||
|
||||
void SortFileNames(const UStringVector &strings, CIntVector &indices)
|
||||
void SortFileNames(const UStringVector &strings, CUIntVector &indices)
|
||||
{
|
||||
indices.Clear();
|
||||
int numItems = strings.Size();
|
||||
indices.Reserve(numItems);
|
||||
for(int i = 0; i < numItems; i++)
|
||||
indices.Add(i);
|
||||
unsigned numItems = strings.Size();
|
||||
indices.ClearAndSetSize(numItems);
|
||||
unsigned *vals = &indices[0];
|
||||
for (unsigned i = 0; i < numItems; i++)
|
||||
vals[i] = i;
|
||||
indices.Sort(CompareStrings, (void *)&strings);
|
||||
}
|
||||
|
||||
8
CPP/7zip/UI/Common/SortUtils.h
Executable file → Normal file
8
CPP/7zip/UI/Common/SortUtils.h
Executable file → Normal file
@@ -1,10 +1,10 @@
|
||||
// SortUtils.h
|
||||
|
||||
#ifndef __SORTUTLS_H
|
||||
#define __SORTUTLS_H
|
||||
#ifndef __SORT_UTLS_H
|
||||
#define __SORT_UTLS_H
|
||||
|
||||
#include "Common/MyString.h"
|
||||
#include "../../../Common/MyString.h"
|
||||
|
||||
void SortFileNames(const UStringVector &strings, CIntVector &indices);
|
||||
void SortFileNames(const UStringVector &strings, CUIntVector &indices);
|
||||
|
||||
#endif
|
||||
|
||||
5
CPP/7zip/UI/Common/StdAfx.h
Executable file → Normal file
5
CPP/7zip/UI/Common/StdAfx.h
Executable file → Normal file
@@ -1,9 +1,8 @@
|
||||
// stdafx.h
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
#include "../../../Common/NewHandler.h"
|
||||
#include "../../../Common/Common.h"
|
||||
|
||||
#endif
|
||||
|
||||
6
CPP/7zip/UI/Common/TempFiles.cpp
Executable file → Normal file
6
CPP/7zip/UI/Common/TempFiles.cpp
Executable file → Normal file
@@ -2,9 +2,9 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "TempFiles.h"
|
||||
#include "../../../Windows/FileDir.h"
|
||||
|
||||
#include "Windows/FileDir.h"
|
||||
#include "TempFiles.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
@@ -13,7 +13,7 @@ void CTempFiles::Clear()
|
||||
{
|
||||
while (!Paths.IsEmpty())
|
||||
{
|
||||
NDirectory::DeleteFileAlways(Paths.Back());
|
||||
NDir::DeleteFileAlways(Paths.Back());
|
||||
Paths.DeleteBack();
|
||||
}
|
||||
}
|
||||
|
||||
2
CPP/7zip/UI/Common/TempFiles.h
Executable file → Normal file
2
CPP/7zip/UI/Common/TempFiles.h
Executable file → Normal file
@@ -3,7 +3,7 @@
|
||||
#ifndef __TEMP_FILES_H
|
||||
#define __TEMP_FILES_H
|
||||
|
||||
#include "Common/MyString.h"
|
||||
#include "../../../Common/MyString.h"
|
||||
|
||||
class CTempFiles
|
||||
{
|
||||
|
||||
1008
CPP/7zip/UI/Common/Update.cpp
Executable file → Normal file
1008
CPP/7zip/UI/Common/Update.cpp
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
129
CPP/7zip/UI/Common/Update.h
Executable file → Normal file
129
CPP/7zip/UI/Common/Update.h
Executable file → Normal file
@@ -3,14 +3,22 @@
|
||||
#ifndef __COMMON_UPDATE_H
|
||||
#define __COMMON_UPDATE_H
|
||||
|
||||
#include "Common/Wildcard.h"
|
||||
#include "../../../Common/Wildcard.h"
|
||||
|
||||
#include "ArchiveOpenCallback.h"
|
||||
#include "LoadCodecs.h"
|
||||
#include "OpenArchive.h"
|
||||
#include "Property.h"
|
||||
#include "UpdateAction.h"
|
||||
#include "UpdateCallback.h"
|
||||
|
||||
enum EArcNameMode
|
||||
{
|
||||
k_ArcNameMode_Smart,
|
||||
k_ArcNameMode_Exact,
|
||||
k_ArcNameMode_Add,
|
||||
};
|
||||
|
||||
struct CArchivePath
|
||||
{
|
||||
UString OriginalPath;
|
||||
@@ -26,52 +34,11 @@ struct CArchivePath
|
||||
|
||||
CArchivePath(): Temp(false) {};
|
||||
|
||||
void ParseFromPath(const UString &path)
|
||||
{
|
||||
OriginalPath = path;
|
||||
|
||||
SplitPathToParts(path, Prefix, Name);
|
||||
int dotPos = Name.ReverseFind(L'.');
|
||||
if (dotPos < 0)
|
||||
return;
|
||||
if (dotPos == Name.Length() - 1)
|
||||
{
|
||||
Name = Name.Left(dotPos);
|
||||
BaseExtension.Empty();
|
||||
return;
|
||||
}
|
||||
if (BaseExtension.CompareNoCase(Name.Mid(dotPos + 1)) == 0)
|
||||
{
|
||||
BaseExtension = Name.Mid(dotPos + 1);
|
||||
Name = Name.Left(dotPos);
|
||||
}
|
||||
else
|
||||
BaseExtension.Empty();
|
||||
}
|
||||
|
||||
UString GetPathWithoutExt() const
|
||||
{
|
||||
return Prefix + Name;
|
||||
}
|
||||
|
||||
UString GetFinalPath() const
|
||||
{
|
||||
UString path = GetPathWithoutExt();
|
||||
if (!BaseExtension.IsEmpty())
|
||||
path += UString(L'.') + BaseExtension;
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
FString GetTempPath() const
|
||||
{
|
||||
FString path = TempPrefix + us2fs(Name);
|
||||
if (!BaseExtension.IsEmpty())
|
||||
path += FString(FTEXT('.')) + us2fs(BaseExtension);
|
||||
path += FTEXT(".tmp");
|
||||
path += TempPostfix;
|
||||
return path;
|
||||
}
|
||||
void ParseFromPath(const UString &path, EArcNameMode mode);
|
||||
UString GetPathWithoutExt() const { return Prefix + Name; }
|
||||
UString GetFinalPath() const;
|
||||
UString GetFinalVolPath() const;
|
||||
FString GetTempPath() const;
|
||||
};
|
||||
|
||||
struct CUpdateArchiveCommand
|
||||
@@ -83,9 +50,31 @@ struct CUpdateArchiveCommand
|
||||
|
||||
struct CCompressionMethodMode
|
||||
{
|
||||
int FormatIndex;
|
||||
bool Type_Defined;
|
||||
COpenType Type;
|
||||
CObjectVector<CProperty> Properties;
|
||||
CCompressionMethodMode(): FormatIndex(-1) {}
|
||||
|
||||
CCompressionMethodMode(): Type_Defined(false) {}
|
||||
};
|
||||
|
||||
namespace NRecursedType { enum EEnum
|
||||
{
|
||||
kRecursed,
|
||||
kWildcardOnlyRecursed,
|
||||
kNonRecursed
|
||||
};}
|
||||
|
||||
struct CRenamePair
|
||||
{
|
||||
UString OldName;
|
||||
UString NewName;
|
||||
bool WildcardParsing;
|
||||
NRecursedType::EEnum RecursedType;
|
||||
|
||||
CRenamePair(): WildcardParsing(true), RecursedType(NRecursedType::kNonRecursed) {}
|
||||
|
||||
bool Prepare();
|
||||
bool GetNewPath(bool isFolder, const UString &src, UString &dest) const;
|
||||
};
|
||||
|
||||
struct CUpdateOptions
|
||||
@@ -95,7 +84,8 @@ struct CUpdateOptions
|
||||
CObjectVector<CUpdateArchiveCommand> Commands;
|
||||
bool UpdateArchiveItself;
|
||||
CArchivePath ArchivePath;
|
||||
|
||||
EArcNameMode ArcNameMode;
|
||||
|
||||
bool SfxMode;
|
||||
FString SfxModule;
|
||||
|
||||
@@ -110,8 +100,22 @@ struct CUpdateOptions
|
||||
UString EMailAddress;
|
||||
|
||||
FString WorkingDir;
|
||||
NWildcard::ECensorPathMode PathMode;
|
||||
UString AddPathPrefix;
|
||||
|
||||
bool Init(const CCodecs *codecs, const CIntVector &formatIndices, const UString &arcPath);
|
||||
CBoolPair NtSecurity;
|
||||
CBoolPair AltStreams;
|
||||
CBoolPair HardLinks;
|
||||
CBoolPair SymLinks;
|
||||
|
||||
bool DeleteAfterCompressing;
|
||||
|
||||
bool SetArcMTime;
|
||||
|
||||
CObjectVector<CRenamePair> RenamePairs;
|
||||
|
||||
bool InitFormatIndex(const CCodecs *codecs, const CObjectVector<COpenType> &types, const UString &arcPath);
|
||||
bool SetArcPath(const CCodecs *codecs, const UString &arcPath);
|
||||
|
||||
CUpdateOptions():
|
||||
UpdateArchiveItself(true),
|
||||
@@ -120,14 +124,20 @@ struct CUpdateOptions
|
||||
StdOutMode(false),
|
||||
EMailMode(false),
|
||||
EMailRemoveAfter(false),
|
||||
OpenShareForWrite(false)
|
||||
OpenShareForWrite(false),
|
||||
ArcNameMode(k_ArcNameMode_Smart),
|
||||
PathMode(NWildcard::k_RelatPath),
|
||||
|
||||
DeleteAfterCompressing(false),
|
||||
SetArcMTime(false)
|
||||
|
||||
{};
|
||||
|
||||
void SetAddActionCommand()
|
||||
void SetActionCommand_Add()
|
||||
{
|
||||
Commands.Clear();
|
||||
CUpdateArchiveCommand c;
|
||||
c.ActionSet = NUpdateArchive::kAddActionSet;
|
||||
c.ActionSet = NUpdateArchive::k_ActionSet_Add;
|
||||
Commands.Add(c);
|
||||
}
|
||||
|
||||
@@ -151,9 +161,9 @@ struct CUpdateErrorInfo: public CErrorInfo
|
||||
|
||||
#define INTERFACE_IUpdateCallbackUI2(x) \
|
||||
INTERFACE_IUpdateCallbackUI(x) \
|
||||
virtual HRESULT OpenResult(const wchar_t *name, HRESULT result) x; \
|
||||
virtual HRESULT OpenResult(const wchar_t *name, HRESULT result, const wchar_t *errorArcType) x; \
|
||||
virtual HRESULT StartScanning() x; \
|
||||
virtual HRESULT ScanProgress(UInt64 numFolders, UInt64 numFiles, const wchar_t *path) x; \
|
||||
virtual HRESULT ScanProgress(UInt64 numFolders, UInt64 numFiles, UInt64 totalSize, const wchar_t *path, bool isDir) x; \
|
||||
virtual HRESULT CanNotFindError(const wchar_t *name, DWORD systemError) x; \
|
||||
virtual HRESULT FinishScanning() x; \
|
||||
virtual HRESULT StartArchive(const wchar_t *name, bool updating) x; \
|
||||
@@ -166,10 +176,13 @@ struct IUpdateCallbackUI2: public IUpdateCallbackUI
|
||||
|
||||
HRESULT UpdateArchive(
|
||||
CCodecs *codecs,
|
||||
const NWildcard::CCensor &censor,
|
||||
const CObjectVector<COpenType> &types,
|
||||
const UString &cmdArcPath2,
|
||||
NWildcard::CCensor &censor,
|
||||
CUpdateOptions &options,
|
||||
CUpdateErrorInfo &errorInfo,
|
||||
IOpenCallbackUI *openCallback,
|
||||
IUpdateCallbackUI2 *callback);
|
||||
IUpdateCallbackUI2 *callback,
|
||||
bool needSetPath);
|
||||
|
||||
#endif
|
||||
|
||||
10
CPP/7zip/UI/Common/UpdateAction.cpp
Executable file → Normal file
10
CPP/7zip/UI/Common/UpdateAction.cpp
Executable file → Normal file
@@ -6,7 +6,7 @@
|
||||
|
||||
namespace NUpdateArchive {
|
||||
|
||||
const CActionSet kAddActionSet =
|
||||
const CActionSet k_ActionSet_Add =
|
||||
{{
|
||||
NPairAction::kCopy,
|
||||
NPairAction::kCopy,
|
||||
@@ -17,7 +17,7 @@ const CActionSet kAddActionSet =
|
||||
NPairAction::kCompress
|
||||
}};
|
||||
|
||||
const CActionSet kUpdateActionSet =
|
||||
const CActionSet k_ActionSet_Update =
|
||||
{{
|
||||
NPairAction::kCopy,
|
||||
NPairAction::kCopy,
|
||||
@@ -28,7 +28,7 @@ const CActionSet kUpdateActionSet =
|
||||
NPairAction::kCompress
|
||||
}};
|
||||
|
||||
const CActionSet kFreshActionSet =
|
||||
const CActionSet k_ActionSet_Fresh =
|
||||
{{
|
||||
NPairAction::kCopy,
|
||||
NPairAction::kCopy,
|
||||
@@ -39,7 +39,7 @@ const CActionSet kFreshActionSet =
|
||||
NPairAction::kCompress
|
||||
}};
|
||||
|
||||
const CActionSet kSynchronizeActionSet =
|
||||
const CActionSet k_ActionSet_Sync =
|
||||
{{
|
||||
NPairAction::kCopy,
|
||||
NPairAction::kIgnore,
|
||||
@@ -50,7 +50,7 @@ const CActionSet kSynchronizeActionSet =
|
||||
NPairAction::kCompress,
|
||||
}};
|
||||
|
||||
const CActionSet kDeleteActionSet =
|
||||
const CActionSet k_ActionSet_Delete =
|
||||
{{
|
||||
NPairAction::kCopy,
|
||||
NPairAction::kIgnore,
|
||||
|
||||
23
CPP/7zip/UI/Common/UpdateAction.h
Executable file → Normal file
23
CPP/7zip/UI/Common/UpdateAction.h
Executable file → Normal file
@@ -7,7 +7,7 @@ namespace NUpdateArchive {
|
||||
|
||||
namespace NPairState
|
||||
{
|
||||
const int kNumValues = 7;
|
||||
const unsigned kNumValues = 7;
|
||||
enum EEnum
|
||||
{
|
||||
kNotMasked = 0,
|
||||
@@ -34,9 +34,18 @@ namespace NUpdateArchive {
|
||||
struct CActionSet
|
||||
{
|
||||
NPairAction::EEnum StateActions[NPairState::kNumValues];
|
||||
|
||||
const bool IsEqualTo(const CActionSet &a) const
|
||||
{
|
||||
for (unsigned i = 0; i < NPairState::kNumValues; i++)
|
||||
if (StateActions[i] != a.StateActions[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NeedScanning() const
|
||||
{
|
||||
int i;
|
||||
unsigned i;
|
||||
for (i = 0; i < NPairState::kNumValues; i++)
|
||||
if (StateActions[i] == NPairAction::kCompress)
|
||||
return true;
|
||||
@@ -47,11 +56,11 @@ namespace NUpdateArchive {
|
||||
}
|
||||
};
|
||||
|
||||
extern const CActionSet kAddActionSet;
|
||||
extern const CActionSet kUpdateActionSet;
|
||||
extern const CActionSet kFreshActionSet;
|
||||
extern const CActionSet kSynchronizeActionSet;
|
||||
extern const CActionSet kDeleteActionSet;
|
||||
extern const CActionSet k_ActionSet_Add;
|
||||
extern const CActionSet k_ActionSet_Update;
|
||||
extern const CActionSet k_ActionSet_Fresh;
|
||||
extern const CActionSet k_ActionSet_Sync;
|
||||
extern const CActionSet k_ActionSet_Delete;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
456
CPP/7zip/UI/Common/UpdateCallback.cpp
Executable file → Normal file
456
CPP/7zip/UI/Common/UpdateCallback.cpp
Executable file → Normal file
@@ -2,18 +2,32 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/ComTry.h"
|
||||
#include "Common/Defs.h"
|
||||
#include "Common/IntToString.h"
|
||||
#include "Common/StringConvert.h"
|
||||
#include "../../../Common/ComTry.h"
|
||||
#include "../../../Common/IntToString.h"
|
||||
#include "../../../Common/StringConvert.h"
|
||||
#include "../../../Common/Wildcard.h"
|
||||
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "../../../Windows/FileDir.h"
|
||||
#include "../../../Windows/FileName.h"
|
||||
#include "../../../Windows/PropVariant.h"
|
||||
#include "../../../Windows/Synchronization.h"
|
||||
|
||||
#include "../../Common/FileStreams.h"
|
||||
#include "../../Common/StreamObjects.h"
|
||||
|
||||
#include "UpdateCallback.h"
|
||||
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
#define _USE_SECURITY_CODE
|
||||
#include "../../../Windows/SecurityUtils.h"
|
||||
#endif
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
|
||||
#ifdef _USE_SECURITY_CODE
|
||||
bool InitLocalPrivileges();
|
||||
#endif
|
||||
|
||||
CArchiveUpdateCallback::CArchiveUpdateCallback():
|
||||
Callback(0),
|
||||
@@ -23,8 +37,18 @@ CArchiveUpdateCallback::CArchiveUpdateCallback():
|
||||
ArcItems(0),
|
||||
UpdatePairs(0),
|
||||
NewNames(0),
|
||||
KeepOriginalItemNames(0)
|
||||
{}
|
||||
KeepOriginalItemNames(false),
|
||||
ProcessedItemsStatuses(NULL),
|
||||
ParentDirItem(NULL),
|
||||
StoreNtSecurity(false),
|
||||
StoreHardLinks(false),
|
||||
StoreSymLinks(false),
|
||||
_hardIndex_From((UInt32)(Int32)-1)
|
||||
{
|
||||
#ifdef _USE_SECURITY_CODE
|
||||
_saclEnabled = InitLocalPrivileges();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size)
|
||||
@@ -50,7 +74,7 @@ STDMETHODIMP CArchiveUpdateCallback::SetRatioInfo(const UInt64 *inSize, const UI
|
||||
|
||||
|
||||
/*
|
||||
STATPROPSTG kProperties[] =
|
||||
static const STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
{ NULL, kpidIsDir, VT_BOOL},
|
||||
@@ -64,7 +88,7 @@ STATPROPSTG kProperties[] =
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **)
|
||||
{
|
||||
return CStatPropEnumerator::CreateEnumerator(kProperties, sizeof(kProperties) / sizeof(kProperties[0]), enumerator);
|
||||
return CStatPropEnumerator::CreateEnumerator(kProps, ARRAY_SIZE(kProps), enumerator);
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -74,11 +98,11 @@ STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index,
|
||||
COM_TRY_BEGIN
|
||||
RINOK(Callback->CheckBreak());
|
||||
const CUpdatePair2 &up = (*UpdatePairs)[index];
|
||||
if (newData != NULL) *newData = BoolToInt(up.NewData);
|
||||
if (newProps != NULL) *newProps = BoolToInt(up.NewProps);
|
||||
if (indexInArchive != NULL)
|
||||
if (newData) *newData = BoolToInt(up.NewData);
|
||||
if (newProps) *newProps = BoolToInt(up.NewProps);
|
||||
if (indexInArchive)
|
||||
{
|
||||
*indexInArchive = (UInt32)-1;
|
||||
*indexInArchive = (UInt32)(Int32)-1;
|
||||
if (up.ExistInArchive())
|
||||
*indexInArchive = (ArcItems == 0) ? up.ArcIndex : (*ArcItems)[up.ArcIndex].IndexInServer;
|
||||
}
|
||||
@@ -86,84 +110,302 @@ 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;
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *parentType)
|
||||
{
|
||||
*parentType = NParentType::kDir;
|
||||
*parent = (UInt32)(Int32)-1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::GetNumRawProps(UInt32 *numProps)
|
||||
{
|
||||
*numProps = 0;
|
||||
if (StoreNtSecurity)
|
||||
*numProps = 1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID)
|
||||
{
|
||||
*name = NULL;
|
||||
*propID = kpidNtSecure;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::GetRootRawProp(PROPID
|
||||
#ifdef _USE_SECURITY_CODE
|
||||
propID
|
||||
#endif
|
||||
, const void **data, UInt32 *dataSize, UInt32 *propType)
|
||||
{
|
||||
*data = 0;
|
||||
*dataSize = 0;
|
||||
*propType = 0;
|
||||
if (!StoreNtSecurity)
|
||||
return S_OK;
|
||||
#ifdef _USE_SECURITY_CODE
|
||||
if (propID == kpidNtSecure)
|
||||
{
|
||||
if (StdInMode)
|
||||
return S_OK;
|
||||
|
||||
if (ParentDirItem)
|
||||
{
|
||||
if (ParentDirItem->SecureIndex < 0)
|
||||
return S_OK;
|
||||
const CByteBuffer &buf = DirItems->SecureBlocks.Bufs[ParentDirItem->SecureIndex];
|
||||
*data = buf;
|
||||
*dataSize = (UInt32)buf.Size();
|
||||
*propType = NPropDataType::kRaw;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (GetRootProps)
|
||||
return GetRootProps->GetRootRawProp(propID, data, dataSize, propType);
|
||||
}
|
||||
#endif
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// #ifdef _USE_SECURITY_CODE
|
||||
// #endif
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)
|
||||
{
|
||||
*data = 0;
|
||||
*dataSize = 0;
|
||||
*propType = 0;
|
||||
|
||||
if (propID == kpidNtSecure ||
|
||||
propID == kpidNtReparse)
|
||||
{
|
||||
if (StdInMode)
|
||||
return S_OK;
|
||||
|
||||
const CUpdatePair2 &up = (*UpdatePairs)[index];
|
||||
if (up.UseArcProps && up.ExistInArchive() && GetRawProps)
|
||||
return GetRawProps->GetRawProp(
|
||||
ArcItems ? (*ArcItems)[up.ArcIndex].IndexInServer : up.ArcIndex,
|
||||
propID, data, dataSize, propType);
|
||||
|
||||
{
|
||||
const CUpdatePair2 &up = (*UpdatePairs)[index];
|
||||
/*
|
||||
if (!up.NewData)
|
||||
return E_FAIL;
|
||||
*/
|
||||
if (up.IsAnti)
|
||||
return S_OK;
|
||||
|
||||
#ifndef UNDER_CE
|
||||
const CDirItem &di = DirItems->Items[up.DirIndex];
|
||||
#endif
|
||||
|
||||
#ifdef _USE_SECURITY_CODE
|
||||
if (propID == kpidNtSecure)
|
||||
{
|
||||
if (!StoreNtSecurity)
|
||||
return S_OK;
|
||||
if (di.SecureIndex < 0)
|
||||
return S_OK;
|
||||
const CByteBuffer &buf = DirItems->SecureBlocks.Bufs[di.SecureIndex];
|
||||
*data = buf;
|
||||
*dataSize = (UInt32)buf.Size();
|
||||
*propType = NPropDataType::kRaw;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// propID == kpidNtReparse
|
||||
if (!StoreSymLinks)
|
||||
return S_OK;
|
||||
#ifndef UNDER_CE
|
||||
const CByteBuffer *buf = &di.ReparseData2;
|
||||
if (buf->Size() == 0)
|
||||
buf = &di.ReparseData;
|
||||
if (buf->Size() != 0)
|
||||
{
|
||||
*data = *buf;
|
||||
*dataSize = (UInt32)buf->Size();
|
||||
*propType = NPropDataType::kRaw;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#ifndef UNDER_CE
|
||||
|
||||
static UString GetRelativePath(const UString &to, const UString &from)
|
||||
{
|
||||
UStringVector partsTo, partsFrom;
|
||||
SplitPathToParts(to, partsTo);
|
||||
SplitPathToParts(from, partsFrom);
|
||||
|
||||
unsigned i;
|
||||
for (i = 0;; i++)
|
||||
{
|
||||
if (i + 1 >= partsFrom.Size() ||
|
||||
i + 1 >= partsTo.Size())
|
||||
break;
|
||||
if (CompareFileNames(partsFrom[i], partsTo[i]) != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (NName::IsDrivePath(to) ||
|
||||
NName::IsDrivePath(from))
|
||||
return to;
|
||||
#endif
|
||||
}
|
||||
|
||||
UString s;
|
||||
unsigned k;
|
||||
|
||||
for (k = i + 1; k < partsFrom.Size(); k++)
|
||||
s += L".." WSTRING_PATH_SEPARATOR;
|
||||
|
||||
for (k = i; k < partsTo.Size(); k++)
|
||||
{
|
||||
if (k != i)
|
||||
s += WCHAR_PATH_SEPARATOR;
|
||||
s += partsTo[k];
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
const CUpdatePair2 &up = (*UpdatePairs)[index];
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
|
||||
if (propID == kpidIsAnti)
|
||||
{
|
||||
prop = up.IsAnti;
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
NCOM::CPropVariant prop;
|
||||
|
||||
if (up.IsAnti)
|
||||
if (up.NewData)
|
||||
{
|
||||
switch(propID)
|
||||
/*
|
||||
if (propID == kpidIsHardLink)
|
||||
{
|
||||
case kpidIsDir:
|
||||
case kpidPath:
|
||||
break;
|
||||
case kpidSize:
|
||||
prop = (UInt64)0;
|
||||
prop = _isHardLink;
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
*/
|
||||
if (propID == kpidSymLink)
|
||||
{
|
||||
if (index == _hardIndex_From)
|
||||
{
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
default:
|
||||
}
|
||||
if (up.DirIndex >= 0)
|
||||
{
|
||||
#ifndef UNDER_CE
|
||||
const CDirItem &di = DirItems->Items[up.DirIndex];
|
||||
// if (di.IsDir())
|
||||
{
|
||||
di.ReparseData;
|
||||
CReparseAttr attr;
|
||||
if (attr.Parse(di.ReparseData, di.ReparseData.Size()))
|
||||
{
|
||||
UString simpleName = attr.GetPath();
|
||||
if (attr.IsRelative())
|
||||
prop = simpleName;
|
||||
else
|
||||
{
|
||||
const UString phyPath = DirItems->GetPhyPath(up.DirIndex);
|
||||
FString fullPath;
|
||||
if (NDir::MyGetFullPathName(us2fs(phyPath), fullPath))
|
||||
{
|
||||
prop = GetRelativePath(simpleName, fs2us(fullPath));
|
||||
}
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (propID == kpidHardLink)
|
||||
{
|
||||
if (index == _hardIndex_From)
|
||||
{
|
||||
const CKeyKeyValPair &pair = _map[_hardIndex_To];
|
||||
const CUpdatePair2 &up2 = (*UpdatePairs)[pair.Value];
|
||||
prop = DirItems->GetLogPath(up2.DirIndex);
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
if (up.DirIndex >= 0)
|
||||
{
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (up.ExistOnDisk())
|
||||
if (up.IsAnti
|
||||
&& propID != kpidIsDir
|
||||
&& propID != kpidPath
|
||||
&& propID != kpidIsAltStream)
|
||||
{
|
||||
switch (propID)
|
||||
{
|
||||
case kpidSize: prop = (UInt64)0; break;
|
||||
case kpidIsAnti: prop = true; break;
|
||||
}
|
||||
}
|
||||
else if (propID == kpidPath && up.NewNameIndex >= 0)
|
||||
prop = (*NewNames)[up.NewNameIndex];
|
||||
else if (propID == kpidShortName && up.NewNameIndex >= 0 && up.IsMainRenameItem)
|
||||
{
|
||||
// we can generate new ShortName here;
|
||||
}
|
||||
else if ((up.UseArcProps
|
||||
|| (KeepOriginalItemNames && (propID == kpidPath || propID == kpidIsAltStream)))
|
||||
&& up.ExistInArchive() && Archive)
|
||||
return Archive->GetProperty(ArcItems ? (*ArcItems)[up.ArcIndex].IndexInServer : up.ArcIndex, propID, value);
|
||||
else if (up.ExistOnDisk())
|
||||
{
|
||||
const CDirItem &di = DirItems->Items[up.DirIndex];
|
||||
switch(propID)
|
||||
switch (propID)
|
||||
{
|
||||
case kpidPath:
|
||||
{
|
||||
if (KeepOriginalItemNames)
|
||||
{
|
||||
if (up.ExistInArchive() && Archive)
|
||||
{
|
||||
UInt32 indexInArchive;
|
||||
if (ArcItems == 0)
|
||||
indexInArchive = up.ArcIndex;
|
||||
else
|
||||
indexInArchive = (*ArcItems)[up.ArcIndex].IndexInServer;
|
||||
return Archive->GetProperty(indexInArchive, propID, value);
|
||||
}
|
||||
}
|
||||
prop = DirItems->GetLogPath(up.DirIndex); break;
|
||||
}
|
||||
case kpidPath: prop = DirItems->GetLogPath(up.DirIndex); break;
|
||||
case kpidIsDir: prop = di.IsDir(); break;
|
||||
case kpidSize: prop = 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;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (propID == kpidPath)
|
||||
{
|
||||
if (up.NewNameIndex >= 0)
|
||||
{
|
||||
prop = (*NewNames)[up.NewNameIndex];
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
if (up.ExistInArchive() && Archive)
|
||||
{
|
||||
UInt32 indexInArchive;
|
||||
if (ArcItems == 0)
|
||||
indexInArchive = up.ArcIndex;
|
||||
else
|
||||
indexInArchive = (*ArcItems)[up.ArcIndex].IndexInServer;
|
||||
return Archive->GetProperty(indexInArchive, propID, value);
|
||||
case kpidIsAltStream: prop = di.IsAltStream; break;
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
// case kpidShortName: prop = di.ShortName; break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
prop.Detach(value);
|
||||
@@ -171,9 +413,12 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
static NSynchronization::CCriticalSection CS;
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
*inStream = NULL;
|
||||
const CUpdatePair2 &up = (*UpdatePairs)[index];
|
||||
if (!up.NewData)
|
||||
return E_FAIL;
|
||||
@@ -181,14 +426,33 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream
|
||||
RINOK(Callback->CheckBreak());
|
||||
RINOK(Callback->Finilize());
|
||||
|
||||
bool isDir = IsDir(up);
|
||||
|
||||
if (up.IsAnti)
|
||||
{
|
||||
return Callback->GetStream((*ArcItems)[up.ArcIndex].Name, true);
|
||||
UString name;
|
||||
if (up.ArcIndex >= 0)
|
||||
name = (*ArcItems)[up.ArcIndex].Name;
|
||||
else if (up.DirIndex >= 0)
|
||||
name = DirItems->GetLogPath(up.DirIndex);
|
||||
RINOK(Callback->GetStream(name, true));
|
||||
|
||||
/* 9.33: fixed. Handlers expect real stream object for files, even for anti-file.
|
||||
so we return empty stream */
|
||||
|
||||
if (!isDir)
|
||||
{
|
||||
CBufInStream *inStreamSpec = new CBufInStream();
|
||||
CMyComPtr<ISequentialInStream> inStreamLoc = inStreamSpec;
|
||||
inStreamSpec->Init(NULL, 0);
|
||||
*inStream = inStreamLoc.Detach();
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
const CDirItem &di = DirItems->Items[up.DirIndex];
|
||||
|
||||
RINOK(Callback->GetStream(DirItems->GetLogPath(up.DirIndex), false));
|
||||
|
||||
if (di.IsDir())
|
||||
if (isDir)
|
||||
return S_OK;
|
||||
|
||||
if (StdInMode)
|
||||
@@ -201,13 +465,59 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream
|
||||
{
|
||||
CInFileStream *inStreamSpec = new CInFileStream;
|
||||
CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
|
||||
|
||||
inStreamSpec->SupportHardLinks = StoreHardLinks;
|
||||
|
||||
const UString path = DirItems->GetPhyPath(up.DirIndex);
|
||||
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
if (DirItems->Items[up.DirIndex].AreReparseData())
|
||||
{
|
||||
if (!inStreamSpec->File.OpenReparse(us2fs(path)))
|
||||
{
|
||||
return Callback->OpenFileError(path, ::GetLastError());
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (!inStreamSpec->OpenShared(us2fs(path), ShareForWrite))
|
||||
{
|
||||
return Callback->OpenFileError(path, ::GetLastError());
|
||||
}
|
||||
|
||||
if (StoreHardLinks)
|
||||
{
|
||||
CStreamFileProps props;
|
||||
if (inStreamSpec->GetProps2(&props) == S_OK)
|
||||
{
|
||||
if (props.NumLinks > 1)
|
||||
{
|
||||
CKeyKeyValPair pair;
|
||||
pair.Key1 = props.VolID;
|
||||
pair.Key2 = props.FileID_Low;
|
||||
pair.Value = index;
|
||||
unsigned numItems = _map.Size();
|
||||
unsigned pairIndex = _map.AddToUniqueSorted2(pair);
|
||||
if (numItems == _map.Size())
|
||||
{
|
||||
// const CKeyKeyValPair &pair2 = _map.Pairs[pairIndex];
|
||||
_hardIndex_From = index;
|
||||
_hardIndex_To = pairIndex;
|
||||
// we could return NULL as stream, but it's better to return real stream
|
||||
// return S_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ProcessedItemsStatuses)
|
||||
{
|
||||
NSynchronization::CCriticalSectionLock lock(CS);
|
||||
ProcessedItemsStatuses[up.DirIndex] = 1;
|
||||
}
|
||||
*inStream = inStreamLoc.Detach();
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
@@ -235,8 +545,8 @@ STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOu
|
||||
FChar temp[16];
|
||||
ConvertUInt32ToString(index + 1, temp);
|
||||
FString res = temp;
|
||||
while (res.Length() < 2)
|
||||
res = FString(FTEXT('0')) + res;
|
||||
while (res.Len() < 2)
|
||||
res.InsertAtFront(FTEXT('0'));
|
||||
FString fileName = VolName;
|
||||
fileName += L'.';
|
||||
fileName += res;
|
||||
|
||||
59
CPP/7zip/UI/Common/UpdateCallback.h
Executable file → Normal file
59
CPP/7zip/UI/Common/UpdateCallback.h
Executable file → Normal file
@@ -1,10 +1,9 @@
|
||||
// UpdateCallback.h
|
||||
|
||||
#ifndef __UPDATECALLBACK_H
|
||||
#define __UPDATECALLBACK_H
|
||||
#ifndef __UPDATE_CALLBACK_H
|
||||
#define __UPDATE_CALLBACK_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "Common/MyString.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
#include "../../IPassword.h"
|
||||
#include "../../ICoder.h"
|
||||
@@ -32,16 +31,43 @@ struct IUpdateCallbackUI
|
||||
INTERFACE_IUpdateCallbackUI(=0)
|
||||
};
|
||||
|
||||
struct CKeyKeyValPair
|
||||
{
|
||||
UInt64 Key1;
|
||||
UInt64 Key2;
|
||||
unsigned Value;
|
||||
|
||||
int Compare(const CKeyKeyValPair &a) const
|
||||
{
|
||||
if (Key1 < a.Key1) return -1;
|
||||
if (Key1 > a.Key1) return 1;
|
||||
return MyCompare(Key2, a.Key2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class CArchiveUpdateCallback:
|
||||
public IArchiveUpdateCallback2,
|
||||
public IArchiveGetRawProps,
|
||||
public IArchiveGetRootProps,
|
||||
public ICryptoGetTextPassword2,
|
||||
public ICryptoGetTextPassword,
|
||||
public ICompressProgressInfo,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
bool _saclEnabled;
|
||||
#endif
|
||||
CRecordVector<CKeyKeyValPair> _map;
|
||||
|
||||
UInt32 _hardIndex_From;
|
||||
UInt32 _hardIndex_To;
|
||||
|
||||
public:
|
||||
MY_UNKNOWN_IMP4(
|
||||
MY_UNKNOWN_IMP6(
|
||||
IArchiveUpdateCallback2,
|
||||
IArchiveGetRawProps,
|
||||
IArchiveGetRootProps,
|
||||
ICryptoGetTextPassword2,
|
||||
ICryptoGetTextPassword,
|
||||
ICompressProgressInfo)
|
||||
@@ -49,11 +75,12 @@ public:
|
||||
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
|
||||
|
||||
INTERFACE_IArchiveUpdateCallback2(;)
|
||||
INTERFACE_IArchiveGetRawProps(;)
|
||||
INTERFACE_IArchiveGetRootProps(;)
|
||||
|
||||
STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password);
|
||||
STDMETHOD(CryptoGetTextPassword)(BSTR *password);
|
||||
|
||||
public:
|
||||
CRecordVector<UInt64> VolumesSizes;
|
||||
FString VolName;
|
||||
FString VolExt;
|
||||
@@ -62,14 +89,34 @@ public:
|
||||
|
||||
bool ShareForWrite;
|
||||
bool StdInMode;
|
||||
|
||||
const CDirItems *DirItems;
|
||||
const CDirItem *ParentDirItem;
|
||||
|
||||
const CObjectVector<CArcItem> *ArcItems;
|
||||
const CRecordVector<CUpdatePair2> *UpdatePairs;
|
||||
const UStringVector *NewNames;
|
||||
CMyComPtr<IInArchive> Archive;
|
||||
CMyComPtr<IArchiveGetRawProps> GetRawProps;
|
||||
CMyComPtr<IArchiveGetRootProps> GetRootProps;
|
||||
|
||||
bool KeepOriginalItemNames;
|
||||
bool StoreNtSecurity;
|
||||
bool StoreHardLinks;
|
||||
bool StoreSymLinks;
|
||||
|
||||
Byte *ProcessedItemsStatuses;
|
||||
|
||||
CArchiveUpdateCallback();
|
||||
|
||||
bool IsDir(const CUpdatePair2 &up) const
|
||||
{
|
||||
if (up.DirIndex >= 0)
|
||||
return DirItems->Items[up.DirIndex].IsDir();
|
||||
else if (up.ArcIndex >= 0)
|
||||
return (*ArcItems)[up.ArcIndex].IsDir;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
203
CPP/7zip/UI/Common/UpdatePair.cpp
Executable file → Normal file
203
CPP/7zip/UI/Common/UpdatePair.cpp
Executable file → Normal file
@@ -4,10 +4,9 @@
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "Common/Defs.h"
|
||||
#include "Common/Wildcard.h"
|
||||
#include "../../../Common/Wildcard.h"
|
||||
|
||||
#include "Windows/Time.h"
|
||||
#include "../../../Windows/TimeUtils.h"
|
||||
|
||||
#include "SortUtils.h"
|
||||
#include "UpdatePair.h"
|
||||
@@ -17,7 +16,7 @@ using namespace NTime;
|
||||
|
||||
static int MyCompareTime(NFileTimeType::EEnum fileTimeType, const FILETIME &time1, const FILETIME &time2)
|
||||
{
|
||||
switch(fileTimeType)
|
||||
switch (fileTimeType)
|
||||
{
|
||||
case NFileTimeType::kWindows:
|
||||
return ::CompareFileTime(&time1, &time2);
|
||||
@@ -39,24 +38,38 @@ static int MyCompareTime(NFileTimeType::EEnum fileTimeType, const FILETIME &time
|
||||
throw 4191618;
|
||||
}
|
||||
|
||||
static const wchar_t *kDuplicateFileNameMessage = L"Duplicate filename:";
|
||||
static const wchar_t *kNotCensoredCollisionMessaged = L"Internal file name collision (file on disk, file in archive):";
|
||||
static const char *k_Duplicate_inArc_Message = "Duplicate filename in archive:";
|
||||
static const char *k_Duplicate_inDir_Message = "Duplicate filename on disk:";
|
||||
static const char *k_NotCensoredCollision_Message = "Internal file name collision (file on disk, file in archive):";
|
||||
|
||||
static void ThrowError(const UString &message, const UString &s1, const UString &s2)
|
||||
static void ThrowError(const char *message, const UString &s1, const UString &s2)
|
||||
{
|
||||
UString m = message;
|
||||
m += L'\n';
|
||||
m += s1;
|
||||
m += L'\n';
|
||||
m += s2;
|
||||
UString m;
|
||||
m.SetFromAscii(message);
|
||||
m += L'\n'; m += s1;
|
||||
m += L'\n'; m += s2;
|
||||
throw m;
|
||||
}
|
||||
|
||||
static void TestDuplicateString(const UStringVector &strings, const CIntVector &indices)
|
||||
static int CompareArcItemsBase(const CArcItem &ai1, const CArcItem &ai2)
|
||||
{
|
||||
for(int i = 0; i + 1 < indices.Size(); i++)
|
||||
if (CompareFileNames(strings[indices[i]], strings[indices[i + 1]]) == 0)
|
||||
ThrowError(kDuplicateFileNameMessage, strings[indices[i]], strings[indices[i + 1]]);
|
||||
int res = CompareFileNames(ai1.Name, ai2.Name);
|
||||
if (res != 0)
|
||||
return res;
|
||||
if (ai1.IsDir != ai2.IsDir)
|
||||
return ai1.IsDir ? -1 : 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int CompareArcItems(const unsigned *p1, const unsigned *p2, void *param)
|
||||
{
|
||||
unsigned i1 = *p1;
|
||||
unsigned i2 = *p2;
|
||||
const CObjectVector<CArcItem> &arcItems = *(const CObjectVector<CArcItem> *)param;
|
||||
int res = CompareArcItemsBase(arcItems[i1], arcItems[i2]);
|
||||
if (res != 0)
|
||||
return res;
|
||||
return MyCompare(i1, i2);
|
||||
}
|
||||
|
||||
void GetUpdatePairInfoList(
|
||||
@@ -65,48 +78,103 @@ void GetUpdatePairInfoList(
|
||||
NFileTimeType::EEnum fileTimeType,
|
||||
CRecordVector<CUpdatePair> &updatePairs)
|
||||
{
|
||||
CIntVector dirIndices, arcIndices;
|
||||
|
||||
int numDirItems = dirItems.Items.Size();
|
||||
int numArcItems = arcItems.Size();
|
||||
CUIntVector dirIndices, arcIndices;
|
||||
|
||||
unsigned numDirItems = dirItems.Items.Size();
|
||||
unsigned numArcItems = arcItems.Size();
|
||||
|
||||
CIntArr duplicatedArcItem(numArcItems);
|
||||
{
|
||||
UStringVector arcNames;
|
||||
arcNames.Reserve(numArcItems);
|
||||
for (int i = 0; i < numArcItems; i++)
|
||||
arcNames.Add(arcItems[i].Name);
|
||||
SortFileNames(arcNames, arcIndices);
|
||||
TestDuplicateString(arcNames, arcIndices);
|
||||
int *vals = &duplicatedArcItem[0];
|
||||
for (unsigned i = 0; i < numArcItems; i++)
|
||||
vals[i] = 0;
|
||||
}
|
||||
|
||||
{
|
||||
arcIndices.ClearAndSetSize(numArcItems);
|
||||
{
|
||||
unsigned *vals = &arcIndices[0];
|
||||
for (unsigned i = 0; i < numArcItems; i++)
|
||||
vals[i] = i;
|
||||
}
|
||||
arcIndices.Sort(CompareArcItems, (void *)&arcItems);
|
||||
for (unsigned i = 0; i + 1 < numArcItems; i++)
|
||||
if (CompareArcItemsBase(
|
||||
arcItems[arcIndices[i]],
|
||||
arcItems[arcIndices[i + 1]]) == 0)
|
||||
{
|
||||
duplicatedArcItem[i] = 1;
|
||||
duplicatedArcItem[i + 1] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
UStringVector dirNames;
|
||||
{
|
||||
dirNames.Reserve(numDirItems);
|
||||
for (int i = 0; i < numDirItems; i++)
|
||||
dirNames.Add(dirItems.GetLogPath(i));
|
||||
dirNames.ClearAndReserve(numDirItems);
|
||||
unsigned i;
|
||||
for (i = 0; i < numDirItems; i++)
|
||||
dirNames.AddInReserved(dirItems.GetLogPath(i));
|
||||
SortFileNames(dirNames, dirIndices);
|
||||
TestDuplicateString(dirNames, dirIndices);
|
||||
for (i = 0; i + 1 < numDirItems; i++)
|
||||
{
|
||||
const UString &s1 = dirNames[dirIndices[i]];
|
||||
const UString &s2 = dirNames[dirIndices[i + 1]];
|
||||
if (CompareFileNames(s1, s2) == 0)
|
||||
ThrowError(k_Duplicate_inDir_Message, s1, s2);
|
||||
}
|
||||
}
|
||||
|
||||
int dirIndex = 0, arcIndex = 0;
|
||||
while (dirIndex < numDirItems && arcIndex < numArcItems)
|
||||
unsigned dirIndex = 0;
|
||||
unsigned arcIndex = 0;
|
||||
|
||||
int prevHostFile = -1;
|
||||
const UString *prevHostName = NULL;
|
||||
|
||||
while (dirIndex < numDirItems || arcIndex < numArcItems)
|
||||
{
|
||||
CUpdatePair pair;
|
||||
int dirIndex2 = dirIndices[dirIndex];
|
||||
int arcIndex2 = arcIndices[arcIndex];
|
||||
const CDirItem &di = dirItems.Items[dirIndex2];
|
||||
const CArcItem &ai = arcItems[arcIndex2];
|
||||
int compareResult = CompareFileNames(dirNames[dirIndex2], ai.Name);
|
||||
|
||||
int dirIndex2 = -1;
|
||||
int arcIndex2 = -1;
|
||||
const CDirItem *di = NULL;
|
||||
const CArcItem *ai = NULL;
|
||||
|
||||
int compareResult = -1;
|
||||
const UString *name = NULL;
|
||||
|
||||
if (dirIndex < numDirItems)
|
||||
{
|
||||
dirIndex2 = dirIndices[dirIndex];
|
||||
di = &dirItems.Items[dirIndex2];
|
||||
}
|
||||
|
||||
if (arcIndex < numArcItems)
|
||||
{
|
||||
arcIndex2 = arcIndices[arcIndex];
|
||||
ai = &arcItems[arcIndex2];
|
||||
compareResult = 1;
|
||||
if (dirIndex < numDirItems)
|
||||
{
|
||||
compareResult = CompareFileNames(dirNames[dirIndex2], ai->Name);
|
||||
if (compareResult == 0)
|
||||
{
|
||||
if (di->IsDir() != ai->IsDir)
|
||||
compareResult = (ai->IsDir ? 1 : -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (compareResult < 0)
|
||||
{
|
||||
name = &dirNames[dirIndex2];
|
||||
pair.State = NUpdateArchive::NPairState::kOnlyOnDisk;
|
||||
pair.DirIndex = dirIndex2;
|
||||
dirIndex++;
|
||||
}
|
||||
else if (compareResult > 0)
|
||||
{
|
||||
pair.State = ai.Censored ?
|
||||
name = &ai->Name;
|
||||
pair.State = ai->Censored ?
|
||||
NUpdateArchive::NPairState::kOnlyInArchive:
|
||||
NUpdateArchive::NPairState::kNotMasked;
|
||||
pair.ArcIndex = arcIndex2;
|
||||
@@ -114,43 +182,50 @@ void GetUpdatePairInfoList(
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ai.Censored)
|
||||
ThrowError(kNotCensoredCollisionMessaged, dirNames[dirIndex2], ai.Name);
|
||||
int dupl = duplicatedArcItem[arcIndex];
|
||||
if (dupl != 0)
|
||||
ThrowError(k_Duplicate_inArc_Message, ai->Name, arcItems[arcIndices[arcIndex + dupl]].Name);
|
||||
|
||||
name = &dirNames[dirIndex2];
|
||||
if (!ai->Censored)
|
||||
ThrowError(k_NotCensoredCollision_Message, *name, ai->Name);
|
||||
|
||||
pair.DirIndex = dirIndex2;
|
||||
pair.ArcIndex = arcIndex2;
|
||||
switch (ai.MTimeDefined ? MyCompareTime(
|
||||
ai.TimeType != - 1 ? (NFileTimeType::EEnum)ai.TimeType : fileTimeType,
|
||||
di.MTime, ai.MTime): 0)
|
||||
|
||||
switch (ai->MTimeDefined ? MyCompareTime(
|
||||
ai->TimeType != - 1 ? (NFileTimeType::EEnum)ai->TimeType : fileTimeType,
|
||||
di->MTime, ai->MTime): 0)
|
||||
{
|
||||
case -1: pair.State = NUpdateArchive::NPairState::kNewInArchive; break;
|
||||
case 1: pair.State = NUpdateArchive::NPairState::kOldInArchive; break;
|
||||
case 1: pair.State = NUpdateArchive::NPairState::kOldInArchive; break;
|
||||
default:
|
||||
pair.State = (ai.SizeDefined && di.Size == ai.Size) ?
|
||||
pair.State = (ai->SizeDefined && di->Size == ai->Size) ?
|
||||
NUpdateArchive::NPairState::kSameFiles :
|
||||
NUpdateArchive::NPairState::kUnknowNewerFiles;
|
||||
}
|
||||
|
||||
dirIndex++;
|
||||
arcIndex++;
|
||||
}
|
||||
updatePairs.Add(pair);
|
||||
}
|
||||
|
||||
for (; dirIndex < numDirItems; dirIndex++)
|
||||
{
|
||||
CUpdatePair pair;
|
||||
pair.State = NUpdateArchive::NPairState::kOnlyOnDisk;
|
||||
pair.DirIndex = dirIndices[dirIndex];
|
||||
updatePairs.Add(pair);
|
||||
}
|
||||
|
||||
for (; arcIndex < numArcItems; arcIndex++)
|
||||
{
|
||||
CUpdatePair pair;
|
||||
int arcIndex2 = arcIndices[arcIndex];
|
||||
pair.State = arcItems[arcIndex2].Censored ?
|
||||
NUpdateArchive::NPairState::kOnlyInArchive:
|
||||
NUpdateArchive::NPairState::kNotMasked;
|
||||
pair.ArcIndex = arcIndex2;
|
||||
|
||||
if ((di && di->IsAltStream) ||
|
||||
(ai && ai->IsAltStream))
|
||||
{
|
||||
if (prevHostName)
|
||||
{
|
||||
unsigned hostLen = prevHostName->Len();
|
||||
if (name->Len() > hostLen)
|
||||
if ((*name)[hostLen] == ':' && CompareFileNames(*prevHostName, name->Left(hostLen)) == 0)
|
||||
pair.HostIndex = prevHostFile;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
prevHostFile = updatePairs.Size();
|
||||
prevHostName = name;
|
||||
}
|
||||
|
||||
updatePairs.Add(pair);
|
||||
}
|
||||
|
||||
|
||||
4
CPP/7zip/UI/Common/UpdatePair.h
Executable file → Normal file
4
CPP/7zip/UI/Common/UpdatePair.h
Executable file → Normal file
@@ -13,7 +13,9 @@ struct CUpdatePair
|
||||
NUpdateArchive::NPairState::EEnum State;
|
||||
int ArcIndex;
|
||||
int DirIndex;
|
||||
CUpdatePair(): ArcIndex(-1), DirIndex(-1) {}
|
||||
int HostIndex; // >= 0 for alt streams only, contains index of host pair
|
||||
|
||||
CUpdatePair(): ArcIndex(-1), DirIndex(-1), HostIndex(-1) {}
|
||||
};
|
||||
|
||||
void GetUpdatePairInfoList(
|
||||
|
||||
21
CPP/7zip/UI/Common/UpdateProduce.cpp
Executable file → Normal file
21
CPP/7zip/UI/Common/UpdateProduce.cpp
Executable file → Normal file
@@ -14,17 +14,17 @@ void UpdateProduce(
|
||||
CRecordVector<CUpdatePair2> &operationChain,
|
||||
IUpdateProduceCallback *callback)
|
||||
{
|
||||
for (int i = 0; i < updatePairs.Size(); i++)
|
||||
FOR_VECTOR (i, updatePairs)
|
||||
{
|
||||
const CUpdatePair &pair = updatePairs[i];
|
||||
|
||||
CUpdatePair2 up2;
|
||||
up2.IsAnti = false;
|
||||
up2.DirIndex = pair.DirIndex;
|
||||
up2.ArcIndex = pair.ArcIndex;
|
||||
up2.NewData = up2.NewProps = true;
|
||||
up2.UseArcProps = false;
|
||||
|
||||
switch(actionSet.StateActions[pair.State])
|
||||
switch (actionSet.StateActions[pair.State])
|
||||
{
|
||||
case NPairAction::kIgnore:
|
||||
/*
|
||||
@@ -39,7 +39,21 @@ void UpdateProduce(
|
||||
case NPairAction::kCopy:
|
||||
if (pair.State == NPairState::kOnlyOnDisk)
|
||||
throw kUpdateActionSetCollision;
|
||||
if (pair.State == NPairState::kOnlyInArchive)
|
||||
{
|
||||
if (pair.HostIndex >= 0)
|
||||
{
|
||||
/*
|
||||
ignore alt stream if
|
||||
1) no such alt stream in Disk
|
||||
2) there is Host file in disk
|
||||
*/
|
||||
if (updatePairs[pair.HostIndex].DirIndex >= 0)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
up2.NewData = up2.NewProps = false;
|
||||
up2.UseArcProps = true;
|
||||
break;
|
||||
|
||||
case NPairAction::kCompress:
|
||||
@@ -50,6 +64,7 @@ void UpdateProduce(
|
||||
|
||||
case NPairAction::kCompressAsAnti:
|
||||
up2.IsAnti = true;
|
||||
up2.UseArcProps = (pair.ArcIndex >= 0);
|
||||
break;
|
||||
}
|
||||
operationChain.Add(up2);
|
||||
|
||||
15
CPP/7zip/UI/Common/UpdateProduce.h
Executable file → Normal file
15
CPP/7zip/UI/Common/UpdateProduce.h
Executable file → Normal file
@@ -9,16 +9,27 @@ struct CUpdatePair2
|
||||
{
|
||||
bool NewData;
|
||||
bool NewProps;
|
||||
bool IsAnti;
|
||||
bool UseArcProps; // if (UseArcProps && NewProps), we want to change only some properties.
|
||||
bool IsAnti; // if (!IsAnti) we use other ways to detect Anti status
|
||||
|
||||
int DirIndex;
|
||||
int ArcIndex;
|
||||
int NewNameIndex;
|
||||
|
||||
bool IsMainRenameItem;
|
||||
|
||||
void SetAs_NoChangeArcItem(int arcIndex)
|
||||
{
|
||||
NewData = NewProps = false;
|
||||
UseArcProps = true;
|
||||
IsAnti = false;
|
||||
ArcIndex = arcIndex;
|
||||
}
|
||||
|
||||
bool ExistOnDisk() const { return DirIndex != -1; }
|
||||
bool ExistInArchive() const { return ArcIndex != -1; }
|
||||
|
||||
CUpdatePair2(): IsAnti(false), DirIndex(-1), ArcIndex(-1), NewNameIndex(-1) {}
|
||||
CUpdatePair2(): IsAnti(false), UseArcProps(false), DirIndex(-1), ArcIndex(-1), NewNameIndex(-1) {}
|
||||
};
|
||||
|
||||
struct IUpdateProduceCallback
|
||||
|
||||
12
CPP/7zip/UI/Common/WorkDir.cpp
Executable file → Normal file
12
CPP/7zip/UI/Common/WorkDir.cpp
Executable file → Normal file
@@ -2,16 +2,16 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/Wildcard.h"
|
||||
#include "../../../Common/StringConvert.h"
|
||||
#include "../../../Common/Wildcard.h"
|
||||
|
||||
#include "Windows/FileName.h"
|
||||
#include "../../../Windows/FileName.h"
|
||||
|
||||
#include "WorkDir.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
using namespace NDirectory;
|
||||
using namespace NDir;
|
||||
|
||||
FString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const FString &path, FString &fileName)
|
||||
{
|
||||
@@ -37,7 +37,7 @@ FString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const FString &path, FStr
|
||||
}
|
||||
#endif
|
||||
int pos = path.ReverseFind(FCHAR_PATH_SEPARATOR) + 1;
|
||||
fileName = path.Mid(pos);
|
||||
fileName = path.Ptr(pos);
|
||||
switch (mode)
|
||||
{
|
||||
case NWorkDir::NMode::kCurrent:
|
||||
@@ -66,7 +66,7 @@ HRESULT CWorkDirTempFile::CreateTempFile(const FString &originalPath)
|
||||
workDirInfo.Load();
|
||||
FString namePart;
|
||||
FString workDir = GetWorkDir(workDirInfo, originalPath, namePart);
|
||||
CreateComplexDirectory(workDir);
|
||||
CreateComplexDir(workDir);
|
||||
CTempFile tempFile;
|
||||
_outStreamSpec = new COutFileStream;
|
||||
OutStream = _outStreamSpec;
|
||||
|
||||
8
CPP/7zip/UI/Common/WorkDir.h
Executable file → Normal file
8
CPP/7zip/UI/Common/WorkDir.h
Executable file → Normal file
@@ -3,18 +3,18 @@
|
||||
#ifndef __WORK_DIR_H
|
||||
#define __WORK_DIR_H
|
||||
|
||||
#include "Windows/FileDir.h"
|
||||
|
||||
#include "ZipRegistry.h"
|
||||
#include "../../../Windows/FileDir.h"
|
||||
|
||||
#include "../../Common/FileStreams.h"
|
||||
|
||||
#include "ZipRegistry.h"
|
||||
|
||||
FString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const FString &path, FString &fileName);
|
||||
|
||||
class CWorkDirTempFile
|
||||
{
|
||||
FString _originalPath;
|
||||
NWindows::NFile::NDirectory::CTempFile _tempFile;
|
||||
NWindows::NFile::NDir::CTempFile _tempFile;
|
||||
COutFileStream *_outStreamSpec;
|
||||
public:
|
||||
CMyComPtr<IOutStream> OutStream;
|
||||
|
||||
97
CPP/7zip/UI/Common/ZipRegistry.cpp
Executable file → Normal file
97
CPP/7zip/UI/Common/ZipRegistry.cpp
Executable file → Normal file
@@ -2,11 +2,11 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/IntToString.h"
|
||||
#include "../../../Common/IntToString.h"
|
||||
|
||||
#include "Windows/FileDir.h"
|
||||
#include "Windows/Registry.h"
|
||||
#include "Windows/Synchronization.h"
|
||||
#include "../../../Windows/FileDir.h"
|
||||
#include "../../../Windows/Registry.h"
|
||||
#include "../../../Windows/Synchronization.h"
|
||||
|
||||
#include "ZipRegistry.h"
|
||||
|
||||
@@ -30,6 +30,18 @@ static LONG CreateMainKey(CKey &key, LPCTSTR keyName)
|
||||
return key.Create(HKEY_CURRENT_USER, GetKeyPath(keyName));
|
||||
}
|
||||
|
||||
static void Key_Set_BoolPair(CKey &key, LPCTSTR name, const CBoolPair &b)
|
||||
{
|
||||
if (b.Def)
|
||||
key.SetValue(name, b.Val);
|
||||
}
|
||||
|
||||
static void Key_Get_BoolPair(CKey &key, LPCTSTR name, CBoolPair &b)
|
||||
{
|
||||
b.Val = false;
|
||||
b.Def = (key.GetValue_IfOk(name, b.Val) == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
namespace NExtract
|
||||
{
|
||||
|
||||
@@ -39,15 +51,28 @@ static const TCHAR *kExtractMode = TEXT("ExtractMode");
|
||||
static const TCHAR *kOverwriteMode = TEXT("OverwriteMode");
|
||||
static const TCHAR *kShowPassword = TEXT("ShowPassword");
|
||||
static const TCHAR *kPathHistory = TEXT("PathHistory");
|
||||
static const TCHAR *kSplitDest = TEXT("SplitDest");
|
||||
static const TCHAR *kElimDup = TEXT("ElimDup");
|
||||
// static const TCHAR *kAltStreams = TEXT("AltStreams");
|
||||
static const TCHAR *kNtSecur = TEXT("Security");
|
||||
|
||||
void CInfo::Save() const
|
||||
{
|
||||
CS_LOCK
|
||||
CKey key;
|
||||
CreateMainKey(key, kKeyName);
|
||||
key.SetValue(kExtractMode, (UInt32)PathMode);
|
||||
key.SetValue(kOverwriteMode, (UInt32)OverwriteMode);
|
||||
key.SetValue(kShowPassword, ShowPassword);
|
||||
|
||||
if (PathMode_Force)
|
||||
key.SetValue(kExtractMode, (UInt32)PathMode);
|
||||
if (OverwriteMode_Force)
|
||||
key.SetValue(kOverwriteMode, (UInt32)OverwriteMode);
|
||||
|
||||
Key_Set_BoolPair(key, kSplitDest, SplitDest);
|
||||
Key_Set_BoolPair(key, kElimDup, ElimDup);
|
||||
// Key_Set_BoolPair(key, kAltStreams, AltStreams);
|
||||
Key_Set_BoolPair(key, kNtSecur, NtSecurity);
|
||||
Key_Set_BoolPair(key, kShowPassword, ShowPassword);
|
||||
|
||||
key.RecurseDeleteKey(kPathHistory);
|
||||
key.SetValue_Strings(kPathHistory, Paths);
|
||||
}
|
||||
@@ -62,9 +87,11 @@ void Save_ShowPassword(bool showPassword)
|
||||
|
||||
void CInfo::Load()
|
||||
{
|
||||
PathMode = NPathMode::kCurrentPathnames;
|
||||
OverwriteMode = NOverwriteMode::kAskBefore;
|
||||
ShowPassword = false;
|
||||
PathMode = NPathMode::kCurPaths;
|
||||
PathMode_Force = false;
|
||||
OverwriteMode = NOverwriteMode::kAsk;
|
||||
OverwriteMode_Force = false;
|
||||
|
||||
Paths.Clear();
|
||||
|
||||
CS_LOCK
|
||||
@@ -74,11 +101,24 @@ void CInfo::Load()
|
||||
|
||||
key.GetValue_Strings(kPathHistory, Paths);
|
||||
UInt32 v;
|
||||
if (key.QueryValue(kExtractMode, v) == ERROR_SUCCESS && v <= NPathMode::kNoPathnames)
|
||||
if (key.QueryValue(kExtractMode, v) == ERROR_SUCCESS && v <= NPathMode::kAbsPaths)
|
||||
{
|
||||
PathMode = (NPathMode::EEnum)v;
|
||||
if (key.QueryValue(kOverwriteMode, v) == ERROR_SUCCESS && v <= NOverwriteMode::kAutoRenameExisting)
|
||||
PathMode_Force = true;
|
||||
}
|
||||
if (key.QueryValue(kOverwriteMode, v) == ERROR_SUCCESS && v <= NOverwriteMode::kRenameExisting)
|
||||
{
|
||||
OverwriteMode = (NOverwriteMode::EEnum)v;
|
||||
key.GetValue_IfOk(kShowPassword, ShowPassword);
|
||||
OverwriteMode_Force = true;
|
||||
}
|
||||
|
||||
Key_Get_BoolPair(key, kSplitDest, SplitDest);
|
||||
if (!SplitDest.Def)
|
||||
SplitDest.Val = true;
|
||||
Key_Get_BoolPair(key, kElimDup, ElimDup);
|
||||
// Key_Get_BoolPair(key, kAltStreams, AltStreams);
|
||||
Key_Get_BoolPair(key, kNtSecur, NtSecurity);
|
||||
Key_Get_BoolPair(key, kShowPassword, ShowPassword);
|
||||
}
|
||||
|
||||
bool Read_ShowPassword()
|
||||
@@ -115,6 +155,11 @@ static const WCHAR *kMethod = L"Method";
|
||||
static const WCHAR *kOptions = L"Options";
|
||||
static const WCHAR *kEncryptionMethod = L"EncryptionMethod";
|
||||
|
||||
static const TCHAR *kNtSecur = TEXT("Security");
|
||||
static const TCHAR *kAltStreams = TEXT("AltStreams");
|
||||
static const TCHAR *kHardLinks = TEXT("HardLinks");
|
||||
static const TCHAR *kSymLinks = TEXT("SymLinks");
|
||||
|
||||
static void SetRegString(CKey &key, const WCHAR *name, const UString &value)
|
||||
{
|
||||
if (value.IsEmpty())
|
||||
@@ -125,7 +170,7 @@ static void SetRegString(CKey &key, const WCHAR *name, const UString &value)
|
||||
|
||||
static void SetRegUInt32(CKey &key, const TCHAR *name, UInt32 value)
|
||||
{
|
||||
if (value == (UInt32)-1)
|
||||
if (value == (UInt32)(Int32)-1)
|
||||
key.DeleteValue(name);
|
||||
else
|
||||
key.SetValue(name, value);
|
||||
@@ -140,7 +185,7 @@ static void GetRegString(CKey &key, const WCHAR *name, UString &value)
|
||||
static void GetRegUInt32(CKey &key, const TCHAR *name, UInt32 &value)
|
||||
{
|
||||
if (key.QueryValue(name, value) != ERROR_SUCCESS)
|
||||
value = (UInt32)-1;
|
||||
value = (UInt32)(Int32)-1;
|
||||
}
|
||||
|
||||
void CInfo::Save() const
|
||||
@@ -149,6 +194,13 @@ 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.SetValue(kShowPassword, ShowPassword);
|
||||
key.SetValue(kLevel, (UInt32)Level);
|
||||
key.SetValue(kArchiver, ArcType);
|
||||
key.SetValue(kShowPassword, ShowPassword);
|
||||
@@ -160,7 +212,7 @@ void CInfo::Save() const
|
||||
{
|
||||
CKey optionsKey;
|
||||
optionsKey.Create(key, kOptionsKeyName);
|
||||
for (int i = 0; i < Formats.Size(); i++)
|
||||
FOR_VECTOR (i, Formats)
|
||||
{
|
||||
const CFormatOptions &fo = Formats[i];
|
||||
CKey fk;
|
||||
@@ -195,6 +247,11 @@ void CInfo::Load()
|
||||
if (OpenMainKey(key, kKeyName) != ERROR_SUCCESS)
|
||||
return;
|
||||
|
||||
Key_Get_BoolPair(key, kNtSecur, NtSecurity);
|
||||
Key_Get_BoolPair(key, kAltStreams, AltStreams);
|
||||
Key_Get_BoolPair(key, kHardLinks, HardLinks);
|
||||
Key_Get_BoolPair(key, kSymLinks, SymLinks);
|
||||
|
||||
key.GetValue_Strings(kArcHistory, ArcPaths);
|
||||
|
||||
{
|
||||
@@ -203,7 +260,7 @@ void CInfo::Load()
|
||||
{
|
||||
CSysStringVector formatIDs;
|
||||
optionsKey.EnumKeys(formatIDs);
|
||||
for (int i = 0; i < formatIDs.Size(); i++)
|
||||
FOR_VECTOR (i, formatIDs)
|
||||
{
|
||||
CKey fk;
|
||||
CFormatOptions fo;
|
||||
@@ -290,6 +347,7 @@ void CInfo::Load()
|
||||
|
||||
static const TCHAR *kCascadedMenu = TEXT("CascadedMenu");
|
||||
static const TCHAR *kContextMenu = TEXT("ContextMenu");
|
||||
static const TCHAR *kMenuIcons = TEXT("MenuIcons");
|
||||
|
||||
void CContextMenuInfo::Save() const
|
||||
{
|
||||
@@ -297,17 +355,20 @@ void CContextMenuInfo::Save() const
|
||||
CKey key;
|
||||
CreateMainKey(key, kOptionsInfoKeyName);
|
||||
key.SetValue(kCascadedMenu, Cascaded);
|
||||
key.SetValue(kMenuIcons, MenuIcons);
|
||||
key.SetValue(kContextMenu, Flags);
|
||||
}
|
||||
|
||||
void CContextMenuInfo::Load()
|
||||
{
|
||||
MenuIcons = false;
|
||||
Cascaded = true;
|
||||
Flags = (UInt32)-1;
|
||||
Flags = (UInt32)(Int32)-1;
|
||||
CS_LOCK
|
||||
CKey key;
|
||||
if (OpenMainKey(key, kOptionsInfoKeyName) != ERROR_SUCCESS)
|
||||
return;
|
||||
key.GetValue_IfOk(kCascadedMenu, Cascaded);
|
||||
key.GetValue_IfOk(kMenuIcons, MenuIcons);
|
||||
key.GetValue_IfOk(kContextMenu, Flags);
|
||||
}
|
||||
|
||||
21
CPP/7zip/UI/Common/ZipRegistry.h
Executable file → Normal file
21
CPP/7zip/UI/Common/ZipRegistry.h
Executable file → Normal file
@@ -3,8 +3,8 @@
|
||||
#ifndef __ZIP_REGISTRY_H
|
||||
#define __ZIP_REGISTRY_H
|
||||
|
||||
#include "Common/MyString.h"
|
||||
#include "Common/Types.h"
|
||||
#include "../../../Common/MyTypes.h"
|
||||
#include "../../../Common/MyString.h"
|
||||
|
||||
#include "ExtractMode.h"
|
||||
|
||||
@@ -14,12 +14,21 @@ namespace NExtract
|
||||
{
|
||||
NPathMode::EEnum PathMode;
|
||||
NOverwriteMode::EEnum OverwriteMode;
|
||||
bool ShowPassword;
|
||||
bool PathMode_Force;
|
||||
bool OverwriteMode_Force;
|
||||
|
||||
CBoolPair SplitDest;
|
||||
CBoolPair ElimDup;
|
||||
// CBoolPair AltStreams;
|
||||
CBoolPair NtSecurity;
|
||||
CBoolPair ShowPassword;
|
||||
|
||||
UStringVector Paths;
|
||||
|
||||
void Save() const;
|
||||
void Load();
|
||||
};
|
||||
|
||||
void Save_ShowPassword(bool showPassword);
|
||||
bool Read_ShowPassword();
|
||||
}
|
||||
@@ -59,6 +68,11 @@ namespace NCompression
|
||||
|
||||
CObjectVector<CFormatOptions> Formats;
|
||||
|
||||
CBoolPair NtSecurity;
|
||||
CBoolPair AltStreams;
|
||||
CBoolPair HardLinks;
|
||||
CBoolPair SymLinks;
|
||||
|
||||
void Save() const;
|
||||
void Load();
|
||||
};
|
||||
@@ -98,6 +112,7 @@ namespace NWorkDir
|
||||
struct CContextMenuInfo
|
||||
{
|
||||
bool Cascaded;
|
||||
bool MenuIcons;
|
||||
UInt32 Flags;
|
||||
|
||||
void Save() const;
|
||||
|
||||
2
CPP/7zip/UI/Console/BenchCon.cpp
Executable file → Normal file
2
CPP/7zip/UI/Console/BenchCon.cpp
Executable file → Normal file
@@ -32,7 +32,7 @@ HRESULT CPrintBenchCallback::CheckBreak()
|
||||
}
|
||||
|
||||
HRESULT BenchCon(DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
const CObjectVector<CProperty> props, UInt32 numIterations, FILE *f)
|
||||
const CObjectVector<CProperty> &props, UInt32 numIterations, FILE *f)
|
||||
{
|
||||
CPrintBenchCallback callback;
|
||||
callback._file = f;
|
||||
|
||||
2
CPP/7zip/UI/Console/BenchCon.h
Executable file → Normal file
2
CPP/7zip/UI/Console/BenchCon.h
Executable file → Normal file
@@ -9,6 +9,6 @@
|
||||
#include "../../UI/Common/Property.h"
|
||||
|
||||
HRESULT BenchCon(DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
const CObjectVector<CProperty> props, UInt32 numIterations, FILE *f);
|
||||
const CObjectVector<CProperty> &props, UInt32 numIterations, FILE *f);
|
||||
|
||||
#endif
|
||||
|
||||
157
CPP/7zip/UI/Console/Console.dsp
Executable file → Normal file
157
CPP/7zip/UI/Console/Console.dsp
Executable file → Normal file
@@ -44,7 +44,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "WIN_LONG_PATH" /D "EXTERNAL_CODECS" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /FAs /Yu"StdAfx.h" /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "WIN_LONG_PATH" /D "EXTERNAL_CODECS" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /FAs /Yu"StdAfx.h" /FD /c
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
# ADD RSC /l 0x419 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -52,7 +52,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"C:\UTIL\7z.exe" /OPT:NOWIN98
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"C:\UTIL\7z.exe" /OPT:NOWIN98
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "Console - Win32 Debug"
|
||||
@@ -69,7 +69,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "../../../" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "WIN_LONG_PATH" /D "EXTERNAL_CODECS" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "WIN_LONG_PATH" /D "EXTERNAL_CODECS" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
# ADD RSC /l 0x419 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -77,7 +77,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"C:\UTIL\7z.exe" /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"C:\UTIL\7z.exe" /pdbtype:sept
|
||||
|
||||
!ELSEIF "$(CFG)" == "Console - Win32 ReleaseU"
|
||||
|
||||
@@ -94,7 +94,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "WIN_LONG_PATH" /D "EXTERNAL_CODECS" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /c
|
||||
# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "WIN_LONG_PATH" /D "EXTERNAL_CODECS" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /c
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
# ADD RSC /l 0x419 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -102,7 +102,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"C:\UTIL\7z.exe"
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"C:\UTIL\7zn.exe" /OPT:NOWIN98
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"C:\UTIL\7zn.exe" /OPT:NOWIN98
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "Console - Win32 DebugU"
|
||||
@@ -120,7 +120,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "../../../" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "../../../" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "WIN_LONG_PATH" /D "EXTERNAL_CODECS" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "WIN_LONG_PATH" /D "EXTERNAL_CODECS" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
# ADD RSC /l 0x419 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -128,7 +128,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"C:\UTIL\7z.exe" /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"C:\UTIL\7z.exe" /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"C:\UTIL\7z.exe" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
@@ -184,6 +184,14 @@ SOURCE=.\ExtractCallbackConsole.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\HashCon.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\HashCon.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\List.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -244,11 +252,11 @@ SOURCE=..\..\..\Windows\DLL.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\Error.cpp
|
||||
SOURCE=..\..\..\Windows\ErrorMsg.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\Error.h
|
||||
SOURCE=..\..\..\Windows\ErrorMsg.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -276,6 +284,14 @@ SOURCE=..\..\..\Windows\FileIO.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\FileLink.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\FileMapping.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\FileName.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -284,6 +300,14 @@ SOURCE=..\..\..\Windows\FileName.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\FileSystem.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\FileSystem.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\MemoryLock.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -304,11 +328,11 @@ SOURCE=..\..\..\Windows\PropVariant.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\PropVariantConversions.cpp
|
||||
SOURCE=..\..\..\Windows\PropVariantConv.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\PropVariantConversions.h
|
||||
SOURCE=..\..\..\Windows\PropVariantConv.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -320,6 +344,10 @@ SOURCE=..\..\..\Windows\Registry.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\Synchronization.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\System.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -328,11 +356,15 @@ SOURCE=..\..\..\Windows\System.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\Time.cpp
|
||||
SOURCE=..\..\..\Windows\Thread.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\Time.h
|
||||
SOURCE=..\..\..\Windows\TimeUtils.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\TimeUtils.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Common"
|
||||
@@ -340,10 +372,6 @@ SOURCE=..\..\..\Windows\Time.h
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Buffer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\CommandLineParser.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -380,6 +408,10 @@ SOURCE=..\..\..\Common\ListFileUtils.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\MyBuffer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\MyCom.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -392,6 +424,10 @@ SOURCE=..\..\..\Common\MyString.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\MyTypes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\MyVector.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -532,6 +568,18 @@ SOURCE=..\Common\ExtractingFilePath.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ExtractMode.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\HashCalc.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\HashCalc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\IFileExtractCallback.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -668,6 +716,14 @@ SOURCE=..\..\Common\FilterCoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\LimitedStreams.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\LimitedStreams.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\MethodProps.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -684,16 +740,36 @@ SOURCE=..\..\Common\ProgressUtils.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\PropId.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\RegisterArc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\StreamObjects.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\StreamObjects.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\StreamUtils.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\StreamUtils.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\UniqBlocks.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Common\UniqBlocks.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Compress"
|
||||
|
||||
@@ -740,6 +816,10 @@ SOURCE=..\..\..\..\C\7zCrc.h
|
||||
# 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
|
||||
@@ -758,6 +838,15 @@ SOURCE=..\..\..\..\C\CpuArch.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Sort.c
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Sort.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\C\Threads.c
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
# End Source File
|
||||
@@ -839,6 +928,38 @@ InputName=7zCrcOpt
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Interface"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Archive\IArchive.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\ICoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\IDecl.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\IPassword.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\IProgress.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\IStream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\PropID.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
|
||||
0
CPP/7zip/UI/Console/Console.dsw
Executable file → Normal file
0
CPP/7zip/UI/Console/Console.dsw
Executable file → Normal file
35
CPP/7zip/UI/Console/Console.mak
Normal file
35
CPP/7zip/UI/Console/Console.mak
Normal file
@@ -0,0 +1,35 @@
|
||||
CONSOLE_OBJS = \
|
||||
$O\BenchCon.obj \
|
||||
$O\ConsoleClose.obj \
|
||||
$O\ExtractCallbackConsole.obj \
|
||||
$O\HashCon.obj \
|
||||
$O\List.obj \
|
||||
$O\Main.obj \
|
||||
$O\MainAr.obj \
|
||||
$O\OpenCallbackConsole.obj \
|
||||
$O\PercentPrinter.obj \
|
||||
$O\UpdateCallbackConsole.obj \
|
||||
$O\UserInputUtils.obj \
|
||||
|
||||
UI_COMMON_OBJS = \
|
||||
$O\ArchiveCommandLine.obj \
|
||||
$O\ArchiveExtractCallback.obj \
|
||||
$O\ArchiveOpenCallback.obj \
|
||||
$O\Bench.obj \
|
||||
$O\DefaultName.obj \
|
||||
$O\EnumDirItems.obj \
|
||||
$O\Extract.obj \
|
||||
$O\ExtractingFilePath.obj \
|
||||
$O\HashCalc.obj \
|
||||
$O\LoadCodecs.obj \
|
||||
$O\OpenArchive.obj \
|
||||
$O\PropIDUtils.obj \
|
||||
$O\SetProperties.obj \
|
||||
$O\SortUtils.obj \
|
||||
$O\TempFiles.obj \
|
||||
$O\Update.obj \
|
||||
$O\UpdateAction.obj \
|
||||
$O\UpdateCallback.obj \
|
||||
$O\UpdatePair.obj \
|
||||
$O\UpdateProduce.obj \
|
||||
|
||||
0
CPP/7zip/UI/Console/ConsoleClose.cpp
Executable file → Normal file
0
CPP/7zip/UI/Console/ConsoleClose.cpp
Executable file → Normal file
0
CPP/7zip/UI/Console/ConsoleClose.h
Executable file → Normal file
0
CPP/7zip/UI/Console/ConsoleClose.h
Executable file → Normal file
245
CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
Executable file → Normal file
245
CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
Executable file → Normal file
@@ -1,20 +1,21 @@
|
||||
// ExtractCallbackConsole.h
|
||||
// ExtractCallbackConsole.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
// #undef sprintf
|
||||
|
||||
#include "ConsoleClose.h"
|
||||
#include "ExtractCallbackConsole.h"
|
||||
#include "UserInputUtils.h"
|
||||
#include "ConsoleClose.h"
|
||||
|
||||
#include "Common/Wildcard.h"
|
||||
#include "../../../Common/IntToString.h"
|
||||
#include "../../../Common/Wildcard.h"
|
||||
|
||||
#include "Windows/FileDir.h"
|
||||
#include "Windows/FileFind.h"
|
||||
#include "Windows/Time.h"
|
||||
#include "Windows/Defs.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "Windows/Error.h"
|
||||
#include "Windows/PropVariantConversions.h"
|
||||
#include "../../../Windows/FileDir.h"
|
||||
#include "../../../Windows/FileFind.h"
|
||||
#include "../../../Windows/TimeUtils.h"
|
||||
#include "../../../Windows/ErrorMsg.h"
|
||||
#include "../../../Windows/PropVariantConv.h"
|
||||
|
||||
#include "../../Common/FilePathAutoRename.h"
|
||||
|
||||
@@ -22,11 +23,11 @@
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
using namespace NDirectory;
|
||||
using namespace NDir;
|
||||
|
||||
static const char *kTestString = "Testing ";
|
||||
static const char *kExtractString = "Extracting ";
|
||||
static const char *kSkipString = "Skipping ";
|
||||
static const char *kSkipString = "Skipping ";
|
||||
|
||||
// static const char *kCantAutoRename = "can not create file with auto name\n";
|
||||
// static const char *kCantRenameFile = "can not rename existing file\n";
|
||||
@@ -43,7 +44,27 @@ static const char *kCrcFailed = "CRC Failed";
|
||||
static const char *kCrcFailedEncrypted = "CRC Failed in encrypted file. Wrong password?";
|
||||
static const char *kDataError = "Data Error";
|
||||
static const char *kDataErrorEncrypted = "Data Error in encrypted file. Wrong password?";
|
||||
static const char *kUnknownError = "Unknown Error";
|
||||
static const char *kUnavailableData = "Unavailable data";
|
||||
static const char *kUnexpectedEnd = "Unexpected end of data";
|
||||
static const char *kDataAfterEnd = "There are some data after the end of the payload data";
|
||||
static const char *kIsNotArc = "Is not archive";
|
||||
static const char *kHeadersError = "Headers Error";
|
||||
|
||||
static const char *k_ErrorFlagsMessages[] =
|
||||
{
|
||||
"Is not archive"
|
||||
, "Headers Error"
|
||||
, "Headers Error in encrypted archive. Wrong password?"
|
||||
, "Unavailable start of archive"
|
||||
, "Unconfirmed start of archive"
|
||||
, "Unexpected end of archive"
|
||||
, "There are data after the end of archive"
|
||||
, "Unsupported method"
|
||||
, "Unsupported feature"
|
||||
, "Data Error"
|
||||
, "CRC Error"
|
||||
};
|
||||
|
||||
|
||||
STDMETHODIMP CExtractCallbackConsole::SetTotal(UInt64)
|
||||
{
|
||||
@@ -64,13 +85,13 @@ STDMETHODIMP CExtractCallbackConsole::AskOverwrite(
|
||||
const wchar_t *newName, const FILETIME *, const UInt64 *,
|
||||
Int32 *answer)
|
||||
{
|
||||
(*OutStream) << "file " << existName <<
|
||||
"\nalready exists. Overwrite with " << endl;
|
||||
(*OutStream) << newName;
|
||||
(*OutStream) << "file " << existName << endl <<
|
||||
"already exists. Overwrite with" << endl <<
|
||||
newName;
|
||||
|
||||
NUserAnswerMode::EEnum overwriteAnswer = ScanUserYesNoAllQuit(OutStream);
|
||||
|
||||
switch(overwriteAnswer)
|
||||
switch (overwriteAnswer)
|
||||
{
|
||||
case NUserAnswerMode::kQuit: return E_ABORT;
|
||||
case NUserAnswerMode::kNo: *answer = NOverwriteAnswer::kNo; break;
|
||||
@@ -85,13 +106,15 @@ STDMETHODIMP CExtractCallbackConsole::AskOverwrite(
|
||||
|
||||
STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, bool /* isFolder */, Int32 askExtractMode, const UInt64 *position)
|
||||
{
|
||||
const char *s;
|
||||
switch (askExtractMode)
|
||||
{
|
||||
case NArchive::NExtract::NAskMode::kExtract: (*OutStream) << kExtractString; break;
|
||||
case NArchive::NExtract::NAskMode::kTest: (*OutStream) << kTestString; break;
|
||||
case NArchive::NExtract::NAskMode::kSkip: (*OutStream) << kSkipString; break;
|
||||
case NArchive::NExtract::NAskMode::kExtract: s = kExtractString; break;
|
||||
case NArchive::NExtract::NAskMode::kTest: s = kTestString; break;
|
||||
case NArchive::NExtract::NAskMode::kSkip: s = kSkipString; break;
|
||||
default: s = ""; // return E_FAIL;
|
||||
};
|
||||
(*OutStream) << name;
|
||||
(*OutStream) << s << name;
|
||||
if (position != 0)
|
||||
(*OutStream) << " <" << *position << ">";
|
||||
return S_OK;
|
||||
@@ -100,35 +123,57 @@ STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, bool
|
||||
STDMETHODIMP CExtractCallbackConsole::MessageError(const wchar_t *message)
|
||||
{
|
||||
(*OutStream) << message << endl;
|
||||
NumFileErrorsInCurrentArchive++;
|
||||
NumFileErrorsInCurrent++;
|
||||
NumFileErrors++;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackConsole::SetOperationResult(Int32 operationResult, bool encrypted)
|
||||
{
|
||||
switch(operationResult)
|
||||
switch (operationResult)
|
||||
{
|
||||
case NArchive::NExtract::NOperationResult::kOK:
|
||||
break;
|
||||
default:
|
||||
{
|
||||
NumFileErrorsInCurrentArchive++;
|
||||
NumFileErrorsInCurrent++;
|
||||
NumFileErrors++;
|
||||
(*OutStream) << " ";
|
||||
switch(operationResult)
|
||||
(*OutStream) << " : ";
|
||||
const char *s = NULL;
|
||||
switch (operationResult)
|
||||
{
|
||||
case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
|
||||
(*OutStream) << kUnsupportedMethod;
|
||||
case NArchive::NExtract::NOperationResult::kUnsupportedMethod:
|
||||
s = kUnsupportedMethod;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kCRCError:
|
||||
(*OutStream) << (encrypted ? kCrcFailedEncrypted: kCrcFailed);
|
||||
s = (encrypted ? kCrcFailedEncrypted : kCrcFailed);
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kDataError:
|
||||
(*OutStream) << (encrypted ? kDataErrorEncrypted : kDataError);
|
||||
s = (encrypted ? kDataErrorEncrypted : kDataError);
|
||||
break;
|
||||
default:
|
||||
(*OutStream) << kUnknownError;
|
||||
case NArchive::NExtract::NOperationResult::kUnavailable:
|
||||
s = kUnavailableData;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kUnexpectedEnd:
|
||||
s = kUnexpectedEnd;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kDataAfterEnd:
|
||||
s = kDataAfterEnd;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kIsNotArc:
|
||||
s = kIsNotArc;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kHeadersError:
|
||||
s = kHeadersError;
|
||||
break;
|
||||
}
|
||||
if (s)
|
||||
(*OutStream) << "Error : " << s;
|
||||
else
|
||||
{
|
||||
char temp[16];
|
||||
ConvertUInt32ToString(operationResult, temp);
|
||||
(*OutStream) << "Error #" << temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -159,8 +204,10 @@ STDMETHODIMP CExtractCallbackConsole::CryptoGetTextPassword(BSTR *password)
|
||||
|
||||
HRESULT CExtractCallbackConsole::BeforeOpen(const wchar_t *name)
|
||||
{
|
||||
NumArchives++;
|
||||
NumFileErrorsInCurrentArchive = 0;
|
||||
NumTryArcs++;
|
||||
ThereIsErrorInCurrent = false;
|
||||
ThereIsWarningInCurrent = false;
|
||||
NumFileErrorsInCurrent = 0;
|
||||
(*OutStream) << endl << kProcessing << name << endl;
|
||||
return S_OK;
|
||||
}
|
||||
@@ -182,13 +229,95 @@ HRESULT CExtractCallbackConsole::OpenResult(const wchar_t * /* name */, HRESULT
|
||||
if (result == E_OUTOFMEMORY)
|
||||
(*OutStream) << "Can't allocate required memory";
|
||||
else
|
||||
(*OutStream) << NError::MyFormatMessageW(result);
|
||||
(*OutStream) << NError::MyFormatMessage(result);
|
||||
}
|
||||
(*OutStream) << endl;
|
||||
NumArchiveErrors++;
|
||||
NumCantOpenArcs++;
|
||||
ThereIsErrorInCurrent = true;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
AString GetOpenArcErrorMessage(UInt32 errorFlags)
|
||||
{
|
||||
AString s;
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(k_ErrorFlagsMessages); i++)
|
||||
{
|
||||
UInt32 f = (1 << i);
|
||||
if ((errorFlags & f) == 0)
|
||||
continue;
|
||||
const char *m = k_ErrorFlagsMessages[i];
|
||||
if (!s.IsEmpty())
|
||||
s += '\n';
|
||||
s += m;
|
||||
errorFlags &= ~f;
|
||||
}
|
||||
if (errorFlags != 0)
|
||||
{
|
||||
char sz[16];
|
||||
sz[0] = '0';
|
||||
sz[1] = 'x';
|
||||
ConvertUInt32ToHex(errorFlags, sz + 2);
|
||||
if (!s.IsEmpty())
|
||||
s += '\n';
|
||||
s += sz;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
HRESULT CExtractCallbackConsole::SetError(int level, const wchar_t *name,
|
||||
UInt32 errorFlags, const wchar_t *errors,
|
||||
UInt32 warningFlags, const wchar_t *warnings)
|
||||
{
|
||||
if (level != 0)
|
||||
{
|
||||
(*OutStream) << name << endl;
|
||||
}
|
||||
|
||||
if (errorFlags != 0)
|
||||
{
|
||||
(*OutStream) << "Errors: ";
|
||||
(*OutStream) << endl;
|
||||
(*OutStream) << GetOpenArcErrorMessage(errorFlags);
|
||||
(*OutStream) << endl;
|
||||
NumOpenArcErrors++;
|
||||
ThereIsErrorInCurrent = true;
|
||||
}
|
||||
|
||||
if (errors && wcslen(errors) != 0)
|
||||
{
|
||||
(*OutStream) << "Errors: ";
|
||||
(*OutStream) << endl;
|
||||
(*OutStream) << errors;
|
||||
(*OutStream) << endl;
|
||||
NumOpenArcErrors++;
|
||||
ThereIsErrorInCurrent = true;
|
||||
}
|
||||
|
||||
if (warningFlags != 0)
|
||||
{
|
||||
(*OutStream) << "Warnings: ";
|
||||
(*OutStream) << endl;
|
||||
(*OutStream) << GetOpenArcErrorMessage(warningFlags);
|
||||
(*OutStream) << endl;
|
||||
NumOpenArcWarnings++;
|
||||
ThereIsWarningInCurrent = true;
|
||||
}
|
||||
|
||||
if (warnings && wcslen(warnings) != 0)
|
||||
{
|
||||
(*OutStream) << "Warnings: ";
|
||||
(*OutStream) << endl;
|
||||
(*OutStream) << warnings;
|
||||
(*OutStream) << endl;
|
||||
NumOpenArcWarnings++;
|
||||
ThereIsWarningInCurrent = true;
|
||||
}
|
||||
|
||||
(*OutStream) << endl;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CExtractCallbackConsole::ThereAreNoFiles()
|
||||
{
|
||||
@@ -201,24 +330,54 @@ HRESULT CExtractCallbackConsole::ExtractResult(HRESULT result)
|
||||
if (result == S_OK)
|
||||
{
|
||||
(*OutStream) << endl;
|
||||
if (NumFileErrorsInCurrentArchive == 0)
|
||||
|
||||
if (NumFileErrorsInCurrent == 0 && !ThereIsErrorInCurrent)
|
||||
{
|
||||
if (ThereIsWarningInCurrent)
|
||||
NumArcsWithWarnings++;
|
||||
else
|
||||
NumOkArcs++;
|
||||
(*OutStream) << kEverythingIsOk << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
NumArchiveErrors++;
|
||||
(*OutStream) << "Sub items Errors: " << NumFileErrorsInCurrentArchive << endl;
|
||||
NumArcsWithError++;
|
||||
if (NumFileErrorsInCurrent != 0)
|
||||
(*OutStream) << "Sub items Errors: " << NumFileErrorsInCurrent << endl;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
if (result == S_OK)
|
||||
return result;
|
||||
NumArchiveErrors++;
|
||||
|
||||
NumArcsWithError++;
|
||||
if (result == E_ABORT || result == ERROR_DISK_FULL)
|
||||
return result;
|
||||
(*OutStream) << endl << kError;
|
||||
if (result == E_OUTOFMEMORY)
|
||||
(*OutStream) << kMemoryExceptionMessage;
|
||||
else
|
||||
(*OutStream) << NError::MyFormatMessageW(result);
|
||||
(*OutStream) << NError::MyFormatMessage(result);
|
||||
(*OutStream) << endl;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CExtractCallbackConsole::OpenTypeWarning(const wchar_t *name, const wchar_t *okType, const wchar_t *errorType)
|
||||
{
|
||||
UString s = L"Warning:\n";
|
||||
if (wcscmp(okType, errorType) == 0)
|
||||
{
|
||||
s += L"The archive is open with offset";
|
||||
}
|
||||
else
|
||||
{
|
||||
s += name;
|
||||
s += L"\nCan not open the file as [";
|
||||
s += errorType;
|
||||
s += L"] archive\n";
|
||||
s += L"The file is open as [";
|
||||
s += okType;
|
||||
s += L"] archive";
|
||||
}
|
||||
(*OutStream) << s << endl << endl;
|
||||
ThereIsWarningInCurrent = true;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
42
CPP/7zip/UI/Console/ExtractCallbackConsole.h
Executable file → Normal file
42
CPP/7zip/UI/Console/ExtractCallbackConsole.h
Executable file → Normal file
@@ -3,11 +3,15 @@
|
||||
#ifndef __EXTRACTCALLBACKCONSOLE_H
|
||||
#define __EXTRACTCALLBACKCONSOLE_H
|
||||
|
||||
#include "Common/MyString.h"
|
||||
#include "Common/StdOutStream.h"
|
||||
#include "../../../Common/MyString.h"
|
||||
#include "../../../Common/StdOutStream.h"
|
||||
|
||||
#include "../../Common/FileStreams.h"
|
||||
|
||||
#include "../../IPassword.h"
|
||||
|
||||
#include "../../Archive/IArchive.h"
|
||||
|
||||
#include "../Common/ArchiveExtractCallback.h"
|
||||
|
||||
class CExtractCallbackConsole:
|
||||
@@ -40,8 +44,13 @@ public:
|
||||
|
||||
HRESULT BeforeOpen(const wchar_t *name);
|
||||
HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted);
|
||||
HRESULT SetError(int level, const wchar_t *name,
|
||||
UInt32 errorFlags, const wchar_t *errors,
|
||||
UInt32 warningFlags, const wchar_t *warnings);
|
||||
|
||||
HRESULT ThereAreNoFiles();
|
||||
HRESULT ExtractResult(HRESULT result);
|
||||
HRESULT OpenTypeWarning(const wchar_t *name, const wchar_t *okType, const wchar_t *errorType);
|
||||
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
@@ -53,19 +62,36 @@ public:
|
||||
|
||||
#endif
|
||||
|
||||
UInt64 NumArchives;
|
||||
UInt64 NumArchiveErrors;
|
||||
UInt64 NumTryArcs;
|
||||
bool ThereIsErrorInCurrent;
|
||||
bool ThereIsWarningInCurrent;
|
||||
|
||||
UInt64 NumCantOpenArcs;
|
||||
UInt64 NumOkArcs;
|
||||
UInt64 NumArcsWithError;
|
||||
UInt64 NumArcsWithWarnings;
|
||||
|
||||
UInt64 NumProblemArcsLevs;
|
||||
UInt64 NumOpenArcErrors;
|
||||
UInt64 NumOpenArcWarnings;
|
||||
|
||||
UInt64 NumFileErrors;
|
||||
UInt64 NumFileErrorsInCurrentArchive;
|
||||
UInt64 NumFileErrorsInCurrent;
|
||||
|
||||
CStdOutStream *OutStream;
|
||||
|
||||
void Init()
|
||||
{
|
||||
NumArchives = 0;
|
||||
NumArchiveErrors = 0;
|
||||
NumTryArcs = 0;
|
||||
NumOkArcs = 0;
|
||||
NumCantOpenArcs = 0;
|
||||
NumArcsWithError = 0;
|
||||
NumArcsWithWarnings = 0;
|
||||
|
||||
NumOpenArcErrors = 0;
|
||||
NumOpenArcWarnings = 0;
|
||||
NumFileErrors = 0;
|
||||
NumFileErrorsInCurrentArchive = 0;
|
||||
NumFileErrorsInCurrent = 0;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
274
CPP/7zip/UI/Console/HashCon.cpp
Normal file
274
CPP/7zip/UI/Console/HashCon.cpp
Normal file
@@ -0,0 +1,274 @@
|
||||
// HashCon.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../Common/IntToString.h"
|
||||
#include "../../../Common/StringConvert.h"
|
||||
|
||||
#include "../../../Windows/ErrorMsg.h"
|
||||
|
||||
#include "ConsoleClose.h"
|
||||
#include "HashCon.h"
|
||||
|
||||
static const wchar_t *kEmptyFileAlias = L"[Content]";
|
||||
|
||||
static const char *kScanningMessage = "Scanning";
|
||||
|
||||
HRESULT CHashCallbackConsole::CheckBreak()
|
||||
{
|
||||
return NConsoleClose::TestBreakSignal() ? E_ABORT : S_OK;
|
||||
}
|
||||
|
||||
HRESULT CHashCallbackConsole::StartScanning()
|
||||
{
|
||||
(*OutStream) << kScanningMessage;
|
||||
return CheckBreak();
|
||||
}
|
||||
|
||||
HRESULT CHashCallbackConsole::ScanProgress(UInt64 /* numFolders */, UInt64 /* numFiles */, UInt64 /* totalSize */, const wchar_t * /* path */, bool /* isDir */)
|
||||
{
|
||||
return CheckBreak();
|
||||
}
|
||||
|
||||
HRESULT CHashCallbackConsole::CanNotFindError(const wchar_t *name, DWORD systemError)
|
||||
{
|
||||
return CanNotFindError_Base(name, systemError);
|
||||
}
|
||||
|
||||
HRESULT CHashCallbackConsole::FinishScanning()
|
||||
{
|
||||
(*OutStream) << endl << endl;
|
||||
return CheckBreak();
|
||||
}
|
||||
|
||||
HRESULT CHashCallbackConsole::SetNumFiles(UInt64 /* numFiles */)
|
||||
{
|
||||
return CheckBreak();
|
||||
}
|
||||
|
||||
HRESULT CHashCallbackConsole::SetTotal(UInt64 size)
|
||||
{
|
||||
if (EnablePercents)
|
||||
m_PercentPrinter.SetTotal(size);
|
||||
return CheckBreak();
|
||||
}
|
||||
|
||||
HRESULT CHashCallbackConsole::SetCompleted(const UInt64 *completeValue)
|
||||
{
|
||||
if (completeValue && EnablePercents)
|
||||
{
|
||||
m_PercentPrinter.SetRatio(*completeValue);
|
||||
m_PercentPrinter.PrintRatio();
|
||||
}
|
||||
return CheckBreak();
|
||||
}
|
||||
|
||||
static void AddMinuses(AString &s, unsigned num)
|
||||
{
|
||||
for (unsigned i = 0; i < num; i++)
|
||||
s += '-';
|
||||
}
|
||||
|
||||
static void SetSpaces(char *s, int num)
|
||||
{
|
||||
for (int i = 0; i < num; i++)
|
||||
s[i] = ' ';
|
||||
}
|
||||
|
||||
static void SetSpacesAndNul(char *s, int num)
|
||||
{
|
||||
SetSpaces(s, num);
|
||||
s[num] = 0;
|
||||
}
|
||||
|
||||
static void AddSpaces(UString &s, int num)
|
||||
{
|
||||
for (int i = 0; i < num; i++)
|
||||
s += ' ';
|
||||
}
|
||||
|
||||
static const int kSizeField_Len = 13;
|
||||
static const int kNameField_Len = 12;
|
||||
|
||||
static unsigned GetColumnWidth(unsigned digestSize)
|
||||
{
|
||||
unsigned width = digestSize * 2;
|
||||
const unsigned kMinColumnWidth = 8;
|
||||
return width < kMinColumnWidth ? kMinColumnWidth: width;
|
||||
}
|
||||
|
||||
void CHashCallbackConsole::PrintSeparatorLine(const CObjectVector<CHasherState> &hashers)
|
||||
{
|
||||
AString s;
|
||||
for (unsigned i = 0; i < hashers.Size(); i++)
|
||||
{
|
||||
const CHasherState &h = hashers[i];
|
||||
AddMinuses(s, GetColumnWidth(h.DigestSize));
|
||||
s += ' ';
|
||||
}
|
||||
AddMinuses(s, kSizeField_Len);
|
||||
s += " ";
|
||||
AddMinuses(s, kNameField_Len);
|
||||
m_PercentPrinter.PrintString(s);
|
||||
m_PercentPrinter.PrintNewLine();
|
||||
}
|
||||
|
||||
HRESULT CHashCallbackConsole::BeforeFirstFile(const CHashBundle &hb)
|
||||
{
|
||||
UString s;
|
||||
FOR_VECTOR (i, hb.Hashers)
|
||||
{
|
||||
const CHasherState &h = hb.Hashers[i];
|
||||
s += h.Name;
|
||||
AddSpaces(s, (int)GetColumnWidth(h.DigestSize) - h.Name.Len() + 1);
|
||||
}
|
||||
UString s2 = L"Size";
|
||||
AddSpaces(s, kSizeField_Len - s2.Len());
|
||||
s += s2;
|
||||
s += L" ";
|
||||
s += L"Name";
|
||||
m_PercentPrinter.PrintString(s);
|
||||
m_PercentPrinter.PrintNewLine();
|
||||
PrintSeparatorLine(hb.Hashers);
|
||||
return CheckBreak();
|
||||
}
|
||||
|
||||
HRESULT CHashCallbackConsole::OpenFileError(const wchar_t *name, DWORD systemError)
|
||||
{
|
||||
FailedCodes.Add(systemError);
|
||||
FailedFiles.Add(name);
|
||||
// if (systemError == ERROR_SHARING_VIOLATION)
|
||||
{
|
||||
m_PercentPrinter.PrintString(name);
|
||||
m_PercentPrinter.PrintString(": WARNING: ");
|
||||
m_PercentPrinter.PrintString(NWindows::NError::MyFormatMessage(systemError));
|
||||
return S_FALSE;
|
||||
}
|
||||
// return systemError;
|
||||
}
|
||||
|
||||
HRESULT CHashCallbackConsole::GetStream(const wchar_t *name, bool /* isFolder */)
|
||||
{
|
||||
m_FileName = name;
|
||||
return CheckBreak();
|
||||
}
|
||||
|
||||
void CHashCallbackConsole::PrintResultLine(UInt64 fileSize,
|
||||
const CObjectVector<CHasherState> &hashers, unsigned digestIndex, bool showHash)
|
||||
{
|
||||
FOR_VECTOR (i, hashers)
|
||||
{
|
||||
const CHasherState &h = hashers[i];
|
||||
|
||||
char s[k_HashCalc_DigestSize_Max * 2 + 64];
|
||||
s[0] = 0;
|
||||
if (showHash)
|
||||
AddHashHexToString(s, h.Digests[digestIndex], h.DigestSize);
|
||||
SetSpacesAndNul(s + strlen(s), (int)GetColumnWidth(h.DigestSize) - (int)strlen(s) + 1);
|
||||
m_PercentPrinter.PrintString(s);
|
||||
}
|
||||
char s[64];
|
||||
s[0] = 0;
|
||||
char *p = s;
|
||||
if (showHash && fileSize != 0)
|
||||
{
|
||||
p = s + 32;
|
||||
ConvertUInt64ToString(fileSize, p);
|
||||
int numSpaces = kSizeField_Len - (int)strlen(p);
|
||||
if (numSpaces > 0)
|
||||
{
|
||||
p -= numSpaces;
|
||||
SetSpaces(p, numSpaces);
|
||||
}
|
||||
}
|
||||
else
|
||||
SetSpacesAndNul(s, kSizeField_Len - (int)strlen(s));
|
||||
unsigned len = (unsigned)strlen(p);
|
||||
p[len] = ' ';
|
||||
p[len + 1] = ' ';
|
||||
p[len + 2] = 0;
|
||||
m_PercentPrinter.PrintString(p);
|
||||
}
|
||||
|
||||
HRESULT CHashCallbackConsole::SetOperationResult(UInt64 fileSize, const CHashBundle &hb, bool showHash)
|
||||
{
|
||||
PrintResultLine(fileSize, hb.Hashers, k_HashCalc_Index_Current, showHash);
|
||||
if (m_FileName.IsEmpty())
|
||||
m_PercentPrinter.PrintString(kEmptyFileAlias);
|
||||
else
|
||||
m_PercentPrinter.PrintString(m_FileName);
|
||||
m_PercentPrinter.PrintNewLine();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const char *k_DigestTitles[] =
|
||||
{
|
||||
" :"
|
||||
, " for data: "
|
||||
, " for data and names: "
|
||||
, " for streams and names: "
|
||||
};
|
||||
|
||||
static void PrintSum(CStdOutStream &p, const CHasherState &h, unsigned digestIndex)
|
||||
{
|
||||
char s[k_HashCalc_DigestSize_Max * 2 + 64];
|
||||
UString name = h.Name;
|
||||
AddSpaces(name, 6 - (int)name.Len());
|
||||
p << name;
|
||||
p << k_DigestTitles[digestIndex];
|
||||
s[0] = 0;
|
||||
AddHashHexToString(s, h.Digests[digestIndex], h.DigestSize);
|
||||
p << s;
|
||||
p << "\n";
|
||||
}
|
||||
|
||||
|
||||
void PrintHashStat(CStdOutStream &p, const CHashBundle &hb)
|
||||
{
|
||||
FOR_VECTOR (i, hb.Hashers)
|
||||
{
|
||||
const CHasherState &h = hb.Hashers[i];
|
||||
p << "\n";
|
||||
PrintSum(p, h, k_HashCalc_Index_DataSum);
|
||||
if (hb.NumFiles != 1 || hb.NumDirs != 0)
|
||||
PrintSum(p, h, k_HashCalc_Index_NamesSum);
|
||||
if (hb.NumAltStreams != 0)
|
||||
PrintSum(p, h, k_HashCalc_Index_StreamsSum);
|
||||
}
|
||||
}
|
||||
|
||||
void CHashCallbackConsole::PrintProperty(const char *name, UInt64 value)
|
||||
{
|
||||
char s[32];
|
||||
s[0] = ':';
|
||||
s[1] = ' ';
|
||||
ConvertUInt64ToString(value, s + 2);
|
||||
m_PercentPrinter.PrintString(name);
|
||||
m_PercentPrinter.PrintString(s);
|
||||
m_PercentPrinter.PrintNewLine();
|
||||
}
|
||||
|
||||
HRESULT CHashCallbackConsole::AfterLastFile(const CHashBundle &hb)
|
||||
{
|
||||
PrintSeparatorLine(hb.Hashers);
|
||||
|
||||
PrintResultLine(hb.FilesSize, hb.Hashers, k_HashCalc_Index_DataSum, true);
|
||||
m_PercentPrinter.PrintNewLine();
|
||||
m_PercentPrinter.PrintNewLine();
|
||||
|
||||
if (hb.NumFiles != 1 || hb.NumDirs != 0)
|
||||
{
|
||||
if (hb.NumDirs != 0)
|
||||
PrintProperty("Folders", hb.NumDirs);
|
||||
PrintProperty("Files", hb.NumFiles);
|
||||
}
|
||||
PrintProperty("Size", hb.FilesSize);
|
||||
if (hb.NumAltStreams != 0)
|
||||
{
|
||||
PrintProperty("AltStreams", hb.NumAltStreams);
|
||||
PrintProperty("AltStreams size", hb.AltStreamsSize);
|
||||
}
|
||||
PrintHashStat(*m_PercentPrinter.OutStream, hb);
|
||||
m_PercentPrinter.PrintNewLine();
|
||||
return S_OK;
|
||||
}
|
||||
26
CPP/7zip/UI/Console/HashCon.h
Normal file
26
CPP/7zip/UI/Console/HashCon.h
Normal file
@@ -0,0 +1,26 @@
|
||||
// HashCon.h
|
||||
|
||||
#ifndef __HASH_CON_H
|
||||
#define __HASH_CON_H
|
||||
|
||||
#include "../Common/HashCalc.h"
|
||||
|
||||
#include "UpdateCallbackConsole.h"
|
||||
|
||||
class CHashCallbackConsole: public IHashCallbackUI, public CCallbackConsoleBase
|
||||
{
|
||||
UString m_FileName;
|
||||
|
||||
void PrintSeparatorLine(const CObjectVector<CHasherState> &hashers);
|
||||
void PrintResultLine(UInt64 fileSize,
|
||||
const CObjectVector<CHasherState> &hashers, unsigned digestIndex, bool showHash);
|
||||
void PrintProperty(const char *name, UInt64 value);
|
||||
public:
|
||||
~CHashCallbackConsole() { }
|
||||
|
||||
INTERFACE_IHashCallbackUI(;)
|
||||
};
|
||||
|
||||
void PrintHashStat(CStdOutStream &stdStream, const CHashBundle &hb);
|
||||
|
||||
#endif
|
||||
1244
CPP/7zip/UI/Console/List.cpp
Executable file → Normal file
1244
CPP/7zip/UI/Console/List.cpp
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
15
CPP/7zip/UI/Console/List.h
Executable file → Normal file
15
CPP/7zip/UI/Console/List.h
Executable file → Normal file
@@ -3,18 +3,25 @@
|
||||
#ifndef __LIST_H
|
||||
#define __LIST_H
|
||||
|
||||
#include "Common/Wildcard.h"
|
||||
#include "../../../Common/Wildcard.h"
|
||||
|
||||
#include "../Common/LoadCodecs.h"
|
||||
|
||||
HRESULT ListArchives(CCodecs *codecs, const CIntVector &formatIndices,
|
||||
HRESULT ListArchives(CCodecs *codecs,
|
||||
const CObjectVector<COpenType> &types,
|
||||
const CIntVector &excludedFormats,
|
||||
bool stdInMode,
|
||||
UStringVector &archivePaths, UStringVector &archivePathsFull,
|
||||
bool processAltStreams, bool showAltStreams,
|
||||
const NWildcard::CCensorNode &wildcardCensor,
|
||||
bool enableHeaders, bool techMode,
|
||||
#ifndef _NO_CRYPTO
|
||||
bool &passwordEnabled, UString &password,
|
||||
#endif
|
||||
UInt64 &errors);
|
||||
#ifndef _SFX
|
||||
const CObjectVector<CProperty> *props,
|
||||
#endif
|
||||
UInt64 &errors,
|
||||
UInt64 &numWarnings);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
803
CPP/7zip/UI/Console/Main.cpp
Executable file → Normal file
803
CPP/7zip/UI/Console/Main.cpp
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
17
CPP/7zip/UI/Console/MainAr.cpp
Executable file → Normal file
17
CPP/7zip/UI/Console/MainAr.cpp
Executable file → Normal file
@@ -2,11 +2,11 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/MyException.h"
|
||||
#include "Common/StdOutStream.h"
|
||||
#include "../../../Common/MyException.h"
|
||||
#include "../../../Common/StdOutStream.h"
|
||||
|
||||
#include "Windows/Error.h"
|
||||
#include "Windows/NtCheck.h"
|
||||
#include "../../../Windows/ErrorMsg.h"
|
||||
#include "../../../Windows/NtCheck.h"
|
||||
|
||||
#include "../Common/ArchiveCommandLine.h"
|
||||
#include "../Common/ExitCode.h"
|
||||
@@ -23,6 +23,7 @@ extern int Main2(
|
||||
#endif
|
||||
);
|
||||
|
||||
static const char *kException_CmdLine_Error_Message = "\n\nCommand Line Error:\n";
|
||||
static const char *kExceptionErrorMessage = "\n\nError:\n";
|
||||
static const char *kUserBreak = "\nBreak signaled\n";
|
||||
static const char *kMemoryExceptionMessage = "\n\nERROR: Can't allocate required memory!\n";
|
||||
@@ -62,9 +63,9 @@ int MY_CDECL main
|
||||
(*g_StdStream) << endl << kUserBreak;
|
||||
return (NExitCode::kUserBreak);
|
||||
}
|
||||
catch(const CArchiveCommandLineException &e)
|
||||
catch(const CArcCmdLineException &e)
|
||||
{
|
||||
(*g_StdStream) << kExceptionErrorMessage << e << endl;
|
||||
(*g_StdStream) << kException_CmdLine_Error_Message << e << endl;
|
||||
return (NExitCode::kUserError);
|
||||
}
|
||||
catch(const CSystemException &systemError)
|
||||
@@ -80,7 +81,7 @@ int MY_CDECL main
|
||||
return (NExitCode::kUserBreak);
|
||||
}
|
||||
(*g_StdStream) << endl << endl << "System error:" << endl <<
|
||||
NError::MyFormatMessageW(systemError.ErrorCode) << endl;
|
||||
NError::MyFormatMessage(systemError.ErrorCode) << endl;
|
||||
return (NExitCode::kFatalError);
|
||||
}
|
||||
catch(NExitCode::EEnum &exitCode)
|
||||
@@ -120,5 +121,5 @@ int MY_CDECL main
|
||||
(*g_StdStream) << kUnknownExceptionMessage;
|
||||
return (NExitCode::kFatalError);
|
||||
}
|
||||
return res;
|
||||
return res;
|
||||
}
|
||||
|
||||
6
CPP/7zip/UI/Console/OpenCallbackConsole.cpp
Executable file → Normal file
6
CPP/7zip/UI/Console/OpenCallbackConsole.cpp
Executable file → Normal file
@@ -38,10 +38,10 @@ HRESULT COpenCallbackConsole::Open_CryptoGetTextPassword(BSTR *password)
|
||||
return StringToBstr(Password, password);
|
||||
}
|
||||
|
||||
HRESULT COpenCallbackConsole::Open_GetPasswordIfAny(UString &password)
|
||||
HRESULT COpenCallbackConsole::Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password)
|
||||
{
|
||||
if (PasswordIsDefined)
|
||||
password = Password;
|
||||
passwordIsDefined = PasswordIsDefined;
|
||||
password = Password;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
7
CPP/7zip/UI/Console/OpenCallbackConsole.h
Executable file → Normal file
7
CPP/7zip/UI/Console/OpenCallbackConsole.h
Executable file → Normal file
@@ -1,9 +1,10 @@
|
||||
// OpenCallbackConsole.h
|
||||
|
||||
#ifndef __OPENCALLBACKCONSOLE_H
|
||||
#define __OPENCALLBACKCONSOLE_H
|
||||
#ifndef __OPEN_CALLBACK_CONSOLE_H
|
||||
#define __OPEN_CALLBACK_CONSOLE_H
|
||||
|
||||
#include "../../../Common/StdOutStream.h"
|
||||
|
||||
#include "Common/StdOutStream.h"
|
||||
#include "../Common/ArchiveOpenCallback.h"
|
||||
|
||||
class COpenCallbackConsole: public IOpenCallbackUI
|
||||
|
||||
4
CPP/7zip/UI/Console/PercentPrinter.cpp
Executable file → Normal file
4
CPP/7zip/UI/Console/PercentPrinter.cpp
Executable file → Normal file
@@ -2,8 +2,8 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/IntToString.h"
|
||||
#include "Common/MyString.h"
|
||||
#include "../../../Common/Defs.h"
|
||||
#include "../../../Common/IntToString.h"
|
||||
|
||||
#include "PercentPrinter.h"
|
||||
|
||||
|
||||
2
CPP/7zip/UI/Console/PercentPrinter.h
Executable file → Normal file
2
CPP/7zip/UI/Console/PercentPrinter.h
Executable file → Normal file
@@ -3,7 +3,7 @@
|
||||
#ifndef __PERCENT_PRINTER_H
|
||||
#define __PERCENT_PRINTER_H
|
||||
|
||||
#include "Common/StdOutStream.h"
|
||||
#include "../../../Common/StdOutStream.h"
|
||||
|
||||
class CPercentPrinter
|
||||
{
|
||||
|
||||
0
CPP/7zip/UI/Console/StdAfx.cpp
Executable file → Normal file
0
CPP/7zip/UI/Console/StdAfx.cpp
Executable file → Normal file
3
CPP/7zip/UI/Console/StdAfx.h
Executable file → Normal file
3
CPP/7zip/UI/Console/StdAfx.h
Executable file → Normal file
@@ -3,7 +3,6 @@
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
#include "../../../Common/NewHandler.h"
|
||||
#include "../../../Common/Common.h"
|
||||
|
||||
#endif
|
||||
|
||||
39
CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
Executable file → Normal file
39
CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
Executable file → Normal file
@@ -2,15 +2,14 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "UpdateCallbackConsole.h"
|
||||
|
||||
#include "Windows/Error.h"
|
||||
#include "../../../Windows/ErrorMsg.h"
|
||||
#ifndef _7ZIP_ST
|
||||
#include "Windows/Synchronization.h"
|
||||
#include "../../../Windows/Synchronization.h"
|
||||
#endif
|
||||
|
||||
#include "ConsoleClose.h"
|
||||
#include "UserInputUtils.h"
|
||||
#include "UpdateCallbackConsole.h"
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
@@ -28,11 +27,18 @@ static const char *kUpdatingArchiveMessage = "Updating archive ";
|
||||
static const char *kScanningMessage = "Scanning";
|
||||
|
||||
|
||||
HRESULT CUpdateCallbackConsole::OpenResult(const wchar_t *name, HRESULT result)
|
||||
HRESULT CUpdateCallbackConsole::OpenResult(const wchar_t *name, HRESULT result, const wchar_t *errorArcType)
|
||||
{
|
||||
(*OutStream) << endl;
|
||||
if (result != S_OK)
|
||||
(*OutStream) << "Error: " << name << " is not supported archive" << endl;
|
||||
{
|
||||
(*OutStream) << "Error: " << name;
|
||||
if (errorArcType)
|
||||
(*OutStream) << " : can not open the file as [" << errorArcType << "] archive";
|
||||
else
|
||||
(*OutStream) << " is not supported archive";
|
||||
(*OutStream) << endl;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -42,12 +48,12 @@ HRESULT CUpdateCallbackConsole::StartScanning()
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackConsole::ScanProgress(UInt64 /* numFolders */, UInt64 /* numFiles */, const wchar_t * /* path */)
|
||||
HRESULT CUpdateCallbackConsole::ScanProgress(UInt64 /* numFolders */, UInt64 /* numFiles */, UInt64 /* totalSize */, const wchar_t * /* path */, bool /* isDir */)
|
||||
{
|
||||
return CheckBreak();
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackConsole::CanNotFindError(const wchar_t *name, DWORD systemError)
|
||||
HRESULT CCallbackConsoleBase::CanNotFindError_Base(const wchar_t *name, DWORD systemError)
|
||||
{
|
||||
CantFindFiles.Add(name);
|
||||
CantFindCodes.Add(systemError);
|
||||
@@ -60,11 +66,16 @@ HRESULT CUpdateCallbackConsole::CanNotFindError(const wchar_t *name, DWORD syste
|
||||
}
|
||||
m_PercentPrinter.PrintString(name);
|
||||
m_PercentPrinter.PrintString(": WARNING: ");
|
||||
m_PercentPrinter.PrintString(NError::MyFormatMessageW(systemError));
|
||||
m_PercentPrinter.PrintString(NError::MyFormatMessage(systemError));
|
||||
m_PercentPrinter.PrintNewLine();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackConsole::CanNotFindError(const wchar_t *name, DWORD systemError)
|
||||
{
|
||||
return CanNotFindError_Base(name, systemError);
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackConsole::FinishScanning()
|
||||
{
|
||||
(*OutStream) << endl << endl;
|
||||
@@ -176,15 +187,19 @@ HRESULT CUpdateCallbackConsole::OpenFileError(const wchar_t *name, DWORD systemE
|
||||
MT_LOCK
|
||||
FailedCodes.Add(systemError);
|
||||
FailedFiles.Add(name);
|
||||
// if (systemError == ERROR_SHARING_VIOLATION)
|
||||
/*
|
||||
if (systemError == ERROR_SHARING_VIOLATION)
|
||||
{
|
||||
*/
|
||||
m_PercentPrinter.ClosePrint();
|
||||
m_PercentPrinter.PrintNewLine();
|
||||
m_PercentPrinter.PrintString("WARNING: ");
|
||||
m_PercentPrinter.PrintString(NError::MyFormatMessageW(systemError));
|
||||
m_PercentPrinter.PrintString(NError::MyFormatMessage(systemError));
|
||||
return S_FALSE;
|
||||
/*
|
||||
}
|
||||
// return systemError;
|
||||
return systemError;
|
||||
*/
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackConsole::SetOperationResult(Int32 )
|
||||
|
||||
57
CPP/7zip/UI/Console/UpdateCallbackConsole.h
Executable file → Normal file
57
CPP/7zip/UI/Console/UpdateCallbackConsole.h
Executable file → Normal file
@@ -3,55 +3,39 @@
|
||||
#ifndef __UPDATE_CALLBACK_CONSOLE_H
|
||||
#define __UPDATE_CALLBACK_CONSOLE_H
|
||||
|
||||
#include "Common/StdOutStream.h"
|
||||
#include "../../../Common/StdOutStream.h"
|
||||
|
||||
#include "../Common/Update.h"
|
||||
|
||||
#include "PercentPrinter.h"
|
||||
|
||||
class CUpdateCallbackConsole: public IUpdateCallbackUI2
|
||||
class CCallbackConsoleBase
|
||||
{
|
||||
CPercentPrinter m_PercentPrinter;
|
||||
bool m_NeedBeClosed;
|
||||
bool m_NeedNewLine;
|
||||
|
||||
bool m_WarningsMode;
|
||||
protected:
|
||||
CPercentPrinter m_PercentPrinter;
|
||||
|
||||
CStdOutStream *OutStream;
|
||||
HRESULT CanNotFindError_Base(const wchar_t *name, DWORD systemError);
|
||||
public:
|
||||
bool EnablePercents;
|
||||
bool StdOutMode;
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
bool PasswordIsDefined;
|
||||
UString Password;
|
||||
bool AskPassword;
|
||||
#endif
|
||||
|
||||
CUpdateCallbackConsole():
|
||||
CCallbackConsoleBase():
|
||||
m_PercentPrinter(1 << 16),
|
||||
#ifndef _NO_CRYPTO
|
||||
PasswordIsDefined(false),
|
||||
AskPassword(false),
|
||||
#endif
|
||||
StdOutMode(false),
|
||||
EnablePercents(true),
|
||||
m_WarningsMode(false)
|
||||
{}
|
||||
|
||||
~CUpdateCallbackConsole() { Finilize(); }
|
||||
void Init(CStdOutStream *outStream)
|
||||
{
|
||||
m_NeedBeClosed = false;
|
||||
m_NeedNewLine = false;
|
||||
FailedFiles.Clear();
|
||||
FailedCodes.Clear();
|
||||
OutStream = outStream;
|
||||
m_PercentPrinter.OutStream = outStream;
|
||||
}
|
||||
|
||||
INTERFACE_IUpdateCallbackUI2(;)
|
||||
|
||||
UStringVector FailedFiles;
|
||||
CRecordVector<HRESULT> FailedCodes;
|
||||
|
||||
@@ -59,4 +43,33 @@ public:
|
||||
CRecordVector<HRESULT> CantFindCodes;
|
||||
};
|
||||
|
||||
class CUpdateCallbackConsole: public IUpdateCallbackUI2, public CCallbackConsoleBase
|
||||
{
|
||||
bool m_NeedBeClosed;
|
||||
bool m_NeedNewLine;
|
||||
public:
|
||||
#ifndef _NO_CRYPTO
|
||||
bool PasswordIsDefined;
|
||||
UString Password;
|
||||
bool AskPassword;
|
||||
#endif
|
||||
|
||||
CUpdateCallbackConsole()
|
||||
#ifndef _NO_CRYPTO
|
||||
:
|
||||
PasswordIsDefined(false),
|
||||
AskPassword(false)
|
||||
#endif
|
||||
{}
|
||||
|
||||
void Init(CStdOutStream *outStream)
|
||||
{
|
||||
m_NeedBeClosed = false;
|
||||
m_NeedNewLine = false;
|
||||
CCallbackConsoleBase::Init(outStream);
|
||||
}
|
||||
~CUpdateCallbackConsole() { Finilize(); }
|
||||
INTERFACE_IUpdateCallbackUI2(;)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
41
CPP/7zip/UI/Console/UserInputUtils.cpp
Executable file → Normal file
41
CPP/7zip/UI/Console/UserInputUtils.cpp
Executable file → Normal file
@@ -2,17 +2,17 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/StdInStream.h"
|
||||
#include "Common/StringConvert.h"
|
||||
#include "../../../Common/StdInStream.h"
|
||||
#include "../../../Common/StringConvert.h"
|
||||
|
||||
#include "UserInputUtils.h"
|
||||
|
||||
static const char kYes = 'Y';
|
||||
static const char kNo = 'N';
|
||||
static const char kYesAll = 'A';
|
||||
static const char kNoAll = 'S';
|
||||
static const char kAutoRenameAll = 'U';
|
||||
static const char kQuit = 'Q';
|
||||
static const char kYes = 'y';
|
||||
static const char kNo = 'n';
|
||||
static const char kYesAll = 'a';
|
||||
static const char kNoAll = 's';
|
||||
static const char kAutoRenameAll = 'u';
|
||||
static const char kQuit = 'q';
|
||||
|
||||
static const char *kFirstQuestionMessage = "?\n";
|
||||
static const char *kHelpQuestionMessage =
|
||||
@@ -30,25 +30,14 @@ NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream)
|
||||
AString scannedString = g_StdIn.ScanStringUntilNewLine();
|
||||
scannedString.Trim();
|
||||
if (!scannedString.IsEmpty())
|
||||
switch(
|
||||
::MyCharUpper(
|
||||
#ifdef UNDER_CE
|
||||
(wchar_t)
|
||||
#endif
|
||||
scannedString[0]))
|
||||
switch(::MyCharLower_Ascii(scannedString[0]))
|
||||
{
|
||||
case kYes:
|
||||
return NUserAnswerMode::kYes;
|
||||
case kNo:
|
||||
return NUserAnswerMode::kNo;
|
||||
case kYesAll:
|
||||
return NUserAnswerMode::kYesAll;
|
||||
case kNoAll:
|
||||
return NUserAnswerMode::kNoAll;
|
||||
case kAutoRenameAll:
|
||||
return NUserAnswerMode::kAutoRenameAll;
|
||||
case kQuit:
|
||||
return NUserAnswerMode::kQuit;
|
||||
case kYes: return NUserAnswerMode::kYes;
|
||||
case kNo: return NUserAnswerMode::kNo;
|
||||
case kYesAll: return NUserAnswerMode::kYesAll;
|
||||
case kNoAll: return NUserAnswerMode::kNoAll;
|
||||
case kAutoRenameAll: return NUserAnswerMode::kAutoRenameAll;
|
||||
case kQuit: return NUserAnswerMode::kQuit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
6
CPP/7zip/UI/Console/UserInputUtils.h
Executable file → Normal file
6
CPP/7zip/UI/Console/UserInputUtils.h
Executable file → Normal file
@@ -1,9 +1,9 @@
|
||||
// UserInputUtils.h
|
||||
|
||||
#ifndef __USERINPUTUTILS_H
|
||||
#define __USERINPUTUTILS_H
|
||||
#ifndef __USER_INPUT_UTILS_H
|
||||
#define __USER_INPUT_UTILS_H
|
||||
|
||||
#include "Common/StdOutStream.h"
|
||||
#include "../../../Common/StdOutStream.h"
|
||||
|
||||
namespace NUserAnswerMode {
|
||||
|
||||
|
||||
87
CPP/7zip/UI/Console/makefile
Executable file → Normal file
87
CPP/7zip/UI/Console/makefile
Executable file → Normal file
@@ -1,24 +1,13 @@
|
||||
PROG = 7z.exe
|
||||
MY_CONSOLE = 1
|
||||
CFLAGS = $(CFLAGS) -I ../../../ \
|
||||
CFLAGS = $(CFLAGS) \
|
||||
-DEXTERNAL_CODECS \
|
||||
|
||||
!IFNDEF UNDER_CE
|
||||
CFLAGS = $(CFLAGS) -DWIN_LONG_PATH -D_7ZIP_LARGE_PAGES -DSUPPORT_DEVICE_FILE
|
||||
!ENDIF
|
||||
|
||||
|
||||
CONSOLE_OBJS = \
|
||||
$O\ConsoleClose.obj \
|
||||
$O\ExtractCallbackConsole.obj \
|
||||
$O\List.obj \
|
||||
$O\BenchCon.obj \
|
||||
$O\Main.obj \
|
||||
$O\MainAr.obj \
|
||||
$O\OpenCallbackConsole.obj \
|
||||
$O\PercentPrinter.obj \
|
||||
$O\UpdateCallbackConsole.obj \
|
||||
$O\UserInputUtils.obj \
|
||||
CURRENT_OBJS = \
|
||||
|
||||
COMMON_OBJS = \
|
||||
$O\CommandLineParser.obj \
|
||||
@@ -37,88 +26,46 @@ COMMON_OBJS = \
|
||||
|
||||
WIN_OBJS = \
|
||||
$O\DLL.obj \
|
||||
$O\Error.obj \
|
||||
$O\ErrorMsg.obj \
|
||||
$O\FileDir.obj \
|
||||
$O\FileFind.obj \
|
||||
$O\FileIO.obj \
|
||||
$O\FileLink.obj \
|
||||
$O\FileName.obj \
|
||||
$O\FileSystem.obj \
|
||||
$O\MemoryLock.obj \
|
||||
$O\PropVariant.obj \
|
||||
$O\PropVariantConversions.obj \
|
||||
$O\PropVariantConv.obj \
|
||||
$O\Registry.obj \
|
||||
$O\System.obj \
|
||||
$O\Time.obj \
|
||||
$O\TimeUtils.obj \
|
||||
|
||||
7ZIP_COMMON_OBJS = \
|
||||
$O\CreateCoder.obj \
|
||||
$O\FilePathAutoRename.obj \
|
||||
$O\FileStreams.obj \
|
||||
$O\FilterCoder.obj \
|
||||
$O\LimitedStreams.obj \
|
||||
$O\MethodProps.obj \
|
||||
$O\ProgressUtils.obj \
|
||||
$O\PropId.obj \
|
||||
$O\StreamObjects.obj \
|
||||
$O\StreamUtils.obj \
|
||||
|
||||
UI_COMMON_OBJS = \
|
||||
$O\ArchiveCommandLine.obj \
|
||||
$O\ArchiveExtractCallback.obj \
|
||||
$O\ArchiveOpenCallback.obj \
|
||||
$O\DefaultName.obj \
|
||||
$O\EnumDirItems.obj \
|
||||
$O\Extract.obj \
|
||||
$O\ExtractingFilePath.obj \
|
||||
$O\Bench.obj \
|
||||
$O\LoadCodecs.obj \
|
||||
$O\OpenArchive.obj \
|
||||
$O\PropIDUtils.obj \
|
||||
$O\SetProperties.obj \
|
||||
$O\SortUtils.obj \
|
||||
$O\TempFiles.obj \
|
||||
$O\Update.obj \
|
||||
$O\UpdateAction.obj \
|
||||
$O\UpdateCallback.obj \
|
||||
$O\UpdatePair.obj \
|
||||
$O\UpdateProduce.obj \
|
||||
$O\UniqBlocks.obj \
|
||||
|
||||
AR_COMMON_OBJS = \
|
||||
$O\OutStreamWithCRC.obj \
|
||||
|
||||
COMPRESS_OBJS = \
|
||||
$O\CopyCoder.obj \
|
||||
|
||||
C_OBJS = \
|
||||
$O\Alloc.obj \
|
||||
$O\CpuArch.obj \
|
||||
$O\Sort.obj \
|
||||
$O\Threads.obj \
|
||||
|
||||
!include "../../Crc.mak"
|
||||
!include "Console.mak"
|
||||
|
||||
OBJS = \
|
||||
$O\StdAfx.obj \
|
||||
$(CONSOLE_OBJS) \
|
||||
$(COMMON_OBJS) \
|
||||
$(WIN_OBJS) \
|
||||
$(7ZIP_COMMON_OBJS) \
|
||||
$(UI_COMMON_OBJS) \
|
||||
$(AR_COMMON_OBJS) \
|
||||
$O\CopyCoder.obj \
|
||||
$(C_OBJS) \
|
||||
$(ASM_OBJS) \
|
||||
$O\resource.res
|
||||
|
||||
!include "../../../Build.mak"
|
||||
|
||||
$(CONSOLE_OBJS): $(*B).cpp
|
||||
$(COMPL)
|
||||
$(COMMON_OBJS): ../../../Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(WIN_OBJS): ../../../Windows/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(UI_COMMON_OBJS): ../Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
$O\CopyCoder.obj: ../../Compress/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(C_OBJS): ../../../../C/$(*B).c
|
||||
$(COMPL_O2)
|
||||
|
||||
!include "../../Asm.mak"
|
||||
!include "../../7zip.mak"
|
||||
|
||||
0
CPP/7zip/UI/Console/resource.rc
Executable file → Normal file
0
CPP/7zip/UI/Console/resource.rc
Executable file → Normal file
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user