mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-10 02:07:07 -06:00
4.20
This commit is contained in:
committed by
Kornel Lesiński
parent
8c1b5c7b7e
commit
3c510ba80b
@@ -8,11 +8,10 @@
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "Windows/FileFind.h"
|
||||
|
||||
#include "../Common/OpenArchive.h"
|
||||
#include "../Common/DefaultName.h"
|
||||
#include "../Common/ArchiveExtractCallback.h"
|
||||
|
||||
#include "Agent.h"
|
||||
#include "ArchiveExtractCallback.h"
|
||||
|
||||
#ifdef FORMAT_7Z
|
||||
#include "../../Archive/7z/7zHandler.h"
|
||||
@@ -62,8 +61,7 @@ STDMETHODIMP CAgentFolder::GetProperty(UINT32 itemIndex, PROPID propID, PROPVARI
|
||||
break;
|
||||
default:
|
||||
if (item.IsLeaf)
|
||||
return _agentSpec->_archive->GetProperty(item.Index,
|
||||
propID, value);
|
||||
return _agentSpec->GetArchive()->GetProperty(item.Index, propID, value);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -79,7 +77,7 @@ STDMETHODIMP CAgentFolder::GetProperty(UINT32 itemIndex, PROPID propID, PROPVARI
|
||||
propVariant = item.Name;
|
||||
break;
|
||||
default:
|
||||
return _agentSpec->_archive->GetProperty(item.Index,
|
||||
return _agentSpec->GetArchive()->GetProperty(item.Index,
|
||||
propID, value);
|
||||
}
|
||||
}
|
||||
@@ -140,7 +138,7 @@ struct CArchiveItemPropertyTemp
|
||||
STDMETHODIMP CAgentFolder::GetNumberOfProperties(UINT32 *numProperties)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
return _agentSpec->_archive->GetNumberOfProperties(numProperties);
|
||||
return _agentSpec->GetArchive()->GetNumberOfProperties(numProperties);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
@@ -148,7 +146,7 @@ STDMETHODIMP CAgentFolder::GetPropertyInfo(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
RINOK(_agentSpec->_archive->GetPropertyInfo(index, name, propID, varType));
|
||||
RINOK(_agentSpec->GetArchive()->GetPropertyInfo(index, name, propID, varType));
|
||||
if (*propID == kpidPath)
|
||||
*propID = kpidName;
|
||||
return S_OK;
|
||||
@@ -200,8 +198,8 @@ STDMETHODIMP CAgentFolder::GetPath(BSTR *path)
|
||||
|
||||
STDMETHODIMP CAgentFolder::Extract(const UINT32 *indices,
|
||||
UINT32 numItems,
|
||||
NExtractionMode::NPath::EEnum pathMode,
|
||||
NExtractionMode::NOverwrite::EEnum overwriteMode,
|
||||
NExtract::NPathMode::EEnum pathMode,
|
||||
NExtract::NOverwriteMode::EEnum overwriteMode,
|
||||
const wchar_t *path,
|
||||
INT32 testMode,
|
||||
IFolderArchiveExtractCallback *extractCallback2)
|
||||
@@ -216,8 +214,9 @@ STDMETHODIMP CAgentFolder::Extract(const UINT32 *indices,
|
||||
pathParts.Insert(0, currentProxyFolder->Name);
|
||||
currentProxyFolder = currentProxyFolder->Parent;
|
||||
}
|
||||
extractCallbackSpec->Init(_agentSpec->_archive,
|
||||
extractCallbackSpec->Init(_agentSpec->GetArchive(),
|
||||
extractCallback2,
|
||||
false,
|
||||
path,
|
||||
pathMode,
|
||||
overwriteMode,
|
||||
@@ -229,7 +228,7 @@ STDMETHODIMP CAgentFolder::Extract(const UINT32 *indices,
|
||||
);
|
||||
CUIntVector realIndices;
|
||||
_proxyFolderItem->GetRealIndices(indices, numItems, realIndices);
|
||||
return _agentSpec->_archive->Extract(&realIndices.Front(),
|
||||
return _agentSpec->GetArchive()->Extract(&realIndices.Front(),
|
||||
realIndices.Size(), testMode, extractCallback);
|
||||
COM_TRY_END
|
||||
}
|
||||
@@ -262,23 +261,19 @@ STDMETHODIMP CAgent::Open(
|
||||
return ::GetLastError();
|
||||
if (fileInfo.IsDirectory())
|
||||
return E_FAIL;
|
||||
CArchiverInfo archiverInfo;
|
||||
int subExtIndex;
|
||||
HRESULT res = OpenArchive(_archiveFilePath,
|
||||
#ifndef EXCLUDE_COM
|
||||
&_library,
|
||||
#endif
|
||||
&_archive, archiverInfo, subExtIndex, openArchiveCallback);
|
||||
CArchiverInfo archiverInfo0, archiverInfo1;
|
||||
HRESULT res = OpenArchive(_archiveFilePath, _archiveLink, openArchiveCallback);
|
||||
// _archive = _archiveLink.GetArchive();
|
||||
DefaultName = _archiveLink.GetDefaultItemName();
|
||||
const CArchiverInfo &ai = _archiveLink.GetArchiverInfo();
|
||||
|
||||
RINOK(res);
|
||||
DefaultName = GetDefaultName(_archiveFilePath,
|
||||
archiverInfo.Extensions[subExtIndex].Extension,
|
||||
archiverInfo.Extensions[subExtIndex].AddExtension);
|
||||
DefaultTime = fileInfo.LastWriteTime;
|
||||
DefaultAttributes = fileInfo.Attributes;
|
||||
ArchiveType = archiverInfo.Name;
|
||||
ArchiveType = ai.Name;
|
||||
if (archiveType != 0)
|
||||
{
|
||||
CMyComBSTR name = archiverInfo.Name;
|
||||
CMyComBSTR name = ArchiveType;
|
||||
*archiveType = name.Detach();
|
||||
}
|
||||
return S_OK;
|
||||
@@ -295,7 +290,7 @@ STDMETHODIMP CAgent::ReOpen(
|
||||
delete _proxyArchive;
|
||||
_proxyArchive = NULL;
|
||||
}
|
||||
RINOK(ReOpenArchive(_archive, _archiveFilePath));
|
||||
RINOK(ReOpenArchive(_archiveLink, _archiveFilePath));
|
||||
return ReadItems();
|
||||
COM_TRY_END
|
||||
}
|
||||
@@ -303,7 +298,13 @@ STDMETHODIMP CAgent::ReOpen(
|
||||
STDMETHODIMP CAgent::Close()
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
return _archive->Close();
|
||||
RINOK(_archiveLink.Close());
|
||||
if (_archiveLink.GetNumLevels() > 1)
|
||||
{
|
||||
// return S_OK;
|
||||
}
|
||||
// _archive->Close();
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
@@ -319,7 +320,7 @@ HRESULT CAgent::ReadItems()
|
||||
if (_proxyArchive != NULL)
|
||||
return S_OK;
|
||||
_proxyArchive = new CProxyArchive();
|
||||
return _proxyArchive->Load(_archive,
|
||||
return _proxyArchive->Load(GetArchive(),
|
||||
DefaultName,
|
||||
// _defaultTime,
|
||||
// _defaultAttributes,
|
||||
@@ -340,8 +341,8 @@ STDMETHODIMP CAgent::BindToRootFolder(IFolderFolder **resultFolder)
|
||||
|
||||
|
||||
STDMETHODIMP CAgent::Extract(
|
||||
NExtractionMode::NPath::EEnum pathMode,
|
||||
NExtractionMode::NOverwrite::EEnum overwriteMode,
|
||||
NExtract::NPathMode::EEnum pathMode,
|
||||
NExtract::NOverwriteMode::EEnum overwriteMode,
|
||||
const wchar_t *path,
|
||||
INT32 testMode,
|
||||
IFolderArchiveExtractCallback *extractCallback2)
|
||||
@@ -349,8 +350,9 @@ STDMETHODIMP CAgent::Extract(
|
||||
COM_TRY_BEGIN
|
||||
CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
|
||||
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
|
||||
extractCallbackSpec->Init(_archive,
|
||||
extractCallbackSpec->Init(GetArchive(),
|
||||
extractCallback2,
|
||||
false,
|
||||
path,
|
||||
pathMode,
|
||||
overwriteMode,
|
||||
@@ -360,14 +362,14 @@ STDMETHODIMP CAgent::Extract(
|
||||
DefaultAttributes
|
||||
// ,_srcDirectoryPrefix
|
||||
);
|
||||
return _archive->Extract(0, -1, testMode, extractCallback);
|
||||
return GetArchive()->Extract(0, -1, testMode, extractCallback);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgent::GetNumberOfProperties(UINT32 *numProperties)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
return _archive->GetNumberOfProperties(numProperties);
|
||||
return GetArchive()->GetNumberOfProperties(numProperties);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
@@ -375,7 +377,7 @@ STDMETHODIMP CAgent::GetPropertyInfo(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
RINOK(_archive->GetPropertyInfo(index, name, propID, varType));
|
||||
RINOK(GetArchive()->GetPropertyInfo(index, name, propID, varType));
|
||||
if (*propID == kpidPath)
|
||||
*propID = kpidName;
|
||||
return S_OK;
|
||||
@@ -385,14 +387,14 @@ STDMETHODIMP CAgent::GetPropertyInfo(UINT32 index,
|
||||
STDMETHODIMP CAgent::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
return _archive->GetArchiveProperty(propID, value);
|
||||
return GetArchive()->GetArchiveProperty(propID, value);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgent::GetNumberOfArchiveProperties(UINT32 *numProperties)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
return _archive->GetNumberOfArchiveProperties(numProperties);
|
||||
return GetArchive()->GetNumberOfArchiveProperties(numProperties);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
@@ -400,7 +402,7 @@ STDMETHODIMP CAgent::GetArchivePropertyInfo(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
return _archive->GetArchivePropertyInfo(index,
|
||||
return GetArchive()->GetArchivePropertyInfo(index,
|
||||
name, propID, varType);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
// Agent/Agent.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __AGENT_AGENT_H
|
||||
#define __AGENT_AGENT_H
|
||||
|
||||
#include "Windows/PropVariant.h"
|
||||
#include <vector>
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
|
||||
#include "../Common/UpdateAction.h"
|
||||
#include "../Common/ArchiverInfo.h"
|
||||
#include "../Common/OpenArchive.h"
|
||||
|
||||
#include "IFolderArchive.h"
|
||||
#include "AgentProxy.h"
|
||||
@@ -74,8 +75,8 @@ public:
|
||||
|
||||
// IArchiveFolder
|
||||
STDMETHOD(Extract)(const UINT32 *indices, UINT32 numItems,
|
||||
NExtractionMode::NPath::EEnum pathMode,
|
||||
NExtractionMode::NOverwrite::EEnum overwriteMode,
|
||||
NExtract::NPathMode::EEnum pathMode,
|
||||
NExtract::NOverwriteMode::EEnum overwriteMode,
|
||||
const wchar_t *path,
|
||||
INT32 testMode,
|
||||
IFolderArchiveExtractCallback *extractCallback);
|
||||
@@ -137,6 +138,7 @@ public:
|
||||
CMyComPtr<IFolderFolder> _parentFolder;
|
||||
CMyComPtr<IInFolderArchive> _agent;
|
||||
CAgent *_agentSpec;
|
||||
private:
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-1000-000100030000}
|
||||
@@ -189,8 +191,8 @@ public:
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
||||
STDMETHOD(BindToRootFolder)(IFolderFolder **resultFolder);
|
||||
STDMETHOD(Extract)(
|
||||
NExtractionMode::NPath::EEnum pathMode,
|
||||
NExtractionMode::NOverwrite::EEnum overwriteMode,
|
||||
NExtract::NPathMode::EEnum pathMode,
|
||||
NExtract::NOverwriteMode::EEnum overwriteMode,
|
||||
const wchar_t *path,
|
||||
INT32 testMode,
|
||||
IFolderArchiveExtractCallback *extractCallback2);
|
||||
@@ -204,11 +206,12 @@ public:
|
||||
const wchar_t *filePath,
|
||||
const CLSID *clsID,
|
||||
const wchar_t *newArchiveName,
|
||||
const BYTE *stateActions,
|
||||
const Byte *stateActions,
|
||||
const wchar_t *sfxModule,
|
||||
IFolderArchiveUpdateCallback *updateCallback);
|
||||
|
||||
HRESULT CommonUpdate(const wchar_t *newArchiveName,
|
||||
HRESULT CommonUpdate(
|
||||
const wchar_t *newArchiveName,
|
||||
int numUpdateItems,
|
||||
IArchiveUpdateCallback *updateCallback);
|
||||
|
||||
@@ -224,7 +227,7 @@ public:
|
||||
IFolderArchiveUpdateCallback *updateCallback100);
|
||||
|
||||
// ISetProperties
|
||||
STDMETHOD(SetProperties)(const BSTR *names, const PROPVARIANT *values, INT32 numProperties);
|
||||
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, INT32 numProperties);
|
||||
#endif
|
||||
|
||||
CAgent();
|
||||
@@ -234,16 +237,14 @@ private:
|
||||
public:
|
||||
CProxyArchive *_proxyArchive;
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
NWindows::NDLL::CLibrary _library;
|
||||
#endif
|
||||
|
||||
CMyComPtr<IInArchive> _archive;
|
||||
CArchiveLink _archiveLink;
|
||||
// IInArchive *_archive2;
|
||||
|
||||
// CLSID _CLSID;
|
||||
// CMyComPtr<IArchiveFolder> m_RootFolder;
|
||||
|
||||
UString DefaultName;
|
||||
|
||||
FILETIME DefaultTime;
|
||||
UINT32 DefaultAttributes;
|
||||
|
||||
@@ -258,9 +259,12 @@ public:
|
||||
UString _archiveFilePath;
|
||||
|
||||
#ifndef EXTRACT_ONLY
|
||||
CObjectVector<CMyComBSTR> m_PropNames;
|
||||
CObjectVector<UString> m_PropNames;
|
||||
std::vector<NWindows::NCOM::CPropVariant> m_PropValues;
|
||||
#endif
|
||||
|
||||
IInArchive *GetArchive() { return _archiveLink.GetArchive(); }
|
||||
bool CanUpdate() const { return _archiveLink.GetNumLevels() <= 1; }
|
||||
};
|
||||
|
||||
#ifdef NEW_FOLDER_INTERFACE
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
// Zip/Handler.cpp
|
||||
// AgentOutcpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../Common/UpdatePair.h"
|
||||
#include "../Common/EnumDirItems.h"
|
||||
#include "../Common/HandlerLoader.h"
|
||||
// #include "../Common/UpdatePairAction.h"
|
||||
// #include "../Common/CompressEngineCommon.h"
|
||||
// #include "../Common/UpdateProducer.h"
|
||||
#include "../../Compress/Copy/CopyCoder.h"
|
||||
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/IntToString.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "Windows/PropVariantConversions.h"
|
||||
#include "Windows/FileDir.h"
|
||||
|
||||
#include "../../Compress/Copy/CopyCoder.h"
|
||||
#include "../../Common/FileStreams.h"
|
||||
|
||||
#include "../Common/UpdatePair.h"
|
||||
#include "../Common/EnumDirItems.h"
|
||||
#include "../Common/HandlerLoader.h"
|
||||
#include "../Common/UpdateCallback.h"
|
||||
#include "../Common/OpenArchive.h"
|
||||
|
||||
#include "Agent.h"
|
||||
#include "ArchiveUpdateCallback.h"
|
||||
#include "UpdateCallbackAgent.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NCOM;
|
||||
@@ -90,7 +90,7 @@ STDMETHODIMP CAgent::SetFiles(const wchar_t *folderPrefix,
|
||||
static HRESULT GetFileTime(CAgent *agent, UINT32 itemIndex, FILETIME &fileTime)
|
||||
{
|
||||
CPropVariant property;
|
||||
RINOK(agent->_archive->GetProperty(itemIndex, kpidLastWriteTime, &property));
|
||||
RINOK(agent->GetArchive()->GetProperty(itemIndex, kpidLastWriteTime, &property));
|
||||
if (property.vt == VT_FILETIME)
|
||||
fileTime = property.filetime;
|
||||
else if (property.vt == VT_EMPTY)
|
||||
@@ -114,9 +114,9 @@ static HRESULT EnumerateArchiveItems(CAgent *agent,
|
||||
RINOK(::GetFileTime(agent, fileItem.Index, archiveItem.LastWriteTime));
|
||||
|
||||
CPropVariant property;
|
||||
agent->_archive->GetProperty(fileItem.Index, kpidSize, &property);
|
||||
agent->GetArchive()->GetProperty(fileItem.Index, kpidSize, &property);
|
||||
if (archiveItem.SizeIsDefined = (property.vt != VT_EMPTY))
|
||||
archiveItem.Size = ConvertPropVariantToUINT64(property);
|
||||
archiveItem.Size = ConvertPropVariantToUInt64(property);
|
||||
archiveItem.IsDirectory = false;
|
||||
archiveItem.Name = prefix + fileItem.Name;
|
||||
archiveItem.Censored = true; // test it
|
||||
@@ -147,10 +147,12 @@ STDMETHODIMP CAgent::DoOperation(
|
||||
const wchar_t *filePath,
|
||||
const CLSID *clsID,
|
||||
const wchar_t *newArchiveName,
|
||||
const BYTE *stateActions,
|
||||
const Byte *stateActions,
|
||||
const wchar_t *sfxModule,
|
||||
IFolderArchiveUpdateCallback *updateCallback100)
|
||||
{
|
||||
if (!CanUpdate())
|
||||
return E_NOTIMPL;
|
||||
NUpdateArchive::CActionSet actionSet;
|
||||
for (int i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
|
||||
actionSet.StateActions[i] = (NUpdateArchive::NPairAction::EEnum)stateActions[i];
|
||||
@@ -159,18 +161,20 @@ STDMETHODIMP CAgent::DoOperation(
|
||||
|
||||
UString folderPrefix = _folderPrefix;
|
||||
NFile::NName::NormalizeDirPathPrefix(folderPrefix);
|
||||
::EnumerateDirItems(folderPrefix, _names, _archiveNamePrefix, dirItems);
|
||||
RINOK(::EnumerateDirItems(folderPrefix, _names, _archiveNamePrefix, dirItems));
|
||||
|
||||
NWindows::NDLL::CLibrary library;
|
||||
|
||||
CMyComPtr<IOutArchive> outArchive;
|
||||
if (_archive)
|
||||
if (GetArchive())
|
||||
{
|
||||
RINOK(_archive.QueryInterface(IID_IOutArchive, &outArchive));
|
||||
RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive));
|
||||
}
|
||||
else
|
||||
{
|
||||
CHandlerLoader loader;
|
||||
RINOK(loader.CreateHandler(filePath, *clsID, (void **)&outArchive, true));
|
||||
_library.Attach(loader.Detach());
|
||||
library.Attach(loader.Detach());
|
||||
}
|
||||
|
||||
NFileTimeType::EEnum fileTimeType;
|
||||
@@ -191,7 +195,7 @@ STDMETHODIMP CAgent::DoOperation(
|
||||
CObjectVector<CUpdatePair> updatePairs;
|
||||
|
||||
CObjectVector<CArchiveItem> archiveItems;
|
||||
if (_archive)
|
||||
if (GetArchive())
|
||||
{
|
||||
RINOK(ReadItems());
|
||||
EnumerateArchiveItems(this, _proxyArchive->RootFolder, L"", archiveItems);
|
||||
@@ -199,16 +203,22 @@ STDMETHODIMP CAgent::DoOperation(
|
||||
|
||||
GetUpdatePairInfoList(dirItems, archiveItems, fileTimeType, updatePairs);
|
||||
|
||||
CObjectVector<CUpdatePair2> operationChain;
|
||||
CObjectVector<CUpdatePair2> updatePairs2;
|
||||
UpdateProduce(dirItems, archiveItems, updatePairs, actionSet,
|
||||
operationChain);
|
||||
updatePairs2);
|
||||
|
||||
CUpdateCallbackAgent updateCallbackAgent;
|
||||
updateCallbackAgent.Callback = updateCallback100;
|
||||
CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
|
||||
CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec );
|
||||
|
||||
updateCallbackSpec->Init(folderPrefix,&dirItems, &archiveItems,
|
||||
&operationChain, NULL, updateCallback100);
|
||||
|
||||
|
||||
updateCallbackSpec->DirPrefix = folderPrefix;
|
||||
updateCallbackSpec->DirItems = &dirItems;
|
||||
updateCallbackSpec->ArchiveItems = &archiveItems;
|
||||
updateCallbackSpec->UpdatePairs = &updatePairs2;
|
||||
updateCallbackSpec->Archive = GetArchive();
|
||||
updateCallbackSpec->Callback = &updateCallbackAgent;
|
||||
|
||||
COutFileStream *outStreamSpec = new COutFileStream;
|
||||
CMyComPtr<IOutStream> outStream(outStreamSpec);
|
||||
UString archiveName = newArchiveName;
|
||||
@@ -219,7 +229,7 @@ STDMETHODIMP CAgent::DoOperation(
|
||||
throw 141716;
|
||||
NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos));
|
||||
}
|
||||
if (!outStreamSpec->Open(archiveName))
|
||||
if (!outStreamSpec->Create(archiveName, true))
|
||||
{
|
||||
// ShowLastErrorMessage();
|
||||
return E_FAIL;
|
||||
@@ -234,11 +244,12 @@ STDMETHODIMP CAgent::DoOperation(
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<BSTR> names;
|
||||
CRecordVector<const wchar_t *> names;
|
||||
for(i = 0; i < m_PropNames.Size(); i++)
|
||||
names.push_back(m_PropNames[i]);
|
||||
RINOK(setProperties->SetProperties(&names.front(),
|
||||
&m_PropValues.front(), names.size()));
|
||||
names.Add((const wchar_t *)m_PropNames[i]);
|
||||
|
||||
RINOK(setProperties->SetProperties(&names.Front(),
|
||||
&m_PropValues.front(), names.Size()));
|
||||
}
|
||||
}
|
||||
m_PropNames.Clear();
|
||||
@@ -253,20 +264,24 @@ STDMETHODIMP CAgent::DoOperation(
|
||||
RINOK(CopyBlock(sfxStream, outStream));
|
||||
}
|
||||
|
||||
return outArchive->UpdateItems(outStream, operationChain.Size(),
|
||||
return outArchive->UpdateItems(outStream, updatePairs2.Size(),
|
||||
updateCallback);
|
||||
}
|
||||
|
||||
|
||||
HRESULT CAgent::CommonUpdate(const wchar_t *newArchiveName,
|
||||
HRESULT CAgent::CommonUpdate(
|
||||
const wchar_t *newArchiveName,
|
||||
int numUpdateItems,
|
||||
IArchiveUpdateCallback *updateCallback)
|
||||
{
|
||||
if (!CanUpdate())
|
||||
return E_NOTIMPL;
|
||||
CMyComPtr<IOutArchive> outArchive;
|
||||
RINOK(_archive.QueryInterface(IID_IOutArchive, &outArchive));
|
||||
RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive));
|
||||
|
||||
COutFileStream *outStreamSpec = new COutFileStream;
|
||||
CMyComPtr<IOutStream> outStream(outStreamSpec);
|
||||
|
||||
UString archiveName = newArchiveName;
|
||||
{
|
||||
UString resultPath;
|
||||
@@ -275,7 +290,30 @@ HRESULT CAgent::CommonUpdate(const wchar_t *newArchiveName,
|
||||
throw 141716;
|
||||
NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos));
|
||||
}
|
||||
if (!outStreamSpec->Open(archiveName))
|
||||
|
||||
/*
|
||||
bool isOK = false;
|
||||
for (int i = 0; i < (1 << 16); i++)
|
||||
{
|
||||
resultName = newArchiveName;
|
||||
if (i > 0)
|
||||
{
|
||||
wchar_t s[32];
|
||||
ConvertUInt64ToString(i, s);
|
||||
resultName += s;
|
||||
}
|
||||
if (outStreamSpec->Open(realPath))
|
||||
{
|
||||
isOK = true;
|
||||
break;
|
||||
}
|
||||
if (::GetLastError() != ERROR_FILE_EXISTS)
|
||||
return ::GetLastError();
|
||||
}
|
||||
if (!isOK)
|
||||
return ::GetLastError();
|
||||
*/
|
||||
if (!outStreamSpec->Create(archiveName, true))
|
||||
{
|
||||
// ShowLastErrorMessage();
|
||||
return E_FAIL;
|
||||
@@ -290,6 +328,10 @@ STDMETHODIMP CAgent::DeleteItems(
|
||||
const UINT32 *indices, UINT32 numItems,
|
||||
IFolderArchiveUpdateCallback *updateCallback100)
|
||||
{
|
||||
if (!CanUpdate())
|
||||
return E_NOTIMPL;
|
||||
CUpdateCallbackAgent updateCallbackAgent;
|
||||
updateCallbackAgent.Callback = updateCallback100;
|
||||
CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
|
||||
CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);
|
||||
|
||||
@@ -298,7 +340,7 @@ STDMETHODIMP CAgent::DeleteItems(
|
||||
CObjectVector<CUpdatePair2> updatePairs;
|
||||
int curIndex = 0;
|
||||
UINT32 numItemsInArchive;
|
||||
RINOK(_archive->GetNumberOfItems(&numItemsInArchive));
|
||||
RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive));
|
||||
for (int i = 0; i < numItemsInArchive; i++)
|
||||
{
|
||||
if (curIndex < realIndices.Size())
|
||||
@@ -311,11 +353,13 @@ STDMETHODIMP CAgent::DeleteItems(
|
||||
updatePair.NewData = updatePair.NewProperties = false;
|
||||
updatePair.ExistInArchive = true;
|
||||
updatePair.ExistOnDisk = false;
|
||||
updatePair.IsAnti = false;
|
||||
updatePair.IsAnti = false; // check it. Maybe it can be undefined
|
||||
updatePair.ArchiveItemIndex = i;
|
||||
updatePairs.Add(updatePair);
|
||||
}
|
||||
updateCallbackSpec->Init(L"", NULL, NULL, &updatePairs, NULL, updateCallback100);
|
||||
updateCallbackSpec->UpdatePairs = &updatePairs;
|
||||
updateCallbackSpec->Archive = GetArchive();
|
||||
updateCallbackSpec->Callback = &updateCallbackAgent;
|
||||
return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback);
|
||||
}
|
||||
|
||||
@@ -324,19 +368,23 @@ HRESULT CAgent::CreateFolder(
|
||||
const wchar_t *folderName,
|
||||
IFolderArchiveUpdateCallback *updateCallback100)
|
||||
{
|
||||
if (!CanUpdate())
|
||||
return E_NOTIMPL;
|
||||
CUpdateCallbackAgent updateCallbackAgent;
|
||||
updateCallbackAgent.Callback = updateCallback100;
|
||||
CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
|
||||
CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);
|
||||
|
||||
CObjectVector<CUpdatePair2> updatePairs;
|
||||
UINT32 numItemsInArchive;
|
||||
RINOK(_archive->GetNumberOfItems(&numItemsInArchive));
|
||||
RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive));
|
||||
for (int i = 0; i < numItemsInArchive; i++)
|
||||
{
|
||||
CUpdatePair2 updatePair;
|
||||
updatePair.NewData = updatePair.NewProperties = false;
|
||||
updatePair.ExistInArchive = true;
|
||||
updatePair.ExistOnDisk = false;
|
||||
updatePair.IsAnti = false;
|
||||
updatePair.IsAnti = false; // check it.
|
||||
updatePair.ArchiveItemIndex = i;
|
||||
updatePairs.Add(updatePair);
|
||||
}
|
||||
@@ -366,7 +414,10 @@ HRESULT CAgent::CreateFolder(
|
||||
|
||||
dirItems.Add(dirItem);
|
||||
|
||||
updateCallbackSpec->Init(L"", &dirItems, NULL, &updatePairs, NULL, updateCallback100);
|
||||
updateCallbackSpec->Callback = &updateCallbackAgent;
|
||||
updateCallbackSpec->DirItems = &dirItems;
|
||||
updateCallbackSpec->UpdatePairs = &updatePairs;
|
||||
updateCallbackSpec->Archive = GetArchive();
|
||||
return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback);
|
||||
}
|
||||
|
||||
@@ -377,8 +428,12 @@ HRESULT CAgent::RenameItem(
|
||||
const wchar_t *newItemName,
|
||||
IFolderArchiveUpdateCallback *updateCallback100)
|
||||
{
|
||||
if (!CanUpdate())
|
||||
return E_NOTIMPL;
|
||||
if (numItems != 1)
|
||||
return E_INVALIDARG;
|
||||
CUpdateCallbackAgent updateCallbackAgent;
|
||||
updateCallbackAgent.Callback = updateCallback100;
|
||||
CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
|
||||
CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);
|
||||
|
||||
@@ -393,7 +448,7 @@ HRESULT CAgent::RenameItem(
|
||||
CObjectVector<CUpdatePair2> updatePairs;
|
||||
int curIndex = 0;
|
||||
UINT32 numItemsInArchive;
|
||||
RINOK(_archive->GetNumberOfItems(&numItemsInArchive));
|
||||
RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive));
|
||||
for (int i = 0; i < numItemsInArchive; i++)
|
||||
{
|
||||
if (curIndex < realIndices.Size())
|
||||
@@ -404,37 +459,19 @@ HRESULT CAgent::RenameItem(
|
||||
updatePair.NewProperties = true;
|
||||
updatePair.ExistInArchive = true;
|
||||
updatePair.ExistOnDisk = false;
|
||||
updatePair.IsAnti = false; // ?
|
||||
RINOK(IsArchiveItemAnti(GetArchive(), i, updatePair.IsAnti));
|
||||
updatePair.ArchiveItemIndex = i;
|
||||
updatePair.NewNameIsDefined = true;
|
||||
|
||||
updatePair.NewName = newItemName;
|
||||
|
||||
UString oldFullPath;
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(_archive->GetProperty(
|
||||
updatePair.ArchiveItemIndex, kpidPath, &propVariant));
|
||||
if (propVariant.vt != VT_BSTR)
|
||||
return E_INVALIDARG;
|
||||
oldFullPath = propVariant.bstrVal;
|
||||
}
|
||||
RINOK(GetArchiveItemPath(GetArchive(), i, DefaultName, oldFullPath));
|
||||
|
||||
if (oldItemPath.CollateNoCase(oldFullPath.Left(oldItemPath.Length())) != 0)
|
||||
return E_INVALIDARG;
|
||||
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(_archive->GetProperty(i, kpidIsAnti, &propVariant));
|
||||
if (propVariant.vt == VT_EMPTY)
|
||||
updatePair.IsAnti = false;
|
||||
else if (propVariant.vt != VT_BOOL)
|
||||
return E_INVALIDARG;
|
||||
else
|
||||
updatePair.IsAnti = (propVariant.boolVal != VARIANT_FALSE);
|
||||
}
|
||||
|
||||
updatePair.NewName = newItemPath + oldFullPath.Mid(oldItemPath.Length());
|
||||
|
||||
updatePairs.Add(updatePair);
|
||||
curIndex++;
|
||||
continue;
|
||||
@@ -447,13 +484,13 @@ HRESULT CAgent::RenameItem(
|
||||
updatePair.ArchiveItemIndex = i;
|
||||
updatePairs.Add(updatePair);
|
||||
}
|
||||
updateCallbackSpec->Init(L"", NULL, NULL, &updatePairs, _archive, updateCallback100);
|
||||
updateCallbackSpec->Callback = &updateCallbackAgent;
|
||||
updateCallbackSpec->UpdatePairs = &updatePairs;
|
||||
updateCallbackSpec->Archive = GetArchive();
|
||||
return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback);
|
||||
}
|
||||
|
||||
|
||||
|
||||
STDMETHODIMP CAgent::SetProperties(const BSTR *names,
|
||||
STDMETHODIMP CAgent::SetProperties(const wchar_t **names,
|
||||
const PROPVARIANT *values, INT32 numProperties)
|
||||
{
|
||||
m_PropNames.Clear();
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "Common/MyCom.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "Windows/Defs.h"
|
||||
#include "../Common/OpenArchive.h"
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
@@ -184,11 +185,9 @@ HRESULT CProxyArchive::ReadObjects(IInArchive *archiveHandler, IProgress *progre
|
||||
}
|
||||
|
||||
NCOM::CPropVariant propVariantIsFolder;
|
||||
RINOK(archiveHandler->GetProperty(i,
|
||||
kpidIsFolder, &propVariantIsFolder));
|
||||
if(propVariantIsFolder.vt != VT_BOOL)
|
||||
return E_FAIL;
|
||||
if(VARIANT_BOOLToBool(propVariantIsFolder.boolVal))
|
||||
bool isFolder;
|
||||
RINOK(IsArchiveItemFolder(archiveHandler, i, isFolder));
|
||||
if(isFolder)
|
||||
currentItem->AddDirSubItem(i, true, fileName);
|
||||
else
|
||||
currentItem->AddFileSubItem(i, fileName);
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// AgentProxy.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __AGENT_PROXY_H
|
||||
#define __AGENT_PROXY_H
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
#include "../../Common/FileStreams.h"
|
||||
|
||||
#include "../Common/UpdatePair.h"
|
||||
#include "../Common/ArchiveExtractCallback.h"
|
||||
|
||||
#include "Agent.h"
|
||||
#include "ArchiveExtractCallback.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NCOM;
|
||||
@@ -41,11 +41,12 @@ STDMETHODIMP CAgentFolder::CopyTo(const UINT32 *indices, UINT32 numItems,
|
||||
IID_IFolderArchiveExtractCallback, &extractCallback2));
|
||||
}
|
||||
|
||||
extractCallbackSpec->Init(_agentSpec->_archive,
|
||||
extractCallbackSpec->Init(_agentSpec->GetArchive(),
|
||||
extractCallback2,
|
||||
false,
|
||||
path,
|
||||
NExtractionMode::NPath::kCurrentPathnames,
|
||||
NExtractionMode::NOverwrite::kAskBefore,
|
||||
NExtract::NPathMode::kCurrentPathnames,
|
||||
NExtract::NOverwriteMode::kAskBefore,
|
||||
pathParts,
|
||||
_agentSpec->DefaultName,
|
||||
_agentSpec->DefaultTime,
|
||||
@@ -54,7 +55,7 @@ STDMETHODIMP CAgentFolder::CopyTo(const UINT32 *indices, UINT32 numItems,
|
||||
);
|
||||
CUIntVector realIndices;
|
||||
_proxyFolderItem->GetRealIndices(indices, numItems, realIndices);
|
||||
return _agentSpec->_archive->Extract(&realIndices.Front(),
|
||||
return _agentSpec->GetArchive()->Extract(&realIndices.Front(),
|
||||
realIndices.Size(), BoolToInt(false), extractCallback);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#include "../Common/OpenArchive.h"
|
||||
|
||||
static const UINT64 kMaxCheckStartPosition = 1 << 20;
|
||||
static const UInt64 kMaxCheckStartPosition = 1 << 20;
|
||||
|
||||
static inline UINT GetCurrentFileCodePage()
|
||||
{ return AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
|
||||
|
||||
@@ -85,7 +85,7 @@ HRESULT CAgentFolder::CommonUpdateOperation(
|
||||
}
|
||||
else
|
||||
{
|
||||
BYTE actionSetByte[NUpdateArchive::NPairState::kNumValues];
|
||||
Byte actionSetByte[NUpdateArchive::NPairState::kNumValues];
|
||||
for (int i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
|
||||
actionSetByte[i] = actionSet->StateActions[i];
|
||||
result = _agentSpec->DoOperation(NULL, NULL,
|
||||
|
||||
@@ -1,229 +0,0 @@
|
||||
// ArchiveUpdateCallback.h
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ArchiveUpdateCallback.h"
|
||||
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/Defs.h"
|
||||
|
||||
#include "Windows/FileName.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
|
||||
#include "../../Common/FileStreams.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
void CArchiveUpdateCallback::Init(const UString &baseFolderPrefix,
|
||||
const CObjectVector<CDirItem> *dirItems,
|
||||
const CObjectVector<CArchiveItem> *archiveItems, // test CItemInfoExList
|
||||
CObjectVector<CUpdatePair2> *updatePairs,
|
||||
IInArchive *inArchive,
|
||||
IFolderArchiveUpdateCallback *updateCallback)
|
||||
{
|
||||
m_BaseFolderPrefix = baseFolderPrefix;
|
||||
NFile::NName::NormalizeDirPathPrefix(m_BaseFolderPrefix);
|
||||
m_DirItems = dirItems;
|
||||
m_ArchiveItems = archiveItems;
|
||||
m_UpdatePairs = updatePairs;
|
||||
m_UpdateCallback = updateCallback;
|
||||
m_CodePage = ::AreFileApisANSI() ? CP_ACP : CP_OEMCP;
|
||||
_inArchive = inArchive;;
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::SetTotal(UINT64 size)
|
||||
{
|
||||
if (m_UpdateCallback)
|
||||
return m_UpdateCallback->SetTotal(size);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UINT64 *completeValue)
|
||||
{
|
||||
if (m_UpdateCallback)
|
||||
return m_UpdateCallback->SetCompleted(completeValue);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
STATPROPSTG kProperties[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
{ NULL, kpidIsFolder, VT_BOOL},
|
||||
{ NULL, kpidSize, VT_UI8},
|
||||
{ NULL, kpidLastAccessTime, VT_FILETIME},
|
||||
{ NULL, kpidCreationTime, VT_FILETIME},
|
||||
{ NULL, kpidLastWriteTime, VT_FILETIME},
|
||||
{ NULL, kpidAttributes, VT_UI4},
|
||||
{ NULL, kpidIsAnti, VT_BOOL}
|
||||
};
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **enumerator)
|
||||
{
|
||||
return CStatPropEnumerator::CreateEnumerator(kProperties,
|
||||
sizeof(kProperties) / sizeof(kProperties[0]), enumerator);
|
||||
}
|
||||
*/
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UINT32 index,
|
||||
INT32 *newData, INT32 *newProperties, UINT32 *indexInArchive)
|
||||
{
|
||||
const CUpdatePair2 &updatePair = (*m_UpdatePairs)[index];
|
||||
if(newData != NULL)
|
||||
*newData = BoolToInt(updatePair.NewData);
|
||||
if(newProperties != NULL)
|
||||
*newProperties = BoolToInt(updatePair.NewProperties);
|
||||
if(indexInArchive != NULL)
|
||||
{
|
||||
if (updatePair.ExistInArchive)
|
||||
{
|
||||
if (m_ArchiveItems == 0)
|
||||
*indexInArchive = updatePair.ArchiveItemIndex;
|
||||
else
|
||||
*indexInArchive = (*m_ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer;
|
||||
}
|
||||
else
|
||||
*indexInArchive = UINT32(-1);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
const CUpdatePair2 &updatePair = (*m_UpdatePairs)[index];
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
|
||||
if (propID == kpidIsAnti)
|
||||
{
|
||||
propVariant = updatePair.IsAnti;
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (updatePair.IsAnti)
|
||||
{
|
||||
switch(propID)
|
||||
{
|
||||
case kpidIsFolder:
|
||||
case kpidPath:
|
||||
break;
|
||||
case kpidSize:
|
||||
propVariant = (UINT64)0;
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
default:
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if(updatePair.ExistOnDisk)
|
||||
{
|
||||
const CDirItem &dirItem = (*m_DirItems)[updatePair.DirItemIndex];
|
||||
switch(propID)
|
||||
{
|
||||
case kpidPath:
|
||||
propVariant = dirItem.Name;
|
||||
break;
|
||||
case kpidIsFolder:
|
||||
propVariant = dirItem.IsDirectory();
|
||||
break;
|
||||
case kpidSize:
|
||||
propVariant = dirItem.Size;
|
||||
break;
|
||||
case kpidAttributes:
|
||||
propVariant = dirItem.Attributes;
|
||||
break;
|
||||
case kpidLastAccessTime:
|
||||
propVariant = dirItem.LastAccessTime;
|
||||
break;
|
||||
case kpidCreationTime:
|
||||
propVariant = dirItem.CreationTime;
|
||||
break;
|
||||
case kpidLastWriteTime:
|
||||
propVariant = dirItem.LastWriteTime;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (propID == kpidPath)
|
||||
{
|
||||
if (updatePair.NewNameIsDefined)
|
||||
{
|
||||
propVariant = updatePair.NewName;
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
if (updatePair.ExistInArchive && _inArchive)
|
||||
{
|
||||
UINT32 indexInArchive;
|
||||
if (m_ArchiveItems == 0)
|
||||
indexInArchive = updatePair.ArchiveItemIndex;
|
||||
else
|
||||
indexInArchive = (*m_ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer;
|
||||
return _inArchive->GetProperty(indexInArchive, propID, value);
|
||||
}
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::GetStream(UINT32 index,
|
||||
IInStream **inStream)
|
||||
{
|
||||
const CUpdatePair2 &updatePair = (*m_UpdatePairs)[index];
|
||||
if(!updatePair.NewData)
|
||||
return E_FAIL;
|
||||
const CDirItem &dirItem = (*m_DirItems)[updatePair.DirItemIndex];
|
||||
|
||||
/*
|
||||
m_PercentPrinter.PrintString("Compressing ");
|
||||
m_PercentCanBePrint = true;
|
||||
m_PercentPrinter.PrintString(UnicodeStringToMultiByte(dirItem.Name, CP_OEMCP));
|
||||
m_PercentPrinter.PreparePrint();
|
||||
m_PercentPrinter.RePrintRatio();
|
||||
*/
|
||||
|
||||
if (m_UpdateCallback)
|
||||
{
|
||||
RINOK(m_UpdateCallback->CompressOperation(
|
||||
GetUnicodeString(dirItem.FullPath, m_CodePage)));
|
||||
}
|
||||
|
||||
if(dirItem.IsDirectory())
|
||||
return S_OK;
|
||||
|
||||
CInFileStream *inStreamSpec = new CInFileStream;
|
||||
CMyComPtr<IInStream> inStreamLoc(inStreamSpec);
|
||||
if(!inStreamSpec->Open(m_BaseFolderPrefix + dirItem.FullPath))
|
||||
return ::GetLastError();
|
||||
|
||||
*inStream = inStreamLoc.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(INT32 operationResult)
|
||||
{
|
||||
if (m_UpdateCallback)
|
||||
return m_UpdateCallback->OperationResult(operationResult);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(INT32 *passwordIsDefined, BSTR *password)
|
||||
{
|
||||
*passwordIsDefined = BoolToInt(false);
|
||||
if (!_cryptoGetTextPassword)
|
||||
{
|
||||
if (!m_UpdateCallback)
|
||||
return S_OK;
|
||||
HRESULT result = m_UpdateCallback.QueryInterface(
|
||||
IID_ICryptoGetTextPassword2, &_cryptoGetTextPassword);
|
||||
if (result != S_OK)
|
||||
return S_OK;
|
||||
}
|
||||
return _cryptoGetTextPassword->CryptoGetTextPassword2(passwordIsDefined, password);
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
// ArchiveUpdateCallback.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVEUPDATECALLBACK_H
|
||||
#define __ARCHIVEUPDATECALLBACK_H
|
||||
|
||||
#include "../../Archive/IArchive.h"
|
||||
#include "../../IPassword.h"
|
||||
#include "IFolderArchive.h"
|
||||
|
||||
#include "Common/String.h"
|
||||
#include "Common/MyCom.h"
|
||||
|
||||
#include "../Common/UpdateProduce.h"
|
||||
// #include "Interface/CryptoInterface.h"
|
||||
// #include "Interface/MyCom.h"
|
||||
|
||||
class CArchiveUpdateCallback:
|
||||
public IArchiveUpdateCallback,
|
||||
public ICryptoGetTextPassword2,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP1(ICryptoGetTextPassword2)
|
||||
|
||||
|
||||
// IProgress
|
||||
|
||||
STDMETHOD(SetTotal)(UINT64 size);
|
||||
STDMETHOD(SetCompleted)(const UINT64 *completeValue);
|
||||
|
||||
// IArchiveUpdateCallback
|
||||
// STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator);
|
||||
STDMETHOD(GetUpdateItemInfo)(UINT32 index,
|
||||
INT32 *newData, // 1 - new data, 0 - old data
|
||||
INT32 *newProperties, // 1 - new properties, 0 - old properties
|
||||
UINT32 *indexInArchive// set if existInArchive == true
|
||||
);
|
||||
|
||||
STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value);
|
||||
|
||||
STDMETHOD(GetStream)(UINT32 index, IInStream **anInStream);
|
||||
STDMETHOD(SetOperationResult)(INT32 operationResult);
|
||||
STDMETHOD(CryptoGetTextPassword2)(INT32 *passwordIsDefined, BSTR *password);
|
||||
|
||||
private:
|
||||
UString m_BaseFolderPrefix;
|
||||
const CObjectVector<CDirItem> *m_DirItems;
|
||||
const CObjectVector<CArchiveItem> *m_ArchiveItems;
|
||||
const CObjectVector<CUpdatePair2> *m_UpdatePairs;
|
||||
CMyComPtr<IFolderArchiveUpdateCallback> m_UpdateCallback;
|
||||
CMyComPtr<ICryptoGetTextPassword2> _cryptoGetTextPassword;
|
||||
UINT m_CodePage;
|
||||
|
||||
CMyComPtr<IInArchive> _inArchive;
|
||||
|
||||
public:
|
||||
void Init(const UString &baseFolderPrefix,
|
||||
const CObjectVector<CDirItem> *dirItems,
|
||||
const CObjectVector<CArchiveItem> *archiveItems, // test CItemInfoExList
|
||||
CObjectVector<CUpdatePair2> *updatePairs,
|
||||
// UINT codePage,
|
||||
IInArchive *inArchive,
|
||||
IFolderArchiveUpdateCallback *updateCallback);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,65 +1,13 @@
|
||||
// IFolderArchive.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __IFOLDERARCHIVE_H
|
||||
#define __IFOLDERARCHIVE_H
|
||||
#ifndef __IFOLDER_ARCHIVE_H
|
||||
#define __IFOLDER_ARCHIVE_H
|
||||
|
||||
#include "../../Archive/IArchive.h"
|
||||
// #include "../Format/Common/ArchiveInterface.h"
|
||||
#include "../../FileManager/IFolder.h"
|
||||
|
||||
namespace NExtractionMode {
|
||||
namespace NPath
|
||||
{
|
||||
enum EEnum
|
||||
{
|
||||
kFullPathnames,
|
||||
kCurrentPathnames,
|
||||
kNoPathnames
|
||||
};
|
||||
}
|
||||
namespace NOverwrite
|
||||
{
|
||||
enum EEnum
|
||||
{
|
||||
kAskBefore,
|
||||
kWithoutPrompt,
|
||||
kSkipExisting,
|
||||
kAutoRename
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
namespace NOverwriteAnswer
|
||||
{
|
||||
enum EEnum
|
||||
{
|
||||
kYes,
|
||||
kYesToAll,
|
||||
kNo,
|
||||
kNoToAll,
|
||||
kAutoRename,
|
||||
kCancel,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// {23170F69-40C1-278A-0000-000100070000}
|
||||
DEFINE_GUID(IID_IFolderArchiveExtractCallback,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000100070000")
|
||||
IFolderArchiveExtractCallback: public IProgress
|
||||
{
|
||||
public:
|
||||
STDMETHOD(AskOverwrite)(
|
||||
const wchar_t *existName, const FILETIME *existTime, const UINT64 *existSize,
|
||||
const wchar_t *newName, const FILETIME *newTime, const UINT64 *newSize,
|
||||
INT32 *answer);
|
||||
STDMETHOD(PrepareOperation)(const wchar_t *name, INT32 askExtractMode) PURE;
|
||||
STDMETHOD(MessageError)(const wchar_t *message) PURE;
|
||||
STDMETHOD(SetOperationResult)(INT32 operationResult) PURE;
|
||||
};
|
||||
#include "../Common/IFileExtractCallback.h"
|
||||
#include "../Common/ExtractMode.h"
|
||||
|
||||
// {23170F69-40C1-278A-0000-000100050000}
|
||||
DEFINE_GUID(IID_IArchiveFolder,
|
||||
@@ -69,8 +17,8 @@ IArchiveFolder: public IUnknown
|
||||
{
|
||||
public:
|
||||
STDMETHOD(Extract)(const UINT32 *indices, UINT32 numItems,
|
||||
NExtractionMode::NPath::EEnum pathMode,
|
||||
NExtractionMode::NOverwrite::EEnum overwriteMode,
|
||||
NExtract::NPathMode::EEnum pathMode,
|
||||
NExtract::NOverwriteMode::EEnum overwriteMode,
|
||||
const wchar_t *path,
|
||||
INT32 testMode,
|
||||
IFolderArchiveExtractCallback *extractCallback2) PURE;
|
||||
@@ -100,8 +48,8 @@ public:
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType) PURE;
|
||||
STDMETHOD(BindToRootFolder)(IFolderFolder **resultFolder) PURE;
|
||||
STDMETHOD(Extract)(
|
||||
NExtractionMode::NPath::EEnum pathMode,
|
||||
NExtractionMode::NOverwrite::EEnum overwriteMode,
|
||||
NExtract::NPathMode::EEnum pathMode,
|
||||
NExtract::NOverwriteMode::EEnum overwriteMode,
|
||||
const wchar_t *path,
|
||||
INT32 testMode,
|
||||
IFolderArchiveExtractCallback *extractCallback2) PURE;
|
||||
@@ -117,6 +65,7 @@ public:
|
||||
STDMETHOD(CompressOperation)(const wchar_t *name) PURE;
|
||||
STDMETHOD(DeleteOperation)(const wchar_t *name) PURE;
|
||||
STDMETHOD(OperationResult)(INT32 operationResult) PURE;
|
||||
STDMETHOD(UpdateErrorMessage)(const wchar_t *message) PURE;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-0001000A0000}
|
||||
@@ -133,7 +82,7 @@ IOutFolderArchive: public IUnknown
|
||||
const wchar_t *filePath,
|
||||
const CLSID *clsID,
|
||||
const wchar_t *newArchiveName,
|
||||
const BYTE *stateActions,
|
||||
const Byte *stateActions,
|
||||
const wchar_t *sfxModule,
|
||||
IFolderArchiveUpdateCallback *updateCallback) PURE;
|
||||
};
|
||||
|
||||
80
7zip/UI/Agent/UpdateCallbackAgent.cpp
Executable file
80
7zip/UI/Agent/UpdateCallbackAgent.cpp
Executable file
@@ -0,0 +1,80 @@
|
||||
// UpdateCallbackAgent.h
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Windows/Error.h"
|
||||
|
||||
#include "UpdateCallbackAgent.h"
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
HRESULT CUpdateCallbackAgent::SetTotal(UINT64 size)
|
||||
{
|
||||
if (Callback)
|
||||
return Callback->SetTotal(size);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackAgent::SetCompleted(const UINT64 *completeValue)
|
||||
{
|
||||
if (Callback)
|
||||
return Callback->SetCompleted(completeValue);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackAgent::CheckBreak()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackAgent::Finilize()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackAgent::OpenFileError(const wchar_t *name, DWORD systemError)
|
||||
{
|
||||
// if (systemError == ERROR_SHARING_VIOLATION)
|
||||
{
|
||||
if (Callback)
|
||||
{
|
||||
RINOK(Callback->UpdateErrorMessage(
|
||||
UString(L"WARNING: ") +
|
||||
NError::MyFormatMessageW(systemError) +
|
||||
UString(L": ") +
|
||||
UString(name)));
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
// FailedFiles.Add(name);
|
||||
return systemError;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackAgent::GetStream(const wchar_t *name, bool isAnti)
|
||||
{
|
||||
if (Callback)
|
||||
return Callback->CompressOperation(name);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackAgent::SetOperationResult(INT32 operationResult)
|
||||
{
|
||||
if (Callback)
|
||||
return Callback->OperationResult(operationResult);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackAgent::CryptoGetTextPassword2(INT32 *passwordIsDefined, BSTR *password)
|
||||
{
|
||||
*passwordIsDefined = BoolToInt(false);
|
||||
if (!_cryptoGetTextPassword)
|
||||
{
|
||||
if (!Callback)
|
||||
return S_OK;
|
||||
HRESULT result = Callback.QueryInterface(
|
||||
IID_ICryptoGetTextPassword2, &_cryptoGetTextPassword);
|
||||
if (result != S_OK)
|
||||
return S_OK;
|
||||
}
|
||||
return _cryptoGetTextPassword->CryptoGetTextPassword2(passwordIsDefined, password);
|
||||
}
|
||||
24
7zip/UI/Agent/UpdateCallbackAgent.h
Executable file
24
7zip/UI/Agent/UpdateCallbackAgent.h
Executable file
@@ -0,0 +1,24 @@
|
||||
// UpdateCallbackAgent.h
|
||||
|
||||
#ifndef __UPDATECALLBACKAGENT_H
|
||||
#define __UPDATECALLBACKAGENT_H
|
||||
|
||||
#include "../Common/UpdateCallback.h"
|
||||
#include "IFolderArchive.h"
|
||||
|
||||
class CUpdateCallbackAgent: public IUpdateCallbackUI
|
||||
{
|
||||
virtual HRESULT SetTotal(UINT64 size);
|
||||
virtual HRESULT SetCompleted(const UINT64 *completeValue);
|
||||
virtual HRESULT CheckBreak();
|
||||
virtual HRESULT Finilize();
|
||||
virtual HRESULT GetStream(const wchar_t *name, bool isAnti);
|
||||
virtual HRESULT OpenFileError(const wchar_t *name, DWORD systemError);
|
||||
virtual HRESULT SetOperationResult(INT32 operationResult);
|
||||
virtual HRESULT CryptoGetTextPassword2(INT32 *passwordIsDefined, BSTR *password);
|
||||
CMyComPtr<ICryptoGetTextPassword2> _cryptoGetTextPassword;
|
||||
public:
|
||||
CMyComPtr<IFolderArchiveUpdateCallback> Callback;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
// Client7z.cpp : Defines the entry point for the console application.
|
||||
// Client7z.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include <initguid.h>
|
||||
|
||||
@@ -59,9 +59,9 @@ int main(int argc, char* argv[])
|
||||
}
|
||||
if (archive->Open(file, 0, 0) != S_OK)
|
||||
return 0;
|
||||
UINT32 numItems = 0;
|
||||
UInt32 numItems = 0;
|
||||
archive->GetNumberOfItems(&numItems);
|
||||
for (UINT32 i = 0; i < numItems; i++)
|
||||
for (UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
archive->GetProperty(i, kpidPath, &propVariant);
|
||||
|
||||
@@ -81,35 +81,19 @@ LINK32=link.exe
|
||||
|
||||
# Name "Client7z - Win32 Release"
|
||||
# Name "Client7z - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
# Begin Group "Spec"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Client7z.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.cpp
|
||||
# ADD CPP /Yc"stdafx.h"
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# Begin Group "SDK"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# End Group
|
||||
# Begin Group "Windows"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
@@ -186,5 +170,9 @@ SOURCE=..\..\Common\FileStreams.cpp
|
||||
SOURCE=..\..\Common\FileStreams.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Client7z.cpp
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// Client7z.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
// stdafx.h
|
||||
|
||||
#pragma once
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
@@ -9,4 +7,3 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
830
7zip/UI/Common/ArchiveCommandLine.cpp
Executable file
830
7zip/UI/Common/ArchiveCommandLine.cpp
Executable file
@@ -0,0 +1,830 @@
|
||||
// ArchiveCommandLine.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include <io.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "Common/ListFileUtils.h"
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/StringToInt.h"
|
||||
|
||||
#include "Windows/FileName.h"
|
||||
#include "Windows/FileDir.h"
|
||||
#ifdef _WIN32
|
||||
#include "Windows/FileMapping.h"
|
||||
#include "Windows/Synchronization.h"
|
||||
#endif
|
||||
|
||||
#include "ArchiveCommandLine.h"
|
||||
#include "UpdateAction.h"
|
||||
#include "Update.h"
|
||||
#include "ArchiverInfo.h"
|
||||
#include "SortUtils.h"
|
||||
#include "EnumDirItems.h"
|
||||
|
||||
using namespace NCommandLineParser;
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
|
||||
static const int kNumSwitches = 24;
|
||||
|
||||
namespace NKey {
|
||||
enum Enum
|
||||
{
|
||||
kHelp1 = 0,
|
||||
kHelp2,
|
||||
kDisableHeaders,
|
||||
kDisablePercents,
|
||||
kArchiveType,
|
||||
kYes,
|
||||
kPassword,
|
||||
kProperty,
|
||||
kOutputDir,
|
||||
kWorkingDir,
|
||||
kInclude,
|
||||
kExclude,
|
||||
kArInclude,
|
||||
kArExclude,
|
||||
kNoArName,
|
||||
kUpdate,
|
||||
kVolume,
|
||||
kRecursed,
|
||||
kSfx,
|
||||
kStdIn,
|
||||
kStdOut,
|
||||
kOverwrite,
|
||||
kEmail,
|
||||
kShowDialog
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
static const wchar_t kRecursedIDChar = 'R';
|
||||
static const wchar_t *kRecursedPostCharSet = L"0-";
|
||||
|
||||
static const wchar_t *kDefaultArchiveType = L"7z";
|
||||
static const wchar_t *kSFXExtension = L"exe";
|
||||
|
||||
namespace NRecursedPostCharIndex {
|
||||
enum EEnum
|
||||
{
|
||||
kWildCardRecursionOnly = 0,
|
||||
kNoRecursion = 1
|
||||
};
|
||||
}
|
||||
|
||||
static const char kImmediateNameID = '!';
|
||||
static const char kMapNameID = '#';
|
||||
static const char kFileListID = '@';
|
||||
|
||||
static const char kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must be
|
||||
static const char kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must be
|
||||
|
||||
static const wchar_t *kOverwritePostCharSet = L"asut";
|
||||
|
||||
NExtract::NOverwriteMode::EEnum k_OverwriteModes[] =
|
||||
{
|
||||
NExtract::NOverwriteMode::kWithoutPrompt,
|
||||
NExtract::NOverwriteMode::kSkipExisting,
|
||||
NExtract::NOverwriteMode::kAutoRename,
|
||||
NExtract::NOverwriteMode::kAutoRenameExisting
|
||||
};
|
||||
|
||||
static const CSwitchForm kSwitchForms[kNumSwitches] =
|
||||
{
|
||||
{ L"?", NSwitchType::kSimple, false },
|
||||
{ L"H", NSwitchType::kSimple, false },
|
||||
{ L"BA", NSwitchType::kSimple, false },
|
||||
{ L"BD", NSwitchType::kSimple, false },
|
||||
{ L"T", NSwitchType::kUnLimitedPostString, false, 1 },
|
||||
{ L"Y", NSwitchType::kSimple, false },
|
||||
{ L"P", NSwitchType::kUnLimitedPostString, false, 0 },
|
||||
{ L"M", NSwitchType::kUnLimitedPostString, true, 1 },
|
||||
{ L"O", NSwitchType::kUnLimitedPostString, false, 1 },
|
||||
{ L"W", NSwitchType::kUnLimitedPostString, false, 0 },
|
||||
{ L"I", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
|
||||
{ L"X", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
|
||||
{ L"AI", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
|
||||
{ L"AX", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
|
||||
{ L"AN", NSwitchType::kSimple, false },
|
||||
{ L"U", NSwitchType::kUnLimitedPostString, true, 1},
|
||||
{ L"V", NSwitchType::kUnLimitedPostString, true, 1},
|
||||
{ L"R", NSwitchType::kPostChar, false, 0, 0, kRecursedPostCharSet },
|
||||
{ L"SFX", NSwitchType::kUnLimitedPostString, false, 0 },
|
||||
{ L"SI", NSwitchType::kUnLimitedPostString, false, 0 },
|
||||
{ L"SO", NSwitchType::kSimple, false, 0 },
|
||||
{ L"AO", NSwitchType::kPostChar, false, 1, 1, kOverwritePostCharSet},
|
||||
{ L"SEML", NSwitchType::kUnLimitedPostString, false, 0},
|
||||
{ L"AD", NSwitchType::kSimple, false }
|
||||
};
|
||||
|
||||
static const int kNumCommandForms = 7;
|
||||
|
||||
static const CCommandForm g_CommandForms[kNumCommandForms] =
|
||||
{
|
||||
{ L"A", false },
|
||||
{ L"U", false },
|
||||
{ L"D", false },
|
||||
{ L"T", false },
|
||||
{ L"E", false },
|
||||
{ L"X", false },
|
||||
{ L"L", false }
|
||||
};
|
||||
|
||||
static const int kMaxCmdLineSize = 1000;
|
||||
static const wchar_t *kUniversalWildcard = L"*";
|
||||
static const int kMinNonSwitchWords = 1;
|
||||
static const int kCommandIndex = 0;
|
||||
|
||||
// ---------------------------
|
||||
// exception messages
|
||||
|
||||
static const char *kUserErrorMessage = "Incorrect command line";
|
||||
static const char *kIncorrectListFile = "Incorrect wildcard in listfile";
|
||||
static const char *kIncorrectWildCardInListFile = "Incorrect wildcard in listfile";
|
||||
static const char *kIncorrectWildCardInCommandLine = "Incorrect wildcard in command line";
|
||||
static const char *kTerminalOutError = "I won't write compressed data to a terminal";
|
||||
|
||||
// ---------------------------
|
||||
|
||||
bool CArchiveCommand::IsFromExtractGroup() const
|
||||
{
|
||||
switch(CommandType)
|
||||
{
|
||||
case NCommandType::kTest:
|
||||
case NCommandType::kExtract:
|
||||
case NCommandType::kFullExtract:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
NExtract::NPathMode::EEnum CArchiveCommand::GetPathMode() const
|
||||
{
|
||||
switch(CommandType)
|
||||
{
|
||||
case NCommandType::kTest:
|
||||
case NCommandType::kFullExtract:
|
||||
return NExtract::NPathMode::kFullPathnames;
|
||||
default:
|
||||
return NExtract::NPathMode::kNoPathnames;
|
||||
}
|
||||
}
|
||||
|
||||
bool CArchiveCommand::IsFromUpdateGroup() const
|
||||
{
|
||||
return (CommandType == NCommandType::kAdd ||
|
||||
CommandType == NCommandType::kUpdate ||
|
||||
CommandType == NCommandType::kDelete);
|
||||
}
|
||||
|
||||
static NRecursedType::EEnum GetRecursedTypeFromIndex(int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case NRecursedPostCharIndex::kWildCardRecursionOnly:
|
||||
return NRecursedType::kWildCardOnlyRecursed;
|
||||
case NRecursedPostCharIndex::kNoRecursion:
|
||||
return NRecursedType::kNonRecursed;
|
||||
default:
|
||||
return NRecursedType::kRecursed;
|
||||
}
|
||||
}
|
||||
|
||||
static bool ParseArchiveCommand(const UString &commandString, CArchiveCommand &command)
|
||||
{
|
||||
UString commandStringUpper = commandString;
|
||||
commandStringUpper.MakeUpper();
|
||||
UString postString;
|
||||
int commandIndex = ParseCommand(kNumCommandForms, g_CommandForms, commandStringUpper,
|
||||
postString) ;
|
||||
if (commandIndex < 0)
|
||||
return false;
|
||||
command.CommandType = (NCommandType::EEnum)commandIndex;
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// filenames functions
|
||||
|
||||
static bool AddNameToCensor(NWildcard::CCensor &wildcardCensor,
|
||||
const UString &name, bool include, NRecursedType::EEnum type)
|
||||
{
|
||||
bool isWildCard = DoesNameContainWildCard(name);
|
||||
bool recursed;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case NRecursedType::kWildCardOnlyRecursed:
|
||||
recursed = isWildCard;
|
||||
break;
|
||||
case NRecursedType::kRecursed:
|
||||
recursed = true;
|
||||
break;
|
||||
case NRecursedType::kNonRecursed:
|
||||
recursed = false;
|
||||
break;
|
||||
}
|
||||
wildcardCensor.AddItem(name, include, recursed);
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline UINT GetCurrentCodePage()
|
||||
{ return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
|
||||
|
||||
static void AddToCensorFromListFile(NWildcard::CCensor &wildcardCensor,
|
||||
LPCWSTR fileName, bool include, NRecursedType::EEnum type)
|
||||
{
|
||||
UStringVector names;
|
||||
if (!ReadNamesFromListFile(GetSystemString(fileName,
|
||||
GetCurrentCodePage()), names))
|
||||
throw kIncorrectListFile;
|
||||
for (int i = 0; i < names.Size(); i++)
|
||||
if (!AddNameToCensor(wildcardCensor, names[i], include, type))
|
||||
throw kIncorrectWildCardInListFile;
|
||||
}
|
||||
|
||||
static void AddCommandLineWildCardToCensr(NWildcard::CCensor &wildcardCensor,
|
||||
const UString &name, bool include, NRecursedType::EEnum recursedType)
|
||||
{
|
||||
if (!AddNameToCensor(wildcardCensor, name, include, recursedType))
|
||||
throw kIncorrectWildCardInCommandLine;
|
||||
}
|
||||
|
||||
static void AddToCensorFromNonSwitchesStrings(
|
||||
int startIndex,
|
||||
NWildcard::CCensor &wildcardCensor,
|
||||
const UStringVector &nonSwitchStrings, NRecursedType::EEnum type,
|
||||
bool thereAreSwitchIncludes)
|
||||
{
|
||||
if(nonSwitchStrings.Size() == startIndex && (!thereAreSwitchIncludes))
|
||||
AddCommandLineWildCardToCensr(wildcardCensor, kUniversalWildcard, true, type);
|
||||
for(int i = startIndex; i < nonSwitchStrings.Size(); i++)
|
||||
{
|
||||
const UString &s = nonSwitchStrings[i];
|
||||
if (s[0] == kFileListID)
|
||||
AddToCensorFromListFile(wildcardCensor, s.Mid(1), true, type);
|
||||
else
|
||||
AddCommandLineWildCardToCensr(wildcardCensor, s, true, type);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static void ParseMapWithPaths(NWildcard::CCensor &wildcardCensor,
|
||||
const UString &switchParam, bool include,
|
||||
NRecursedType::EEnum commonRecursedType)
|
||||
{
|
||||
int splitPos = switchParam.Find(L':');
|
||||
if (splitPos < 0)
|
||||
throw kUserErrorMessage;
|
||||
UString mappingName = switchParam.Left(splitPos);
|
||||
|
||||
UString switchParam2 = switchParam.Mid(splitPos + 1);
|
||||
splitPos = switchParam2.Find(L':');
|
||||
if (splitPos < 0)
|
||||
throw kUserErrorMessage;
|
||||
|
||||
UString mappingSize = switchParam2.Left(splitPos);
|
||||
UString eventName = switchParam2.Mid(splitPos + 1);
|
||||
|
||||
UInt64 dataSize64 = ConvertStringToUInt64(mappingSize, NULL);
|
||||
UInt32 dataSize = (UInt32)dataSize64;
|
||||
{
|
||||
CFileMapping fileMapping;
|
||||
if (!fileMapping.Open(FILE_MAP_READ, false, GetSystemString(mappingName)))
|
||||
throw L"Can not open mapping";
|
||||
LPVOID data = fileMapping.MapViewOfFile(FILE_MAP_READ, 0, dataSize);
|
||||
if (data == NULL)
|
||||
throw L"MapViewOfFile error";
|
||||
try
|
||||
{
|
||||
const wchar_t *curData = (const wchar_t *)data;
|
||||
if (*curData != 0)
|
||||
throw L"Incorrect mapping data";
|
||||
UInt32 numChars = dataSize / sizeof(wchar_t);
|
||||
UString name;
|
||||
for (UInt32 i = 1; i < numChars; i++)
|
||||
{
|
||||
wchar_t c = curData[i];
|
||||
if (c == L'\0')
|
||||
{
|
||||
AddCommandLineWildCardToCensr(wildcardCensor,
|
||||
name, include, commonRecursedType);
|
||||
name.Empty();
|
||||
}
|
||||
else
|
||||
name += c;
|
||||
}
|
||||
if (!name.IsEmpty())
|
||||
throw L"data error";
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
UnmapViewOfFile(data);
|
||||
throw;
|
||||
}
|
||||
UnmapViewOfFile(data);
|
||||
}
|
||||
|
||||
{
|
||||
NSynchronization::CEvent event;
|
||||
event.Open(EVENT_MODIFY_STATE, false, GetSystemString(eventName));
|
||||
event.Set();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void AddSwitchWildCardsToCensor(NWildcard::CCensor &wildcardCensor,
|
||||
const UStringVector &strings, bool include,
|
||||
NRecursedType::EEnum commonRecursedType)
|
||||
{
|
||||
for(int i = 0; i < strings.Size(); i++)
|
||||
{
|
||||
const UString &name = strings[i];
|
||||
NRecursedType::EEnum recursedType;
|
||||
int pos = 0;
|
||||
if (name.Length() < kSomeCludePostStringMinSize)
|
||||
throw kUserErrorMessage;
|
||||
if (::MyCharUpper(name[pos]) == kRecursedIDChar)
|
||||
{
|
||||
pos++;
|
||||
int index = UString(kRecursedPostCharSet).Find(name[pos]);
|
||||
recursedType = GetRecursedTypeFromIndex(index);
|
||||
if (index >= 0)
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
recursedType = commonRecursedType;
|
||||
if (name.Length() < pos + kSomeCludeAfterRecursedPostStringMinSize)
|
||||
throw kUserErrorMessage;
|
||||
UString tail = name.Mid(pos + 1);
|
||||
if (name[pos] == kImmediateNameID)
|
||||
AddCommandLineWildCardToCensr(wildcardCensor, tail, include, recursedType);
|
||||
else if (name[pos] == kFileListID)
|
||||
AddToCensorFromListFile(wildcardCensor, tail, include, recursedType);
|
||||
#ifdef _WIN32
|
||||
else if (name[pos] == kMapNameID)
|
||||
ParseMapWithPaths(wildcardCensor, tail, include, recursedType);
|
||||
#endif
|
||||
else
|
||||
throw kUserErrorMessage;
|
||||
}
|
||||
}
|
||||
|
||||
static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i)
|
||||
{
|
||||
switch(i)
|
||||
{
|
||||
case NUpdateArchive::NPairAction::kIgnore: return NUpdateArchive::NPairAction::kIgnore;
|
||||
case NUpdateArchive::NPairAction::kCopy: return NUpdateArchive::NPairAction::kCopy;
|
||||
case NUpdateArchive::NPairAction::kCompress: return NUpdateArchive::NPairAction::kCompress;
|
||||
case NUpdateArchive::NPairAction::kCompressAsAnti: return NUpdateArchive::NPairAction::kCompressAsAnti;
|
||||
}
|
||||
throw 98111603;
|
||||
}
|
||||
|
||||
const UString kUpdatePairStateIDSet = L"PQRXYZW";
|
||||
const int kUpdatePairStateNotSupportedActions[] = {2, 2, 1, -1, -1, -1, -1};
|
||||
|
||||
const UString kUpdatePairActionIDSet = L"0123"; //Ignore, Copy, Compress, Create Anti
|
||||
|
||||
const wchar_t *kUpdateIgnoreItselfPostStringID = L"-";
|
||||
const wchar_t kUpdateNewArchivePostCharID = '!';
|
||||
|
||||
|
||||
static bool ParseUpdateCommandString2(const UString &command,
|
||||
NUpdateArchive::CActionSet &actionSet, UString &postString)
|
||||
{
|
||||
for(int i = 0; i < command.Length();)
|
||||
{
|
||||
wchar_t c = MyCharUpper(command[i]);
|
||||
int statePos = kUpdatePairStateIDSet.Find(c);
|
||||
if (statePos < 0)
|
||||
{
|
||||
postString = command.Mid(i);
|
||||
return true;
|
||||
}
|
||||
i++;
|
||||
if (i >= command.Length())
|
||||
return false;
|
||||
int actionPos = kUpdatePairActionIDSet.Find(::MyCharUpper(command[i]));
|
||||
if (actionPos < 0)
|
||||
return false;
|
||||
actionSet.StateActions[statePos] = GetUpdatePairActionType(actionPos);
|
||||
if (kUpdatePairStateNotSupportedActions[statePos] == actionPos)
|
||||
return false;
|
||||
i++;
|
||||
}
|
||||
postString.Empty();
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ParseUpdateCommandString(CUpdateOptions &options,
|
||||
const UStringVector &updatePostStrings,
|
||||
const NUpdateArchive::CActionSet &defaultActionSet)
|
||||
{
|
||||
for(int i = 0; i < updatePostStrings.Size(); i++)
|
||||
{
|
||||
const UString &updateString = updatePostStrings[i];
|
||||
if(updateString.CompareNoCase(kUpdateIgnoreItselfPostStringID) == 0)
|
||||
{
|
||||
if(options.UpdateArchiveItself)
|
||||
{
|
||||
options.UpdateArchiveItself = false;
|
||||
options.Commands.Delete(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NUpdateArchive::CActionSet actionSet = defaultActionSet;
|
||||
|
||||
UString postString;
|
||||
if (!ParseUpdateCommandString2(updateString, actionSet, postString))
|
||||
throw kUserErrorMessage;
|
||||
if(postString.IsEmpty())
|
||||
{
|
||||
if(options.UpdateArchiveItself)
|
||||
options.Commands[0].ActionSet = actionSet;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(MyCharUpper(postString[0]) != kUpdateNewArchivePostCharID)
|
||||
throw kUserErrorMessage;
|
||||
CUpdateArchiveCommand uc;
|
||||
UString archivePath = postString.Mid(1);
|
||||
if (archivePath.IsEmpty())
|
||||
throw kUserErrorMessage;
|
||||
uc.ArchivePath.BaseExtension = options.ArchivePath.BaseExtension;
|
||||
uc.ArchivePath.VolExtension = options.ArchivePath.VolExtension;
|
||||
uc.ArchivePath.ParseFromPath(archivePath);
|
||||
uc.ActionSet = actionSet;
|
||||
options.Commands.Add(uc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const char kByteSymbol = 'B';
|
||||
static const char kKiloSymbol = 'K';
|
||||
static const char kMegaSymbol = 'M';
|
||||
static const char kGigaSymbol = 'G';
|
||||
|
||||
static bool ParseComplexSize(const UString &src, UInt64 &result)
|
||||
{
|
||||
UString s = src;
|
||||
s.MakeUpper();
|
||||
|
||||
const wchar_t *start = s;
|
||||
const wchar_t *end;
|
||||
UInt64 number = ConvertStringToUInt64(start, &end);
|
||||
int numDigits = end - start;
|
||||
if (numDigits == 0 || s.Length() > numDigits + 1)
|
||||
return false;
|
||||
if (s.Length() == numDigits)
|
||||
{
|
||||
result = number;
|
||||
return true;
|
||||
}
|
||||
int numBits;
|
||||
switch (s[numDigits])
|
||||
{
|
||||
case kByteSymbol:
|
||||
result = number;
|
||||
return true;
|
||||
case kKiloSymbol:
|
||||
numBits = 10;
|
||||
break;
|
||||
case kMegaSymbol:
|
||||
numBits = 20;
|
||||
break;
|
||||
case kGigaSymbol:
|
||||
numBits = 30;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (number >= ((UInt64)1 << (64 - numBits)))
|
||||
return false;
|
||||
result = number << numBits;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void SetAddCommandOptions(
|
||||
NCommandType::EEnum commandType,
|
||||
const CParser &parser,
|
||||
CUpdateOptions &options)
|
||||
{
|
||||
NUpdateArchive::CActionSet defaultActionSet;
|
||||
switch(commandType)
|
||||
{
|
||||
case NCommandType::kAdd:
|
||||
defaultActionSet = NUpdateArchive::kAddActionSet;
|
||||
break;
|
||||
case NCommandType::kDelete:
|
||||
defaultActionSet = NUpdateArchive::kDeleteActionSet;
|
||||
break;
|
||||
default:
|
||||
defaultActionSet = NUpdateArchive::kUpdateActionSet;
|
||||
}
|
||||
|
||||
options.UpdateArchiveItself = true;
|
||||
|
||||
options.Commands.Clear();
|
||||
CUpdateArchiveCommand updateMainCommand;
|
||||
updateMainCommand.ActionSet = defaultActionSet;
|
||||
options.Commands.Add(updateMainCommand);
|
||||
if(parser[NKey::kUpdate].ThereIs)
|
||||
ParseUpdateCommandString(options, parser[NKey::kUpdate].PostStrings,
|
||||
defaultActionSet);
|
||||
if(parser[NKey::kWorkingDir].ThereIs)
|
||||
{
|
||||
const UString &postString = parser[NKey::kWorkingDir].PostStrings[0];
|
||||
if (postString.IsEmpty())
|
||||
NDirectory::MyGetTempPath(options.WorkingDir);
|
||||
else
|
||||
options.WorkingDir = postString;
|
||||
}
|
||||
if(options.SfxMode = parser[NKey::kSfx].ThereIs)
|
||||
options.SfxModule = parser[NKey::kSfx].PostStrings[0];
|
||||
|
||||
if (parser[NKey::kVolume].ThereIs)
|
||||
{
|
||||
const UStringVector &sv = parser[NKey::kVolume].PostStrings;
|
||||
for (int i = 0; i < sv.Size(); i++)
|
||||
{
|
||||
const UString &s = sv[i];
|
||||
UInt64 size;
|
||||
if (!ParseComplexSize(sv[i], size))
|
||||
throw "incorrect volume size";
|
||||
options.VolumesSizes.Add(size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SetMethodOptions(const CParser &parser,
|
||||
CUpdateOptions &options)
|
||||
{
|
||||
if (parser[NKey::kProperty].ThereIs)
|
||||
{
|
||||
// options.MethodMode.Properties.Clear();
|
||||
for(int i = 0; i < parser[NKey::kProperty].PostStrings.Size(); i++)
|
||||
{
|
||||
CProperty property;
|
||||
const UString &postString = parser[NKey::kProperty].PostStrings[i];
|
||||
int index = postString.Find(L'=');
|
||||
if (index < 0)
|
||||
property.Name = postString;
|
||||
else
|
||||
{
|
||||
property.Name = postString.Left(index);
|
||||
property.Value = postString.Mid(index + 1);
|
||||
}
|
||||
options.MethodMode.Properties.Add(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void SetArchiveType(const UString &archiveType,
|
||||
#ifndef EXCLUDE_COM
|
||||
UString &filePath, CLSID &classID,
|
||||
#else
|
||||
UString &formatName,
|
||||
#endif
|
||||
UString &archiveExtension)
|
||||
{
|
||||
CObjectVector<CArchiverInfo> archiverInfoVector;
|
||||
ReadArchiverInfoList(archiverInfoVector);
|
||||
if (archiverInfoVector.Size() == 0)
|
||||
throw "There are no installed archive handlers";
|
||||
if (archiveType.IsEmpty())
|
||||
throw "Incorrect archive type was assigned";
|
||||
for (int i = 0; i < archiverInfoVector.Size(); i++)
|
||||
{
|
||||
const CArchiverInfo &archiverInfo = archiverInfoVector[i];
|
||||
if (archiverInfo.Name.CompareNoCase(archiveType) == 0)
|
||||
{
|
||||
#ifndef EXCLUDE_COM
|
||||
classID = archiverInfo.ClassID;
|
||||
filePath = archiverInfo.FilePath;
|
||||
#else
|
||||
formatName = archiverInfo.Name;
|
||||
|
||||
#endif
|
||||
|
||||
archiveExtension = archiverInfo.GetMainExtension();
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw "Incorrect archive type was assigned";
|
||||
}
|
||||
|
||||
|
||||
CArchiveCommandLineParser::CArchiveCommandLineParser(): parser(kNumSwitches) {}
|
||||
|
||||
void CArchiveCommandLineParser::Parse1(UStringVector commandStrings,
|
||||
CArchiveCommandLineOptions &options)
|
||||
{
|
||||
try
|
||||
{
|
||||
parser.ParseStrings(kSwitchForms, commandStrings);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
throw kUserErrorMessage;
|
||||
}
|
||||
|
||||
options.IsInTerminal = (isatty(fileno(stdin)) != 0);
|
||||
options.IsStdOutTerminal = (isatty(fileno(stdout)) != 0);
|
||||
options.IsStdErrTerminal = (isatty(fileno(stderr)) != 0);
|
||||
options.StdOutMode = parser[NKey::kStdOut].ThereIs;
|
||||
options.EnableHeaders = !parser[NKey::kDisableHeaders].ThereIs;
|
||||
options.HelpMode = parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs;
|
||||
}
|
||||
|
||||
void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
|
||||
{
|
||||
const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
|
||||
int numNonSwitchStrings = nonSwitchStrings.Size();
|
||||
if(numNonSwitchStrings < kMinNonSwitchWords)
|
||||
throw kUserErrorMessage;
|
||||
|
||||
if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], options.Command))
|
||||
throw kUserErrorMessage;
|
||||
|
||||
NRecursedType::EEnum recursedType;
|
||||
if (parser[NKey::kRecursed].ThereIs)
|
||||
recursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex);
|
||||
else
|
||||
recursedType = NRecursedType::kNonRecursed;
|
||||
|
||||
bool thereAreSwitchIncludes = false;
|
||||
if (parser[NKey::kInclude].ThereIs)
|
||||
{
|
||||
thereAreSwitchIncludes = true;
|
||||
AddSwitchWildCardsToCensor(options.WildcardCensor,
|
||||
parser[NKey::kInclude].PostStrings, true, recursedType);
|
||||
}
|
||||
if (parser[NKey::kExclude].ThereIs)
|
||||
AddSwitchWildCardsToCensor(options.WildcardCensor,
|
||||
parser[NKey::kExclude].PostStrings, false, recursedType);
|
||||
|
||||
int curCommandIndex = kCommandIndex + 1;
|
||||
bool thereIsArchiveName = !parser[NKey::kNoArName].ThereIs;
|
||||
if (thereIsArchiveName)
|
||||
{
|
||||
if(curCommandIndex >= numNonSwitchStrings)
|
||||
throw kUserErrorMessage;
|
||||
options.ArchiveName = nonSwitchStrings[curCommandIndex++];
|
||||
}
|
||||
|
||||
AddToCensorFromNonSwitchesStrings(
|
||||
curCommandIndex, options.WildcardCensor,
|
||||
nonSwitchStrings, recursedType, thereAreSwitchIncludes);
|
||||
|
||||
options.YesToAll = parser[NKey::kYes].ThereIs;
|
||||
|
||||
bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
|
||||
|
||||
options.PasswordEnabled = parser[NKey::kPassword].ThereIs;
|
||||
|
||||
if(options.PasswordEnabled)
|
||||
options.Password = parser[NKey::kPassword].PostStrings[0];
|
||||
|
||||
options.StdInMode = parser[NKey::kStdIn].ThereIs;
|
||||
options.ShowDialog = parser[NKey::kShowDialog].ThereIs;
|
||||
|
||||
if(isExtractGroupCommand || options.Command.CommandType == NCommandType::kList)
|
||||
{
|
||||
if (options.StdInMode)
|
||||
throw "reading archives from stdin is not implemented";
|
||||
if (!options.WildcardCensor.AllAreRelative())
|
||||
throw "cannot use absolute pathnames for this command";
|
||||
|
||||
NWildcard::CCensor archiveWildcardCensor;
|
||||
|
||||
if (parser[NKey::kArInclude].ThereIs)
|
||||
{
|
||||
AddSwitchWildCardsToCensor(archiveWildcardCensor,
|
||||
parser[NKey::kArInclude].PostStrings, true, NRecursedType::kNonRecursed);
|
||||
}
|
||||
if (parser[NKey::kArExclude].ThereIs)
|
||||
AddSwitchWildCardsToCensor(archiveWildcardCensor,
|
||||
parser[NKey::kArExclude].PostStrings, false, NRecursedType::kNonRecursed);
|
||||
|
||||
if (thereIsArchiveName)
|
||||
AddCommandLineWildCardToCensr(archiveWildcardCensor, options.ArchiveName, true, NRecursedType::kNonRecursed);
|
||||
|
||||
CObjectVector<CDirItem> dirItems;
|
||||
EnumerateItems(archiveWildcardCensor, dirItems, NULL);
|
||||
UStringVector archivePaths;
|
||||
int i;
|
||||
for (i = 0; i < dirItems.Size(); i++)
|
||||
archivePaths.Add(dirItems[i].FullPath);
|
||||
|
||||
if (archivePaths.Size() == 0)
|
||||
throw "there is no such archive";
|
||||
|
||||
UStringVector archivePathsFull;
|
||||
|
||||
for (i = 0; i < archivePaths.Size(); i++)
|
||||
{
|
||||
UString fullPath;
|
||||
NFile::NDirectory::MyGetFullPathName(archivePaths[i], fullPath);
|
||||
archivePathsFull.Add(fullPath);
|
||||
}
|
||||
CIntVector indices;
|
||||
SortStringsToIndices(archivePathsFull, indices);
|
||||
options.ArchivePathsSorted.Reserve(indices.Size());
|
||||
options.ArchivePathsFullSorted.Reserve(indices.Size());
|
||||
for (i = 0; i < indices.Size(); i++)
|
||||
{
|
||||
options.ArchivePathsSorted.Add(archivePaths[indices[i]]);
|
||||
options.ArchivePathsFullSorted.Add(archivePathsFull[indices[i]]);
|
||||
}
|
||||
|
||||
if(isExtractGroupCommand)
|
||||
{
|
||||
if (options.StdOutMode && options.IsStdOutTerminal)
|
||||
throw kTerminalOutError;
|
||||
if(parser[NKey::kOutputDir].ThereIs)
|
||||
{
|
||||
options.OutputDir = parser[NKey::kOutputDir].PostStrings[0];
|
||||
NFile::NName::NormalizeDirPathPrefix(options.OutputDir);
|
||||
}
|
||||
|
||||
options.OverwriteMode = NExtract::NOverwriteMode::kAskBefore;
|
||||
if(parser[NKey::kOverwrite].ThereIs)
|
||||
options.OverwriteMode =
|
||||
k_OverwriteModes[parser[NKey::kOverwrite].PostCharIndex];
|
||||
else if (options.YesToAll)
|
||||
options.OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt;
|
||||
}
|
||||
}
|
||||
else if(options.Command.IsFromUpdateGroup())
|
||||
{
|
||||
CUpdateOptions &updateOptions = options.UpdateOptions;
|
||||
|
||||
UString archiveType;
|
||||
if(parser[NKey::kArchiveType].ThereIs)
|
||||
archiveType = parser[NKey::kArchiveType].PostStrings[0];
|
||||
else
|
||||
archiveType = kDefaultArchiveType;
|
||||
|
||||
UString typeExtension;
|
||||
if (!archiveType.IsEmpty())
|
||||
{
|
||||
#ifndef EXCLUDE_COM
|
||||
SetArchiveType(archiveType, updateOptions.MethodMode.FilePath,
|
||||
updateOptions.MethodMode.ClassID, typeExtension);
|
||||
#else
|
||||
SetArchiveType(archiveType, updateOptions.MethodMode.Name, typeExtension);
|
||||
#endif
|
||||
}
|
||||
UString extension = typeExtension;
|
||||
if(parser[NKey::kSfx].ThereIs)
|
||||
extension = kSFXExtension;
|
||||
updateOptions.ArchivePath.BaseExtension = extension;
|
||||
updateOptions.ArchivePath.VolExtension = typeExtension;
|
||||
updateOptions.ArchivePath.ParseFromPath(options.ArchiveName);
|
||||
SetAddCommandOptions(options.Command.CommandType, parser,
|
||||
updateOptions);
|
||||
|
||||
SetMethodOptions(parser, updateOptions);
|
||||
|
||||
options.EnablePercents = !parser[NKey::kDisablePercents].ThereIs;
|
||||
|
||||
if (options.EnablePercents)
|
||||
{
|
||||
if ((options.StdOutMode && !options.IsStdErrTerminal) ||
|
||||
(!options.StdOutMode && !options.IsStdOutTerminal))
|
||||
options.EnablePercents = false;
|
||||
}
|
||||
|
||||
if (updateOptions.EMailMode = parser[NKey::kEmail].ThereIs)
|
||||
{
|
||||
updateOptions.EMailAddress = parser[NKey::kEmail].PostStrings.Front();
|
||||
if (updateOptions.EMailAddress.Length() > 0)
|
||||
if (updateOptions.EMailAddress[0] == L'.')
|
||||
{
|
||||
updateOptions.EMailRemoveAfter = true;
|
||||
updateOptions.EMailAddress.Delete(0);
|
||||
}
|
||||
}
|
||||
|
||||
updateOptions.StdOutMode = options.StdOutMode;
|
||||
updateOptions.StdInMode = options.StdInMode;
|
||||
|
||||
if (updateOptions.StdOutMode && updateOptions.EMailMode)
|
||||
throw "stdout mode and email mode cannot be combined";
|
||||
if (updateOptions.StdOutMode && options.IsStdOutTerminal)
|
||||
throw kTerminalOutError;
|
||||
if(updateOptions.StdInMode)
|
||||
updateOptions.StdInFileName = parser[NKey::kStdIn].PostStrings.Front();
|
||||
}
|
||||
else
|
||||
throw kUserErrorMessage;
|
||||
}
|
||||
84
7zip/UI/Common/ArchiveCommandLine.h
Executable file
84
7zip/UI/Common/ArchiveCommandLine.h
Executable file
@@ -0,0 +1,84 @@
|
||||
// ArchiveCommandLine.h
|
||||
|
||||
#ifndef __ARCHIVECOMMANDLINE_H
|
||||
#define __ARCHIVECOMMANDLINE_H
|
||||
|
||||
#include "Common/Wildcard.h"
|
||||
#include "Common/CommandLineParser.h"
|
||||
|
||||
#include "Extract.h"
|
||||
#include "Update.h"
|
||||
|
||||
namespace NCommandType { enum EEnum
|
||||
{
|
||||
kAdd = 0,
|
||||
kUpdate,
|
||||
kDelete,
|
||||
kTest,
|
||||
kExtract,
|
||||
kFullExtract,
|
||||
kList
|
||||
};}
|
||||
|
||||
namespace NRecursedType { enum EEnum
|
||||
{
|
||||
kRecursed,
|
||||
kWildCardOnlyRecursed,
|
||||
kNonRecursed,
|
||||
};}
|
||||
|
||||
struct CArchiveCommand
|
||||
{
|
||||
NCommandType::EEnum CommandType;
|
||||
bool IsFromExtractGroup() const;
|
||||
bool IsFromUpdateGroup() const;
|
||||
bool IsTestMode() const { return CommandType == NCommandType::kTest; }
|
||||
NExtract::NPathMode::EEnum GetPathMode() const;
|
||||
};
|
||||
|
||||
struct CArchiveCommandLineOptions
|
||||
{
|
||||
bool HelpMode;
|
||||
|
||||
bool IsInTerminal;
|
||||
bool IsStdOutTerminal;
|
||||
bool IsStdErrTerminal;
|
||||
bool StdInMode;
|
||||
bool StdOutMode;
|
||||
bool EnableHeaders;
|
||||
|
||||
bool YesToAll;
|
||||
bool ShowDialog;
|
||||
// NWildcard::CCensor ArchiveWildcardCensor;
|
||||
NWildcard::CCensor WildcardCensor;
|
||||
|
||||
CArchiveCommand Command;
|
||||
UString ArchiveName;
|
||||
|
||||
bool PasswordEnabled;
|
||||
UString Password;
|
||||
|
||||
// Extract
|
||||
bool AppendName;
|
||||
UString OutputDir;
|
||||
NExtract::NOverwriteMode::EEnum OverwriteMode;
|
||||
UStringVector ArchivePathsSorted;
|
||||
UStringVector ArchivePathsFullSorted;
|
||||
|
||||
CUpdateOptions UpdateOptions;
|
||||
bool EnablePercents;
|
||||
|
||||
CArchiveCommandLineOptions(): StdInMode(false), StdOutMode(false) {};
|
||||
|
||||
};
|
||||
|
||||
class CArchiveCommandLineParser
|
||||
{
|
||||
NCommandLineParser::CParser parser;
|
||||
public:
|
||||
CArchiveCommandLineParser();
|
||||
void Parse1(const UStringVector commandStrings, CArchiveCommandLineOptions &options);
|
||||
void Parse2(CArchiveCommandLineOptions &options);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
// ExtractCallback.cpp
|
||||
// ArchiveExtractCallback.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -18,49 +18,47 @@
|
||||
#include "../../Common/FilePathAutoRename.h"
|
||||
|
||||
#include "../Common/ExtractingFilePath.h"
|
||||
#include "OpenArchive.h"
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
static const wchar_t *kCantAutoRename = L"ERROR: Can not create file with auto name";
|
||||
static const wchar_t *kCantRenameFile = L"ERROR: Can not rename existing file ";
|
||||
static const wchar_t *kCantDeleteOutputFile = L"ERROR: Can not delete output file ";
|
||||
|
||||
|
||||
void CArchiveExtractCallback::Init(
|
||||
IInArchive *archiveHandler,
|
||||
IFolderArchiveExtractCallback *extractCallback2,
|
||||
bool stdOutMode,
|
||||
const UString &directoryPath,
|
||||
NExtractionMode::NPath::EEnum pathMode,
|
||||
NExtractionMode::NOverwrite::EEnum overwriteMode,
|
||||
NExtract::NPathMode::EEnum pathMode,
|
||||
NExtract::NOverwriteMode::EEnum overwriteMode,
|
||||
const UStringVector &removePathParts,
|
||||
const UString &itemDefaultName,
|
||||
const FILETIME &utcLastWriteTimeDefault,
|
||||
UINT32 attributesDefault)
|
||||
// bool passwordIsDefined, const UString &password
|
||||
// UString srcDirectoryPrefix)
|
||||
UInt32 attributesDefault)
|
||||
{
|
||||
_extractCallback2 = extractCallback2;
|
||||
// m_PasswordIsDefined = passwordIsDefined;
|
||||
// m_Password = password;
|
||||
_stdOutMode = stdOutMode;
|
||||
_numErrors = 0;
|
||||
|
||||
_extractCallback2 = extractCallback2;
|
||||
_itemDefaultName = itemDefaultName;
|
||||
_utcLastWriteTimeDefault = utcLastWriteTimeDefault;
|
||||
_attributesDefault = attributesDefault;
|
||||
|
||||
_removePathParts = removePathParts;
|
||||
|
||||
_pathMode = pathMode;
|
||||
_overwriteMode = overwriteMode;
|
||||
|
||||
_archiveHandler = archiveHandler;
|
||||
_directoryPath = directoryPath;
|
||||
NFile::NName::NormalizeDirPathPrefix(_directoryPath);
|
||||
|
||||
// _srcDirectoryPrefix = srcDirectoryPrefix;
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveExtractCallback::SetTotal(UINT64 size)
|
||||
STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 size)
|
||||
{
|
||||
return _extractCallback2->SetTotal(size);
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UINT64 *completeValue)
|
||||
STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue)
|
||||
{
|
||||
return _extractCallback2->SetCompleted(completeValue);
|
||||
}
|
||||
@@ -89,8 +87,8 @@ static UString MakePathNameFromParts(const UStringVector &parts)
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CArchiveExtractCallback::GetStream(UINT32 index,
|
||||
ISequentialOutStream **outStream, INT32 askExtractMode)
|
||||
STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index,
|
||||
ISequentialOutStream **outStream, Int32 askExtractMode)
|
||||
{
|
||||
*outStream = 0;
|
||||
_outFileStream.Release();
|
||||
@@ -99,9 +97,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UINT32 index,
|
||||
|
||||
UString fullPath;
|
||||
if(propVariant.vt == VT_EMPTY)
|
||||
{
|
||||
fullPath = _itemDefaultName;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(propVariant.vt != VT_BSTR)
|
||||
@@ -111,9 +107,26 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UINT32 index,
|
||||
|
||||
// UString fullPathCorrect = GetCorrectPath(fullPath);
|
||||
_filePath = fullPath;
|
||||
_isSplit = false;
|
||||
|
||||
RINOK(_archiveHandler->GetProperty(index, kpidPosition, &propVariant));
|
||||
if (propVariant.vt != VT_EMPTY)
|
||||
{
|
||||
if (propVariant.vt != VT_UI8)
|
||||
return E_FAIL;
|
||||
_position = propVariant.uhVal.QuadPart;
|
||||
_isSplit = true;
|
||||
}
|
||||
|
||||
if(askExtractMode == NArchive::NExtract::NAskMode::kExtract)
|
||||
{
|
||||
if (_stdOutMode)
|
||||
{
|
||||
CMyComPtr<ISequentialOutStream> outStreamLoc = new CStdOutFileStream;
|
||||
*outStream = outStreamLoc.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
RINOK(_archiveHandler->GetProperty(index, kpidAttributes, &propVariant));
|
||||
if (propVariant.vt == VT_EMPTY)
|
||||
{
|
||||
@@ -128,8 +141,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UINT32 index,
|
||||
_processedFileInfo.AttributesAreDefined = true;
|
||||
}
|
||||
|
||||
RINOK(_archiveHandler->GetProperty(index, kpidIsFolder, &propVariant));
|
||||
_processedFileInfo.IsDirectory = VARIANT_BOOLToBool(propVariant.boolVal);
|
||||
RINOK(IsArchiveItemFolder(_archiveHandler, index, _processedFileInfo.IsDirectory));
|
||||
|
||||
RINOK(_archiveHandler->GetProperty(index, kpidLastWriteTime, &propVariant));
|
||||
switch(propVariant.vt)
|
||||
@@ -146,9 +158,9 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UINT32 index,
|
||||
|
||||
RINOK(_archiveHandler->GetProperty(index, kpidSize, &propVariant));
|
||||
bool newFileSizeDefined = (propVariant.vt != VT_EMPTY);
|
||||
UINT64 newFileSize;
|
||||
UInt64 newFileSize;
|
||||
if (newFileSizeDefined)
|
||||
newFileSize = ConvertPropVariantToUINT64(propVariant);
|
||||
newFileSize = ConvertPropVariantToUInt64(propVariant);
|
||||
|
||||
bool isAnti = false;
|
||||
{
|
||||
@@ -160,8 +172,6 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UINT32 index,
|
||||
}
|
||||
|
||||
UStringVector pathParts;
|
||||
|
||||
// SplitPathToParts(fullPathCorrect, pathParts);
|
||||
SplitPathToParts(fullPath, pathParts);
|
||||
|
||||
if(pathParts.IsEmpty())
|
||||
@@ -169,14 +179,14 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UINT32 index,
|
||||
UString processedPath;
|
||||
switch(_pathMode)
|
||||
{
|
||||
case NExtractionMode::NPath::kFullPathnames:
|
||||
case NExtract::NPathMode::kFullPathnames:
|
||||
{
|
||||
// processedPath = fullPathCorrect;
|
||||
processedPath = GetCorrectPath(fullPath);
|
||||
processedPath = fullPath;
|
||||
break;
|
||||
}
|
||||
case NExtractionMode::NPath::kCurrentPathnames:
|
||||
case NExtract::NPathMode::kCurrentPathnames:
|
||||
{
|
||||
// for incorrect paths: "/dir1/dir2/file"
|
||||
int numRemovePathParts = _removePathParts.Size();
|
||||
if(pathParts.Size() <= numRemovePathParts)
|
||||
return E_FAIL;
|
||||
@@ -185,28 +195,25 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UINT32 index,
|
||||
return E_FAIL;
|
||||
pathParts.Delete(0, numRemovePathParts);
|
||||
processedPath = MakePathNameFromParts(pathParts);
|
||||
processedPath = GetCorrectPath(processedPath);
|
||||
break;
|
||||
}
|
||||
case NExtractionMode::NPath::kNoPathnames:
|
||||
case NExtract::NPathMode::kNoPathnames:
|
||||
{
|
||||
processedPath = pathParts.Back();
|
||||
pathParts.Delete(0, pathParts.Size() - 1); // Test it!!
|
||||
break;
|
||||
}
|
||||
}
|
||||
processedPath = GetCorrectPath(processedPath);
|
||||
if(!_processedFileInfo.IsDirectory)
|
||||
pathParts.DeleteBack();
|
||||
|
||||
for(int i = 0; i < pathParts.Size(); i++)
|
||||
pathParts[i] = GetCorrectFileName(pathParts[i]);
|
||||
MakeCorrectPath(pathParts);
|
||||
|
||||
if (!isAnti)
|
||||
if (!pathParts.IsEmpty())
|
||||
CreateComplexDirectory(pathParts);
|
||||
|
||||
|
||||
const UString fullProcessedPathUnicode = _directoryPath + processedPath;
|
||||
UString fullProcessedPath = _directoryPath + processedPath;
|
||||
|
||||
if(_processedFileInfo.IsDirectory)
|
||||
@@ -217,18 +224,20 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UINT32 index,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (!_isSplit)
|
||||
{
|
||||
NFile::NFind::CFileInfoW fileInfo;
|
||||
if(NFile::NFind::FindFile(fullProcessedPath, fileInfo))
|
||||
{
|
||||
switch(_overwriteMode)
|
||||
{
|
||||
case NExtractionMode::NOverwrite::kSkipExisting:
|
||||
case NExtract::NOverwriteMode::kSkipExisting:
|
||||
return S_OK;
|
||||
case NExtractionMode::NOverwrite::kAskBefore:
|
||||
case NExtract::NOverwriteMode::kAskBefore:
|
||||
{
|
||||
INT32 overwiteResult;
|
||||
Int32 overwiteResult;
|
||||
RINOK(_extractCallback2->AskOverwrite(
|
||||
fullProcessedPathUnicode, &fileInfo.LastWriteTime, &fileInfo.Size,
|
||||
fullProcessedPath, &fileInfo.LastWriteTime, &fileInfo.Size,
|
||||
fullPath, &_processedFileInfo.UTCLastWriteTime, newFileSizeDefined?
|
||||
&newFileSize : NULL, &overwiteResult))
|
||||
|
||||
@@ -239,27 +248,43 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UINT32 index,
|
||||
case NOverwriteAnswer::kNo:
|
||||
return S_OK;
|
||||
case NOverwriteAnswer::kNoToAll:
|
||||
_overwriteMode = NExtractionMode::NOverwrite::kSkipExisting;
|
||||
_overwriteMode = NExtract::NOverwriteMode::kSkipExisting;
|
||||
return S_OK;
|
||||
case NOverwriteAnswer::kYesToAll:
|
||||
_overwriteMode = NExtractionMode::NOverwrite::kWithoutPrompt;
|
||||
_overwriteMode = NExtract::NOverwriteMode::kWithoutPrompt;
|
||||
break;
|
||||
case NOverwriteAnswer::kYes:
|
||||
break;
|
||||
case NOverwriteAnswer::kAutoRename:
|
||||
_overwriteMode = NExtractionMode::NOverwrite::kAutoRename;
|
||||
_overwriteMode = NExtract::NOverwriteMode::kAutoRename;
|
||||
break;
|
||||
default:
|
||||
throw 20413;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_overwriteMode == NExtractionMode::NOverwrite::kAutoRename)
|
||||
if (_overwriteMode == NExtract::NOverwriteMode::kAutoRename)
|
||||
{
|
||||
if (!AutoRenamePath(fullProcessedPath))
|
||||
{
|
||||
UString message = UString(L"can not create name of file ") +
|
||||
fullProcessedPathUnicode;
|
||||
UString message = UString(kCantAutoRename) +
|
||||
fullProcessedPath;
|
||||
RINOK(_extractCallback2->MessageError(message));
|
||||
return E_ABORT;
|
||||
}
|
||||
}
|
||||
else if (_overwriteMode == NExtract::NOverwriteMode::kAutoRenameExisting)
|
||||
{
|
||||
UString existPath = fullProcessedPath;
|
||||
if (!AutoRenamePath(existPath))
|
||||
{
|
||||
UString message = kCantAutoRename + fullProcessedPath;
|
||||
RINOK(_extractCallback2->MessageError(message));
|
||||
return E_ABORT;
|
||||
}
|
||||
if(!NFile::NDirectory::MyMoveFile(fullProcessedPath, existPath))
|
||||
{
|
||||
UString message = UString(kCantRenameFile) + fullProcessedPath;
|
||||
RINOK(_extractCallback2->MessageError(message));
|
||||
return E_ABORT;
|
||||
}
|
||||
@@ -267,21 +292,30 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UINT32 index,
|
||||
else
|
||||
if (!NFile::NDirectory::DeleteFileAlways(fullProcessedPath))
|
||||
{
|
||||
UString message = UString(L"can not delete output file ") +
|
||||
fullProcessedPathUnicode;
|
||||
UString message = UString(kCantDeleteOutputFile) +
|
||||
fullProcessedPath;
|
||||
RINOK(_extractCallback2->MessageError(message));
|
||||
return E_ABORT;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isAnti)
|
||||
{
|
||||
_outFileStreamSpec = new COutFileStream;
|
||||
CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
|
||||
if (!_outFileStreamSpec->Open(fullProcessedPath))
|
||||
if (!_outFileStreamSpec->File.Open(fullProcessedPath,
|
||||
_isSplit ? OPEN_ALWAYS: CREATE_ALWAYS))
|
||||
{
|
||||
UString message = L"can not open output file " + fullProcessedPathUnicode;
|
||||
RINOK(_extractCallback2->MessageError(message));
|
||||
return S_OK;
|
||||
// if (::GetLastError() != ERROR_FILE_EXISTS || !isSplit)
|
||||
{
|
||||
UString message = L"can not open output file " + fullProcessedPath;
|
||||
RINOK(_extractCallback2->MessageError(message));
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
if (_isSplit)
|
||||
{
|
||||
RINOK(_outFileStreamSpec->Seek(_position, STREAM_SEEK_SET, NULL));
|
||||
}
|
||||
_outFileStream = outStreamLoc;
|
||||
*outStream = outStreamLoc.Detach();
|
||||
@@ -295,7 +329,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UINT32 index,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveExtractCallback::PrepareOperation(INT32 askExtractMode)
|
||||
STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)
|
||||
{
|
||||
_extractMode = false;
|
||||
switch (askExtractMode)
|
||||
@@ -303,7 +337,7 @@ STDMETHODIMP CArchiveExtractCallback::PrepareOperation(INT32 askExtractMode)
|
||||
case NArchive::NExtract::NAskMode::kExtract:
|
||||
_extractMode = true;
|
||||
};
|
||||
return _extractCallback2->PrepareOperation(_filePath, askExtractMode);
|
||||
return _extractCallback2->PrepareOperation(_filePath, askExtractMode, _isSplit ? &_position: 0);
|
||||
}
|
||||
|
||||
void CArchiveExtractCallback::AddErrorMessage(LPCTSTR message)
|
||||
@@ -311,7 +345,7 @@ void CArchiveExtractCallback::AddErrorMessage(LPCTSTR message)
|
||||
_messages.Add(message);
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveExtractCallback::SetOperationResult(INT32 operationResult)
|
||||
STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
|
||||
{
|
||||
switch(operationResult)
|
||||
{
|
||||
@@ -1,12 +1,10 @@
|
||||
// ArchiveExtractCallback.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVEEXTRACTCALLBACK_H
|
||||
#define __ARCHIVEEXTRACTCALLBACK_H
|
||||
|
||||
#include "../../Archive/IArchive.h"
|
||||
#include "IFolderArchive.h"
|
||||
#include "IFileExtractCallback.h"
|
||||
|
||||
#include "Common/String.h"
|
||||
#include "Common/MyCom.h"
|
||||
@@ -14,6 +12,8 @@
|
||||
#include "../../Common/FileStreams.h"
|
||||
#include "../../IPassword.h"
|
||||
|
||||
#include "ExtractMode.h"
|
||||
|
||||
class CArchiveExtractCallback:
|
||||
public IArchiveExtractCallback,
|
||||
// public IArchiveVolumeExtractCallback,
|
||||
@@ -25,14 +25,14 @@ public:
|
||||
// COM_INTERFACE_ENTRY(IArchiveVolumeExtractCallback)
|
||||
|
||||
// IProgress
|
||||
STDMETHOD(SetTotal)(UINT64 aize);
|
||||
STDMETHOD(SetCompleted)(const UINT64 *completeValue);
|
||||
STDMETHOD(SetTotal)(UInt64 aize);
|
||||
STDMETHOD(SetCompleted)(const UInt64 *completeValue);
|
||||
|
||||
// IExtractCallBack
|
||||
STDMETHOD(GetStream)(UINT32 anIndex, ISequentialOutStream **outStream,
|
||||
INT32 askExtractMode);
|
||||
STDMETHOD(PrepareOperation)(INT32 askExtractMode);
|
||||
STDMETHOD(SetOperationResult)(INT32 resultEOperationResult);
|
||||
STDMETHOD(GetStream)(UInt32 anIndex, ISequentialOutStream **outStream,
|
||||
Int32 askExtractMode);
|
||||
STDMETHOD(PrepareOperation)(Int32 askExtractMode);
|
||||
STDMETHOD(SetOperationResult)(Int32 resultEOperationResult);
|
||||
|
||||
// IArchiveVolumeExtractCallback
|
||||
// STDMETHOD(GetInStream)(const wchar_t *name, ISequentialInStream **inStream);
|
||||
@@ -45,10 +45,12 @@ private:
|
||||
CMyComPtr<IFolderArchiveExtractCallback> _extractCallback2;
|
||||
CMyComPtr<ICryptoGetTextPassword> _cryptoGetTextPassword;
|
||||
UString _directoryPath;
|
||||
NExtractionMode::NPath::EEnum _pathMode;
|
||||
NExtractionMode::NOverwrite::EEnum _overwriteMode;
|
||||
NExtract::NPathMode::EEnum _pathMode;
|
||||
NExtract::NOverwriteMode::EEnum _overwriteMode;
|
||||
|
||||
UString _filePath;
|
||||
UInt64 _position;
|
||||
bool _isSplit;
|
||||
|
||||
UString _diskFilePath;
|
||||
|
||||
@@ -60,48 +62,34 @@ private:
|
||||
FILETIME UTCLastWriteTime;
|
||||
bool IsDirectory;
|
||||
bool AttributesAreDefined;
|
||||
UINT32 Attributes;
|
||||
UInt32 Attributes;
|
||||
} _processedFileInfo;
|
||||
|
||||
|
||||
COutFileStream *_outFileStreamSpec;
|
||||
CMyComPtr<ISequentialOutStream> _outFileStream;
|
||||
UStringVector _removePathParts;
|
||||
|
||||
UString _itemDefaultName;
|
||||
FILETIME _utcLastWriteTimeDefault;
|
||||
UINT32 _attributesDefault;
|
||||
|
||||
// bool m_PasswordIsDefined;
|
||||
// UString m_Password;
|
||||
|
||||
|
||||
// UString _srcDirectoryPrefix;
|
||||
UInt32 _attributesDefault;
|
||||
bool _stdOutMode;
|
||||
|
||||
void CreateComplexDirectory(const UStringVector &dirPathParts);
|
||||
/*
|
||||
void GetPropertyValue(LPITEMIDLIST anItemIDList, PROPID aPropId,
|
||||
PROPVARIANT *aValue);
|
||||
bool IsEncrypted(LPITEMIDLIST anItemIDList);
|
||||
*/
|
||||
void AddErrorMessage(LPCTSTR message);
|
||||
public:
|
||||
// CProgressDialog m_ProcessDialog;
|
||||
void Init(
|
||||
IInArchive *archiveHandler,
|
||||
IFolderArchiveExtractCallback *extractCallback2,
|
||||
bool stdOutMode,
|
||||
const UString &directoryPath,
|
||||
NExtractionMode::NPath::EEnum pathMode,
|
||||
NExtractionMode::NOverwrite::EEnum overwriteMode,
|
||||
NExtract::NPathMode::EEnum pathMode,
|
||||
NExtract::NOverwriteMode::EEnum overwriteMode,
|
||||
const UStringVector &removePathParts,
|
||||
const UString &itemDefaultName,
|
||||
const FILETIME &utcLastWriteTimeDefault,
|
||||
UINT32 anAttributesDefault
|
||||
// bool passwordIsDefined, const UString &password
|
||||
// UString srcDirectoryPrefix
|
||||
);
|
||||
UInt32 attributesDefault);
|
||||
|
||||
UINT64 _numErrors;
|
||||
UInt64 _numErrors;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -29,7 +29,7 @@ UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName)
|
||||
{
|
||||
NFile::NFind::CFileInfoW fileInfo;
|
||||
if (!NFile::NFind::FindFile(srcName, fileInfo))
|
||||
return ::GetLastError();
|
||||
return resultName;
|
||||
resultName = fileInfo.Name;
|
||||
if (!fileInfo.IsDirectory() && !keepName)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// ArchiveName.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVENAME_H
|
||||
#define __ARCHIVENAME_H
|
||||
|
||||
@@ -9,4 +7,4 @@
|
||||
|
||||
UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
117
7zip/UI/Common/ArchiveOpenCallback.cpp
Executable file
117
7zip/UI/Common/ArchiveOpenCallback.cpp
Executable file
@@ -0,0 +1,117 @@
|
||||
// ArchiveOpenCallback.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ArchiveOpenCallback.h"
|
||||
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
|
||||
#include "../../Common/FileStreams.h"
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
STDMETHODIMP COpenCallbackImp::SetTotal(const UInt64 *files, const UInt64 *bytes)
|
||||
{
|
||||
return Callback->SetTotal(files, bytes);
|
||||
}
|
||||
|
||||
STDMETHODIMP COpenCallbackImp::SetCompleted(const UInt64 *files, const UInt64 *bytes)
|
||||
{
|
||||
return Callback->SetTotal(files, bytes);
|
||||
}
|
||||
|
||||
STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
if (_subArchiveMode)
|
||||
{
|
||||
switch(propID)
|
||||
{
|
||||
case kpidName:
|
||||
propVariant = _subArchiveName;
|
||||
break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
switch(propID)
|
||||
{
|
||||
case kpidName:
|
||||
propVariant = _fileInfo.Name;
|
||||
break;
|
||||
case kpidIsFolder:
|
||||
propVariant = _fileInfo.IsDirectory();
|
||||
break;
|
||||
case kpidSize:
|
||||
propVariant = _fileInfo.Size;
|
||||
break;
|
||||
case kpidAttributes:
|
||||
propVariant = (UInt32)_fileInfo.Attributes;
|
||||
break;
|
||||
case kpidLastAccessTime:
|
||||
propVariant = _fileInfo.LastAccessTime;
|
||||
break;
|
||||
case kpidCreationTime:
|
||||
propVariant = _fileInfo.CreationTime;
|
||||
break;
|
||||
case kpidLastWriteTime:
|
||||
propVariant = _fileInfo.LastWriteTime;
|
||||
break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
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;
|
||||
COpenCallbackImp *OpenCallbackImp;
|
||||
CMyComPtr<IArchiveOpenCallback> OpenCallbackRef;
|
||||
~CInFileStreamVol()
|
||||
{
|
||||
int index = OpenCallbackImp->FindName(Name);
|
||||
if (index >= 0)
|
||||
OpenCallbackImp->FileNames.Delete(index);
|
||||
}
|
||||
};
|
||||
|
||||
STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name,
|
||||
IInStream **inStream)
|
||||
{
|
||||
if (_subArchiveMode)
|
||||
return S_FALSE;
|
||||
RINOK(Callback->CheckBreak());
|
||||
*inStream = NULL;
|
||||
UString fullPath = _folderPrefix + name;
|
||||
if (!NFile::NFind::FindFile(fullPath, _fileInfo))
|
||||
return S_FALSE;
|
||||
if (_fileInfo.IsDirectory())
|
||||
return S_FALSE;
|
||||
CInFileStreamVol *inFile = new CInFileStreamVol;
|
||||
CMyComPtr<IInStream> inStreamTemp = inFile;
|
||||
if (!inFile->Open(fullPath))
|
||||
return ::GetLastError();
|
||||
*inStream = inStreamTemp.Detach();
|
||||
inFile->Name = name;
|
||||
inFile->OpenCallbackImp = this;
|
||||
inFile->OpenCallbackRef = this;
|
||||
FileNames.Add(name);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
STDMETHODIMP COpenCallbackImp::CryptoGetTextPassword(BSTR *password)
|
||||
{
|
||||
return Callback->CryptoGetTextPassword(password);
|
||||
}
|
||||
#endif
|
||||
|
||||
87
7zip/UI/Common/ArchiveOpenCallback.h
Executable file
87
7zip/UI/Common/ArchiveOpenCallback.h
Executable file
@@ -0,0 +1,87 @@
|
||||
// ArchiveOpenCallback.h
|
||||
|
||||
#ifndef __ARCHIVE_OPEN_CALLBACK_H
|
||||
#define __ARCHIVE_OPEN_CALLBACK_H
|
||||
|
||||
#include "Common/String.h"
|
||||
#include "Common/MyCom.h"
|
||||
#include "Windows/FileFind.h"
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
#include "../../IPassword.h"
|
||||
#endif
|
||||
#include "../../Archive/IArchive.h"
|
||||
|
||||
struct IOpenCallbackUI
|
||||
{
|
||||
virtual HRESULT CheckBreak() = 0;
|
||||
virtual HRESULT SetTotal(const UInt64 *files, const UInt64 *bytes) = 0;
|
||||
virtual HRESULT SetCompleted(const UInt64 *files, const UInt64 *bytes) = 0;
|
||||
#ifndef _NO_CRYPTO
|
||||
virtual HRESULT CryptoGetTextPassword(BSTR *password) = 0;
|
||||
virtual HRESULT GetPasswordIfAny(UString &password) = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
class COpenCallbackImp:
|
||||
public IArchiveOpenCallback,
|
||||
public IArchiveOpenVolumeCallback,
|
||||
public IArchiveOpenSetSubArchiveName,
|
||||
#ifndef _NO_CRYPTO
|
||||
public ICryptoGetTextPassword,
|
||||
#endif
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
#ifndef _NO_CRYPTO
|
||||
MY_UNKNOWN_IMP3(
|
||||
IArchiveOpenVolumeCallback,
|
||||
ICryptoGetTextPassword,
|
||||
IArchiveOpenSetSubArchiveName
|
||||
)
|
||||
#else
|
||||
MY_UNKNOWN_IMP2(
|
||||
IArchiveOpenVolumeCallback,
|
||||
IArchiveOpenSetSubArchiveName
|
||||
)
|
||||
#endif
|
||||
|
||||
STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes);
|
||||
STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes);
|
||||
|
||||
// IArchiveOpenVolumeCallback
|
||||
STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value);
|
||||
STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream);
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
// ICryptoGetTextPassword
|
||||
STDMETHOD(CryptoGetTextPassword)(BSTR *password);
|
||||
#endif
|
||||
|
||||
STDMETHOD(SetSubArchiveName(const wchar_t *name))
|
||||
{
|
||||
_subArchiveMode = true;
|
||||
_subArchiveName = name;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
UString _folderPrefix;
|
||||
NWindows::NFile::NFind::CFileInfoW _fileInfo;
|
||||
bool _subArchiveMode;
|
||||
UString _subArchiveName;
|
||||
public:
|
||||
UStringVector FileNames;
|
||||
IOpenCallbackUI *Callback;
|
||||
void Init(const UString &folderPrefix, const UString &fileName)
|
||||
{
|
||||
_folderPrefix = folderPrefix;
|
||||
if (!NWindows::NFile::NFind::FindFile(_folderPrefix + fileName, _fileInfo))
|
||||
throw 1;
|
||||
FileNames.Clear();
|
||||
_subArchiveMode = false;
|
||||
}
|
||||
int FindName(const UString &name);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -10,7 +10,9 @@
|
||||
#include "Windows/FileFind.h"
|
||||
#include "Windows/FileName.h"
|
||||
#include "Windows/DLL.h"
|
||||
#ifdef _WIN32
|
||||
#include "Windows/Registry.h"
|
||||
#endif
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "../../Archive/IArchive.h"
|
||||
|
||||
@@ -48,7 +50,7 @@ static void SplitString(const UString &srcString, UStringVector &destStrings)
|
||||
destStrings.Add(string);
|
||||
}
|
||||
|
||||
typedef UINT32 (WINAPI * GetHandlerPropertyFunc)(
|
||||
typedef UInt32 (WINAPI * GetHandlerPropertyFunc)(
|
||||
PROPID propID, PROPVARIANT *value);
|
||||
|
||||
/*
|
||||
@@ -72,7 +74,7 @@ static wchar_t *kFormatFolderName = L"Formats";
|
||||
static LPCTSTR kRegistryPath = TEXT("Software\\7-zip");
|
||||
static LPCTSTR kProgramPathValue = TEXT("Path");
|
||||
|
||||
UString GetBaseFolderPrefix()
|
||||
static UString GetBaseFolderPrefixFromRegistry()
|
||||
{
|
||||
UString moduleFolderPrefix = GetModuleFolderPrefix();
|
||||
NFind::CFileInfoW fileInfo;
|
||||
@@ -80,6 +82,7 @@ UString GetBaseFolderPrefix()
|
||||
if (fileInfo.IsDirectory())
|
||||
return moduleFolderPrefix;
|
||||
CSysString pathSys;
|
||||
#ifdef _WIN32
|
||||
{
|
||||
NRegistry::CKey key;
|
||||
if(key.Open(HKEY_CURRENT_USER, kRegistryPath, KEY_READ) == ERROR_SUCCESS)
|
||||
@@ -100,16 +103,25 @@ UString GetBaseFolderPrefix()
|
||||
return path;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return moduleFolderPrefix;
|
||||
}
|
||||
|
||||
typedef UINT32 (WINAPI *CreateObjectPointer)(
|
||||
typedef UInt32 (WINAPI *CreateObjectPointer)(
|
||||
const GUID *clsID,
|
||||
const GUID *interfaceID,
|
||||
void **outObject);
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _SFX
|
||||
static void SetBuffer(CByteBuffer &bb, const Byte *data, int size)
|
||||
{
|
||||
bb.SetCapacity(size);
|
||||
memmove((Byte *)bb, data, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers)
|
||||
{
|
||||
archivers.Clear();
|
||||
@@ -123,6 +135,10 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers)
|
||||
item.KeepName = false;
|
||||
item.Name = L"7z";
|
||||
item.Extensions.Add(CArchiverExtInfo(L"7z"));
|
||||
#ifndef _SFX
|
||||
const unsigned char kSig[] = {'7' , 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
||||
SetBuffer(item.StartSignature, kSig, 6);
|
||||
#endif
|
||||
archivers.Add(item);
|
||||
}
|
||||
#endif
|
||||
@@ -135,6 +151,10 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers)
|
||||
item.Name = L"BZip2";
|
||||
item.Extensions.Add(CArchiverExtInfo(L"bz2"));
|
||||
item.Extensions.Add(CArchiverExtInfo(L"tbz2", L".tar"));
|
||||
#ifndef _SFX
|
||||
const unsigned char sig[] = {'B' , 'Z', 'h' };
|
||||
SetBuffer(item.StartSignature, sig, 3);
|
||||
#endif
|
||||
archivers.Add(item);
|
||||
}
|
||||
#endif
|
||||
@@ -147,6 +167,21 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers)
|
||||
item.Name = L"GZip";
|
||||
item.Extensions.Add(CArchiverExtInfo(L"gz"));
|
||||
item.Extensions.Add(CArchiverExtInfo(L"tgz", L".tar"));
|
||||
#ifndef _SFX
|
||||
const unsigned char sig[] = { 0x1F, 0x8B };
|
||||
SetBuffer(item.StartSignature, sig, 2);
|
||||
#endif
|
||||
archivers.Add(item);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FORMAT_SPLIT
|
||||
{
|
||||
CArchiverInfo item;
|
||||
item.UpdateEnabled = false;
|
||||
item.KeepName = true;
|
||||
item.Name = L"Split";
|
||||
item.Extensions.Add(CArchiverExtInfo(L"001"));
|
||||
archivers.Add(item);
|
||||
}
|
||||
#endif
|
||||
@@ -169,6 +204,10 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers)
|
||||
item.KeepName = false;
|
||||
item.Name = L"Zip";
|
||||
item.Extensions.Add(CArchiverExtInfo(L"zip"));
|
||||
#ifndef _SFX
|
||||
const unsigned char sig[] = { 0x50, 0x4B, 0x03, 0x04 };
|
||||
SetBuffer(item.StartSignature, sig, 4);
|
||||
#endif
|
||||
archivers.Add(item);
|
||||
}
|
||||
#endif
|
||||
@@ -199,13 +238,31 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers)
|
||||
item.UpdateEnabled = false;
|
||||
item.Name = L"Arj";
|
||||
item.Extensions.Add(CArchiverExtInfo(L"arj"));
|
||||
#ifndef _SFX
|
||||
const unsigned char sig[] = { 0x60, 0xEA };
|
||||
SetBuffer(item.StartSignature, sig, 2);
|
||||
#endif
|
||||
archivers.Add(item);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FORMAT_Z
|
||||
{
|
||||
CArchiverInfo item;
|
||||
item.UpdateEnabled = false;
|
||||
item.Name = L"Z";
|
||||
item.Extensions.Add(CArchiverExtInfo(L"Z"));
|
||||
#ifndef _SFX
|
||||
const unsigned char sig[] = { 0x1F, 0x9D };
|
||||
SetBuffer(item.StartSignature, sig, 2);
|
||||
#endif
|
||||
archivers.Add(item);
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
UString folderPath = GetBaseFolderPrefix() +
|
||||
UString folderPath = GetBaseFolderPrefixFromRegistry() +
|
||||
kFormatFolderName + L"\\";
|
||||
NFind::CEnumeratorW enumerator(folderPath + L"*");
|
||||
NFind::CFileInfoW fileInfo;
|
||||
@@ -253,6 +310,7 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers)
|
||||
|
||||
UString ext = prop.bstrVal;
|
||||
// item.Extension = prop.bstrVal;
|
||||
prop.Clear();
|
||||
|
||||
UString addExt;
|
||||
|
||||
@@ -282,23 +340,30 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers)
|
||||
item.Extensions.Add(extInfo);
|
||||
}
|
||||
|
||||
if (getHandlerProperty(NArchive::kUpdate, &prop) != S_OK)
|
||||
continue;
|
||||
if (prop.vt != VT_BOOL)
|
||||
continue;
|
||||
item.UpdateEnabled = VARIANT_BOOLToBool(prop.boolVal);
|
||||
if (getHandlerProperty(NArchive::kUpdate, &prop) == S_OK)
|
||||
if (prop.vt == VT_BOOL)
|
||||
item.UpdateEnabled = VARIANT_BOOLToBool(prop.boolVal);
|
||||
prop.Clear();
|
||||
|
||||
if (item.UpdateEnabled)
|
||||
{
|
||||
if (getHandlerProperty(NArchive::kKeepName, &prop) != S_OK)
|
||||
continue;
|
||||
if (prop.vt != VT_BOOL)
|
||||
continue;
|
||||
item.KeepName = VARIANT_BOOLToBool(prop.boolVal);
|
||||
if (getHandlerProperty(NArchive::kKeepName, &prop) == S_OK)
|
||||
if (prop.vt == VT_BOOL)
|
||||
item.KeepName = VARIANT_BOOLToBool(prop.boolVal);
|
||||
prop.Clear();
|
||||
}
|
||||
|
||||
if (getHandlerProperty(NArchive::kStartSignature, &prop) == S_OK)
|
||||
{
|
||||
if (prop.vt == VT_BSTR)
|
||||
{
|
||||
UINT len = ::SysStringByteLen(prop.bstrVal);
|
||||
item.StartSignature.SetCapacity(len);
|
||||
memmove(item.StartSignature, prop.bstrVal, len);
|
||||
}
|
||||
}
|
||||
prop.Clear();
|
||||
|
||||
archivers.Add(item);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
// ArchiverInfo.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARCHIVERINFO_H
|
||||
#define __ARCHIVERINFO_H
|
||||
|
||||
#include "Common/String.h"
|
||||
#include "Common/Types.h"
|
||||
#include "Common/Buffer.h"
|
||||
|
||||
struct CArchiverExtInfo
|
||||
{
|
||||
@@ -27,6 +26,10 @@ struct CArchiverInfo
|
||||
#endif
|
||||
UString Name;
|
||||
CObjectVector<CArchiverExtInfo> Extensions;
|
||||
#ifndef _SFX
|
||||
CByteBuffer StartSignature;
|
||||
CByteBuffer FinishSignature;
|
||||
#endif
|
||||
int FindExtension(const UString &ext) const
|
||||
{
|
||||
for (int i = 0; i < Extensions.Size(); i++)
|
||||
|
||||
@@ -11,14 +11,18 @@
|
||||
|
||||
#include "Windows/Synchronization.h"
|
||||
#include "Windows/FileMapping.h"
|
||||
#include "Windows/FileDir.h"
|
||||
|
||||
#include "../../FileManager/ProgramLocation.h"
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
static LPCWSTR kShowDialogSwitch = L" -ad";
|
||||
static LPCWSTR kEmailSwitch = L" -seml";
|
||||
static LPCWSTR kEmailSwitch = L" -seml.";
|
||||
static LPCWSTR kMapSwitch = L" -i#";
|
||||
static LPCWSTR kArchiveNoNameSwitch = L" -an";
|
||||
static LPCWSTR kArchiveMapSwitch = L" -ai#";
|
||||
static LPCWSTR kStopSwitchParsing = L" --";
|
||||
|
||||
|
||||
static bool IsItWindowsNT()
|
||||
@@ -31,6 +35,7 @@ static bool IsItWindowsNT()
|
||||
}
|
||||
|
||||
HRESULT MyCreateProcess(const UString ¶ms,
|
||||
LPCTSTR curDir,
|
||||
NWindows::NSynchronization::CEvent *event)
|
||||
{
|
||||
STARTUPINFO startupInfo;
|
||||
@@ -45,7 +50,8 @@ HRESULT MyCreateProcess(const UString ¶ms,
|
||||
PROCESS_INFORMATION processInformation;
|
||||
BOOL result = ::CreateProcess(NULL, (TCHAR *)(const TCHAR *)
|
||||
GetSystemString(params),
|
||||
NULL, NULL, FALSE, 0, NULL, NULL,
|
||||
NULL, NULL, FALSE, 0, NULL,
|
||||
curDir,
|
||||
&startupInfo, &processInformation);
|
||||
if (result == 0)
|
||||
return ::GetLastError();
|
||||
@@ -70,7 +76,7 @@ static UString GetQuotedString(const UString &s)
|
||||
|
||||
static UString Get7zGuiPath()
|
||||
{
|
||||
UString path = L"\"";
|
||||
UString path;
|
||||
UString folder;
|
||||
if (GetProgramFolderPath(folder))
|
||||
path += folder;
|
||||
@@ -78,28 +84,117 @@ static UString Get7zGuiPath()
|
||||
path += L"7zgn.exe";
|
||||
else
|
||||
path += L"7zg.exe";
|
||||
path += L"\"";
|
||||
return path;
|
||||
// path += L"7z.exe";
|
||||
return GetQuotedString(path);
|
||||
}
|
||||
|
||||
static HRESULT CreateMap(const UStringVector &names,
|
||||
const UString &id,
|
||||
CFileMapping &fileMapping, NSynchronization::CEvent &event,
|
||||
UString ¶ms)
|
||||
{
|
||||
UInt32 extraSize = 2;
|
||||
UInt32 dataSize = 0;
|
||||
for (int i = 0; i < names.Size(); i++)
|
||||
dataSize += (names[i].Length() + 1) * sizeof(wchar_t);
|
||||
UInt32 totalSize = extraSize + dataSize;
|
||||
|
||||
UString mappingName;
|
||||
UString eventName;
|
||||
|
||||
CRandom random;
|
||||
random.Init(GetTickCount());
|
||||
while(true)
|
||||
{
|
||||
int number = random.Generate();
|
||||
wchar_t temp[32];
|
||||
ConvertUInt64ToString(UInt32(number), temp);
|
||||
mappingName = id;
|
||||
mappingName += L"Mapping";
|
||||
mappingName += temp;
|
||||
if (!fileMapping.Create(INVALID_HANDLE_VALUE, NULL,
|
||||
PAGE_READWRITE, totalSize, GetSystemString(mappingName)))
|
||||
return E_FAIL;
|
||||
if (::GetLastError() != ERROR_ALREADY_EXISTS)
|
||||
break;
|
||||
fileMapping.Close();
|
||||
}
|
||||
|
||||
while(true)
|
||||
{
|
||||
int number = random.Generate();
|
||||
wchar_t temp[32];
|
||||
ConvertUInt64ToString(UInt32(number), temp);
|
||||
eventName = id;
|
||||
eventName += L"MappingEndEvent";
|
||||
eventName += temp;
|
||||
if (!event.Create(true, false, GetSystemString(eventName)))
|
||||
return E_FAIL;
|
||||
if (::GetLastError() != ERROR_ALREADY_EXISTS)
|
||||
break;
|
||||
event.Close();
|
||||
}
|
||||
|
||||
params += mappingName;
|
||||
params += L":";
|
||||
wchar_t string[10];
|
||||
ConvertUInt64ToString(totalSize, string);
|
||||
params += string;
|
||||
|
||||
params += L":";
|
||||
params += eventName;
|
||||
|
||||
LPVOID data = fileMapping.MapViewOfFile(FILE_MAP_WRITE, 0, totalSize);
|
||||
if (data == NULL)
|
||||
return E_FAIL;
|
||||
try
|
||||
{
|
||||
wchar_t *curData = (wchar_t *)data;
|
||||
*curData = 0;
|
||||
curData++;
|
||||
for (int i = 0; i < names.Size(); i++)
|
||||
{
|
||||
const UString &s = names[i];
|
||||
memcpy(curData, (const wchar_t *)s, s.Length() * sizeof(wchar_t));
|
||||
curData += s.Length();
|
||||
*curData++ = L'\0';
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
UnmapViewOfFile(data);
|
||||
throw;
|
||||
}
|
||||
// UnmapViewOfFile(data);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CompressFiles(
|
||||
const UString &curDir,
|
||||
const UString &archiveName,
|
||||
const UStringVector &names,
|
||||
// const UString &outFolder,
|
||||
bool email,
|
||||
bool showDialog)
|
||||
{
|
||||
/*
|
||||
UString curDir;
|
||||
if (names.Size() > 0)
|
||||
{
|
||||
NFile::NDirectory::GetOnlyDirPrefix(names[0], curDir);
|
||||
}
|
||||
*/
|
||||
UString params;
|
||||
params = Get7zGuiPath();
|
||||
params += L" a";
|
||||
params += kMapSwitch;
|
||||
// params += _fileNames[0];
|
||||
|
||||
UINT32 extraSize = 2;
|
||||
UINT32 dataSize = 0;
|
||||
UInt32 extraSize = 2;
|
||||
UInt32 dataSize = 0;
|
||||
for (int i = 0; i < names.Size(); i++)
|
||||
dataSize += (names[i].Length() + 1) * sizeof(wchar_t);
|
||||
UINT32 totalSize = extraSize + dataSize;
|
||||
UInt32 totalSize = extraSize + dataSize;
|
||||
|
||||
UString mappingName;
|
||||
UString eventName;
|
||||
@@ -111,7 +206,7 @@ HRESULT CompressFiles(
|
||||
{
|
||||
int number = random.Generate();
|
||||
wchar_t temp[32];
|
||||
ConvertUINT64ToString(UINT32(number), temp);
|
||||
ConvertUInt64ToString(UInt32(number), temp);
|
||||
mappingName = L"7zCompressMapping";
|
||||
mappingName += temp;
|
||||
if (!fileMapping.Create(INVALID_HANDLE_VALUE, NULL,
|
||||
@@ -130,7 +225,7 @@ HRESULT CompressFiles(
|
||||
{
|
||||
int number = random.Generate();
|
||||
wchar_t temp[32];
|
||||
ConvertUINT64ToString(UINT32(number), temp);
|
||||
ConvertUInt64ToString(UInt32(number), temp);
|
||||
eventName = L"7zCompressMappingEndEvent";
|
||||
eventName += temp;
|
||||
if (!event.Create(true, false, GetSystemString(eventName)))
|
||||
@@ -146,7 +241,7 @@ HRESULT CompressFiles(
|
||||
params += mappingName;
|
||||
params += L":";
|
||||
wchar_t string[10];
|
||||
ConvertUINT64ToString(totalSize, string);
|
||||
ConvertUInt64ToString(totalSize, string);
|
||||
params += string;
|
||||
|
||||
params += L":";
|
||||
@@ -158,7 +253,9 @@ HRESULT CompressFiles(
|
||||
if (showDialog)
|
||||
params += kShowDialogSwitch;
|
||||
|
||||
params += kStopSwitchParsing;
|
||||
params += L" ";
|
||||
|
||||
params += GetQuotedString(archiveName);
|
||||
|
||||
LPVOID data = fileMapping.MapViewOfFile(FILE_MAP_WRITE, 0, totalSize);
|
||||
@@ -177,11 +274,14 @@ HRESULT CompressFiles(
|
||||
const UString &unicodeString = names[i];
|
||||
memcpy(curData, (const wchar_t *)unicodeString ,
|
||||
unicodeString .Length() * sizeof(wchar_t));
|
||||
curData += unicodeString .Length();
|
||||
curData += unicodeString.Length();
|
||||
*curData++ = L'\0';
|
||||
}
|
||||
// MessageBox(0, params, 0, 0);
|
||||
RINOK(MyCreateProcess(params, &event));
|
||||
CSysString sysCurDir = GetSystemString(curDir);
|
||||
RINOK(MyCreateProcess(params,
|
||||
(sysCurDir.IsEmpty()? 0: (LPCTSTR)sysCurDir),
|
||||
&event));
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
@@ -190,8 +290,7 @@ HRESULT CompressFiles(
|
||||
}
|
||||
UnmapViewOfFile(data);
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
CThreadCompressMain *compressor = new CThreadCompressMain();;
|
||||
compressor->FileNames = _fileNames;
|
||||
@@ -202,13 +301,24 @@ HRESULT CompressFiles(
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT ExtractArchive(const UString &archiveName,
|
||||
static HRESULT ExtractGroupCommand(const UStringVector &archivePaths,
|
||||
const UString ¶ms)
|
||||
{
|
||||
UString params2 = params;
|
||||
params2 += kArchiveNoNameSwitch;
|
||||
params2 += kArchiveMapSwitch;
|
||||
CFileMapping fileMapping;
|
||||
NSynchronization::CEvent event;
|
||||
RINOK(CreateMap(archivePaths, L"7zExtract", fileMapping, event, params2));
|
||||
return MyCreateProcess(params2, 0, &event);
|
||||
}
|
||||
|
||||
HRESULT ExtractArchives(const UStringVector &archivePaths,
|
||||
const UString &outFolder, bool showDialog)
|
||||
{
|
||||
UString params;
|
||||
params = Get7zGuiPath();
|
||||
params += L" x ";
|
||||
params += GetQuotedString(archiveName);
|
||||
params += L" x";
|
||||
if (!outFolder.IsEmpty())
|
||||
{
|
||||
params += L" -o";
|
||||
@@ -216,14 +326,13 @@ HRESULT ExtractArchive(const UString &archiveName,
|
||||
}
|
||||
if (showDialog)
|
||||
params += kShowDialogSwitch;
|
||||
return MyCreateProcess(params);
|
||||
return ExtractGroupCommand(archivePaths, params);
|
||||
}
|
||||
|
||||
HRESULT TestArchive(const UString &archiveName)
|
||||
HRESULT TestArchives(const UStringVector &archivePaths)
|
||||
{
|
||||
UString params;
|
||||
params = Get7zGuiPath();
|
||||
params += L" t ";
|
||||
params += GetQuotedString(archiveName);
|
||||
return MyCreateProcess(params);
|
||||
params += L" t";
|
||||
return ExtractGroupCommand(archivePaths, params);
|
||||
}
|
||||
|
||||
@@ -6,17 +6,21 @@
|
||||
#include "Common/String.h"
|
||||
#include "Windows/Synchronization.h"
|
||||
|
||||
HRESULT MyCreateProcess(const UString ¶ms,
|
||||
NWindows::NSynchronization::CEvent *event = NULL);
|
||||
HRESULT CompressFiles(const UString &archiveName,
|
||||
HRESULT MyCreateProcess(const UString ¶ms,
|
||||
LPCTSTR lpCurrentDirectory,
|
||||
NWindows::NSynchronization::CEvent *event = NULL);
|
||||
HRESULT CompressFiles(
|
||||
const UString &curDir,
|
||||
const UString &archiveName,
|
||||
const UStringVector &names,
|
||||
// const UString &outFolder,
|
||||
bool email, bool showDialog);
|
||||
|
||||
HRESULT ExtractArchive(const UString &archiveName,
|
||||
HRESULT ExtractArchives(
|
||||
const UStringVector &archivePaths,
|
||||
const UString &outFolder, bool showDialog);
|
||||
|
||||
HRESULT TestArchive(const UString &archiveName);
|
||||
HRESULT TestArchives(const UStringVector &archivePaths);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2,32 +2,22 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Windows/FileDir.h"
|
||||
|
||||
#include "Common/StringConvert.h"
|
||||
#include "DefaultName.h"
|
||||
|
||||
const wchar_t *kEmptyFileAlias = L"[Content]";
|
||||
static const wchar_t *kEmptyFileAlias = L"[Content]";
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
using namespace NDirectory;
|
||||
|
||||
UString GetDefaultName(const UString &fullFileName,
|
||||
UString GetDefaultName2(const UString &fileName,
|
||||
const UString &extension, const UString &addSubExtension)
|
||||
{
|
||||
UString fileName;
|
||||
if (!GetOnlyName(fullFileName, fileName))
|
||||
throw 5011749;
|
||||
int extLength = extension.Length();
|
||||
int fileNameLength = fileName.Length();
|
||||
if (fileNameLength <= extLength + 1)
|
||||
return kEmptyFileAlias;
|
||||
int dotPos = fileNameLength - (extLength + 1);
|
||||
if (fileName[dotPos] != '.')
|
||||
return kEmptyFileAlias;
|
||||
if (extension.CollateNoCase(fileName.Mid(dotPos + 1)) == 0)
|
||||
return fileName.Left(dotPos) + addSubExtension;
|
||||
if (fileNameLength > extLength + 1)
|
||||
{
|
||||
int dotPos = fileNameLength - (extLength + 1);
|
||||
if (fileName[dotPos] == '.')
|
||||
if (extension.CollateNoCase(fileName.Mid(dotPos + 1)) == 0)
|
||||
return fileName.Left(dotPos) + addSubExtension;
|
||||
}
|
||||
return kEmptyFileAlias;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
// DefaultName.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DEFAULTNAME_H
|
||||
#define __DEFAULTNAME_H
|
||||
|
||||
#include "Common/String.h"
|
||||
|
||||
UString GetDefaultName(const UString &fullFileName,
|
||||
UString GetDefaultName2(const UString &fileName,
|
||||
const UString &extension, const UString &addSubExtension);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
// DirItem.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DIR_ITEM_H
|
||||
#define __DIR_ITEM_H
|
||||
|
||||
// #include "Common/Types.h"
|
||||
#include "Common/String.h"
|
||||
// #include "Windows/PropVariant.h"
|
||||
#include "Common/Types.h"
|
||||
|
||||
struct CDirItem
|
||||
{
|
||||
UINT32 Attributes;
|
||||
UInt32 Attributes;
|
||||
FILETIME CreationTime;
|
||||
FILETIME LastAccessTime;
|
||||
FILETIME LastWriteTime;
|
||||
UINT64 Size;
|
||||
UInt64 Size;
|
||||
UString Name;
|
||||
UString FullPath;
|
||||
bool IsDirectory() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0 ; }
|
||||
@@ -28,7 +25,7 @@ struct CArchiveItem
|
||||
// NWindows::NCOM::CPropVariant LastWriteTime;
|
||||
FILETIME LastWriteTime;
|
||||
bool SizeIsDefined;
|
||||
UINT64 Size;
|
||||
UInt64 Size;
|
||||
UString Name;
|
||||
bool Censored;
|
||||
int IndexInServer;
|
||||
|
||||
@@ -2,8 +2,11 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "EnumDirItems.h"
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/Wildcard.h"
|
||||
#include "Common/MyCom.h"
|
||||
|
||||
#include "EnumDirItems.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
@@ -28,27 +31,33 @@ void AddDirFileInfo(
|
||||
dirItems.Add(item);
|
||||
}
|
||||
|
||||
static void EnumerateDirectory(
|
||||
static HRESULT EnumerateDirectory(
|
||||
const UString &baseFolderPrefix,
|
||||
const UString &directory,
|
||||
const UString &prefix,
|
||||
CObjectVector<CDirItem> &dirItems)
|
||||
{
|
||||
NFind::CEnumeratorW enumerator(baseFolderPrefix + directory + wchar_t(kAnyStringWildcard));
|
||||
NFind::CFileInfoW fileInfo;
|
||||
while (enumerator.Next(fileInfo))
|
||||
while (true)
|
||||
{
|
||||
NFind::CFileInfoW fileInfo;
|
||||
bool found;
|
||||
if (!enumerator.Next(fileInfo, found))
|
||||
return ::GetLastError();
|
||||
if (!found)
|
||||
break;
|
||||
AddDirFileInfo(prefix, directory + fileInfo.Name, fileInfo,
|
||||
dirItems);
|
||||
if (fileInfo.IsDirectory())
|
||||
{
|
||||
EnumerateDirectory(baseFolderPrefix, directory + fileInfo.Name + wchar_t(kDirDelimiter),
|
||||
prefix + fileInfo.Name + wchar_t(kDirDelimiter), dirItems);
|
||||
RINOK(EnumerateDirectory(baseFolderPrefix, directory + fileInfo.Name + wchar_t(kDirDelimiter),
|
||||
prefix + fileInfo.Name + wchar_t(kDirDelimiter), dirItems));
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void EnumerateDirItems(
|
||||
HRESULT EnumerateDirItems(
|
||||
const UString &baseFolderPrefix,
|
||||
const UStringVector &fileNames,
|
||||
const UString &archiveNamePrefix,
|
||||
@@ -63,9 +72,88 @@ void EnumerateDirItems(
|
||||
AddDirFileInfo(archiveNamePrefix, fileName, fileInfo, dirItems);
|
||||
if (fileInfo.IsDirectory())
|
||||
{
|
||||
EnumerateDirectory(baseFolderPrefix, fileName + wchar_t(kDirDelimiter),
|
||||
RINOK(EnumerateDirectory(baseFolderPrefix, fileName + wchar_t(kDirDelimiter),
|
||||
archiveNamePrefix + fileInfo.Name + wchar_t(kDirDelimiter),
|
||||
dirItems);
|
||||
dirItems));
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT EnumerateDirItems(
|
||||
const NWildcard::CCensorNode &curNode,
|
||||
const UString &diskPrefix,
|
||||
const UString &archivePrefix,
|
||||
const UString &addArchivePrefix,
|
||||
CObjectVector<CDirItem> &dirItems,
|
||||
bool enterToSubFolders,
|
||||
IEnumDirItemCallback *callback)
|
||||
{
|
||||
if (!enterToSubFolders)
|
||||
if (curNode.NeedCheckSubDirs())
|
||||
enterToSubFolders = true;
|
||||
if (callback)
|
||||
RINOK(callback->CheckBreak());
|
||||
NFind::CEnumeratorW enumerator(diskPrefix + wchar_t(kAnyStringWildcard));
|
||||
while (true)
|
||||
{
|
||||
NFind::CFileInfoW fileInfo;
|
||||
bool found;
|
||||
if (!enumerator.Next(fileInfo, found))
|
||||
return ::GetLastError();
|
||||
if (!found)
|
||||
break;
|
||||
|
||||
if (callback)
|
||||
RINOK(callback->CheckBreak());
|
||||
UString name = fileInfo.Name;
|
||||
bool enterToSubFolders2 = enterToSubFolders;
|
||||
if (curNode.CheckPathToRoot(addArchivePrefix + name, !fileInfo.IsDirectory()))
|
||||
{
|
||||
AddDirFileInfo(archivePrefix, diskPrefix + fileInfo.Name, fileInfo, dirItems);
|
||||
if (fileInfo.IsDirectory())
|
||||
enterToSubFolders2 = true;;
|
||||
}
|
||||
if (!fileInfo.IsDirectory())
|
||||
continue;
|
||||
|
||||
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;
|
||||
|
||||
UString archivePrefixNew = archivePrefix;
|
||||
UString addArchivePrefixNew = addArchivePrefix;
|
||||
if (nextNode == 0)
|
||||
{
|
||||
nextNode = &curNode;
|
||||
addArchivePrefixNew += name;
|
||||
addArchivePrefixNew += wchar_t(kDirDelimiter);
|
||||
}
|
||||
archivePrefixNew += name;
|
||||
archivePrefixNew += wchar_t(kDirDelimiter);
|
||||
RINOK(EnumerateDirItems(*nextNode,
|
||||
diskPrefix + fileInfo.Name + wchar_t(kDirDelimiter),
|
||||
archivePrefixNew, addArchivePrefixNew,
|
||||
dirItems, enterToSubFolders2, callback));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT EnumerateItems(const NWildcard::CCensor &censor,
|
||||
CObjectVector<CDirItem> &dirItems, IEnumDirItemCallback *callback)
|
||||
{
|
||||
for (int i = 0; i < censor.Pairs.Size(); i++)
|
||||
{
|
||||
if (callback)
|
||||
RINOK(callback->CheckBreak());
|
||||
const NWildcard::CPair &pair = censor.Pairs[i];
|
||||
RINOK(EnumerateDirItems(pair.Head, pair.Prefix, L"", L"", dirItems, false, callback));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
// EnumDirItems.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ENUM_DIR_ITEMS_H
|
||||
#define __ENUM_DIR_ITEMS_H
|
||||
|
||||
#include "Common/String.h"
|
||||
#include "Common/Vector.h"
|
||||
#include "Common/Wildcard.h"
|
||||
#include "DirItem.h"
|
||||
// #include "UpdatePairBasic.h"
|
||||
|
||||
#include "Windows/FileFind.h"
|
||||
|
||||
@@ -18,16 +14,20 @@ void AddDirFileInfo(
|
||||
NWindows::NFile::NFind::CFileInfoW &fileInfo,
|
||||
CObjectVector<CDirItem> &dirItems);
|
||||
|
||||
void EnumerateDirItems(
|
||||
|
||||
HRESULT EnumerateDirItems(
|
||||
const UString &baseFolderPrefix,
|
||||
const UStringVector &fileNames,
|
||||
const UString &archiveNamePrefix,
|
||||
CObjectVector<CDirItem> &dirItems);
|
||||
|
||||
/*
|
||||
void EnumerateItems(const CSysStringVector &filePaths,
|
||||
const UString &archiveNamePrefix,
|
||||
CArchiveStyleDirItemInfoVector &dirFileInfoVector, UINT codePage);
|
||||
*/
|
||||
struct IEnumDirItemCallback
|
||||
{
|
||||
virtual HRESULT CheckBreak() { return S_OK; }
|
||||
};
|
||||
|
||||
|
||||
HRESULT EnumerateItems(const NWildcard::CCensor &censor,
|
||||
CObjectVector<CDirItem> &dirItems, IEnumDirItemCallback *callback);
|
||||
|
||||
#endif
|
||||
|
||||
27
7zip/UI/Common/ExitCode.h
Executable file
27
7zip/UI/Common/ExitCode.h
Executable file
@@ -0,0 +1,27 @@
|
||||
// ExitCode.h
|
||||
|
||||
#ifndef __EXIT_CODE_H
|
||||
#define __EXIT_CODE_H
|
||||
|
||||
namespace NExitCode {
|
||||
|
||||
enum EEnum {
|
||||
|
||||
kSuccess = 0, // Successful operation
|
||||
kWarning = 1, // Non fatal error(s) occurred
|
||||
kFatalError = 2, // A fatal error occurred
|
||||
// kCRCError = 3, // A CRC error occurred when unpacking
|
||||
// kLockedArchive = 4, // Attempt to modify an archive previously locked
|
||||
// kWriteError = 5, // Write to disk error
|
||||
// kOpenError = 6, // Open file error
|
||||
kUserError = 7, // Command line option error
|
||||
kMemoryError = 8, // Not enough memory for operation
|
||||
// kCreateFileError = 9, // Create file error
|
||||
|
||||
kUserBreak = 255 // User stopped the process
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
127
7zip/UI/Common/Extract.cpp
Executable file
127
7zip/UI/Common/Extract.cpp
Executable file
@@ -0,0 +1,127 @@
|
||||
// Extract.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Extract.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "Windows/FileDir.h"
|
||||
|
||||
#include "OpenArchive.h"
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
#include "Windows/DLL.h"
|
||||
#endif
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
HRESULT DecompressArchive(
|
||||
IInArchive *archive,
|
||||
const UString &defaultName,
|
||||
const NWildcard::CCensorNode &wildcardCensor,
|
||||
const CExtractOptions &options,
|
||||
IExtractCallbackUI *callback)
|
||||
{
|
||||
CRecordVector<UInt32> realIndices;
|
||||
UInt32 numItems;
|
||||
RINOK(archive->GetNumberOfItems(&numItems));
|
||||
|
||||
for(UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
UString filePath;
|
||||
RINOK(GetArchiveItemPath(archive, i, options.DefaultItemName, filePath));
|
||||
bool isFolder;
|
||||
RINOK(IsArchiveItemFolder(archive, i, isFolder));
|
||||
if (!wildcardCensor.CheckPath(filePath, !isFolder))
|
||||
continue;
|
||||
realIndices.Add(i);
|
||||
}
|
||||
if (realIndices.Size() == 0)
|
||||
{
|
||||
callback->ThereAreNoFiles();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
|
||||
CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec);
|
||||
|
||||
UStringVector removePathParts;
|
||||
|
||||
UString outDir = options.OutputDir;
|
||||
outDir.Replace(L"*", defaultName);
|
||||
if(!outDir.IsEmpty())
|
||||
if(!NFile::NDirectory::CreateComplexDirectory(outDir))
|
||||
{
|
||||
throw UString(L"Can not create output directory ") + outDir;
|
||||
}
|
||||
|
||||
extractCallbackSpec->Init(
|
||||
archive,
|
||||
callback,
|
||||
options.StdOutMode,
|
||||
outDir,
|
||||
options.PathMode,
|
||||
options.OverwriteMode,
|
||||
removePathParts,
|
||||
options.DefaultItemName,
|
||||
options.ArchiveFileInfo.LastWriteTime,
|
||||
options.ArchiveFileInfo.Attributes);
|
||||
|
||||
HRESULT result = archive->Extract(&realIndices.Front(),
|
||||
realIndices.Size(), options.TestMode? 1: 0,
|
||||
extractCallback);
|
||||
|
||||
return callback->ExtractResult(result);
|
||||
}
|
||||
|
||||
HRESULT DecompressArchives(
|
||||
UStringVector &archivePaths, UStringVector &archivePathsFull,
|
||||
const NWildcard::CCensorNode &wildcardCensor,
|
||||
const CExtractOptions &optionsSpec,
|
||||
IOpenCallbackUI *openCallback,
|
||||
IExtractCallbackUI *extractCallback)
|
||||
{
|
||||
CExtractOptions options = optionsSpec;
|
||||
for (int i = 0; i < archivePaths.Size(); i++)
|
||||
{
|
||||
const UString &archivePath = archivePaths[i];
|
||||
NFile::NFind::CFileInfoW archiveFileInfo;
|
||||
if (!NFile::NFind::FindFile(archivePath, archiveFileInfo))
|
||||
throw "there is no such archive";
|
||||
|
||||
if (archiveFileInfo.IsDirectory())
|
||||
throw "there is no such archive";
|
||||
|
||||
options.ArchiveFileInfo = archiveFileInfo;
|
||||
|
||||
RINOK(extractCallback->BeforeOpen(archivePath));
|
||||
CArchiveLink archiveLink;
|
||||
HRESULT result = MyOpenArchive(archivePath, archiveLink, openCallback);
|
||||
RINOK(extractCallback->OpenResult(archivePath, result));
|
||||
if (result != S_OK)
|
||||
continue;
|
||||
|
||||
for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)
|
||||
{
|
||||
int index = archivePathsFull.FindInSorted(archiveLink.VolumePaths[v]);
|
||||
if (index >= 0 && index > i)
|
||||
{
|
||||
archivePaths.Delete(index);
|
||||
archivePathsFull.Delete(index);
|
||||
}
|
||||
}
|
||||
UString password;
|
||||
RINOK(openCallback->GetPasswordIfAny(password));
|
||||
if (!password.IsEmpty())
|
||||
{
|
||||
RINOK(extractCallback->SetPassword(password));
|
||||
}
|
||||
|
||||
options.DefaultItemName = archiveLink.GetDefaultItemName();
|
||||
RINOK(DecompressArchive(
|
||||
archiveLink.GetArchive(), archiveLink.GetDefaultItemName(),
|
||||
wildcardCensor, options, extractCallback));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
55
7zip/UI/Common/Extract.h
Executable file
55
7zip/UI/Common/Extract.h
Executable file
@@ -0,0 +1,55 @@
|
||||
// Extract.h
|
||||
|
||||
#ifndef __EXTRACT_H
|
||||
#define __EXTRACT_H
|
||||
|
||||
#include "Common/Wildcard.h"
|
||||
#include "Windows/FileFind.h"
|
||||
|
||||
#include "../../Archive/IArchive.h"
|
||||
#include "../Common/ZipRegistry.h"
|
||||
|
||||
#include "ArchiveExtractCallback.h"
|
||||
#include "ArchiveOpenCallback.h"
|
||||
#include "ExtractMode.h"
|
||||
|
||||
class CExtractOptions
|
||||
{
|
||||
public:
|
||||
bool StdOutMode;
|
||||
bool TestMode;
|
||||
NExtract::NPathMode::EEnum PathMode;
|
||||
|
||||
UString OutputDir;
|
||||
bool YesToAll;
|
||||
UString DefaultItemName;
|
||||
NWindows::NFile::NFind::CFileInfoW ArchiveFileInfo;
|
||||
|
||||
// bool ShowDialog;
|
||||
// bool PasswordEnabled;
|
||||
// UString Password;
|
||||
|
||||
NExtract::NOverwriteMode::EEnum OverwriteMode;
|
||||
|
||||
CExtractOptions():
|
||||
StdOutMode(false),
|
||||
YesToAll(false),
|
||||
TestMode(false),
|
||||
PathMode(NExtract::NPathMode::kFullPathnames),
|
||||
OverwriteMode(NExtract::NOverwriteMode::kAskBefore)
|
||||
{}
|
||||
|
||||
/*
|
||||
bool FullPathMode() const { return (ExtractMode == NExtractMode::kTest) ||
|
||||
(ExtractMode == NExtractMode::kFullPath); }
|
||||
*/
|
||||
};
|
||||
|
||||
HRESULT DecompressArchives(
|
||||
UStringVector &archivePaths, UStringVector &archivePathsFull,
|
||||
const NWildcard::CCensorNode &wildcardCensor,
|
||||
const CExtractOptions &options,
|
||||
IOpenCallbackUI *openCallback,
|
||||
IExtractCallbackUI *extractCallback);
|
||||
|
||||
#endif
|
||||
31
7zip/UI/Common/ExtractMode.h
Executable file
31
7zip/UI/Common/ExtractMode.h
Executable file
@@ -0,0 +1,31 @@
|
||||
// ExtractMode.h
|
||||
|
||||
#ifndef __EXTRACT_MODE_H
|
||||
#define __EXTRACT_MODE_H
|
||||
|
||||
namespace NExtract {
|
||||
|
||||
namespace NPathMode
|
||||
{
|
||||
enum EEnum
|
||||
{
|
||||
kFullPathnames,
|
||||
kCurrentPathnames,
|
||||
kNoPathnames
|
||||
};
|
||||
}
|
||||
|
||||
namespace NOverwriteMode
|
||||
{
|
||||
enum EEnum
|
||||
{
|
||||
kAskBefore,
|
||||
kWithoutPrompt,
|
||||
kSkipExisting,
|
||||
kAutoRename,
|
||||
kAutoRenameExisting
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -3,20 +3,32 @@
|
||||
#include "StdAfx.h"
|
||||
#include "ExtractingFilePath.h"
|
||||
|
||||
static void ReplaceDisk(UString &s)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < s.Length(); i++)
|
||||
if (s[i] != ' ')
|
||||
break;
|
||||
if (s.Length() > i + 1)
|
||||
{
|
||||
if (s[i + 1] == L':')
|
||||
{
|
||||
s.Delete(i + 1);
|
||||
// s.Insert(i + 1, L'_');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UString GetCorrectFileName(const UString &path)
|
||||
{
|
||||
UString result = path;
|
||||
result.Trim();
|
||||
result.Replace(L"..\\", L"");
|
||||
result.Replace(L"../", L"");
|
||||
if (result.Length() > 1)
|
||||
{
|
||||
if (result[1] == L':')
|
||||
{
|
||||
result.Delete(1);
|
||||
// result.Insert(first + 1, L'_');
|
||||
}
|
||||
UString test = path;
|
||||
test.Trim();
|
||||
if (test == L"..")
|
||||
result.Replace(L"..", L"");
|
||||
}
|
||||
ReplaceDisk(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -29,7 +41,6 @@ UString GetCorrectPath(const UString &path)
|
||||
break;
|
||||
while(result.Length() > first)
|
||||
{
|
||||
|
||||
if (result[first] == L'\\' || result[first] == L'/')
|
||||
{
|
||||
result.Delete(first);
|
||||
@@ -40,15 +51,19 @@ UString GetCorrectPath(const UString &path)
|
||||
result.Replace(L"..\\", L"");
|
||||
result.Replace(L"../", L"");
|
||||
|
||||
if (result.Length() > 1)
|
||||
{
|
||||
if (result[first + 1] == L':')
|
||||
{
|
||||
result.Delete(first + 1);
|
||||
// result.Insert(first + 1, L'_');
|
||||
}
|
||||
}
|
||||
ReplaceDisk(result);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
void MakeCorrectPath(UStringVector &pathParts)
|
||||
{
|
||||
for (int i = 0; i < pathParts.Size();)
|
||||
{
|
||||
UString &s = pathParts[i];
|
||||
s = GetCorrectFileName(s);
|
||||
if (s.IsEmpty())
|
||||
pathParts.Delete(i);
|
||||
else
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// ExtractingFilePath.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __EXTRACTINGFILEPATH_H
|
||||
#define __EXTRACTINGFILEPATH_H
|
||||
|
||||
@@ -9,5 +7,6 @@
|
||||
|
||||
UString GetCorrectFileName(const UString &path);
|
||||
UString GetCorrectPath(const UString &path);
|
||||
void MakeCorrectPath(UStringVector &pathParts);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
// HandlerLoader.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __HANDLERLOADER_H
|
||||
#define __HANDLERLOADER_H
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "Windows/DLL.h"
|
||||
|
||||
typedef UINT32 (WINAPI * CreateObjectFunc)(
|
||||
typedef UInt32 (WINAPI * CreateObjectFunc)(
|
||||
const GUID *clsID,
|
||||
const GUID *interfaceID,
|
||||
void **outObject);
|
||||
@@ -37,6 +35,4 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
46
7zip/UI/Common/IFileExtractCallback.h
Executable file
46
7zip/UI/Common/IFileExtractCallback.h
Executable file
@@ -0,0 +1,46 @@
|
||||
// IFileExtractCallback.h
|
||||
|
||||
#ifndef __IFILEEXTRACTCALLBACK_H
|
||||
#define __IFILEEXTRACTCALLBACK_H
|
||||
|
||||
#include "Common/String.h"
|
||||
|
||||
namespace NOverwriteAnswer
|
||||
{
|
||||
enum EEnum
|
||||
{
|
||||
kYes,
|
||||
kYesToAll,
|
||||
kNo,
|
||||
kNoToAll,
|
||||
kAutoRename,
|
||||
kCancel,
|
||||
};
|
||||
}
|
||||
|
||||
// {23170F69-40C1-278A-0000-000100070000}
|
||||
DEFINE_GUID(IID_IFolderArchiveExtractCallback,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000100070000")
|
||||
IFolderArchiveExtractCallback: public IProgress
|
||||
{
|
||||
public:
|
||||
STDMETHOD(AskOverwrite)(
|
||||
const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize,
|
||||
const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize,
|
||||
Int32 *answer) PURE;
|
||||
STDMETHOD(PrepareOperation)(const wchar_t *name, Int32 askExtractMode, const UInt64 *position) PURE;
|
||||
STDMETHOD(MessageError)(const wchar_t *message) PURE;
|
||||
STDMETHOD(SetOperationResult)(Int32 operationResult) PURE;
|
||||
};
|
||||
|
||||
struct IExtractCallbackUI: IFolderArchiveExtractCallback
|
||||
{
|
||||
virtual HRESULT BeforeOpen(const wchar_t *name) = 0;
|
||||
virtual HRESULT OpenResult(const wchar_t *name, HRESULT result) = 0;
|
||||
virtual HRESULT ThereAreNoFiles() = 0;
|
||||
virtual HRESULT ExtractResult(HRESULT result) = 0;
|
||||
virtual HRESULT SetPassword(const UString &password) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -4,9 +4,12 @@
|
||||
|
||||
#include "OpenArchive.h"
|
||||
|
||||
#include "Common/Wildcard.h"
|
||||
|
||||
#include "Windows/FileName.h"
|
||||
#include "Windows/FileDir.h"
|
||||
#include "Windows/Defs.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
|
||||
#include "../../Common/FileStreams.h"
|
||||
|
||||
@@ -24,6 +27,10 @@
|
||||
#include "../../Archive/GZip/GZipHandler.h"
|
||||
#endif
|
||||
|
||||
#ifdef FORMAT_SPLIT
|
||||
#include "../../Archive/Split/SplitHandler.h"
|
||||
#endif
|
||||
|
||||
#ifdef FORMAT_TAR
|
||||
#include "../../Archive/Tar/TarHandler.h"
|
||||
#endif
|
||||
@@ -32,17 +39,86 @@
|
||||
#include "../../Archive/Zip/ZipHandler.h"
|
||||
#endif
|
||||
|
||||
#ifdef FORMAT_Z
|
||||
#include "../../Archive/Z/ZHandler.h"
|
||||
#endif
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
#include "HandlerLoader.h"
|
||||
#endif
|
||||
|
||||
#include "DefaultName.h"
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
const UINT64 kMaxCheckStartPosition = 1 << 20;
|
||||
HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, UString &result)
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(archive->GetProperty(index, kpidPath, &prop));
|
||||
if(prop.vt == VT_BSTR)
|
||||
result = prop.bstrVal;
|
||||
else if (prop.vt == VT_EMPTY)
|
||||
result.Empty();
|
||||
else
|
||||
return E_FAIL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT ReOpenArchive(IInArchive *archive,
|
||||
const UString &fileName)
|
||||
HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, const UString &defaultName, UString &result)
|
||||
{
|
||||
RINOK(GetArchiveItemPath(archive, index, result));
|
||||
if (result.IsEmpty())
|
||||
result = defaultName;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT GetArchiveItemFileTime(IInArchive *archive, UInt32 index,
|
||||
const FILETIME &defaultFileTime, FILETIME &fileTime)
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(archive->GetProperty(index, kpidLastWriteTime, &prop));
|
||||
if (prop.vt == VT_FILETIME)
|
||||
fileTime = prop.filetime;
|
||||
else if (prop.vt == VT_EMPTY)
|
||||
fileTime = defaultFileTime;
|
||||
else
|
||||
return E_FAIL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result)
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(archive->GetProperty(index, propID, &prop));
|
||||
if(prop.vt == VT_BOOL)
|
||||
result = VARIANT_BOOLToBool(prop.boolVal);
|
||||
else if (prop.vt == VT_EMPTY)
|
||||
result = false;
|
||||
else
|
||||
return E_FAIL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result)
|
||||
{
|
||||
return IsArchiveItemProp(archive, index, kpidIsFolder, result);
|
||||
}
|
||||
|
||||
HRESULT IsArchiveItemAnti(IInArchive *archive, UInt32 index, bool &result)
|
||||
{
|
||||
return IsArchiveItemProp(archive, index, kpidIsAnti, result);
|
||||
}
|
||||
|
||||
// Static-SFX (for Linux) can be big
|
||||
const UInt64 kMaxCheckStartPosition =
|
||||
#ifdef _WIN32
|
||||
1 << 20;
|
||||
#else
|
||||
1 << 22;
|
||||
#endif
|
||||
|
||||
|
||||
HRESULT ReOpenArchive(IInArchive *archive, const UString &fileName)
|
||||
{
|
||||
CInFileStream *inStreamSpec = new CInFileStream;
|
||||
CMyComPtr<IInStream> inStream(inStreamSpec);
|
||||
@@ -50,49 +126,87 @@ HRESULT ReOpenArchive(IInArchive *archive,
|
||||
return archive->Open(inStream, &kMaxCheckStartPosition, NULL);
|
||||
}
|
||||
|
||||
HRESULT OpenArchive(const UString &fileName,
|
||||
#ifndef _SFX
|
||||
static inline bool TestSignature(const Byte *p1, const Byte *p2, UInt32 size)
|
||||
{
|
||||
for (UInt32 i = 0; i < size; i++)
|
||||
if (p1[i] != p2[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
HRESULT OpenArchive(
|
||||
IInStream *inStream,
|
||||
const UString &fileName,
|
||||
#ifndef EXCLUDE_COM
|
||||
HMODULE *module,
|
||||
#endif
|
||||
IInArchive **archiveResult,
|
||||
CArchiverInfo &archiverInfoResult,
|
||||
int &subExtIndex,
|
||||
UString &defaultItemName,
|
||||
IArchiveOpenCallback *openArchiveCallback)
|
||||
{
|
||||
CInFileStream *inStreamSpec = new CInFileStream;
|
||||
CMyComPtr<IInStream> inStream(inStreamSpec);
|
||||
if (!inStreamSpec->Open(fileName))
|
||||
return GetLastError();
|
||||
|
||||
*archiveResult = NULL;
|
||||
CObjectVector<CArchiverInfo> archiverInfoList;
|
||||
ReadArchiverInfoList(archiverInfoList);
|
||||
UString extension;
|
||||
{
|
||||
UString name, pureName, dot;
|
||||
if(!NFile::NDirectory::GetOnlyName(fileName, name))
|
||||
return E_FAIL;
|
||||
NFile::NName::SplitNameToPureNameAndExtension(name, pureName, dot, extension);
|
||||
int dotPos = fileName.ReverseFind(L'.');
|
||||
if (dotPos >= 0)
|
||||
extension = fileName.Mid(dotPos + 1);
|
||||
}
|
||||
CIntVector orderIndices;
|
||||
int firstArchiverIndex;
|
||||
for(firstArchiverIndex = 0;
|
||||
firstArchiverIndex < archiverInfoList.Size(); firstArchiverIndex++)
|
||||
int i;
|
||||
bool finded = false;
|
||||
for(i = 0; i < archiverInfoList.Size(); i++)
|
||||
{
|
||||
int subIndex = archiverInfoList[firstArchiverIndex].FindExtension(extension);
|
||||
if (subIndex >= 0)
|
||||
break;
|
||||
if (archiverInfoList[i].FindExtension(extension) >= 0)
|
||||
{
|
||||
orderIndices.Insert(0, i);
|
||||
finded = true;
|
||||
}
|
||||
else
|
||||
orderIndices.Add(i);
|
||||
}
|
||||
if(firstArchiverIndex < archiverInfoList.Size())
|
||||
orderIndices.Add(firstArchiverIndex);
|
||||
for(int j = 0; j < archiverInfoList.Size(); j++)
|
||||
if(j != firstArchiverIndex)
|
||||
orderIndices.Add(j);
|
||||
|
||||
HRESULT badResult = S_OK;
|
||||
for(int i = 0; i < orderIndices.Size(); i++)
|
||||
#ifndef _SFX
|
||||
if (!finded)
|
||||
{
|
||||
inStreamSpec->Seek(0, STREAM_SEEK_SET, NULL);
|
||||
CByteBuffer byteBuffer;
|
||||
const UInt32 kBufferSize = (200 << 10);
|
||||
byteBuffer.SetCapacity(kBufferSize);
|
||||
Byte *buffer = byteBuffer;
|
||||
RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
|
||||
UInt32 processedSize;
|
||||
RINOK(inStream->Read(buffer, kBufferSize, &processedSize));
|
||||
int numFinded = 0;
|
||||
for (int pos = (int)processedSize; pos >= 0 ; pos--)
|
||||
{
|
||||
for(int i = numFinded; i < orderIndices.Size(); i++)
|
||||
{
|
||||
int index = orderIndices[i];
|
||||
const CArchiverInfo &ai = archiverInfoList[index];
|
||||
const CByteBuffer &sig = ai.StartSignature;
|
||||
if (sig.GetCapacity() == 0)
|
||||
continue;
|
||||
if (pos + sig.GetCapacity() > processedSize)
|
||||
continue;
|
||||
if (TestSignature(buffer + pos, sig, sig.GetCapacity()))
|
||||
{
|
||||
orderIndices.Delete(i);
|
||||
orderIndices.Insert(0, index);
|
||||
numFinded++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
HRESULT badResult = S_OK;
|
||||
for(i = 0; i < orderIndices.Size(); i++)
|
||||
{
|
||||
inStream->Seek(0, STREAM_SEEK_SET, NULL);
|
||||
const CArchiverInfo &archiverInfo = archiverInfoList[orderIndices[i]];
|
||||
#ifndef EXCLUDE_COM
|
||||
CHandlerLoader loader;
|
||||
@@ -114,6 +228,11 @@ HRESULT OpenArchive(const UString &fileName,
|
||||
archive = new NArchive::NGZip::CHandler;
|
||||
#endif
|
||||
|
||||
#ifdef FORMAT_SPLIT
|
||||
if (archiverInfo.Name.CompareNoCase(L"Split") == 0)
|
||||
archive = new NArchive::NSplit::CHandler;
|
||||
#endif
|
||||
|
||||
#ifdef FORMAT_TAR
|
||||
if (archiverInfo.Name.CompareNoCase(L"Tar") == 0)
|
||||
archive = new NArchive::NTar::CHandler;
|
||||
@@ -124,6 +243,11 @@ HRESULT OpenArchive(const UString &fileName,
|
||||
archive = new NArchive::NZip::CHandler;
|
||||
#endif
|
||||
|
||||
#ifdef FORMAT_Z
|
||||
if (archiverInfo.Name.CompareNoCase(L"Z") == 0)
|
||||
archive = new NArchive::NZ::CHandler;
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
if (!archive)
|
||||
@@ -144,28 +268,260 @@ HRESULT OpenArchive(const UString &fileName,
|
||||
if(result != S_OK)
|
||||
{
|
||||
badResult = result;
|
||||
if(result == E_ABORT)
|
||||
break;
|
||||
continue;
|
||||
// return result;
|
||||
}
|
||||
*archiveResult = archive.Detach();
|
||||
#ifndef EXCLUDE_COM
|
||||
*module = loader.Detach();
|
||||
#endif
|
||||
archiverInfoResult = archiverInfo;
|
||||
subExtIndex = archiverInfo.FindExtension(extension);
|
||||
int subExtIndex = archiverInfo.FindExtension(extension);
|
||||
if (subExtIndex < 0)
|
||||
subExtIndex = 0;
|
||||
defaultItemName = GetDefaultName2(fileName,
|
||||
archiverInfo.Extensions[subExtIndex].Extension,
|
||||
archiverInfo.Extensions[subExtIndex].AddExtension);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
if (badResult != S_OK)
|
||||
return badResult;
|
||||
return S_FALSE;
|
||||
|
||||
/*
|
||||
#else
|
||||
return S_FALSE;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
|
||||
HRESULT OpenArchive(const UString &filePath,
|
||||
#ifndef EXCLUDE_COM
|
||||
HMODULE *module,
|
||||
#endif
|
||||
IInArchive **archiveResult,
|
||||
CArchiverInfo &archiverInfo,
|
||||
UString &defaultItemName,
|
||||
IArchiveOpenCallback *openArchiveCallback)
|
||||
{
|
||||
CInFileStream *inStreamSpec = new CInFileStream;
|
||||
CMyComPtr<IInStream> inStream(inStreamSpec);
|
||||
if (!inStreamSpec->Open(filePath))
|
||||
return GetLastError();
|
||||
return OpenArchive(inStream, ExtractFileNameFromPath(filePath),
|
||||
#ifndef EXCLUDE_COM
|
||||
module,
|
||||
#endif
|
||||
archiveResult, archiverInfo,
|
||||
defaultItemName, openArchiveCallback);
|
||||
}
|
||||
|
||||
static void MakeDefaultName(UString &name)
|
||||
{
|
||||
int dotPos = name.ReverseFind(L'.');
|
||||
if (dotPos < 0)
|
||||
return;
|
||||
UString ext = name.Mid(dotPos + 1);
|
||||
if (ext.IsEmpty())
|
||||
return;
|
||||
for (int pos = 0; pos < ext.Length(); pos++)
|
||||
if (ext[pos] < L'0' || ext[pos] > L'9')
|
||||
return;
|
||||
name = name.Left(dotPos);
|
||||
}
|
||||
|
||||
HRESULT OpenArchive(const UString &fileName,
|
||||
#ifndef EXCLUDE_COM
|
||||
HMODULE *module0,
|
||||
HMODULE *module1,
|
||||
#endif
|
||||
IInArchive **archive0,
|
||||
IInArchive **archive1,
|
||||
CArchiverInfo &archiverInfo0,
|
||||
CArchiverInfo &archiverInfo1,
|
||||
UString &defaultItemName0,
|
||||
UString &defaultItemName1,
|
||||
IArchiveOpenCallback *openArchiveCallback)
|
||||
{
|
||||
HRESULT result = OpenArchive(fileName,
|
||||
#ifndef EXCLUDE_COM
|
||||
module0,
|
||||
#endif
|
||||
archive0, archiverInfo0, defaultItemName0, openArchiveCallback);
|
||||
RINOK(result);
|
||||
CMyComPtr<IInArchiveGetStream> getStream;
|
||||
result = (*archive0)->QueryInterface(IID_IInArchiveGetStream, (void **)&getStream);
|
||||
if (result != S_OK || getStream == 0)
|
||||
return S_OK;
|
||||
|
||||
CMyComPtr<ISequentialInStream> subSeqStream;
|
||||
result = getStream->GetStream(0, &subSeqStream);
|
||||
if (result != S_OK)
|
||||
return S_OK;
|
||||
|
||||
CMyComPtr<IInStream> subStream;
|
||||
if (subSeqStream.QueryInterface(IID_IInStream, &subStream) != S_OK)
|
||||
return S_OK;
|
||||
if (!subStream)
|
||||
return S_OK;
|
||||
|
||||
UInt32 numItems;
|
||||
RINOK((*archive0)->GetNumberOfItems(&numItems));
|
||||
if (numItems < 1)
|
||||
return S_OK;
|
||||
|
||||
UString subPath;
|
||||
RINOK(GetArchiveItemPath(*archive0, 0, subPath))
|
||||
if (subPath.IsEmpty())
|
||||
{
|
||||
MakeDefaultName(defaultItemName0);
|
||||
subPath = defaultItemName0;
|
||||
if (archiverInfo0.Name.CompareNoCase(L"7z") == 0)
|
||||
{
|
||||
if (subPath.Right(3).CompareNoCase(L".7z") != 0)
|
||||
subPath += L".7z";
|
||||
}
|
||||
}
|
||||
else
|
||||
subPath = ExtractFileNameFromPath(subPath);
|
||||
|
||||
CMyComPtr<IArchiveOpenSetSubArchiveName> setSubArchiveName;
|
||||
openArchiveCallback->QueryInterface(IID_IArchiveOpenSetSubArchiveName, (void **)&setSubArchiveName);
|
||||
if (setSubArchiveName)
|
||||
setSubArchiveName->SetSubArchiveName(subPath);
|
||||
|
||||
result = OpenArchive(subStream, subPath,
|
||||
#ifndef EXCLUDE_COM
|
||||
module1,
|
||||
#endif
|
||||
archive1, archiverInfo1, defaultItemName1, openArchiveCallback);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT MyOpenArchive(const UString &archiveName,
|
||||
#ifndef EXCLUDE_COM
|
||||
HMODULE *module,
|
||||
#endif
|
||||
IInArchive **archive,
|
||||
UString &defaultItemName,
|
||||
IOpenCallbackUI *openCallbackUI)
|
||||
{
|
||||
COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;
|
||||
CMyComPtr<IArchiveOpenCallback> openCallback = openCallbackSpec;
|
||||
openCallbackSpec->Callback = openCallbackUI;
|
||||
|
||||
UString fullName;
|
||||
int fileNamePartStartIndex;
|
||||
NFile::NDirectory::MyGetFullPathName(archiveName, fullName, fileNamePartStartIndex);
|
||||
openCallbackSpec->Init(
|
||||
fullName.Left(fileNamePartStartIndex),
|
||||
fullName.Mid(fileNamePartStartIndex));
|
||||
|
||||
CArchiverInfo archiverInfo;
|
||||
return OpenArchive(archiveName,
|
||||
#ifndef EXCLUDE_COM
|
||||
module,
|
||||
#endif
|
||||
archive,
|
||||
archiverInfo,
|
||||
defaultItemName,
|
||||
openCallback);
|
||||
}
|
||||
|
||||
HRESULT MyOpenArchive(const UString &archiveName,
|
||||
#ifndef EXCLUDE_COM
|
||||
HMODULE *module0,
|
||||
HMODULE *module1,
|
||||
#endif
|
||||
IInArchive **archive0,
|
||||
IInArchive **archive1,
|
||||
UString &defaultItemName0,
|
||||
UString &defaultItemName1,
|
||||
UStringVector &volumePaths,
|
||||
IOpenCallbackUI *openCallbackUI)
|
||||
{
|
||||
COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;
|
||||
CMyComPtr<IArchiveOpenCallback> openCallback = openCallbackSpec;
|
||||
openCallbackSpec->Callback = openCallbackUI;
|
||||
|
||||
UString fullName;
|
||||
int fileNamePartStartIndex;
|
||||
NFile::NDirectory::MyGetFullPathName(archiveName, fullName, fileNamePartStartIndex);
|
||||
UString prefix = fullName.Left(fileNamePartStartIndex);
|
||||
UString name = fullName.Mid(fileNamePartStartIndex);
|
||||
openCallbackSpec->Init(prefix, name);
|
||||
|
||||
CArchiverInfo archiverInfo0, archiverInfo1;
|
||||
HRESULT result = OpenArchive(archiveName,
|
||||
#ifndef EXCLUDE_COM
|
||||
module0,
|
||||
module1,
|
||||
#endif
|
||||
archive0,
|
||||
archive1,
|
||||
archiverInfo0,
|
||||
archiverInfo1,
|
||||
defaultItemName0,
|
||||
defaultItemName1,
|
||||
openCallback);
|
||||
RINOK(result);
|
||||
volumePaths.Add(prefix + name);
|
||||
for (int i = 0; i < openCallbackSpec->FileNames.Size(); i++)
|
||||
volumePaths.Add(prefix + openCallbackSpec->FileNames[i]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CArchiveLink::Close()
|
||||
{
|
||||
if (Archive1 != 0)
|
||||
RINOK(Archive1->Close());
|
||||
if (Archive0 != 0)
|
||||
RINOK(Archive0->Close());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CArchiveLink::Release()
|
||||
{
|
||||
if (Archive1 != 0)
|
||||
Archive1.Release();
|
||||
if (Archive0 != 0)
|
||||
Archive0.Release();
|
||||
#ifndef EXCLUDE_COM
|
||||
Library1.Free();
|
||||
Library0.Free();
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT OpenArchive(const UString &archiveName,
|
||||
CArchiveLink &archiveLink,
|
||||
IArchiveOpenCallback *openCallback)
|
||||
{
|
||||
return OpenArchive(archiveName,
|
||||
#ifndef EXCLUDE_COM
|
||||
&archiveLink.Library0, &archiveLink.Library1,
|
||||
#endif
|
||||
&archiveLink.Archive0, &archiveLink.Archive1,
|
||||
archiveLink.ArchiverInfo0, archiveLink.ArchiverInfo1,
|
||||
archiveLink.DefaultItemName0, archiveLink.DefaultItemName1,
|
||||
openCallback);
|
||||
}
|
||||
|
||||
HRESULT MyOpenArchive(const UString &archiveName,
|
||||
CArchiveLink &archiveLink,
|
||||
IOpenCallbackUI *openCallbackUI)
|
||||
{
|
||||
return MyOpenArchive(archiveName,
|
||||
#ifndef EXCLUDE_COM
|
||||
&archiveLink.Library0, &archiveLink.Library1,
|
||||
#endif
|
||||
&archiveLink.Archive0, &archiveLink.Archive1,
|
||||
archiveLink.DefaultItemName0, archiveLink.DefaultItemName1,
|
||||
archiveLink.VolumePaths,
|
||||
openCallbackUI);
|
||||
}
|
||||
|
||||
HRESULT ReOpenArchive(CArchiveLink &archiveLink,
|
||||
const UString &fileName)
|
||||
{
|
||||
if (archiveLink.GetNumLevels() > 1)
|
||||
return E_NOTIMPL;
|
||||
if (archiveLink.GetNumLevels() == 0)
|
||||
return MyOpenArchive(fileName, archiveLink, 0);
|
||||
return ReOpenArchive(archiveLink.GetArchive(), fileName);
|
||||
}
|
||||
|
||||
@@ -4,21 +4,130 @@
|
||||
#define __OPENARCHIVE_H
|
||||
|
||||
#include "Common/String.h"
|
||||
#include "Windows/FileFind.h"
|
||||
|
||||
#include "../../Archive/IArchive.h"
|
||||
#include "ArchiverInfo.h"
|
||||
#include "ArchiveOpenCallback.h"
|
||||
|
||||
HRESULT OpenArchive(const UString &fileName,
|
||||
#ifndef EXCLUDE_COM
|
||||
#include "Windows/DLL.h"
|
||||
#endif
|
||||
|
||||
HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, const UString &defaultName, UString &result);
|
||||
HRESULT GetArchiveItemFileTime(IInArchive *archive, UInt32 index,
|
||||
const FILETIME &defaultFileTime, FILETIME &fileTime);
|
||||
HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result);
|
||||
HRESULT IsArchiveItemAnti(IInArchive *archive, UInt32 index, bool &result);
|
||||
|
||||
struct ISetSubArchiveName
|
||||
{
|
||||
virtual void SetSubArchiveName(const wchar_t *name) = 0;
|
||||
};
|
||||
|
||||
HRESULT OpenArchive(
|
||||
IInStream *inStream,
|
||||
const UString &fileName,
|
||||
#ifndef EXCLUDE_COM
|
||||
HMODULE *module,
|
||||
#endif
|
||||
IInArchive **archiveResult,
|
||||
CArchiverInfo &archiverInfoResult,
|
||||
UString &defaultItemName,
|
||||
IArchiveOpenCallback *openArchiveCallback);
|
||||
|
||||
HRESULT OpenArchive(const UString &filePath,
|
||||
#ifndef EXCLUDE_COM
|
||||
HMODULE *module,
|
||||
#endif
|
||||
IInArchive **archive,
|
||||
CArchiverInfo &archiverInfoResult,
|
||||
int &subExtIndex,
|
||||
CArchiverInfo &archiverInfo,
|
||||
UString &defaultItemName,
|
||||
IArchiveOpenCallback *openArchiveCallback);
|
||||
|
||||
HRESULT OpenArchive(const UString &filePath,
|
||||
#ifndef EXCLUDE_COM
|
||||
HMODULE *module0,
|
||||
HMODULE *module1,
|
||||
#endif
|
||||
IInArchive **archive0,
|
||||
IInArchive **archive1,
|
||||
CArchiverInfo &archiverInfo0,
|
||||
CArchiverInfo &archiverInfo1,
|
||||
UString &defaultItemName0,
|
||||
UString &defaultItemName1,
|
||||
IArchiveOpenCallback *openArchiveCallback);
|
||||
|
||||
|
||||
HRESULT ReOpenArchive(IInArchive *archive,
|
||||
const UString &fileName);
|
||||
|
||||
HRESULT MyOpenArchive(const UString &archiveName,
|
||||
#ifndef EXCLUDE_COM
|
||||
HMODULE *module,
|
||||
#endif
|
||||
IInArchive **archive,
|
||||
UString &defaultItemName,
|
||||
IOpenCallbackUI *openCallbackUI);
|
||||
|
||||
HRESULT MyOpenArchive(const UString &archiveName,
|
||||
#ifndef EXCLUDE_COM
|
||||
HMODULE *module0,
|
||||
HMODULE *module1,
|
||||
#endif
|
||||
IInArchive **archive0,
|
||||
IInArchive **archive1,
|
||||
UString &defaultItemName0,
|
||||
UString &defaultItemName1,
|
||||
UStringVector &volumePaths,
|
||||
IOpenCallbackUI *openCallbackUI);
|
||||
|
||||
struct CArchiveLink
|
||||
{
|
||||
#ifndef EXCLUDE_COM
|
||||
NWindows::NDLL::CLibrary Library0;
|
||||
NWindows::NDLL::CLibrary Library1;
|
||||
#endif
|
||||
CMyComPtr<IInArchive> Archive0;
|
||||
CMyComPtr<IInArchive> Archive1;
|
||||
UString DefaultItemName0;
|
||||
UString DefaultItemName1;
|
||||
|
||||
CArchiverInfo ArchiverInfo0;
|
||||
CArchiverInfo ArchiverInfo1;
|
||||
|
||||
UStringVector VolumePaths;
|
||||
|
||||
int GetNumLevels() const
|
||||
{
|
||||
int result = 0;
|
||||
if (Archive0)
|
||||
{
|
||||
result++;
|
||||
if (Archive1)
|
||||
result++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
IInArchive *GetArchive() { return Archive1 != 0 ? Archive1: Archive0; }
|
||||
UString GetDefaultItemName() { return Archive1 != 0 ? DefaultItemName1: DefaultItemName0; }
|
||||
const CArchiverInfo &GetArchiverInfo() { return Archive1 != 0 ? ArchiverInfo1: ArchiverInfo0; }
|
||||
HRESULT Close();
|
||||
void Release();
|
||||
};
|
||||
|
||||
HRESULT OpenArchive(const UString &archiveName,
|
||||
CArchiveLink &archiveLink,
|
||||
IArchiveOpenCallback *openCallback);
|
||||
|
||||
HRESULT MyOpenArchive(const UString &archiveName,
|
||||
CArchiveLink &archiveLink,
|
||||
IOpenCallbackUI *openCallbackUI);
|
||||
|
||||
HRESULT ReOpenArchive(CArchiveLink &archiveLink,
|
||||
const UString &fileName);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -14,13 +14,24 @@
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
static UString ConvertUINT32ToString(UINT32 value)
|
||||
static UString ConvertUInt32ToString(UInt32 value)
|
||||
{
|
||||
wchar_t buffer[32];
|
||||
ConvertUINT64ToString(value, buffer);
|
||||
ConvertUInt64ToString(value, buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static 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';
|
||||
}
|
||||
|
||||
UString ConvertPropertyToString(const PROPVARIANT &propVariant,
|
||||
PROPID propID, bool full)
|
||||
{
|
||||
@@ -38,22 +49,22 @@ UString ConvertPropertyToString(const PROPVARIANT &propVariant,
|
||||
return UString();
|
||||
if (!::FileTimeToLocalFileTime(&propVariant.filetime, &localFileTime))
|
||||
return UString(); // It is error;
|
||||
return ConvertFileTimeToString2(localFileTime, true, full);
|
||||
return ConvertFileTimeToString(localFileTime, true, full);
|
||||
}
|
||||
case kpidCRC:
|
||||
{
|
||||
if(propVariant.vt != VT_UI4)
|
||||
break;
|
||||
TCHAR temp[17];
|
||||
wsprintf(temp, TEXT("%08X"), propVariant.ulVal);
|
||||
return GetUnicodeString(temp);
|
||||
wchar_t temp[12];
|
||||
ConvertUInt32ToHex(propVariant.ulVal, temp);
|
||||
return temp;
|
||||
}
|
||||
case kpidAttributes:
|
||||
{
|
||||
if(propVariant.vt != VT_UI4)
|
||||
break;
|
||||
UString result;
|
||||
UINT32 attributes = propVariant.ulVal;
|
||||
UInt32 attributes = propVariant.ulVal;
|
||||
if (NFile::NFind::NAttributes::IsReadOnly(attributes)) result += L'R';
|
||||
if (NFile::NFind::NAttributes::IsHidden(attributes)) result += L'H';
|
||||
if (NFile::NFind::NAttributes::IsSystem(attributes)) result += L'S';
|
||||
@@ -67,12 +78,12 @@ UString ConvertPropertyToString(const PROPVARIANT &propVariant,
|
||||
{
|
||||
if(propVariant.vt != VT_UI4)
|
||||
break;
|
||||
UINT32 size = propVariant.ulVal;
|
||||
UInt32 size = propVariant.ulVal;
|
||||
if (size % (1 << 20) == 0)
|
||||
return ConvertUINT32ToString(size >> 20) + L"MB";
|
||||
return ConvertUInt32ToString(size >> 20) + L"MB";
|
||||
if (size % (1 << 10) == 0)
|
||||
return ConvertUINT32ToString(size >> 10) + L"KB";
|
||||
return ConvertUINT32ToString(size);
|
||||
return ConvertUInt32ToString(size >> 10) + L"KB";
|
||||
return ConvertUInt32ToString(size);
|
||||
}
|
||||
}
|
||||
return ConvertPropVariantToString(propVariant);
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// PropIDUtils.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __PROPIDUTILS_H
|
||||
#define __PROPIDUTILS_H
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ static int __cdecl CompareStrings(const void *a1, const void *a2)
|
||||
return s1.CompareNoCase(s2);
|
||||
}
|
||||
|
||||
void SortStringsToIndices(UStringVector &strings, CIntVector &indices)
|
||||
void SortStringsToIndices(const UStringVector &strings, CIntVector &indices)
|
||||
{
|
||||
indices.Clear();
|
||||
if (strings.IsEmpty())
|
||||
@@ -22,9 +22,19 @@ void SortStringsToIndices(UStringVector &strings, CIntVector &indices)
|
||||
indices.Reserve(numItems);
|
||||
int i;
|
||||
for(i = 0; i < numItems; i++)
|
||||
pointers.Add(&strings.CPointerVector::operator[](i));
|
||||
pointers.Add((void *)&strings.CPointerVector::operator[](i));
|
||||
void **stringsBase = (void **)pointers[0];
|
||||
qsort(&pointers[0], numItems, sizeof(void *), CompareStrings);
|
||||
for(i = 0; i < numItems; i++)
|
||||
indices.Add((void **)pointers[i] - stringsBase);
|
||||
}
|
||||
|
||||
void SortStrings(const UStringVector &src, UStringVector &dest)
|
||||
{
|
||||
CIntVector indices;
|
||||
SortStringsToIndices(src, indices);
|
||||
dest.Clear();
|
||||
dest.Reserve(indices.Size());
|
||||
for (int i = 0; i < indices.Size(); i++)
|
||||
dest.Add(src[indices[i]]);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
// SortUtils.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __SORTUTLS_H
|
||||
#define __SORTUTLS_H
|
||||
|
||||
#include "Common/String.h"
|
||||
|
||||
void SortStringsToIndices(UStringVector &strings, CIntVector &indices);
|
||||
void SortStringsToIndices(const UStringVector &strings, CIntVector &indices);
|
||||
void SortStrings(const UStringVector &src, UStringVector &dest);
|
||||
|
||||
#endif
|
||||
|
||||
22
7zip/UI/Common/TempFiles.cpp
Executable file
22
7zip/UI/Common/TempFiles.cpp
Executable file
@@ -0,0 +1,22 @@
|
||||
// TempFiles.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "TempFiles.h"
|
||||
|
||||
#include "Windows/FileDir.h"
|
||||
#include "Windows/FileIO.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
|
||||
void CTempFiles::Clear()
|
||||
{
|
||||
while(!Paths.IsEmpty())
|
||||
{
|
||||
NDirectory::DeleteFileAlways(Paths.Back());
|
||||
Paths.DeleteBack();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
16
7zip/UI/Common/TempFiles.h
Executable file
16
7zip/UI/Common/TempFiles.h
Executable file
@@ -0,0 +1,16 @@
|
||||
// TempFiles.h
|
||||
|
||||
#ifndef __TEMPFILES_H
|
||||
#define __TEMPFILES_H
|
||||
|
||||
#include "Common/String.h"
|
||||
|
||||
class CTempFiles
|
||||
{
|
||||
void Clear();
|
||||
public:
|
||||
UStringVector Paths;
|
||||
~CTempFiles() { Clear(); }
|
||||
};
|
||||
|
||||
#endif
|
||||
850
7zip/UI/Common/Update.cpp
Executable file
850
7zip/UI/Common/Update.cpp
Executable file
@@ -0,0 +1,850 @@
|
||||
// Update.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <mapi.h>
|
||||
#endif
|
||||
|
||||
#include "Update.h"
|
||||
|
||||
#include "Common/IntToString.h"
|
||||
#include "Common/StringToInt.h"
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/CommandLineParser.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "Windows/DLL.h"
|
||||
#endif
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
#include "Windows/FileDir.h"
|
||||
#include "Windows/FileFind.h"
|
||||
#include "Windows/FileName.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "Windows/PropVariantConversions.h"
|
||||
// #include "Windows/Synchronization.h"
|
||||
|
||||
#include "../../Common/FileStreams.h"
|
||||
#include "../../Compress/Copy/CopyCoder.h"
|
||||
|
||||
#include "../Common/DirItem.h"
|
||||
#include "../Common/EnumDirItems.h"
|
||||
#include "../Common/UpdateProduce.h"
|
||||
#include "../Common/OpenArchive.h"
|
||||
|
||||
#include "TempFiles.h"
|
||||
#include "UpdateCallback.h"
|
||||
#include "EnumDirItems.h"
|
||||
|
||||
#ifdef FORMAT_7Z
|
||||
#include "../../Archive/7z/7zHandler.h"
|
||||
#endif
|
||||
|
||||
#ifdef FORMAT_BZIP2
|
||||
#include "../../Archive/BZip2/BZip2Handler.h"
|
||||
#endif
|
||||
|
||||
#ifdef FORMAT_GZIP
|
||||
#include "../../Archive/GZip/GZipHandler.h"
|
||||
#endif
|
||||
|
||||
#ifdef FORMAT_TAR
|
||||
#include "../../Archive/Tar/TarHandler.h"
|
||||
#endif
|
||||
|
||||
#ifdef FORMAT_ZIP
|
||||
#include "../../Archive/Zip/ZipHandler.h"
|
||||
#endif
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
#include "../Common/HandlerLoader.h"
|
||||
#endif
|
||||
|
||||
static const char *kUpdateIsNotSupoorted =
|
||||
"update operations are not supported for this archive";
|
||||
|
||||
using namespace NCommandLineParser;
|
||||
using namespace NWindows;
|
||||
using namespace NCOM;
|
||||
using namespace NFile;
|
||||
using namespace NName;
|
||||
|
||||
static const wchar_t *kTempArchiveFilePrefixString = L"7zi";
|
||||
static const wchar_t *kTempFolderPrefix = L"7zE";
|
||||
|
||||
static const char *kIllegalFileNameMessage = "Illegal file name for temp archive";
|
||||
|
||||
using namespace NUpdateArchive;
|
||||
|
||||
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())
|
||||
prop = s;
|
||||
else if (result <= 0xFFFFFFFF)
|
||||
prop = (UInt32)result;
|
||||
else
|
||||
prop = result;
|
||||
}
|
||||
|
||||
static HRESULT CopyBlock(ISequentialInStream *inStream, ISequentialOutStream *outStream)
|
||||
{
|
||||
CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
|
||||
return copyCoder->Code(inStream, outStream, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
class COutMultiVolStream:
|
||||
public IOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
size_t _streamIndex; // required stream
|
||||
UInt64 _offsetPos; // offset from start of _streamIndex index
|
||||
UInt64 _absPos;
|
||||
UInt64 _length;
|
||||
|
||||
struct CSubStreamInfo
|
||||
{
|
||||
CMyComPtr<IOutStream> Stream;
|
||||
UString Name;
|
||||
UInt64 Pos;
|
||||
UInt64 RealSize;
|
||||
};
|
||||
CObjectVector<CSubStreamInfo> Streams;
|
||||
public:
|
||||
// CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
|
||||
CRecordVector<UInt64> Sizes;
|
||||
UString Prefix;
|
||||
CTempFiles *TempFiles;
|
||||
|
||||
void Init()
|
||||
{
|
||||
_streamIndex = 0;
|
||||
_offsetPos = 0;
|
||||
_absPos = 0;
|
||||
_length = 0;
|
||||
}
|
||||
|
||||
MY_UNKNOWN_IMP1(IOutStream)
|
||||
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
|
||||
STDMETHOD(SetSize)(Int64 newSize);
|
||||
};
|
||||
|
||||
// static NSynchronization::CCriticalSection g_TempPathsCS;
|
||||
|
||||
STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
if(processedSize != NULL)
|
||||
*processedSize = 0;
|
||||
while(size > 0)
|
||||
{
|
||||
if (_streamIndex >= (size_t)Streams.Size())
|
||||
{
|
||||
CSubStreamInfo subStream;
|
||||
|
||||
wchar_t temp[32];
|
||||
ConvertUInt64ToString(_streamIndex + 1, temp);
|
||||
UString res = temp;
|
||||
while (res.Length() < 3)
|
||||
res = UString(L'0') + res;
|
||||
UString name = Prefix + res;
|
||||
COutFileStream *streamSpec = new COutFileStream;
|
||||
subStream.Stream = streamSpec;
|
||||
if(!streamSpec->Create(name, false))
|
||||
return ::GetLastError();
|
||||
{
|
||||
// NSynchronization::CCriticalSectionLock lock(g_TempPathsCS);
|
||||
TempFiles->Paths.Add(name);
|
||||
}
|
||||
|
||||
subStream.Pos = 0;
|
||||
subStream.RealSize = 0;
|
||||
subStream.Name = name;
|
||||
Streams.Add(subStream);
|
||||
continue;
|
||||
}
|
||||
CSubStreamInfo &subStream = Streams[_streamIndex];
|
||||
|
||||
int index = _streamIndex;
|
||||
if (index >= Sizes.Size())
|
||||
index = Sizes.Size() - 1;
|
||||
UInt64 volSize = Sizes[index];
|
||||
|
||||
if (_offsetPos >= volSize)
|
||||
{
|
||||
_offsetPos -= volSize;
|
||||
_streamIndex++;
|
||||
continue;
|
||||
}
|
||||
if (_offsetPos != subStream.Pos)
|
||||
{
|
||||
// CMyComPtr<IOutStream> outStream;
|
||||
// RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream));
|
||||
RINOK(subStream.Stream->Seek(_offsetPos, STREAM_SEEK_SET, NULL));
|
||||
subStream.Pos = _offsetPos;
|
||||
}
|
||||
|
||||
UInt32 curSize = (UInt32)MyMin((UInt64)size, volSize - subStream.Pos);
|
||||
UInt32 realProcessed;
|
||||
RINOK(subStream.Stream->Write(data, curSize, &realProcessed));
|
||||
data = (void *)((Byte *)data + realProcessed);
|
||||
size -= realProcessed;
|
||||
subStream.Pos += realProcessed;
|
||||
_offsetPos += realProcessed;
|
||||
_absPos += realProcessed;
|
||||
if (_absPos > _length)
|
||||
_length = _absPos;
|
||||
if (_offsetPos > subStream.RealSize)
|
||||
subStream.RealSize = _offsetPos;
|
||||
if(processedSize != NULL)
|
||||
*processedSize += realProcessed;
|
||||
if (subStream.Pos == volSize)
|
||||
{
|
||||
_streamIndex++;
|
||||
_offsetPos = 0;
|
||||
}
|
||||
if (realProcessed != curSize)
|
||||
return E_FAIL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP COutMultiVolStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
return Write(data, size, processedSize);
|
||||
}
|
||||
|
||||
STDMETHODIMP COutMultiVolStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
|
||||
{
|
||||
if(seekOrigin >= 3)
|
||||
return STG_E_INVALIDFUNCTION;
|
||||
switch(seekOrigin)
|
||||
{
|
||||
case STREAM_SEEK_SET:
|
||||
_absPos = offset;
|
||||
break;
|
||||
case STREAM_SEEK_CUR:
|
||||
_absPos += offset;
|
||||
break;
|
||||
case STREAM_SEEK_END:
|
||||
_absPos = _length + offset;
|
||||
break;
|
||||
}
|
||||
_offsetPos = _absPos;
|
||||
if (newPosition != NULL)
|
||||
*newPosition = _absPos;
|
||||
_streamIndex = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP COutMultiVolStream::SetSize(Int64 newSize)
|
||||
{
|
||||
if (newSize < 0)
|
||||
return E_INVALIDARG;
|
||||
int i = 0;
|
||||
while (i < Streams.Size())
|
||||
{
|
||||
CSubStreamInfo &subStream = Streams[i++];
|
||||
if ((UInt64)newSize < subStream.RealSize)
|
||||
{
|
||||
RINOK(subStream.Stream->SetSize(newSize));
|
||||
subStream.RealSize = newSize;
|
||||
break;
|
||||
}
|
||||
newSize -= subStream.RealSize;
|
||||
}
|
||||
while (i < Streams.Size())
|
||||
{
|
||||
{
|
||||
CSubStreamInfo &subStream = Streams.Back();
|
||||
subStream.Stream.Release();
|
||||
NDirectory::DeleteFileAlways(subStream.Name);
|
||||
}
|
||||
Streams.DeleteBack();
|
||||
}
|
||||
_offsetPos = _absPos;
|
||||
_streamIndex = 0;
|
||||
_length = newSize;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
static HRESULT Compress(
|
||||
const CActionSet &actionSet,
|
||||
IInArchive *archive,
|
||||
const CCompressionMethodMode &compressionMethod,
|
||||
CArchivePath &archivePath,
|
||||
const CObjectVector<CArchiveItem> &archiveItems,
|
||||
bool stdInMode,
|
||||
const UString &stdInFileName,
|
||||
bool stdOutMode,
|
||||
const CObjectVector<CDirItem> &dirItems,
|
||||
bool sfxMode,
|
||||
const UString &sfxModule,
|
||||
const CRecordVector<UInt64> &volumesSizes,
|
||||
CTempFiles &tempFiles,
|
||||
CUpdateErrorInfo &errorInfo,
|
||||
IUpdateCallbackUI *callback)
|
||||
{
|
||||
#ifndef EXCLUDE_COM
|
||||
CHandlerLoader loader;
|
||||
#endif
|
||||
|
||||
CMyComPtr<IOutArchive> outArchive;
|
||||
if(archive != NULL)
|
||||
{
|
||||
CMyComPtr<IInArchive> archive2 = archive;
|
||||
HRESULT result = archive2.QueryInterface(IID_IOutArchive, &outArchive);
|
||||
if(result != S_OK)
|
||||
throw kUpdateIsNotSupoorted;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef EXCLUDE_COM
|
||||
|
||||
if (loader.CreateHandler(compressionMethod.FilePath,
|
||||
compressionMethod.ClassID, (void **)&outArchive, true) != S_OK)
|
||||
throw kUpdateIsNotSupoorted;
|
||||
#endif
|
||||
|
||||
#ifdef FORMAT_7Z
|
||||
if (compressionMethod.Name.CompareNoCase(L"7z") == 0)
|
||||
outArchive = new NArchive::N7z::CHandler;
|
||||
#endif
|
||||
|
||||
#ifdef FORMAT_BZIP2
|
||||
if (compressionMethod.Name.CompareNoCase(L"BZip2") == 0)
|
||||
outArchive = new NArchive::NBZip2::CHandler;
|
||||
#endif
|
||||
|
||||
#ifdef FORMAT_GZIP
|
||||
if (compressionMethod.Name.CompareNoCase(L"GZip") == 0)
|
||||
outArchive = new NArchive::NGZip::CHandler;
|
||||
#endif
|
||||
|
||||
#ifdef FORMAT_TAR
|
||||
if (compressionMethod.Name.CompareNoCase(L"Tar") == 0)
|
||||
outArchive = new NArchive::NTar::CHandler;
|
||||
#endif
|
||||
|
||||
#ifdef FORMAT_ZIP
|
||||
if (compressionMethod.Name.CompareNoCase(L"Zip") == 0)
|
||||
outArchive = new NArchive::NZip::CHandler;
|
||||
#endif
|
||||
|
||||
}
|
||||
if (outArchive == 0)
|
||||
throw kUpdateIsNotSupoorted;
|
||||
|
||||
NFileTimeType::EEnum fileTimeType;
|
||||
UInt32 value;
|
||||
RINOK(outArchive->GetFileTimeType(&value));
|
||||
|
||||
switch(value)
|
||||
{
|
||||
case NFileTimeType::kWindows:
|
||||
case NFileTimeType::kDOS:
|
||||
case NFileTimeType::kUnix:
|
||||
fileTimeType = NFileTimeType::EEnum(value);
|
||||
break;
|
||||
default:
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
CObjectVector<CUpdatePair> updatePairs;
|
||||
GetUpdatePairInfoList(dirItems, archiveItems, fileTimeType, updatePairs); // must be done only once!!!
|
||||
|
||||
CObjectVector<CUpdatePair2> updatePairs2;
|
||||
UpdateProduce(dirItems, archiveItems, updatePairs, actionSet, updatePairs2);
|
||||
|
||||
CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
|
||||
CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec );
|
||||
|
||||
updateCallbackSpec->StdInMode = stdInMode;
|
||||
updateCallbackSpec->Callback = callback;
|
||||
updateCallbackSpec->DirItems = &dirItems;
|
||||
updateCallbackSpec->ArchiveItems = &archiveItems;
|
||||
updateCallbackSpec->UpdatePairs = &updatePairs2;
|
||||
|
||||
CMyComPtr<ISequentialOutStream> outStream;
|
||||
|
||||
const UString &archiveName = archivePath.GetFinalPath();
|
||||
if (!stdOutMode)
|
||||
{
|
||||
UString resultPath;
|
||||
int pos;
|
||||
if(!NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos))
|
||||
throw 1417161;
|
||||
NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos));
|
||||
}
|
||||
if (volumesSizes.Size() == 0)
|
||||
{
|
||||
if (stdOutMode)
|
||||
outStream = new CStdOutFileStream;
|
||||
else
|
||||
{
|
||||
COutFileStream *outStreamSpec = new COutFileStream;
|
||||
outStream = outStreamSpec;
|
||||
bool isOK = false;
|
||||
UString realPath;
|
||||
for (int i = 0; i < (1 << 16); i++)
|
||||
{
|
||||
if (archivePath.Temp)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
wchar_t s[32];
|
||||
ConvertUInt64ToString(i, s);
|
||||
archivePath.TempPostfix = s;
|
||||
}
|
||||
realPath = archivePath.GetTempPath();
|
||||
}
|
||||
else
|
||||
realPath = archivePath.GetFinalPath();
|
||||
if (outStreamSpec->Create(realPath, false))
|
||||
{
|
||||
tempFiles.Paths.Add(realPath);
|
||||
isOK = true;
|
||||
break;
|
||||
}
|
||||
if (::GetLastError() != ERROR_FILE_EXISTS)
|
||||
break;
|
||||
if (!archivePath.Temp)
|
||||
break;
|
||||
}
|
||||
if (!isOK)
|
||||
{
|
||||
errorInfo.SystemError = ::GetLastError();
|
||||
errorInfo.FileName = realPath;
|
||||
errorInfo.Message = L"Can not open file";
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (stdOutMode)
|
||||
return E_FAIL;
|
||||
COutMultiVolStream *volStreamSpec = new COutMultiVolStream;
|
||||
outStream = volStreamSpec;
|
||||
volStreamSpec->Sizes = volumesSizes;
|
||||
volStreamSpec->Prefix = archivePath.GetFinalPath() + UString(L".");
|
||||
volStreamSpec->TempFiles = &tempFiles;
|
||||
volStreamSpec->Init();
|
||||
|
||||
/*
|
||||
updateCallbackSpec->VolumesSizes = volumesSizes;
|
||||
updateCallbackSpec->VolName = archivePath.Prefix + archivePath.Name;
|
||||
if (!archivePath.VolExtension.IsEmpty())
|
||||
updateCallbackSpec->VolExt = UString(L'.') + archivePath.VolExtension;
|
||||
*/
|
||||
}
|
||||
|
||||
CMyComPtr<ISetProperties> setProperties;
|
||||
if (outArchive.QueryInterface(IID_ISetProperties, &setProperties) == S_OK)
|
||||
{
|
||||
UStringVector realNames;
|
||||
CPropVariant *values = new CPropVariant[compressionMethod.Properties.Size()];
|
||||
try
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < compressionMethod.Properties.Size(); i++)
|
||||
{
|
||||
const CProperty &property = compressionMethod.Properties[i];
|
||||
NCOM::CPropVariant propVariant;
|
||||
if (!property.Value.IsEmpty())
|
||||
ParseNumberString(property.Value, propVariant);
|
||||
realNames.Add(property.Name);
|
||||
values[i] = propVariant;
|
||||
}
|
||||
CRecordVector<const wchar_t *> names;
|
||||
for(i = 0; i < realNames.Size(); i++)
|
||||
names.Add((const wchar_t *)realNames[i]);
|
||||
|
||||
RINOK(setProperties->SetProperties(&names.Front(), values, names.Size()));
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
delete []values;
|
||||
throw;
|
||||
}
|
||||
delete []values;
|
||||
}
|
||||
|
||||
if (sfxMode)
|
||||
{
|
||||
CInFileStream *sfxStreamSpec = new CInFileStream;
|
||||
CMyComPtr<IInStream> sfxStream(sfxStreamSpec);
|
||||
if (!sfxStreamSpec->Open(sfxModule))
|
||||
{
|
||||
errorInfo.SystemError = ::GetLastError();
|
||||
errorInfo.Message = L"Can't open sfx module";
|
||||
errorInfo.FileName = sfxModule;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
CMyComPtr<ISequentialOutStream> sfxOutStream;
|
||||
if (volumesSizes.Size() == 0)
|
||||
sfxOutStream = outStream;
|
||||
else
|
||||
{
|
||||
COutFileStream *outStreamSpec = new COutFileStream;
|
||||
sfxOutStream = outStreamSpec;
|
||||
UString realPath = archivePath.GetFinalPath();
|
||||
if (!outStreamSpec->Create(realPath, false))
|
||||
{
|
||||
errorInfo.SystemError = ::GetLastError();
|
||||
errorInfo.FileName = realPath;
|
||||
errorInfo.Message = L"Can not open file";
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
RINOK(CopyBlock(sfxStream, sfxOutStream));
|
||||
}
|
||||
|
||||
HRESULT result = outArchive->UpdateItems(outStream, updatePairs2.Size(),
|
||||
updateCallback);
|
||||
callback->Finilize();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
HRESULT EnumerateInArchiveItems(const NWildcard::CCensor &censor,
|
||||
IInArchive *archive,
|
||||
const UString &defaultItemName,
|
||||
const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo,
|
||||
CObjectVector<CArchiveItem> &archiveItems)
|
||||
{
|
||||
archiveItems.Clear();
|
||||
UInt32 numItems;
|
||||
RINOK(archive->GetNumberOfItems(&numItems));
|
||||
archiveItems.Reserve(numItems);
|
||||
for(UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
CArchiveItem ai;
|
||||
|
||||
RINOK(GetArchiveItemPath(archive, i, defaultItemName, ai.Name));
|
||||
RINOK(IsArchiveItemFolder(archive, i, ai.IsDirectory));
|
||||
ai.Censored = censor.CheckPath(ai.Name, !ai.IsDirectory);
|
||||
RINOK(GetArchiveItemFileTime(archive, i,
|
||||
archiveFileInfo.LastWriteTime, ai.LastWriteTime));
|
||||
|
||||
CPropVariant propertySize;
|
||||
RINOK(archive->GetProperty(i, kpidSize, &propertySize));
|
||||
if (ai.SizeIsDefined = (propertySize.vt != VT_EMPTY))
|
||||
ai.Size = ConvertPropVariantToUInt64(propertySize);
|
||||
|
||||
ai.IndexInServer = i;
|
||||
archiveItems.Add(ai);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
static HRESULT UpdateWithItemLists(
|
||||
CUpdateOptions &options,
|
||||
IInArchive *archive,
|
||||
const CObjectVector<CArchiveItem> &archiveItems,
|
||||
const CObjectVector<CDirItem> &dirItems,
|
||||
CTempFiles &tempFiles,
|
||||
CUpdateErrorInfo &errorInfo,
|
||||
IUpdateCallbackUI2 *callback)
|
||||
{
|
||||
for(int i = 0; i < options.Commands.Size(); i++)
|
||||
{
|
||||
CUpdateArchiveCommand &command = options.Commands[i];
|
||||
if (options.StdOutMode)
|
||||
{
|
||||
RINOK(callback->StartArchive(0, archive != 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(callback->StartArchive(command.ArchivePath.GetFinalPath(),
|
||||
i == 0 && options.UpdateArchiveItself && archive != 0));
|
||||
}
|
||||
|
||||
RINOK(Compress(command.ActionSet, archive,
|
||||
options.MethodMode,
|
||||
command.ArchivePath,
|
||||
archiveItems,
|
||||
options.StdInMode, options.StdInFileName,
|
||||
options.StdOutMode,
|
||||
dirItems,
|
||||
options.SfxMode, options.SfxModule,
|
||||
options.VolumesSizes,
|
||||
tempFiles,
|
||||
errorInfo, callback));
|
||||
|
||||
RINOK(callback->FinishArchive());
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
class CCurrentDirRestorer
|
||||
{
|
||||
CSysString m_CurrentDirectory;
|
||||
public:
|
||||
CCurrentDirRestorer()
|
||||
{ NFile::NDirectory::MyGetCurrentDirectory(m_CurrentDirectory); }
|
||||
~CCurrentDirRestorer()
|
||||
{ RestoreDirectory();}
|
||||
bool RestoreDirectory()
|
||||
{ return BOOLToBool(::SetCurrentDirectory(m_CurrentDirectory)); }
|
||||
};
|
||||
#endif
|
||||
|
||||
struct CEnumDirItemUpdateCallback: public IEnumDirItemCallback
|
||||
{
|
||||
IUpdateCallbackUI2 *Callback;
|
||||
HRESULT CheckBreak() { return Callback->CheckBreak(); }
|
||||
};
|
||||
|
||||
HRESULT UpdateArchive(const NWildcard::CCensor &censor,
|
||||
CUpdateOptions &options,
|
||||
CUpdateErrorInfo &errorInfo,
|
||||
IOpenCallbackUI *openCallback,
|
||||
IUpdateCallbackUI2 *callback)
|
||||
{
|
||||
if (options.StdOutMode && options.EMailMode)
|
||||
return E_FAIL;
|
||||
|
||||
if (options.VolumesSizes.Size() > 0 && (options.EMailMode || options.SfxMode))
|
||||
return E_NOTIMPL;
|
||||
|
||||
if (options.SfxMode)
|
||||
{
|
||||
CProperty property;
|
||||
property.Name = L"rsfx";
|
||||
property.Value = L"on";
|
||||
options.MethodMode.Properties.Add(property);
|
||||
if (options.SfxModule.IsEmpty())
|
||||
{
|
||||
errorInfo.Message = L"sfx file is not specified";
|
||||
return E_FAIL;
|
||||
}
|
||||
UString name = options.SfxModule;
|
||||
if (!NDirectory::MySearchPath(NULL, name, NULL, options.SfxModule))
|
||||
{
|
||||
errorInfo.Message = L"can't find specified sfx module";
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
const UString archiveName = options.ArchivePath.GetFinalPath();
|
||||
|
||||
UString defaultItemName;
|
||||
NFind::CFileInfoW archiveFileInfo;
|
||||
|
||||
CArchiveLink archiveLink;
|
||||
IInArchive *archive = 0;
|
||||
if (NFind::FindFile(archiveName, archiveFileInfo))
|
||||
{
|
||||
if (archiveFileInfo.IsDirectory())
|
||||
throw "there is no such archive";
|
||||
if (options.VolumesSizes.Size() > 0)
|
||||
return E_NOTIMPL;
|
||||
HRESULT result = MyOpenArchive(archiveName, archiveLink, openCallback);
|
||||
RINOK(callback->OpenResult(archiveName, result));
|
||||
RINOK(result);
|
||||
if (archiveLink.VolumePaths.Size() > 1)
|
||||
{
|
||||
errorInfo.SystemError = E_NOTIMPL;
|
||||
errorInfo.Message = L"Updating for multivolume archives is not implemented";
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
archive = archiveLink.GetArchive();
|
||||
defaultItemName = archiveLink.GetDefaultItemName();
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
if (archiveType.IsEmpty())
|
||||
throw "type of archive is not specified";
|
||||
*/
|
||||
}
|
||||
|
||||
CObjectVector<CDirItem> dirItems;
|
||||
if (options.StdInMode)
|
||||
{
|
||||
CDirItem item;
|
||||
item.FullPath = item.Name = options.StdInFileName;
|
||||
item.Size = (UInt64)(Int64)-1;
|
||||
item.Attributes = 0;
|
||||
SYSTEMTIME st;
|
||||
FILETIME ft;
|
||||
GetSystemTime(&st);
|
||||
SystemTimeToFileTime(&st, &ft);
|
||||
item.CreationTime = item.LastAccessTime = item.LastWriteTime = ft;
|
||||
dirItems.Add(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool needScanning = false;
|
||||
for(int i = 0; i < options.Commands.Size(); i++)
|
||||
if (options.Commands[i].ActionSet.NeedScanning())
|
||||
needScanning = true;
|
||||
if (needScanning)
|
||||
{
|
||||
CEnumDirItemUpdateCallback enumCallback;
|
||||
enumCallback.Callback = callback;
|
||||
RINOK(callback->StartScanning());
|
||||
RINOK(EnumerateItems(censor, dirItems, &enumCallback));
|
||||
RINOK(callback->FinishScanning());
|
||||
}
|
||||
}
|
||||
|
||||
UString tempDirPrefix;
|
||||
bool usesTempDir = false;
|
||||
|
||||
#ifdef _WIN32
|
||||
NDirectory::CTempDirectoryW tempDirectory;
|
||||
if (options.EMailMode && options.EMailRemoveAfter)
|
||||
{
|
||||
tempDirectory.Create(kTempFolderPrefix);
|
||||
tempDirPrefix = tempDirectory.GetPath();
|
||||
NormalizeDirPathPrefix(tempDirPrefix);
|
||||
usesTempDir = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
CTempFiles tempFiles;
|
||||
|
||||
bool createTempFile = false;
|
||||
if(!options.StdOutMode && options.UpdateArchiveItself)
|
||||
{
|
||||
CArchivePath &ap = options.Commands[0].ArchivePath;
|
||||
ap = options.ArchivePath;
|
||||
// if ((archive != 0 && !usesTempDir) || !options.WorkingDir.IsEmpty())
|
||||
if ((archive != 0 || !options.WorkingDir.IsEmpty()) && !usesTempDir && options.VolumesSizes.Size() == 0)
|
||||
{
|
||||
createTempFile = true;
|
||||
ap.Temp = true;
|
||||
if (!options.WorkingDir.IsEmpty())
|
||||
{
|
||||
ap.TempPrefix = options.WorkingDir;
|
||||
NormalizeDirPathPrefix(ap.TempPrefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < options.Commands.Size(); i++)
|
||||
{
|
||||
CArchivePath &ap = options.Commands[i].ArchivePath;
|
||||
if (usesTempDir)
|
||||
{
|
||||
// Check it
|
||||
ap.Prefix = tempDirPrefix;
|
||||
// ap.Temp = true;
|
||||
// ap.TempPrefix = tempDirPrefix;
|
||||
}
|
||||
if (i > 0 || !createTempFile)
|
||||
{
|
||||
const UString &path = ap.GetFinalPath();
|
||||
if (NFind::DoesFileExist(path))
|
||||
{
|
||||
errorInfo.SystemError = 0;
|
||||
errorInfo.Message = L"File already exists";
|
||||
errorInfo.FileName = path;
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CObjectVector<CArchiveItem> archiveItems;
|
||||
if (archive != NULL)
|
||||
{
|
||||
RINOK(EnumerateInArchiveItems(censor,
|
||||
archive, defaultItemName, archiveFileInfo, archiveItems));
|
||||
}
|
||||
|
||||
RINOK(UpdateWithItemLists(options, archive, archiveItems, dirItems,
|
||||
tempFiles, errorInfo, callback));
|
||||
|
||||
if (archive != NULL)
|
||||
{
|
||||
RINOK(archiveLink.Close());
|
||||
archiveLink.Release();
|
||||
}
|
||||
|
||||
tempFiles.Paths.Clear();
|
||||
if(createTempFile)
|
||||
{
|
||||
try
|
||||
{
|
||||
CArchivePath &ap = options.Commands[0].ArchivePath;
|
||||
const UString &tempPath = ap.GetTempPath();
|
||||
if (archive != NULL)
|
||||
if (!NDirectory::DeleteFileAlways(archiveName))
|
||||
{
|
||||
errorInfo.SystemError = ::GetLastError();
|
||||
errorInfo.Message = L"delete file error";
|
||||
errorInfo.FileName = archiveName;
|
||||
return E_FAIL;
|
||||
}
|
||||
if (!NDirectory::MyMoveFile(tempPath, archiveName))
|
||||
{
|
||||
errorInfo.SystemError = ::GetLastError();
|
||||
errorInfo.Message = L"move file error";
|
||||
errorInfo.FileName = tempPath;
|
||||
errorInfo.FileName2 = archiveName;
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if (options.EMailMode)
|
||||
{
|
||||
NDLL::CLibrary mapiLib;
|
||||
if (!mapiLib.Load(TEXT("Mapi32.dll")))
|
||||
{
|
||||
errorInfo.SystemError = ::GetLastError();
|
||||
errorInfo.Message = L"can not load Mapi32.dll";
|
||||
return E_FAIL;
|
||||
}
|
||||
LPMAPISENDDOCUMENTS fnSend = (LPMAPISENDDOCUMENTS)
|
||||
mapiLib.GetProcAddress("MAPISendDocuments");
|
||||
if (fnSend == 0)
|
||||
{
|
||||
errorInfo.SystemError = ::GetLastError();
|
||||
errorInfo.Message = L"can not find MAPISendDocuments function";
|
||||
return E_FAIL;
|
||||
}
|
||||
UStringVector fullPaths;
|
||||
int i;
|
||||
for(i = 0; i < options.Commands.Size(); i++)
|
||||
{
|
||||
CArchivePath &ap = options.Commands[i].ArchivePath;
|
||||
UString arcPath;
|
||||
if(!NFile::NDirectory::MyGetFullPathName(ap.GetFinalPath(), arcPath))
|
||||
{
|
||||
errorInfo.SystemError = ::GetLastError();
|
||||
return E_FAIL;
|
||||
}
|
||||
fullPaths.Add(arcPath);
|
||||
}
|
||||
CCurrentDirRestorer curDirRestorer;
|
||||
for(i = 0; i < fullPaths.Size(); i++)
|
||||
{
|
||||
UString arcPath = fullPaths[i];
|
||||
UString fileName = ExtractFileNameFromPath(arcPath);
|
||||
AString path = GetAnsiString(arcPath);
|
||||
AString name = GetAnsiString(fileName);
|
||||
// Warning!!! MAPISendDocuments function changes Current directory
|
||||
fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
157
7zip/UI/Common/Update.h
Executable file
157
7zip/UI/Common/Update.h
Executable file
@@ -0,0 +1,157 @@
|
||||
// Update.h
|
||||
|
||||
#ifndef __UPDATE_H
|
||||
#define __UPDATE_H
|
||||
|
||||
#include "Common/Wildcard.h"
|
||||
#include "Windows/FileFind.h"
|
||||
#include "../../Archive/IArchive.h"
|
||||
|
||||
#include "UpdateAction.h"
|
||||
#include "ArchiveOpenCallback.h"
|
||||
#include "UpdateCallback.h"
|
||||
|
||||
struct CArchivePath
|
||||
{
|
||||
UString Prefix; // path(folder) prefix including slash
|
||||
UString Name; // base name
|
||||
UString BaseExtension; // archive type extension or "exe" extension
|
||||
UString VolExtension; // archive type extension for volumes
|
||||
|
||||
bool Temp;
|
||||
UString TempPrefix; // path(folder) for temp location
|
||||
UString TempPostfix;
|
||||
|
||||
CArchivePath(): Temp(false) {};
|
||||
|
||||
void ParseFromPath(const UString &path)
|
||||
{
|
||||
SplitPathToParts(path, Prefix, Name);
|
||||
if (Name.IsEmpty())
|
||||
return;
|
||||
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)
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
UString GetTempPath() const
|
||||
{
|
||||
UString path = TempPrefix + Name;
|
||||
if (!BaseExtension.IsEmpty())
|
||||
path += UString(L'.') + BaseExtension;
|
||||
path += L".tmp";
|
||||
path += TempPostfix;
|
||||
return path;
|
||||
}
|
||||
};
|
||||
|
||||
struct CUpdateArchiveCommand
|
||||
{
|
||||
CArchivePath ArchivePath;
|
||||
NUpdateArchive::CActionSet ActionSet;
|
||||
};
|
||||
|
||||
struct CProperty
|
||||
{
|
||||
UString Name;
|
||||
UString Value;
|
||||
};
|
||||
|
||||
struct CCompressionMethodMode
|
||||
{
|
||||
#ifndef EXCLUDE_COM
|
||||
UString FilePath;
|
||||
CLSID ClassID;
|
||||
#else
|
||||
UString Name;
|
||||
#endif
|
||||
CObjectVector<CProperty> Properties;
|
||||
};
|
||||
|
||||
struct CUpdateOptions
|
||||
{
|
||||
CCompressionMethodMode MethodMode;
|
||||
|
||||
CObjectVector<CUpdateArchiveCommand> Commands;
|
||||
bool UpdateArchiveItself;
|
||||
CArchivePath ArchivePath;
|
||||
|
||||
bool SfxMode;
|
||||
UString SfxModule;
|
||||
|
||||
bool StdInMode;
|
||||
UString StdInFileName;
|
||||
bool StdOutMode;
|
||||
|
||||
bool EMailMode;
|
||||
bool EMailRemoveAfter;
|
||||
UString EMailAddress;
|
||||
|
||||
UString WorkingDir;
|
||||
|
||||
CUpdateOptions():
|
||||
UpdateArchiveItself(true),
|
||||
SfxMode(false),
|
||||
StdInMode(false),
|
||||
StdOutMode(false),
|
||||
EMailMode(false),
|
||||
EMailRemoveAfter(false)
|
||||
{};
|
||||
CRecordVector<UInt64> VolumesSizes;
|
||||
};
|
||||
|
||||
struct CErrorInfo
|
||||
{
|
||||
DWORD SystemError;
|
||||
UString FileName;
|
||||
UString FileName2;
|
||||
UString Message;
|
||||
CErrorInfo(): SystemError(0) {};
|
||||
};
|
||||
|
||||
struct CUpdateErrorInfo: public CErrorInfo
|
||||
{
|
||||
};
|
||||
|
||||
struct IUpdateCallbackUI2: public IUpdateCallbackUI
|
||||
{
|
||||
virtual HRESULT OpenResult(const wchar_t *name, HRESULT result) = 0;
|
||||
|
||||
virtual HRESULT StartScanning() = 0;
|
||||
virtual HRESULT FinishScanning() = 0;
|
||||
|
||||
virtual HRESULT StartArchive(const wchar_t *name, bool updating) = 0;
|
||||
virtual HRESULT FinishArchive() = 0;
|
||||
};
|
||||
|
||||
HRESULT UpdateArchive(const NWildcard::CCensor &censor,
|
||||
CUpdateOptions &options,
|
||||
CUpdateErrorInfo &errorInfo,
|
||||
IOpenCallbackUI *openCallback,
|
||||
IUpdateCallbackUI2 *callback);
|
||||
|
||||
#endif
|
||||
@@ -1,7 +1,5 @@
|
||||
// UpdateAction.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __UPDATE_ACTION_H
|
||||
#define __UPDATE_ACTION_H
|
||||
|
||||
@@ -34,6 +32,17 @@ namespace NUpdateArchive {
|
||||
struct CActionSet
|
||||
{
|
||||
NPairAction::EEnum StateActions[NPairState::kNumValues];
|
||||
bool NeedScanning() const
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < NPairState::kNumValues; i++)
|
||||
if (StateActions[i] == NPairAction::kCompress)
|
||||
return true;
|
||||
for (i = 1; i < NPairState::kNumValues; i++)
|
||||
if (StateActions[i] != NPairAction::kIgnore)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
extern const CActionSet kAddActionSet;
|
||||
extern const CActionSet kUpdateActionSet;
|
||||
|
||||
242
7zip/UI/Common/UpdateCallback.cpp
Executable file
242
7zip/UI/Common/UpdateCallback.cpp
Executable file
@@ -0,0 +1,242 @@
|
||||
// UpdateCallback.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "UpdateCallback.h"
|
||||
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/IntToString.h"
|
||||
#include "Common/Defs.h"
|
||||
|
||||
#include "Windows/PropVariant.h"
|
||||
|
||||
#include "../../Common/FileStreams.h"
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
CArchiveUpdateCallback::CArchiveUpdateCallback():
|
||||
Callback(0),
|
||||
StdInMode(false),
|
||||
DirItems(0),
|
||||
ArchiveItems(0),
|
||||
UpdatePairs(0)
|
||||
{}
|
||||
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size)
|
||||
{
|
||||
return Callback->SetTotal(size);
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue)
|
||||
{
|
||||
return Callback->SetCompleted(completeValue);
|
||||
}
|
||||
|
||||
/*
|
||||
STATPROPSTG kProperties[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
{ NULL, kpidIsFolder, VT_BOOL},
|
||||
{ NULL, kpidSize, VT_UI8},
|
||||
{ NULL, kpidLastAccessTime, VT_FILETIME},
|
||||
{ NULL, kpidCreationTime, VT_FILETIME},
|
||||
{ NULL, kpidLastWriteTime, VT_FILETIME},
|
||||
{ NULL, kpidAttributes, VT_UI4},
|
||||
{ NULL, kpidIsAnti, VT_BOOL}
|
||||
};
|
||||
*/
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **enumerator)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
/*
|
||||
return CStatPropEnumerator::CreateEnumerator(kProperties,
|
||||
sizeof(kProperties) / sizeof(kProperties[0]), enumerator);
|
||||
*/
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index,
|
||||
Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive)
|
||||
{
|
||||
RINOK(Callback->CheckBreak());
|
||||
const CUpdatePair2 &updatePair = (*UpdatePairs)[index];
|
||||
if(newData != NULL)
|
||||
*newData = BoolToInt(updatePair.NewData);
|
||||
if(newProperties != NULL)
|
||||
*newProperties = BoolToInt(updatePair.NewProperties);
|
||||
if(indexInArchive != NULL)
|
||||
{
|
||||
if (updatePair.ExistInArchive)
|
||||
{
|
||||
if (ArchiveItems == 0)
|
||||
*indexInArchive = updatePair.ArchiveItemIndex;
|
||||
else
|
||||
*indexInArchive = (*ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer;
|
||||
}
|
||||
else
|
||||
*indexInArchive = UInt32(-1);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
const CUpdatePair2 &updatePair = (*UpdatePairs)[index];
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
|
||||
if (propID == kpidIsAnti)
|
||||
{
|
||||
propVariant = updatePair.IsAnti;
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (updatePair.IsAnti)
|
||||
{
|
||||
switch(propID)
|
||||
{
|
||||
case kpidIsFolder:
|
||||
case kpidPath:
|
||||
break;
|
||||
case kpidSize:
|
||||
propVariant = (UInt64)0;
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
default:
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if(updatePair.ExistOnDisk)
|
||||
{
|
||||
const CDirItem &dirItem = (*DirItems)[updatePair.DirItemIndex];
|
||||
switch(propID)
|
||||
{
|
||||
case kpidPath:
|
||||
propVariant = dirItem.Name;
|
||||
break;
|
||||
case kpidIsFolder:
|
||||
propVariant = dirItem.IsDirectory();
|
||||
break;
|
||||
case kpidSize:
|
||||
propVariant = dirItem.Size;
|
||||
break;
|
||||
case kpidAttributes:
|
||||
propVariant = dirItem.Attributes;
|
||||
break;
|
||||
case kpidLastAccessTime:
|
||||
propVariant = dirItem.LastAccessTime;
|
||||
break;
|
||||
case kpidCreationTime:
|
||||
propVariant = dirItem.CreationTime;
|
||||
break;
|
||||
case kpidLastWriteTime:
|
||||
propVariant = dirItem.LastWriteTime;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (propID == kpidPath)
|
||||
{
|
||||
if (updatePair.NewNameIsDefined)
|
||||
{
|
||||
propVariant = updatePair.NewName;
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
if (updatePair.ExistInArchive && Archive)
|
||||
{
|
||||
UInt32 indexInArchive;
|
||||
if (ArchiveItems == 0)
|
||||
indexInArchive = updatePair.ArchiveItemIndex;
|
||||
else
|
||||
indexInArchive = (*ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer;
|
||||
return Archive->GetProperty(indexInArchive, propID, value);
|
||||
}
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index,
|
||||
ISequentialInStream **inStream)
|
||||
{
|
||||
const CUpdatePair2 &updatePair = (*UpdatePairs)[index];
|
||||
if(!updatePair.NewData)
|
||||
return E_FAIL;
|
||||
|
||||
RINOK(Callback->CheckBreak());
|
||||
RINOK(Callback->Finilize());
|
||||
|
||||
if(updatePair.IsAnti)
|
||||
{
|
||||
return Callback->GetStream((*ArchiveItems)[updatePair.ArchiveItemIndex].Name, true);
|
||||
}
|
||||
const CDirItem &dirItem = (*DirItems)[updatePair.DirItemIndex];
|
||||
RINOK(Callback->GetStream(dirItem.Name, false));
|
||||
|
||||
if(dirItem.IsDirectory())
|
||||
return S_OK;
|
||||
|
||||
if (StdInMode)
|
||||
{
|
||||
CStdInFileStream *inStreamSpec = new CStdInFileStream;
|
||||
CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
|
||||
*inStream = inStreamLoc.Detach();
|
||||
}
|
||||
else
|
||||
{
|
||||
CInFileStream *inStreamSpec = new CInFileStream;
|
||||
CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
|
||||
UString path = DirPrefix + dirItem.FullPath;
|
||||
if(!inStreamSpec->Open(path))
|
||||
{
|
||||
return Callback->OpenFileError(path, ::GetLastError());
|
||||
}
|
||||
*inStream = inStreamLoc.Detach();
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 operationResult)
|
||||
{
|
||||
return Callback->SetOperationResult(operationResult);
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)
|
||||
{
|
||||
if (VolumesSizes.Size() == 0)
|
||||
return S_FALSE;
|
||||
if (index >= (UInt32)VolumesSizes.Size())
|
||||
index = VolumesSizes.Size() - 1;
|
||||
*size = VolumesSizes[index];
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)
|
||||
{
|
||||
wchar_t temp[32];
|
||||
ConvertUInt64ToString(index + 1, temp);
|
||||
UString res = temp;
|
||||
while (res.Length() < 2)
|
||||
res = UString(L'0') + res;
|
||||
UString fileName = VolName;
|
||||
fileName += L'.';
|
||||
fileName += res;
|
||||
fileName += VolExt;
|
||||
COutFileStream *streamSpec = new COutFileStream;
|
||||
CMyComPtr<ISequentialOutStream> streamLoc(streamSpec);
|
||||
if(!streamSpec->Create(fileName, false))
|
||||
return ::GetLastError();
|
||||
*volumeStream = streamLoc.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
|
||||
{
|
||||
return Callback->CryptoGetTextPassword2(passwordIsDefined, password);
|
||||
}
|
||||
70
7zip/UI/Common/UpdateCallback.h
Executable file
70
7zip/UI/Common/UpdateCallback.h
Executable file
@@ -0,0 +1,70 @@
|
||||
// UpdateCallback.h
|
||||
|
||||
#ifndef __UPDATECALLBACK_H
|
||||
#define __UPDATECALLBACK_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "Common/String.h"
|
||||
|
||||
#include "../../IPassword.h"
|
||||
|
||||
#include "../Common/UpdatePair.h"
|
||||
#include "../Common/UpdateProduce.h"
|
||||
|
||||
struct IUpdateCallbackUI
|
||||
{
|
||||
virtual HRESULT SetTotal(UInt64 size) = 0;
|
||||
virtual HRESULT SetCompleted(const UInt64 *completeValue) = 0;
|
||||
virtual HRESULT CheckBreak() = 0;
|
||||
virtual HRESULT Finilize() = 0;
|
||||
virtual HRESULT GetStream(const wchar_t *name, bool isAnti) = 0;
|
||||
virtual HRESULT OpenFileError(const wchar_t *name, DWORD systemError) = 0;
|
||||
virtual HRESULT SetOperationResult(Int32 operationResult) = 0;
|
||||
virtual HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) = 0;
|
||||
virtual HRESULT CloseProgress() { return S_OK; };
|
||||
};
|
||||
|
||||
class CArchiveUpdateCallback:
|
||||
public IArchiveUpdateCallback2,
|
||||
public ICryptoGetTextPassword2,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP2(IArchiveUpdateCallback2,
|
||||
ICryptoGetTextPassword2)
|
||||
|
||||
// IProgress
|
||||
STDMETHOD(SetTotal)(UInt64 size);
|
||||
STDMETHOD(SetCompleted)(const UInt64 *completeValue);
|
||||
|
||||
// IUpdateCallback
|
||||
STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator);
|
||||
STDMETHOD(GetUpdateItemInfo)(UInt32 index,
|
||||
Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive);
|
||||
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
|
||||
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream);
|
||||
STDMETHOD(SetOperationResult)(Int32 operationResult);
|
||||
|
||||
STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size);
|
||||
STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream);
|
||||
|
||||
STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password);
|
||||
|
||||
public:
|
||||
CRecordVector<UInt64> VolumesSizes;
|
||||
UString VolName;
|
||||
UString VolExt;
|
||||
|
||||
IUpdateCallbackUI *Callback;
|
||||
|
||||
UString DirPrefix;
|
||||
bool StdInMode;
|
||||
const CObjectVector<CDirItem> *DirItems;
|
||||
const CObjectVector<CArchiveItem> *ArchiveItems;
|
||||
const CObjectVector<CUpdatePair2> *UpdatePairs;
|
||||
CMyComPtr<IInArchive> Archive;
|
||||
|
||||
CArchiveUpdateCallback();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "SortUtils.h"
|
||||
|
||||
using namespace NWindows;
|
||||
// using namespace NCOM;
|
||||
using namespace NTime;
|
||||
|
||||
static int MyCompareTime(NFileTimeType::EEnum fileTimeType,
|
||||
@@ -23,7 +22,7 @@ static int MyCompareTime(NFileTimeType::EEnum fileTimeType,
|
||||
return ::CompareFileTime(&time1, &time2);
|
||||
case NFileTimeType::kUnix:
|
||||
{
|
||||
time_t unixTime1, unixTime2;
|
||||
UInt32 unixTime1, unixTime2;
|
||||
if (!FileTimeToUnixTime(time1, unixTime1))
|
||||
throw 4191614;
|
||||
if (!FileTimeToUnixTime(time2, unixTime2))
|
||||
@@ -32,7 +31,7 @@ static int MyCompareTime(NFileTimeType::EEnum fileTimeType,
|
||||
}
|
||||
case NFileTimeType::kDOS:
|
||||
{
|
||||
UINT32 dosTime1, dosTime2;
|
||||
UInt32 dosTime1, dosTime2;
|
||||
if (!FileTimeToDosTime(time1, dosTime1))
|
||||
throw 4191616;
|
||||
if (!FileTimeToDosTime(time2, dosTime2))
|
||||
@@ -51,23 +50,32 @@ static const char *kSameTimeChangedSizeCollisionMessaged =
|
||||
"Collision between files with same date/time and different sizes:\n";
|
||||
*/
|
||||
|
||||
static void TestDuplicateString(const UStringVector &strings,
|
||||
const CIntVector &indices)
|
||||
static inline int MyFileNameCompare(const UString &s1, const UString &s2)
|
||||
{
|
||||
return
|
||||
#ifdef _WIN32
|
||||
s1.CollateNoCase(s2);
|
||||
#else
|
||||
s1.Compare(s2);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void TestDuplicateString(const UStringVector &strings, const CIntVector &indices)
|
||||
{
|
||||
for(int i = 0; i + 1 < indices.Size(); i++)
|
||||
if (strings[indices[i]].CollateNoCase(strings[indices[i + 1]]) == 0)
|
||||
if (MyFileNameCompare(strings[indices[i]], strings[indices[i + 1]]) == 0)
|
||||
{
|
||||
UString message = kDuplicateFileNameMessage;
|
||||
message += L"\n";
|
||||
message += strings[indices[i]];
|
||||
message += L"\n";
|
||||
message += strings[indices[i+1]];
|
||||
message += strings[indices[i + 1]];
|
||||
throw message;
|
||||
}
|
||||
}
|
||||
|
||||
void GetUpdatePairInfoList(
|
||||
const CObjectVector<CDirItem> &dirItems,
|
||||
const CObjectVector<CDirItem> &dirItems,
|
||||
const CObjectVector<CArchiveItem> &archiveItems,
|
||||
NFileTimeType::EEnum fileTimeType,
|
||||
CObjectVector<CUpdatePair> &updatePairs)
|
||||
@@ -96,7 +104,7 @@ void GetUpdatePairInfoList(
|
||||
archiveItemIndex2 = archiveIndices[archiveItemIndex];
|
||||
const CDirItem &dirItem = dirItems[dirItemIndex2];
|
||||
const CArchiveItem &archiveItem = archiveItems[archiveItemIndex2];
|
||||
int compareResult = dirItem.Name.CollateNoCase(archiveItem.Name);
|
||||
int compareResult = MyFileNameCompare(dirItem.Name, archiveItem.Name);
|
||||
if (compareResult < 0)
|
||||
{
|
||||
pair.State = NUpdateArchive::NPairState::kOnlyOnDisk;
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
// UpdatePair.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __UPDATEPAIR_H
|
||||
#define __UPDATEPAIR_H
|
||||
#ifndef __UPDATE_PAIR_H
|
||||
#define __UPDATE_PAIR_H
|
||||
|
||||
#include "DirItem.h"
|
||||
#include "UpdateAction.h"
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
// UpdateProduce.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __UPDATEPRODUCE_H
|
||||
#define __UPDATEPRODUCE_H
|
||||
#ifndef __UPDATE_PRODUCE_H
|
||||
#define __UPDATE_PRODUCE_H
|
||||
|
||||
#include "UpdatePair.h"
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "WorkDir.h"
|
||||
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/Wildcard.h"
|
||||
|
||||
#include "Windows/FileName.h"
|
||||
#include "Windows/FileDir.h"
|
||||
@@ -16,23 +17,13 @@ using namespace NWindows;
|
||||
using namespace NFile;
|
||||
using namespace NName;
|
||||
|
||||
static UString GetContainingDir(const UString &path)
|
||||
{
|
||||
UString resultPath;
|
||||
int pos;
|
||||
if(!NFile::NDirectory::MyGetFullPathName(path, resultPath, pos))
|
||||
throw 141716;
|
||||
return resultPath.Left(pos);
|
||||
}
|
||||
|
||||
UString GetWorkDir(const NWorkDir::CInfo &workDirInfo,
|
||||
const UString &archiveName)
|
||||
UString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const UString &path)
|
||||
{
|
||||
NWorkDir::NMode::EEnum mode = workDirInfo.Mode;
|
||||
if (workDirInfo.ForRemovableOnly)
|
||||
{
|
||||
mode = NWorkDir::NMode::kCurrent;
|
||||
UString prefix = archiveName.Left(3);
|
||||
UString prefix = path.Left(3);
|
||||
if (prefix[1] == L':' && prefix[2] == L'\\')
|
||||
{
|
||||
UINT driveType = GetDriveType(GetSystemString(prefix, GetCurrentCodePage()));
|
||||
@@ -51,7 +42,7 @@ UString GetWorkDir(const NWorkDir::CInfo &workDirInfo,
|
||||
{
|
||||
case NWorkDir::NMode::kCurrent:
|
||||
{
|
||||
return GetContainingDir(archiveName);
|
||||
return ExtractDirPrefixFromPath(path);
|
||||
}
|
||||
case NWorkDir::NMode::kSpecified:
|
||||
{
|
||||
@@ -59,7 +50,7 @@ UString GetWorkDir(const NWorkDir::CInfo &workDirInfo,
|
||||
NormalizeDirPathPrefix(tempDir);
|
||||
return tempDir;
|
||||
}
|
||||
default: // NZipSettings::NWorkDir::NMode::kSystem:
|
||||
default:
|
||||
{
|
||||
UString tempDir;
|
||||
if(!NFile::NDirectory::MyGetTempPath(tempDir))
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
// WorkDir.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __WORKDIR_H
|
||||
#define __WORKDIR_H
|
||||
|
||||
#include "../Common/ZipRegistry.h"
|
||||
#include "ZipRegistry.h"
|
||||
|
||||
UString GetWorkDir(const NWorkDir::CInfo &workDirInfo,
|
||||
const UString &archiveName);
|
||||
UString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const UString &path);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ static CSysString GetKeyPath(const CSysString &path)
|
||||
return CSysString(kCUBasePath) + CSysString('\\') + CSysString(path);
|
||||
}
|
||||
|
||||
void SaveExtractionInfo(const NExtraction::CInfo &info)
|
||||
void SaveExtractionInfo(const NExtract::CInfo &info)
|
||||
{
|
||||
NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
|
||||
CKey extractionKey;
|
||||
@@ -48,20 +48,20 @@ void SaveExtractionInfo(const NExtraction::CInfo &info)
|
||||
for(int i = 0; i < info.Paths.Size(); i++)
|
||||
{
|
||||
TCHAR numberString[16];
|
||||
ConvertUINT64ToString(i, numberString);
|
||||
ConvertUInt64ToString(i, numberString);
|
||||
pathHistoryKey.SetValue(numberString, info.Paths[i]);
|
||||
}
|
||||
}
|
||||
extractionKey.SetValue(kExtractionExtractModeValueName, UINT32(info.PathMode));
|
||||
extractionKey.SetValue(kExtractionOverwriteModeValueName, UINT32(info.OverwriteMode));
|
||||
extractionKey.SetValue(kExtractionExtractModeValueName, UInt32(info.PathMode));
|
||||
extractionKey.SetValue(kExtractionOverwriteModeValueName, UInt32(info.OverwriteMode));
|
||||
extractionKey.SetValue(kExtractionShowPasswordValueName, info.ShowPassword);
|
||||
}
|
||||
|
||||
void ReadExtractionInfo(NExtraction::CInfo &info)
|
||||
void ReadExtractionInfo(NExtract::CInfo &info)
|
||||
{
|
||||
info.Paths.Clear();
|
||||
info.PathMode = NExtraction::NPathMode::kFullPathnames;
|
||||
info.OverwriteMode = NExtraction::NOverwriteMode::kAskBefore;
|
||||
info.PathMode = NExtract::NPathMode::kCurrentPathnames;
|
||||
info.OverwriteMode = NExtract::NOverwriteMode::kAskBefore;
|
||||
info.ShowPassword = false;
|
||||
|
||||
NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
|
||||
@@ -77,7 +77,7 @@ void ReadExtractionInfo(NExtraction::CInfo &info)
|
||||
while(true)
|
||||
{
|
||||
TCHAR numberString[16];
|
||||
ConvertUINT64ToString(info.Paths.Size(), numberString);
|
||||
ConvertUInt64ToString(info.Paths.Size(), numberString);
|
||||
CSysString path;
|
||||
if (pathHistoryKey.QueryValue(numberString, path) != ERROR_SUCCESS)
|
||||
break;
|
||||
@@ -85,29 +85,29 @@ void ReadExtractionInfo(NExtraction::CInfo &info)
|
||||
}
|
||||
}
|
||||
}
|
||||
UINT32 extractModeIndex;
|
||||
UInt32 extractModeIndex;
|
||||
if (extractionKey.QueryValue(kExtractionExtractModeValueName, extractModeIndex) == ERROR_SUCCESS)
|
||||
{
|
||||
switch (extractModeIndex)
|
||||
{
|
||||
case NExtraction::NPathMode::kFullPathnames:
|
||||
case NExtraction::NPathMode::kCurrentPathnames:
|
||||
case NExtraction::NPathMode::kNoPathnames:
|
||||
info.PathMode = NExtraction::NPathMode::EEnum(extractModeIndex);
|
||||
case NExtract::NPathMode::kFullPathnames:
|
||||
case NExtract::NPathMode::kCurrentPathnames:
|
||||
case NExtract::NPathMode::kNoPathnames:
|
||||
info.PathMode = NExtract::NPathMode::EEnum(extractModeIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
UINT32 overwriteModeIndex;
|
||||
UInt32 overwriteModeIndex;
|
||||
if (extractionKey.QueryValue(kExtractionOverwriteModeValueName, overwriteModeIndex) == ERROR_SUCCESS)
|
||||
{
|
||||
switch (overwriteModeIndex)
|
||||
{
|
||||
case NExtraction::NOverwriteMode::kAskBefore:
|
||||
case NExtraction::NOverwriteMode::kWithoutPrompt:
|
||||
case NExtraction::NOverwriteMode::kSkipExisting:
|
||||
case NExtraction::NOverwriteMode::kAutoRename:
|
||||
case NExtraction::NOverwriteMode::kAutoRenameExisting:
|
||||
info.OverwriteMode = NExtraction::NOverwriteMode::EEnum(overwriteModeIndex);
|
||||
case NExtract::NOverwriteMode::kAskBefore:
|
||||
case NExtract::NOverwriteMode::kWithoutPrompt:
|
||||
case NExtract::NOverwriteMode::kSkipExisting:
|
||||
case NExtract::NOverwriteMode::kAutoRename:
|
||||
case NExtract::NOverwriteMode::kAutoRenameExisting:
|
||||
info.OverwriteMode = NExtract::NOverwriteMode::EEnum(overwriteModeIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -151,7 +151,7 @@ void SaveCompressionInfo(const NCompression::CInfo &info)
|
||||
for(int i = 0; i < info.HistoryArchives.Size(); i++)
|
||||
{
|
||||
TCHAR numberString[16];
|
||||
ConvertUINT64ToString(i, numberString);
|
||||
ConvertUInt64ToString(i, numberString);
|
||||
historyArchivesKey.SetValue(numberString, info.HistoryArchives[i]);
|
||||
}
|
||||
}
|
||||
@@ -171,7 +171,7 @@ void SaveCompressionInfo(const NCompression::CInfo &info)
|
||||
formatKey.DeleteValue(kCompressionOptions);
|
||||
else
|
||||
formatKey.SetValue(kCompressionOptions, fo.Options);
|
||||
if (fo.Level == UINT32(-1))
|
||||
if (fo.Level == UInt32(-1))
|
||||
formatKey.DeleteValue(kCompressionLevel);
|
||||
else
|
||||
formatKey.SetValue(kCompressionLevel, fo.Level);
|
||||
@@ -179,18 +179,18 @@ void SaveCompressionInfo(const NCompression::CInfo &info)
|
||||
formatKey.DeleteValue(kCompressionMethod);
|
||||
else
|
||||
formatKey.SetValue(kCompressionMethod, fo.Method);
|
||||
if (fo.Dictionary == UINT32(-1))
|
||||
if (fo.Dictionary == UInt32(-1))
|
||||
formatKey.DeleteValue(kCompressionDictionary);
|
||||
else
|
||||
formatKey.SetValue(kCompressionDictionary, fo.Dictionary);
|
||||
if (fo.Order == UINT32(-1))
|
||||
if (fo.Order == UInt32(-1))
|
||||
formatKey.DeleteValue(kCompressionOrder);
|
||||
else
|
||||
formatKey.SetValue(kCompressionOrder, fo.Order);
|
||||
}
|
||||
}
|
||||
|
||||
compressionKey.SetValue(kCompressionLevelValueName, UINT32(info.Level));
|
||||
compressionKey.SetValue(kCompressionLevelValueName, UInt32(info.Level));
|
||||
compressionKey.SetValue(kCompressionLastFormatValueName,
|
||||
GetSystemString(info.ArchiveType));
|
||||
|
||||
@@ -235,7 +235,7 @@ void ReadCompressionInfo(NCompression::CInfo &info)
|
||||
while(true)
|
||||
{
|
||||
TCHAR numberString[16];
|
||||
ConvertUINT64ToString(info.HistoryArchives.Size(), numberString);
|
||||
ConvertUInt64ToString(info.HistoryArchives.Size(), numberString);
|
||||
CSysString path;
|
||||
if (historyArchivesKey.QueryValue(numberString, path) != ERROR_SUCCESS)
|
||||
break;
|
||||
@@ -269,13 +269,13 @@ void ReadCompressionInfo(NCompression::CInfo &info)
|
||||
if (formatKey.QueryValue(kCompressionOptions, fo.Options) != ERROR_SUCCESS)
|
||||
fo.Options.Empty();
|
||||
if (formatKey.QueryValue(kCompressionLevel, fo.Level) != ERROR_SUCCESS)
|
||||
fo.Level = UINT32(-1);
|
||||
fo.Level = UInt32(-1);
|
||||
if (formatKey.QueryValue(kCompressionMethod, fo.Method) != ERROR_SUCCESS)
|
||||
fo.Method.Empty();;
|
||||
if (formatKey.QueryValue(kCompressionDictionary, fo.Dictionary) != ERROR_SUCCESS)
|
||||
fo.Dictionary = UINT32(-1);
|
||||
fo.Dictionary = UInt32(-1);
|
||||
if (formatKey.QueryValue(kCompressionOrder, fo.Order) != ERROR_SUCCESS)
|
||||
fo.Order = UINT32(-1);
|
||||
fo.Order = UInt32(-1);
|
||||
info.FormatOptionsVector.Add(fo);
|
||||
}
|
||||
|
||||
@@ -283,7 +283,7 @@ void ReadCompressionInfo(NCompression::CInfo &info)
|
||||
}
|
||||
}
|
||||
|
||||
UINT32 level;
|
||||
UInt32 level;
|
||||
if (compressionKey.QueryValue(kCompressionLevelValueName, level) == ERROR_SUCCESS)
|
||||
info.Level = level;
|
||||
CSysString archiveType;
|
||||
@@ -318,7 +318,7 @@ void SaveWorkDirInfo(const NWorkDir::CInfo &info)
|
||||
NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
|
||||
CKey optionsKey;
|
||||
optionsKey.Create(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName));
|
||||
optionsKey.SetValue(kWorkDirTypeValueName, UINT32(info.Mode));
|
||||
optionsKey.SetValue(kWorkDirTypeValueName, UInt32(info.Mode));
|
||||
optionsKey.SetValue(kWorkDirPathValueName, GetSystemString(info.Path));
|
||||
optionsKey.SetValue(kTempRemovableOnlyValueName, info.ForRemovableOnly);
|
||||
}
|
||||
@@ -332,7 +332,7 @@ void ReadWorkDirInfo(NWorkDir::CInfo &info)
|
||||
if(optionsKey.Open(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName), KEY_READ) != ERROR_SUCCESS)
|
||||
return;
|
||||
|
||||
UINT32 dirType;
|
||||
UInt32 dirType;
|
||||
if (optionsKey.QueryValue(kWorkDirTypeValueName, dirType) != ERROR_SUCCESS)
|
||||
return;
|
||||
switch (dirType)
|
||||
@@ -380,7 +380,7 @@ bool ReadCascadedMenu()
|
||||
{ return ReadOption(kCascadedMenuValueName, false); }
|
||||
|
||||
|
||||
static void SaveValue(const TCHAR *value, UINT32 valueToWrite)
|
||||
static void SaveValue(const TCHAR *value, UInt32 valueToWrite)
|
||||
{
|
||||
NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
|
||||
CKey optionsKey;
|
||||
@@ -388,7 +388,7 @@ static void SaveValue(const TCHAR *value, UINT32 valueToWrite)
|
||||
optionsKey.SetValue(value, valueToWrite);
|
||||
}
|
||||
|
||||
static bool ReadValue(const TCHAR *value, UINT32 &result)
|
||||
static bool ReadValue(const TCHAR *value, UInt32 &result)
|
||||
{
|
||||
NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
|
||||
CKey optionsKey;
|
||||
@@ -397,8 +397,8 @@ static bool ReadValue(const TCHAR *value, UINT32 &result)
|
||||
return (optionsKey.QueryValue(value, result) == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
void SaveContextMenuStatus(UINT32 value)
|
||||
void SaveContextMenuStatus(UInt32 value)
|
||||
{ SaveValue(kContextMenuValueName, value); }
|
||||
|
||||
bool ReadContextMenuStatus(UINT32 &value)
|
||||
bool ReadContextMenuStatus(UInt32 &value)
|
||||
{ return ReadValue(kContextMenuValueName, value); }
|
||||
|
||||
@@ -1,36 +1,14 @@
|
||||
// ZipRegistry.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ZIPREGISTRY_H
|
||||
#define __ZIPREGISTRY_H
|
||||
|
||||
#include "Common/String.h"
|
||||
#include "Common/Types.h"
|
||||
#include "ExtractMode.h"
|
||||
|
||||
namespace NExtraction {
|
||||
|
||||
namespace NPathMode
|
||||
{
|
||||
enum EEnum
|
||||
{
|
||||
kFullPathnames,
|
||||
kCurrentPathnames,
|
||||
kNoPathnames
|
||||
};
|
||||
}
|
||||
|
||||
namespace NOverwriteMode
|
||||
{
|
||||
enum EEnum
|
||||
{
|
||||
kAskBefore,
|
||||
kWithoutPrompt,
|
||||
kSkipExisting,
|
||||
kAutoRename,
|
||||
kAutoRenameExisting
|
||||
};
|
||||
}
|
||||
|
||||
namespace NExtract
|
||||
{
|
||||
struct CInfo
|
||||
{
|
||||
NPathMode::EEnum PathMode;
|
||||
@@ -46,13 +24,13 @@ namespace NCompression {
|
||||
{
|
||||
CSysString FormatID;
|
||||
CSysString Options;
|
||||
UINT32 Level;
|
||||
UInt32 Level;
|
||||
CSysString Method;
|
||||
UINT32 Dictionary;
|
||||
UINT32 Order;
|
||||
UInt32 Dictionary;
|
||||
UInt32 Order;
|
||||
void Init()
|
||||
{
|
||||
Level = Dictionary = Order = UINT32(-1);
|
||||
Level = Dictionary = Order = UInt32(-1);
|
||||
Method.Empty();
|
||||
// Options.Empty();
|
||||
}
|
||||
@@ -63,7 +41,7 @@ namespace NCompression {
|
||||
{
|
||||
CSysStringVector HistoryArchives;
|
||||
// bool LevelIsDefined;
|
||||
UINT32 Level;
|
||||
UInt32 Level;
|
||||
UString ArchiveType;
|
||||
|
||||
bool Solid;
|
||||
@@ -101,8 +79,8 @@ namespace NWorkDir{
|
||||
};
|
||||
}
|
||||
|
||||
void SaveExtractionInfo(const NExtraction::CInfo &info);
|
||||
void ReadExtractionInfo(NExtraction::CInfo &info);
|
||||
void SaveExtractionInfo(const NExtract::CInfo &info);
|
||||
void ReadExtractionInfo(NExtract::CInfo &info);
|
||||
|
||||
void SaveCompressionInfo(const NCompression::CInfo &info);
|
||||
void ReadCompressionInfo(NCompression::CInfo &info);
|
||||
@@ -113,7 +91,7 @@ void ReadWorkDirInfo(NWorkDir::CInfo &info);
|
||||
void SaveCascadedMenu(bool enabled);
|
||||
bool ReadCascadedMenu();
|
||||
|
||||
void SaveContextMenuStatus(UINT32 value);
|
||||
bool ReadContextMenuStatus(UINT32 &value);
|
||||
void SaveContextMenuStatus(UInt32 value);
|
||||
bool ReadContextMenuStatus(UInt32 &value);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
// ArError.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARERROR_H
|
||||
#define __ARERROR_H
|
||||
|
||||
namespace NExitCode {
|
||||
|
||||
struct CSystemError
|
||||
{
|
||||
UINT32 ErrorValue;
|
||||
CSystemError(UINT32 anErrorValue): ErrorValue(anErrorValue) {}
|
||||
};
|
||||
|
||||
struct CMultipleErrors
|
||||
{
|
||||
UINT64 NumErrors;
|
||||
CMultipleErrors(UINT64 aNumErrors): NumErrors(aNumErrors) {}
|
||||
};
|
||||
|
||||
|
||||
enum EEnum {
|
||||
|
||||
kSuccess = 0, // Successful operation (User exit)
|
||||
kWarning = 1, // Non fatal error(s) occurred
|
||||
kFatalError = 2, // A fatal error occurred
|
||||
kCRCError = 3, // A CRC error occurred when unpacking
|
||||
kLockedArchive = 4, // Attempt to modify an archive previously locked
|
||||
kWriteError = 5, // Write to disk error
|
||||
kOpenError = 6, // Open file error
|
||||
kUserError = 7, // Command line option error
|
||||
kMemoryError = 8, // Not enough memory for operation
|
||||
|
||||
|
||||
kNotSupported = 102, // format of file doesn't supported
|
||||
kFileError = 103, //
|
||||
|
||||
kVerError = 110, // Version doesn't supported
|
||||
kMethodError = 111, // Unsupported method
|
||||
|
||||
kUserQuit = 120, // Unsupported method
|
||||
|
||||
kFileIsNotArchive = 130, // File Is Not Archive
|
||||
|
||||
kCommonError = 150,
|
||||
|
||||
kInputArchiveException = 160, // archive file does not exist
|
||||
|
||||
kErrorsDuringDecompression = 170, // Errors during decompression
|
||||
|
||||
|
||||
kDirFileWith64BitSize = 171,
|
||||
kFileTimeWinToDosConvertError = 172,
|
||||
|
||||
kFileChangedDuringOperation = 180,
|
||||
|
||||
kUserBreak = 255 // User stopped the process
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,28 +0,0 @@
|
||||
// CompressionMethodUtils.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __COMPRESSIONMETHODUTILS_H
|
||||
#define __COMPRESSIONMETHODUTILS_H
|
||||
|
||||
struct CProperty
|
||||
{
|
||||
UString Name;
|
||||
UString Value;
|
||||
};
|
||||
|
||||
struct CCompressionMethodMode
|
||||
{
|
||||
#ifndef EXCLUDE_COM
|
||||
UString FilePath;
|
||||
CLSID ClassID1;
|
||||
#else
|
||||
UString Name;
|
||||
#endif
|
||||
CObjectVector<CProperty> Properties;
|
||||
bool PasswordIsDefined;
|
||||
bool AskPassword;
|
||||
UString Password;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -158,14 +158,6 @@ SOURCE=.\StdAfx.h
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ArError.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CompressionMode.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ConsoleClose.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -174,19 +166,11 @@ SOURCE=.\ConsoleClose.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Extract.cpp
|
||||
SOURCE=.\ExtractCallbackConsole.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Extract.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ExtractCallback.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ExtractCallback.h
|
||||
SOURCE=.\ExtractCallbackConsole.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -206,11 +190,11 @@ SOURCE=.\MainAr.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\OpenCallback.cpp
|
||||
SOURCE=.\OpenCallbackConsole.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\OpenCallback.h
|
||||
SOURCE=.\OpenCallbackConsole.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -222,27 +206,11 @@ SOURCE=.\PercentPrinter.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\TempFiles.cpp
|
||||
SOURCE=.\UpdateCallbackConsole.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\TempFiles.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Update.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Update.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\UpdateCallback.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\UpdateCallback.h
|
||||
SOURCE=.\UpdateCallbackConsole.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -328,20 +296,24 @@ SOURCE=..\..\..\Windows\Registry.cpp
|
||||
|
||||
SOURCE=..\..\..\Windows\Registry.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\System.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\System.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Alloc.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Alloc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Buffer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\CommandLineParser.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -422,6 +394,14 @@ SOURCE=..\..\..\Common\StringConvert.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\StringToInt.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\StringToInt.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\UTFConvert.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -450,6 +430,30 @@ SOURCE=..\..\..\Common\Wildcard.h
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ArchiveCommandLine.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ArchiveCommandLine.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ArchiveExtractCallback.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ArchiveExtractCallback.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ArchiveOpenCallback.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ArchiveOpenCallback.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ArchiverInfo.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -458,6 +462,10 @@ SOURCE=..\Common\ArchiverInfo.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\CompressionMode.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\DefaultName.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -478,6 +486,18 @@ SOURCE=..\Common\EnumDirItems.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ExitCode.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\Extract.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\Extract.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ExtractingFilePath.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -490,6 +510,10 @@ SOURCE=..\Common\HandlerLoader.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\IFileExtractCallback.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\OpenArchive.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -514,6 +538,22 @@ SOURCE=..\Common\SortUtils.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\TempFiles.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\TempFiles.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\Update.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\Update.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\UpdateAction.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -522,6 +562,14 @@ SOURCE=..\Common\UpdateAction.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\UpdateCallback.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\UpdateCallback.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\UpdatePair.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -544,6 +592,10 @@ SOURCE=..\Common\WorkDir.cpp
|
||||
|
||||
SOURCE=..\Common\WorkDir.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ZipRegistry.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "7-zip Common"
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// ConsoleCloseUtils.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __CONSOLECLOSEUTILS_H
|
||||
#define __CONSOLECLOSEUTILS_H
|
||||
|
||||
@@ -24,4 +22,3 @@ void CheckCtrlBreak();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
// Extract.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Extract.h"
|
||||
#include "ExtractCallback.h"
|
||||
#include "ArError.h"
|
||||
|
||||
#include "Common/StdOutStream.h"
|
||||
#include "Windows/Defs.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "Windows/FileDir.h"
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
static const char *kEverythingIsOk = "Everything is Ok";
|
||||
|
||||
HRESULT DeCompressArchiveSTD(
|
||||
IInArchive *archive,
|
||||
const NWildcard::CCensor &wildcardCensor,
|
||||
const CExtractOptions &options)
|
||||
{
|
||||
CRecordVector<UINT32> realIndices;
|
||||
UINT32 numItems;
|
||||
RINOK(archive->GetNumberOfItems(&numItems));
|
||||
|
||||
for(UINT32 i = 0; i < numItems; i++)
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(archive->GetProperty(i, kpidPath, &propVariant));
|
||||
UString filePath;
|
||||
if(propVariant.vt == VT_EMPTY)
|
||||
filePath = options.DefaultItemName;
|
||||
else
|
||||
{
|
||||
if(propVariant.vt != VT_BSTR)
|
||||
return E_FAIL;
|
||||
filePath = propVariant.bstrVal;
|
||||
}
|
||||
if (!wildcardCensor.CheckName(filePath))
|
||||
continue;
|
||||
realIndices.Add(i);
|
||||
}
|
||||
if (realIndices.Size() == 0)
|
||||
{
|
||||
g_StdOut << endl << "No files to process" << endl;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
CExtractCallbackImp *extractCallbackSpec = new CExtractCallbackImp;
|
||||
CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec);
|
||||
|
||||
UStringVector removePathParts;
|
||||
|
||||
NExtraction::CInfo extractionInfo;
|
||||
extractionInfo.PathMode = options.FullPathMode() ? NExtraction::NPathMode::kFullPathnames:
|
||||
NExtraction::NPathMode::kNoPathnames;
|
||||
|
||||
if (options.YesToAll)
|
||||
extractionInfo.OverwriteMode = NExtraction::NOverwriteMode::kWithoutPrompt;
|
||||
else
|
||||
{
|
||||
extractionInfo.OverwriteMode = options.OverwriteMode;
|
||||
}
|
||||
|
||||
if(!options.OutputBaseDir.IsEmpty())
|
||||
if(!NFile::NDirectory::CreateComplexDirectory(options.OutputBaseDir))
|
||||
{
|
||||
throw "Can not create output directory";
|
||||
}
|
||||
|
||||
extractCallbackSpec->Init(archive,
|
||||
options.OutputBaseDir,
|
||||
extractionInfo, removePathParts,
|
||||
options.DefaultItemName,
|
||||
options.ArchiveFileInfo.LastWriteTime,
|
||||
options.ArchiveFileInfo.Attributes,
|
||||
options.PasswordEnabled,
|
||||
options.Password);
|
||||
|
||||
HRESULT result = archive->Extract(&realIndices.Front(),
|
||||
realIndices.Size(), options.ExtractMode == NExtractMode::kTest,
|
||||
extractCallback);
|
||||
|
||||
if (extractCallbackSpec->m_NumErrors != 0)
|
||||
throw NExitCode::CMultipleErrors(extractCallbackSpec->m_NumErrors);
|
||||
|
||||
if (result != S_OK)
|
||||
throw NExitCode::CSystemError(result);
|
||||
|
||||
g_StdOut << endl << kEverythingIsOk << endl;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
// Extract.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __EXTRACT_H
|
||||
#define __EXTRACT_H
|
||||
|
||||
#include "Common/Wildcard.h"
|
||||
#include "Windows/FileFind.h"
|
||||
|
||||
#include "../../Archive/IArchive.h"
|
||||
#include "../Common/ZipRegistry.h"
|
||||
|
||||
namespace NExtractMode {
|
||||
|
||||
enum EEnum
|
||||
{
|
||||
kTest,
|
||||
kFullPath,
|
||||
kExtractToOne
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
class CExtractOptions
|
||||
{
|
||||
public:
|
||||
NExtractMode::EEnum ExtractMode;
|
||||
UString OutputBaseDir;
|
||||
bool YesToAll;
|
||||
UString DefaultItemName;
|
||||
NWindows::NFile::NFind::CFileInfoW ArchiveFileInfo;
|
||||
bool PasswordEnabled;
|
||||
UString Password;
|
||||
|
||||
NExtraction::NOverwriteMode::EEnum OverwriteMode;
|
||||
|
||||
|
||||
CExtractOptions(NExtractMode::EEnum extractMode, const UString &outputBaseDir,
|
||||
bool yesToAll, bool passwordEnabled, const UString &password,
|
||||
NExtraction::NOverwriteMode::EEnum overwriteMode):
|
||||
ExtractMode(extractMode),
|
||||
OutputBaseDir(outputBaseDir),
|
||||
YesToAll(yesToAll),
|
||||
PasswordEnabled(passwordEnabled),
|
||||
Password(password),
|
||||
OverwriteMode(overwriteMode)
|
||||
{}
|
||||
|
||||
bool TestMode() const { return (ExtractMode == NExtractMode::kTest); }
|
||||
bool FullPathMode() const { return (ExtractMode == NExtractMode::kTest) ||
|
||||
(ExtractMode == NExtractMode::kFullPath); }
|
||||
};
|
||||
|
||||
HRESULT DeCompressArchiveSTD(IInArchive *archive,
|
||||
const NWildcard::CCensor &wildcardCensor,
|
||||
const CExtractOptions &options);
|
||||
|
||||
/*
|
||||
bool DeCompressArchiveSTD(TTWildCardInputArchive &anArchive,
|
||||
const TTExtractOptions &anOptions);
|
||||
*/
|
||||
|
||||
#endif
|
||||
@@ -1,405 +0,0 @@
|
||||
// ExtractCallback.h
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ExtractCallback.h"
|
||||
#include "UserInputUtils.h"
|
||||
|
||||
#include "ConsoleClose.h"
|
||||
#include "Common/StdOutStream.h"
|
||||
#include "Common/StdInStream.h"
|
||||
#include "Common/Wildcard.h"
|
||||
#include "Common/StringConvert.h"
|
||||
|
||||
#include "Windows/COM.h"
|
||||
#include "Windows/FileDir.h"
|
||||
#include "Windows/FileFind.h"
|
||||
#include "Windows/Time.h"
|
||||
#include "Windows/Defs.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
|
||||
#include "Windows/PropVariantConversions.h"
|
||||
|
||||
#include "../../Common/FilePathAutoRename.h"
|
||||
|
||||
#include "../Common/ExtractingFilePath.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
using namespace NDirectory;
|
||||
|
||||
static const char *kTestingString = "Testing ";
|
||||
static const char *kExtractingString = "Extracting ";
|
||||
static const char *kSkippingString = "Skipping ";
|
||||
|
||||
static const char *kCantAutoRename = "can not create file with auto name\n";
|
||||
static const char *kCantRenameFile = "can not rename existing file\n";
|
||||
static const char *kCantDeleteOutputFile = "can not delete output file ";
|
||||
void CExtractCallbackImp::Init(IInArchive *archive,
|
||||
const UString &directoryPath,
|
||||
const NExtraction::CInfo &extractModeInfo,
|
||||
const UStringVector &removePathParts,
|
||||
const UString &itemDefaultName,
|
||||
const FILETIME &utcLastWriteTimeDefault,
|
||||
UINT32 attributesDefault,
|
||||
bool passwordIsDefined,
|
||||
const UString &password)
|
||||
{
|
||||
m_PasswordIsDefined = passwordIsDefined;
|
||||
m_Password = password;
|
||||
m_NumErrors = 0;
|
||||
|
||||
m_ItemDefaultName = itemDefaultName;
|
||||
m_UTCLastWriteTimeDefault = utcLastWriteTimeDefault;
|
||||
m_AttributesDefault = attributesDefault;
|
||||
|
||||
m_RemovePathParts = removePathParts;
|
||||
m_ExtractModeInfo = extractModeInfo;
|
||||
m_ArchiveHandler = archive;
|
||||
m_DirectoryPath = directoryPath;
|
||||
NFile::NName::NormalizeDirPathPrefix(m_DirectoryPath);
|
||||
}
|
||||
|
||||
bool CExtractCallbackImp::IsEncrypted(UINT32 index)
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
if(m_ArchiveHandler->GetProperty(index, kpidEncrypted, &propVariant) != S_OK)
|
||||
return false;
|
||||
if (propVariant.vt != VT_BOOL)
|
||||
return false;
|
||||
return VARIANT_BOOLToBool(propVariant.boolVal);
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackImp::SetTotal(UINT64 size)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackImp::SetCompleted(const UINT64 *completeValue)
|
||||
{
|
||||
if (NConsoleClose::TestBreakSignal())
|
||||
return E_ABORT;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CExtractCallbackImp::CreateComplexDirectory(const UStringVector &dirPathParts)
|
||||
{
|
||||
UString fullPath = m_DirectoryPath;
|
||||
for(int i = 0; i < dirPathParts.Size(); i++)
|
||||
{
|
||||
fullPath += dirPathParts[i];
|
||||
MyCreateDirectory(fullPath);
|
||||
fullPath += (wchar_t)NFile::NName::kDirDelimiter;
|
||||
}
|
||||
}
|
||||
|
||||
static UString MakePathNameFromParts(const UStringVector &parts)
|
||||
{
|
||||
UString result;
|
||||
for(int i = 0; i < parts.Size(); i++)
|
||||
{
|
||||
if(i != 0)
|
||||
result += wchar_t(NFile::NName::kDirDelimiter);
|
||||
result += parts[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackImp::GetStream(UINT32 index,
|
||||
ISequentialOutStream **outStream, INT32 askExtractMode)
|
||||
{
|
||||
*outStream = NULL;
|
||||
if (NConsoleClose::TestBreakSignal())
|
||||
return E_ABORT;
|
||||
m_OutFileStream.Release();
|
||||
NCOM::CPropVariant propVariantName;
|
||||
RINOK(m_ArchiveHandler->GetProperty(index, kpidPath, &propVariantName));
|
||||
UString fullPath;
|
||||
if(propVariantName.vt == VT_EMPTY)
|
||||
fullPath = m_ItemDefaultName;
|
||||
else
|
||||
{
|
||||
if(propVariantName.vt != VT_BSTR)
|
||||
return E_FAIL;
|
||||
fullPath = propVariantName.bstrVal;
|
||||
}
|
||||
|
||||
m_FilePath = fullPath;
|
||||
|
||||
UString fullPathCorrect = GetCorrectPath(fullPath);
|
||||
|
||||
if(askExtractMode == NArchive::NExtract::NAskMode::kExtract)
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(m_ArchiveHandler->GetProperty(index, kpidAttributes, &propVariant));
|
||||
if (propVariant.vt == VT_EMPTY)
|
||||
{
|
||||
m_ProcessedFileInfo.Attributes = m_AttributesDefault;
|
||||
m_ProcessedFileInfo.AttributesAreDefined = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (propVariant.vt != VT_UI4)
|
||||
throw "incorrect item";
|
||||
m_ProcessedFileInfo.Attributes = propVariant.ulVal;
|
||||
m_ProcessedFileInfo.AttributesAreDefined = true;
|
||||
}
|
||||
|
||||
RINOK(m_ArchiveHandler->GetProperty(index, kpidIsFolder, &propVariant));
|
||||
m_ProcessedFileInfo.IsDirectory = VARIANT_BOOLToBool(propVariant.boolVal);
|
||||
|
||||
bool isAnti = false;
|
||||
{
|
||||
NCOM::CPropVariant propVariantTemp;
|
||||
RINOK(m_ArchiveHandler->GetProperty(index, kpidIsAnti,
|
||||
&propVariantTemp));
|
||||
if (propVariantTemp.vt == VT_BOOL)
|
||||
isAnti = VARIANT_BOOLToBool(propVariantTemp.boolVal);
|
||||
}
|
||||
|
||||
RINOK(m_ArchiveHandler->GetProperty(index, kpidLastWriteTime, &propVariant));
|
||||
switch(propVariant.vt)
|
||||
{
|
||||
case VT_EMPTY:
|
||||
m_ProcessedFileInfo.UTCLastWriteTime = m_UTCLastWriteTimeDefault;
|
||||
break;
|
||||
case VT_FILETIME:
|
||||
m_ProcessedFileInfo.UTCLastWriteTime = propVariant.filetime;
|
||||
break;
|
||||
default:
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// GetPropertyValue(anItemIDList, kpidSize, &propVariant);
|
||||
// UINT64 newFileSize = ConvertPropVariantToUINT64(propVariant);
|
||||
|
||||
UStringVector pathParts;
|
||||
SplitPathToParts(fullPathCorrect, pathParts);
|
||||
if(pathParts.IsEmpty())
|
||||
return E_FAIL;
|
||||
UString processedPath;
|
||||
switch(m_ExtractModeInfo.PathMode)
|
||||
{
|
||||
case NExtraction::NPathMode::kFullPathnames:
|
||||
{
|
||||
processedPath = fullPathCorrect;
|
||||
break;
|
||||
}
|
||||
case NExtraction::NPathMode::kCurrentPathnames:
|
||||
{
|
||||
int numRemovePathParts = m_RemovePathParts.Size();
|
||||
if(pathParts.Size() <= numRemovePathParts)
|
||||
return E_FAIL;
|
||||
for(int i = 0; i < numRemovePathParts; i++)
|
||||
if(m_RemovePathParts[i].CollateNoCase(pathParts[i]) != 0)
|
||||
return E_FAIL;
|
||||
pathParts.Delete(0, numRemovePathParts);
|
||||
processedPath = MakePathNameFromParts(pathParts);
|
||||
break;
|
||||
}
|
||||
case NExtraction::NPathMode::kNoPathnames:
|
||||
{
|
||||
processedPath = pathParts.Back();
|
||||
pathParts.Delete(0, pathParts.Size() - 1); // Test it!!
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!m_ProcessedFileInfo.IsDirectory)
|
||||
pathParts.DeleteBack();
|
||||
if (!pathParts.IsEmpty())
|
||||
{
|
||||
if (!isAnti)
|
||||
CreateComplexDirectory(pathParts);
|
||||
}
|
||||
|
||||
UString fullProcessedPath = m_DirectoryPath + GetCorrectPath(processedPath);
|
||||
|
||||
if(m_ProcessedFileInfo.IsDirectory)
|
||||
{
|
||||
m_DiskFilePath = fullProcessedPath;
|
||||
|
||||
if (isAnti)
|
||||
MyRemoveDirectory(m_DiskFilePath);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
NFile::NFind::CFileInfoW fileInfo;
|
||||
if(NFile::NFind::FindFile(fullProcessedPath, fileInfo))
|
||||
{
|
||||
switch(m_ExtractModeInfo.OverwriteMode)
|
||||
{
|
||||
case NExtraction::NOverwriteMode::kSkipExisting:
|
||||
return S_OK;
|
||||
case NExtraction::NOverwriteMode::kAskBefore:
|
||||
{
|
||||
/*
|
||||
NOverwriteDialog::CFileInfo oldFileInfo, newFileInfo;
|
||||
oldFileInfo.Time = fileInfo.LastWriteTime;
|
||||
oldFileInfo.Size = fileInfo.Size;
|
||||
oldFileInfo.Name = fullProcessedPath;
|
||||
|
||||
newFileInfo.Time = m_ProcessedFileInfo.UTCLastWriteTime;
|
||||
newFileInfo.Size = newFileSize;
|
||||
newFileInfo.Name = fullPath;
|
||||
|
||||
NOverwriteDialog::NResult::EEnum result =
|
||||
NOverwriteDialog::Execute(oldFileInfo, newFileInfo);
|
||||
*/
|
||||
|
||||
g_StdOut << "file " << fullProcessedPath <<
|
||||
"\nalready exists. Overwrite with " << endl;
|
||||
g_StdOut << fullPathCorrect;
|
||||
|
||||
NUserAnswerMode::EEnum overwriteAnswer = ScanUserYesNoAllQuit();
|
||||
|
||||
switch(overwriteAnswer)
|
||||
{
|
||||
case NUserAnswerMode::kQuit:
|
||||
return E_ABORT;
|
||||
case NUserAnswerMode::kNo:
|
||||
return S_OK;
|
||||
case NUserAnswerMode::kNoAll:
|
||||
m_ExtractModeInfo.OverwriteMode = NExtraction::NOverwriteMode::kSkipExisting;
|
||||
return S_OK;
|
||||
case NUserAnswerMode::kYesAll:
|
||||
m_ExtractModeInfo.OverwriteMode = NExtraction::NOverwriteMode::kWithoutPrompt;
|
||||
break;
|
||||
case NUserAnswerMode::kYes:
|
||||
break;
|
||||
case NUserAnswerMode::kAutoRename:
|
||||
m_ExtractModeInfo.OverwriteMode = NExtraction::NOverwriteMode::kAutoRename;
|
||||
break;
|
||||
default:
|
||||
throw 20413;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (m_ExtractModeInfo.OverwriteMode == NExtraction::NOverwriteMode::kAutoRename)
|
||||
{
|
||||
if (!AutoRenamePath(fullProcessedPath))
|
||||
{
|
||||
g_StdOut << kCantAutoRename;
|
||||
g_StdOut << fullProcessedPath;
|
||||
return E_ABORT;
|
||||
}
|
||||
}
|
||||
else if (m_ExtractModeInfo.OverwriteMode == NExtraction::NOverwriteMode::kAutoRenameExisting)
|
||||
{
|
||||
UString existPath = fullProcessedPath;
|
||||
if (!AutoRenamePath(existPath))
|
||||
{
|
||||
g_StdOut << kCantAutoRename;
|
||||
g_StdOut << fullProcessedPath;
|
||||
return E_ABORT;
|
||||
}
|
||||
if(!MyMoveFile(fullProcessedPath, existPath))
|
||||
{
|
||||
g_StdOut << kCantRenameFile;
|
||||
return E_ABORT;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!DeleteFileAlways(fullProcessedPath))
|
||||
{
|
||||
g_StdOut << kCantDeleteOutputFile << endl;
|
||||
g_StdOut << fullProcessedPath;
|
||||
return E_ABORT;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isAnti)
|
||||
{
|
||||
m_OutFileStreamSpec = new COutFileStream;
|
||||
CMyComPtr<ISequentialOutStream> outStreamLoc(m_OutFileStreamSpec);
|
||||
if (!m_OutFileStreamSpec->Open(fullProcessedPath))
|
||||
{
|
||||
m_NumErrors++;
|
||||
g_StdOut << "Can not open output file " << endl;
|
||||
g_StdOut << fullProcessedPath << endl;
|
||||
return S_OK;
|
||||
}
|
||||
m_OutFileStream = outStreamLoc;
|
||||
*outStream = outStreamLoc.Detach();
|
||||
}
|
||||
m_DiskFilePath = fullProcessedPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
*outStream = NULL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackImp::PrepareOperation(INT32 askExtractMode)
|
||||
{
|
||||
m_ExtractMode = false;
|
||||
switch (askExtractMode)
|
||||
{
|
||||
case NArchive::NExtract::NAskMode::kExtract:
|
||||
m_ExtractMode = true;
|
||||
g_StdOut << kExtractingString;
|
||||
break;
|
||||
case NArchive::NExtract::NAskMode::kTest:
|
||||
g_StdOut << kTestingString;
|
||||
break;
|
||||
case NArchive::NExtract::NAskMode::kSkip:
|
||||
g_StdOut << kSkippingString;
|
||||
break;
|
||||
};
|
||||
g_StdOut << m_FilePath;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackImp::SetOperationResult(INT32 resultEOperationResult)
|
||||
{
|
||||
switch(resultEOperationResult)
|
||||
{
|
||||
case NArchive::NExtract::NOperationResult::kOK:
|
||||
{
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
m_NumErrors++;
|
||||
switch(resultEOperationResult)
|
||||
{
|
||||
case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
|
||||
g_StdOut << " Unsupported Method";
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kCRCError:
|
||||
g_StdOut << " CRC Failed";
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kDataError:
|
||||
g_StdOut << " Data Error";
|
||||
break;
|
||||
default:
|
||||
g_StdOut << " Unknown Error";
|
||||
// m_OutFileStream.Release();
|
||||
// return E_FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(m_OutFileStream != NULL)
|
||||
m_OutFileStreamSpec->File.SetLastWriteTime(&m_ProcessedFileInfo.UTCLastWriteTime);
|
||||
m_OutFileStream.Release();
|
||||
if (m_ExtractMode && m_ProcessedFileInfo.AttributesAreDefined)
|
||||
MySetFileAttributes(m_DiskFilePath, m_ProcessedFileInfo.Attributes);
|
||||
g_StdOut << endl;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackImp::CryptoGetTextPassword(BSTR *password)
|
||||
{
|
||||
if (!m_PasswordIsDefined)
|
||||
{
|
||||
g_StdOut << "\nEnter password:";
|
||||
AString oemPassword = g_StdIn.ScanStringUntilNewLine();
|
||||
m_Password = MultiByteToUnicodeString(oemPassword, CP_OEMCP);
|
||||
m_PasswordIsDefined = true;
|
||||
}
|
||||
CMyComBSTR tempName(m_Password);
|
||||
*password = tempName.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
// ExtractCallback.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __EXTRACTCALLBACK_H
|
||||
#define __EXTRACTCALLBACK_H
|
||||
|
||||
#include "Common/String.h"
|
||||
#include "../../Common/FileStreams.h"
|
||||
#include "../../IPassword.h"
|
||||
#include "../../Archive/IArchive.h"
|
||||
#include "../Common/ZipRegistry.h"
|
||||
|
||||
class CExtractCallbackImp:
|
||||
public IArchiveExtractCallback,
|
||||
public ICryptoGetTextPassword,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP1(ICryptoGetTextPassword)
|
||||
|
||||
// IProgress
|
||||
STDMETHOD(SetTotal)(UINT64 size);
|
||||
STDMETHOD(SetCompleted)(const UINT64 *completeValue);
|
||||
|
||||
// IExtractCallback200
|
||||
STDMETHOD(GetStream)(UINT32 index, ISequentialOutStream **outStream,
|
||||
INT32 askExtractMode);
|
||||
STDMETHOD(PrepareOperation)(INT32 askExtractMode);
|
||||
STDMETHOD(SetOperationResult)(INT32 resultEOperationResult);
|
||||
|
||||
// ICryptoGetTextPassword
|
||||
STDMETHOD(CryptoGetTextPassword)(BSTR *password);
|
||||
|
||||
private:
|
||||
CMyComPtr<IInArchive> m_ArchiveHandler;
|
||||
UString m_DirectoryPath;
|
||||
NExtraction::CInfo m_ExtractModeInfo;
|
||||
|
||||
UString m_FilePath;
|
||||
|
||||
UString m_DiskFilePath;
|
||||
|
||||
bool m_ExtractMode;
|
||||
struct CProcessedFileInfo
|
||||
{
|
||||
FILETIME UTCLastWriteTime;
|
||||
bool IsDirectory;
|
||||
bool AttributesAreDefined;
|
||||
UINT32 Attributes;
|
||||
} m_ProcessedFileInfo;
|
||||
|
||||
COutFileStream *m_OutFileStreamSpec;
|
||||
CMyComPtr<ISequentialOutStream> m_OutFileStream;
|
||||
UStringVector m_RemovePathParts;
|
||||
|
||||
UString m_ItemDefaultName;
|
||||
FILETIME m_UTCLastWriteTimeDefault;
|
||||
UINT32 m_AttributesDefault;
|
||||
|
||||
bool m_PasswordIsDefined;
|
||||
UString m_Password;
|
||||
|
||||
void CreateComplexDirectory(const UStringVector &dirPathParts);
|
||||
bool IsEncrypted(UINT32 index);
|
||||
public:
|
||||
void Init(IInArchive *archive, const UString &directoryPath,
|
||||
const NExtraction::CInfo &anExtractModeInfo,
|
||||
const UStringVector &removePathParts,
|
||||
const UString &itemDefaultName,
|
||||
const FILETIME &utcLastWriteTimeDefault, UINT32 attributesDefault,
|
||||
bool passwordIsDefined, const UString &password);
|
||||
|
||||
UINT64 m_NumErrors;
|
||||
};
|
||||
|
||||
#endif
|
||||
227
7zip/UI/Console/ExtractCallbackConsole.cpp
Executable file
227
7zip/UI/Console/ExtractCallbackConsole.cpp
Executable file
@@ -0,0 +1,227 @@
|
||||
// ExtractCallbackConsole.h
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ExtractCallbackConsole.h"
|
||||
#include "UserInputUtils.h"
|
||||
#include "ConsoleClose.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 "../../Common/FilePathAutoRename.h"
|
||||
|
||||
#include "../Common/ExtractingFilePath.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
using namespace NDirectory;
|
||||
|
||||
static const char *kTestingString = "Testing ";
|
||||
static const char *kExtractingString = "Extracting ";
|
||||
static const char *kSkippingString = "Skipping ";
|
||||
|
||||
static const char *kCantAutoRename = "can not create file with auto name\n";
|
||||
static const char *kCantRenameFile = "can not rename existing file\n";
|
||||
static const char *kCantDeleteOutputFile = "can not delete output file ";
|
||||
static const char *kError = "ERROR: ";
|
||||
static const char *kMemoryExceptionMessage = "Can't allocate required memory!";
|
||||
|
||||
static const char *kProcessing = "Processing archive: ";
|
||||
static const char *kEverythingIsOk = "Everything is Ok";
|
||||
static const char *kNoFiles = "No files to process";
|
||||
|
||||
static const char *kUnsupportedMethod = "Unsupported Method";
|
||||
static const char *kCRCFailed = "CRC Failed";
|
||||
static const char *kDataError = "Data Error";
|
||||
static const char *kUnknownError = "Unknown Error";
|
||||
|
||||
STDMETHODIMP CExtractCallbackConsole::SetTotal(UInt64 size)
|
||||
{
|
||||
if (NConsoleClose::TestBreakSignal())
|
||||
return E_ABORT;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackConsole::SetCompleted(const UInt64 *completeValue)
|
||||
{
|
||||
if (NConsoleClose::TestBreakSignal())
|
||||
return E_ABORT;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackConsole::AskOverwrite(
|
||||
const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize,
|
||||
const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize,
|
||||
Int32 *answer)
|
||||
{
|
||||
(*OutStream) << "file " << existName <<
|
||||
"\nalready exists. Overwrite with " << endl;
|
||||
(*OutStream) << newName;
|
||||
|
||||
NUserAnswerMode::EEnum overwriteAnswer = ScanUserYesNoAllQuit(OutStream);
|
||||
|
||||
switch(overwriteAnswer)
|
||||
{
|
||||
case NUserAnswerMode::kQuit:
|
||||
return E_ABORT;
|
||||
case NUserAnswerMode::kNo:
|
||||
*answer = NOverwriteAnswer::kNo;
|
||||
break;
|
||||
case NUserAnswerMode::kNoAll:
|
||||
*answer = NOverwriteAnswer::kNoToAll;
|
||||
break;
|
||||
case NUserAnswerMode::kYesAll:
|
||||
*answer = NOverwriteAnswer::kYesToAll;
|
||||
break;
|
||||
case NUserAnswerMode::kYes:
|
||||
*answer = NOverwriteAnswer::kYes;
|
||||
break;
|
||||
case NUserAnswerMode::kAutoRename:
|
||||
*answer = NOverwriteAnswer::kAutoRename;
|
||||
break;
|
||||
default:
|
||||
return E_FAIL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int32 askExtractMode, const UInt64 *position)
|
||||
{
|
||||
switch (askExtractMode)
|
||||
{
|
||||
case NArchive::NExtract::NAskMode::kExtract:
|
||||
(*OutStream) << kExtractingString;
|
||||
break;
|
||||
case NArchive::NExtract::NAskMode::kTest:
|
||||
(*OutStream) << kTestingString;
|
||||
break;
|
||||
case NArchive::NExtract::NAskMode::kSkip:
|
||||
(*OutStream) << kSkippingString;
|
||||
break;
|
||||
};
|
||||
(*OutStream) << name;
|
||||
if (position != 0)
|
||||
(*OutStream) << " <" << *position << ">";
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackConsole::MessageError(const wchar_t *message)
|
||||
{
|
||||
(*OutStream) << message << endl;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackConsole::SetOperationResult(Int32 operationResult)
|
||||
{
|
||||
switch(operationResult)
|
||||
{
|
||||
case NArchive::NExtract::NOperationResult::kOK:
|
||||
break;
|
||||
default:
|
||||
{
|
||||
NumFileErrorsInCurrentArchive++;
|
||||
NumFileErrors++;
|
||||
(*OutStream) << " ";
|
||||
switch(operationResult)
|
||||
{
|
||||
case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
|
||||
(*OutStream) << kUnsupportedMethod;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kCRCError:
|
||||
(*OutStream) << kCRCFailed;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kDataError:
|
||||
(*OutStream) << kDataError;
|
||||
break;
|
||||
default:
|
||||
(*OutStream) << kUnknownError;
|
||||
}
|
||||
}
|
||||
}
|
||||
(*OutStream) << endl;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackConsole::CryptoGetTextPassword(BSTR *password)
|
||||
{
|
||||
if (!PasswordIsDefined)
|
||||
{
|
||||
Password = GetPassword(OutStream);
|
||||
PasswordIsDefined = true;
|
||||
}
|
||||
CMyComBSTR tempName(Password);
|
||||
*password = tempName.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CExtractCallbackConsole::BeforeOpen(const wchar_t *name)
|
||||
{
|
||||
NumArchives++;
|
||||
NumFileErrorsInCurrentArchive = 0;
|
||||
(*OutStream) << endl << kProcessing << name << endl;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CExtractCallbackConsole::OpenResult(const wchar_t *name, HRESULT result)
|
||||
{
|
||||
(*OutStream) << endl;
|
||||
if (result != S_OK)
|
||||
{
|
||||
(*OutStream) << "Error: " << name << " is not supported archive" << endl;
|
||||
NumArchiveErrors++;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CExtractCallbackConsole::ThereAreNoFiles()
|
||||
{
|
||||
(*OutStream) << endl << kNoFiles << endl;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CExtractCallbackConsole::ExtractResult(HRESULT result)
|
||||
{
|
||||
if (result == S_OK)
|
||||
{
|
||||
(*OutStream) << endl;
|
||||
if (NumFileErrorsInCurrentArchive == 0)
|
||||
(*OutStream) << kEverythingIsOk << endl;
|
||||
else
|
||||
{
|
||||
NumArchiveErrors++;
|
||||
(*OutStream) << "Sub items Errors: " << NumFileErrorsInCurrentArchive << endl;
|
||||
}
|
||||
}
|
||||
if (result == S_OK)
|
||||
return result;
|
||||
if (result == E_ABORT)
|
||||
return result;
|
||||
(*OutStream) << endl << kError;
|
||||
if (result == E_OUTOFMEMORY)
|
||||
(*OutStream) << kMemoryExceptionMessage;
|
||||
else
|
||||
{
|
||||
UString message;
|
||||
NError::MyFormatMessage(result, message);
|
||||
(*OutStream) << message;
|
||||
}
|
||||
(*OutStream) << endl;
|
||||
|
||||
NumArchiveErrors++;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CExtractCallbackConsole::SetPassword(const UString &password)
|
||||
{
|
||||
PasswordIsDefined = true;
|
||||
Password = password;
|
||||
return S_OK;
|
||||
}
|
||||
65
7zip/UI/Console/ExtractCallbackConsole.h
Executable file
65
7zip/UI/Console/ExtractCallbackConsole.h
Executable file
@@ -0,0 +1,65 @@
|
||||
// ExtractCallbackConsole.h
|
||||
|
||||
#ifndef __EXTRACTCALLBACKCONSOLE_H
|
||||
#define __EXTRACTCALLBACKCONSOLE_H
|
||||
|
||||
#include "Common/String.h"
|
||||
#include "Common/StdOutStream.h"
|
||||
#include "../../Common/FileStreams.h"
|
||||
#include "../../IPassword.h"
|
||||
#include "../../Archive/IArchive.h"
|
||||
#include "../Common/ArchiveExtractCallback.h"
|
||||
|
||||
class CExtractCallbackConsole:
|
||||
public IExtractCallbackUI,
|
||||
public ICryptoGetTextPassword,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP2(IFolderArchiveExtractCallback, ICryptoGetTextPassword)
|
||||
|
||||
STDMETHOD(SetTotal)(UInt64 total);
|
||||
STDMETHOD(SetCompleted)(const UInt64 *completeValue);
|
||||
|
||||
// IFolderArchiveExtractCallback
|
||||
STDMETHOD(AskOverwrite)(
|
||||
const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize,
|
||||
const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize,
|
||||
Int32 *answer);
|
||||
STDMETHOD (PrepareOperation)(const wchar_t *name, Int32 askExtractMode, const UInt64 *position);
|
||||
|
||||
STDMETHOD(MessageError)(const wchar_t *message);
|
||||
STDMETHOD(SetOperationResult)(Int32 operationResult);
|
||||
|
||||
// ICryptoGetTextPassword
|
||||
STDMETHOD(CryptoGetTextPassword)(BSTR *password);
|
||||
|
||||
HRESULT BeforeOpen(const wchar_t *name);
|
||||
HRESULT OpenResult(const wchar_t *name, HRESULT result);
|
||||
HRESULT ThereAreNoFiles();
|
||||
HRESULT ExtractResult(HRESULT result);
|
||||
|
||||
HRESULT SetPassword(const UString &password);
|
||||
|
||||
public:
|
||||
bool PasswordIsDefined;
|
||||
UString Password;
|
||||
|
||||
UInt64 NumArchives;
|
||||
UInt64 NumArchiveErrors;
|
||||
UInt64 NumFileErrors;
|
||||
UInt64 NumFileErrorsInCurrentArchive;
|
||||
|
||||
CStdOutStream *OutStream;
|
||||
|
||||
void CExtractCallbackConsole::Init()
|
||||
{
|
||||
NumArchives = 0;
|
||||
NumArchiveErrors = 0;
|
||||
NumFileErrors = 0;
|
||||
NumFileErrorsInCurrentArchive = 0;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -13,45 +13,40 @@
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "Windows/Defs.h"
|
||||
#include "Windows/PropVariantConversions.h"
|
||||
#include "Windows/FileDir.h"
|
||||
|
||||
#include "../../Archive/IArchive.h"
|
||||
|
||||
#include "../Common/PropIDUtils.h"
|
||||
#include "../Common/OpenArchive.h"
|
||||
|
||||
#include "OpenCallbackConsole.h"
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
/*
|
||||
static const char kEmptyFlag = '.';
|
||||
|
||||
static const char kPasswordFlag = '*';
|
||||
static const char kSolidFlag = 'S';
|
||||
static const char kSplitBeforeFlag = 'B';
|
||||
static const char kSplitAfterFlag = 'A';
|
||||
static const char kCommentedFlag = 'C';
|
||||
*/
|
||||
|
||||
static const char kEmptyAttributeChar = '.';
|
||||
//static const char kVolumeAttributeChar = 'V';
|
||||
static const char kDirectoryAttributeChar = 'D';
|
||||
static const char kReadonlyAttributeChar = 'R';
|
||||
static const char kHiddenAttributeChar = 'H';
|
||||
static const char kSystemAttributeChar = 'S';
|
||||
static const char kArchiveAttributeChar = 'A';
|
||||
|
||||
static AString GetAttributesString(DWORD winAttributes, bool directory)
|
||||
static const char *kListing = "Listing archive: ";
|
||||
static const wchar_t *kFilesMessage = L"files";
|
||||
|
||||
static void GetAttributesString(DWORD wa, bool directory, char *s)
|
||||
{
|
||||
AString s;
|
||||
// s = ((winAttributes & kLabelFileAttribute) != 0) ?
|
||||
// kVolumeAttributeChar: kEmptyAttributeChar;
|
||||
s += ((winAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 || directory) ?
|
||||
kDirectoryAttributeChar: kEmptyAttributeChar;
|
||||
s += ((winAttributes & FILE_ATTRIBUTE_READONLY) != 0)?
|
||||
kReadonlyAttributeChar: kEmptyAttributeChar;
|
||||
s += ((winAttributes & FILE_ATTRIBUTE_HIDDEN) != 0) ?
|
||||
kHiddenAttributeChar: kEmptyAttributeChar;
|
||||
s += ((winAttributes & FILE_ATTRIBUTE_SYSTEM) != 0) ?
|
||||
kSystemAttributeChar: kEmptyAttributeChar;
|
||||
s += ((winAttributes & FILE_ATTRIBUTE_ARCHIVE) != 0) ?
|
||||
kArchiveAttributeChar: kEmptyAttributeChar;
|
||||
return s;
|
||||
s[0] = ((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || directory) ?
|
||||
kDirectoryAttributeChar: kEmptyAttributeChar;
|
||||
s[1] = ((wa & FILE_ATTRIBUTE_READONLY) != 0)?
|
||||
kReadonlyAttributeChar: kEmptyAttributeChar;
|
||||
s[2] = ((wa & FILE_ATTRIBUTE_HIDDEN) != 0) ?
|
||||
kHiddenAttributeChar: kEmptyAttributeChar;
|
||||
s[3] = ((wa & FILE_ATTRIBUTE_SYSTEM) != 0) ?
|
||||
kSystemAttributeChar: kEmptyAttributeChar;
|
||||
s[4] = ((wa & FILE_ATTRIBUTE_ARCHIVE) != 0) ?
|
||||
kArchiveAttributeChar: kEmptyAttributeChar;
|
||||
s[5] = '\0';
|
||||
}
|
||||
|
||||
enum EAdjustment
|
||||
@@ -127,9 +122,9 @@ public:
|
||||
HRESULT PrintItemInfo(IInArchive *archive,
|
||||
const UString &defaultItemName,
|
||||
const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo,
|
||||
UINT32 index);
|
||||
HRESULT PrintSummaryInfo(UINT64 numFiles, const UINT64 *size,
|
||||
const UINT64 *compressedSize);
|
||||
UInt32 index);
|
||||
HRESULT PrintSummaryInfo(UInt64 numFiles, const UInt64 *size,
|
||||
const UInt64 *compressedSize);
|
||||
};
|
||||
|
||||
void CFieldPrinter::Init(const CFieldInfoInit *standardFieldTable, int numItems)
|
||||
@@ -155,7 +150,8 @@ void CFieldPrinter::PrintTitle()
|
||||
{
|
||||
const CFieldInfo &fieldInfo = _fields[i];
|
||||
PrintSpaces(fieldInfo.PrefixSpacesWidth);
|
||||
PrintString(fieldInfo.TitleAdjustment, fieldInfo.Width, fieldInfo.Name);
|
||||
PrintString(fieldInfo.TitleAdjustment,
|
||||
((fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width), fieldInfo.Name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,8 +172,7 @@ BOOL IsFileTimeZero(CONST FILETIME *lpFileTime)
|
||||
return (lpFileTime->dwLowDateTime == 0) && (lpFileTime->dwHighDateTime == 0);
|
||||
}
|
||||
|
||||
|
||||
const char *kEmptyTimeString = " ";
|
||||
static const char *kEmptyTimeString = " ";
|
||||
void PrintTime(const NCOM::CPropVariant &propVariant)
|
||||
{
|
||||
if (propVariant.vt != VT_FILETIME)
|
||||
@@ -189,14 +184,9 @@ void PrintTime(const NCOM::CPropVariant &propVariant)
|
||||
FILETIME localFileTime;
|
||||
if (!FileTimeToLocalFileTime(&propVariant.filetime, &localFileTime))
|
||||
throw "FileTimeToLocalFileTime error";
|
||||
SYSTEMTIME st;
|
||||
if (FileTimeToSystemTime(&localFileTime, &st))
|
||||
{
|
||||
char s[32];
|
||||
wsprintfA(s, "%04u-%02u-%02u %02u:%02u:%02u",
|
||||
st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
|
||||
char s[32];
|
||||
if (ConvertFileTimeToString(localFileTime, s, true, true))
|
||||
g_StdOut << s;
|
||||
}
|
||||
else
|
||||
g_StdOut << kEmptyTimeString;
|
||||
}
|
||||
@@ -205,7 +195,7 @@ void PrintTime(const NCOM::CPropVariant &propVariant)
|
||||
HRESULT CFieldPrinter::PrintItemInfo(IInArchive *archive,
|
||||
const UString &defaultItemName,
|
||||
const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo,
|
||||
UINT32 index)
|
||||
UInt32 index)
|
||||
{
|
||||
for (int i = 0; i < _fields.Size(); i++)
|
||||
{
|
||||
@@ -213,8 +203,8 @@ HRESULT CFieldPrinter::PrintItemInfo(IInArchive *archive,
|
||||
PrintSpaces(fieldInfo.PrefixSpacesWidth);
|
||||
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(archive->GetProperty(index,
|
||||
fieldInfo.PropID, &propVariant));
|
||||
RINOK(archive->GetProperty(index, fieldInfo.PropID, &propVariant));
|
||||
int width = (fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width;
|
||||
if (propVariant.vt == VT_EMPTY)
|
||||
{
|
||||
switch(fieldInfo.PropID)
|
||||
@@ -226,7 +216,7 @@ HRESULT CFieldPrinter::PrintItemInfo(IInArchive *archive,
|
||||
propVariant = archiveFileInfo.LastWriteTime;
|
||||
break;
|
||||
default:
|
||||
PrintSpaces(fieldInfo.Width);
|
||||
PrintSpaces(width);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -240,39 +230,37 @@ HRESULT CFieldPrinter::PrintItemInfo(IInArchive *archive,
|
||||
{
|
||||
if (propVariant.vt != VT_UI4)
|
||||
throw "incorrect item";
|
||||
UINT32 attributes = propVariant.ulVal;
|
||||
NCOM::CPropVariant propVariantIsFolder;
|
||||
RINOK(archive->GetProperty(index,
|
||||
kpidIsFolder, &propVariantIsFolder));
|
||||
if(propVariantIsFolder.vt != VT_BOOL)
|
||||
return E_FAIL;
|
||||
g_StdOut << GetAttributesString(attributes, VARIANT_BOOLToBool(propVariantIsFolder.boolVal));
|
||||
UInt32 attributes = propVariant.ulVal;
|
||||
bool isFolder;
|
||||
RINOK(IsArchiveItemFolder(archive, index, isFolder));
|
||||
char s[8];
|
||||
GetAttributesString(attributes, isFolder, s);
|
||||
g_StdOut << s;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (propVariant.vt == VT_BSTR)
|
||||
{
|
||||
PrintString(fieldInfo.TextAdjustment, fieldInfo.Width, propVariant.bstrVal);
|
||||
PrintString(fieldInfo.TextAdjustment, width, propVariant.bstrVal);
|
||||
continue;
|
||||
}
|
||||
PrintString(fieldInfo.TextAdjustment, fieldInfo.Width,
|
||||
PrintString(fieldInfo.TextAdjustment, width,
|
||||
ConvertPropertyToString(propVariant, fieldInfo.PropID));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void PrintNumberString(EAdjustment adjustment, int width, const UINT64 *value)
|
||||
void PrintNumberString(EAdjustment adjustment, int width, const UInt64 *value)
|
||||
{
|
||||
wchar_t textString[32] = { 0 };
|
||||
if (value != NULL)
|
||||
ConvertUINT64ToString(*value, textString);
|
||||
ConvertUInt64ToString(*value, textString);
|
||||
PrintString(adjustment, width, textString);
|
||||
}
|
||||
|
||||
static const wchar_t *kFilesMessage = L"files";
|
||||
|
||||
HRESULT CFieldPrinter::PrintSummaryInfo(UINT64 numFiles,
|
||||
const UINT64 *size, const UINT64 *compressedSize)
|
||||
HRESULT CFieldPrinter::PrintSummaryInfo(UInt64 numFiles,
|
||||
const UInt64 *size, const UInt64 *compressedSize)
|
||||
{
|
||||
for (int i = 0; i < _fields.Size(); i++)
|
||||
{
|
||||
@@ -286,11 +274,11 @@ HRESULT CFieldPrinter::PrintSummaryInfo(UINT64 numFiles,
|
||||
else if (fieldInfo.PropID == kpidPath)
|
||||
{
|
||||
wchar_t textString[32];
|
||||
ConvertUINT64ToString(numFiles, textString);
|
||||
ConvertUInt64ToString(numFiles, textString);
|
||||
UString temp = textString;
|
||||
temp += L" ";
|
||||
temp += kFilesMessage;
|
||||
PrintString(fieldInfo.TextAdjustment, fieldInfo.Width, temp);
|
||||
PrintString(fieldInfo.TextAdjustment, 0, temp);
|
||||
}
|
||||
else
|
||||
PrintString(fieldInfo.TextAdjustment, fieldInfo.Width, L"");
|
||||
@@ -298,84 +286,147 @@ HRESULT CFieldPrinter::PrintSummaryInfo(UINT64 numFiles,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
bool GetUINT64Value(IInArchive *archive, UINT32 index,
|
||||
PROPID propID, UINT64 &value)
|
||||
bool GetUInt64Value(IInArchive *archive, UInt32 index, PROPID propID, UInt64 &value)
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
if (archive->GetProperty(index, propID, &propVariant) != S_OK)
|
||||
throw "GetPropertyValue error";
|
||||
if (propVariant.vt == VT_EMPTY)
|
||||
return false;
|
||||
value = ConvertPropVariantToUINT64(propVariant);
|
||||
value = ConvertPropVariantToUInt64(propVariant);
|
||||
return true;
|
||||
}
|
||||
|
||||
HRESULT ListArchive(IInArchive *archive,
|
||||
const UString &defaultItemName,
|
||||
const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo,
|
||||
const NWildcard::CCensor &wildcardCensor/*, bool fullPathMode,
|
||||
NListMode::EEnum mode*/)
|
||||
HRESULT ListArchives(UStringVector &archivePaths, UStringVector &archivePathsFull,
|
||||
const NWildcard::CCensorNode &wildcardCensor,
|
||||
bool enableHeaders, bool &passwordEnabled, UString &password)
|
||||
{
|
||||
CFieldPrinter fieldPrinter;
|
||||
fieldPrinter.Init(kStandardFieldTable, sizeof(kStandardFieldTable) / sizeof(kStandardFieldTable[0]));
|
||||
fieldPrinter.PrintTitle();
|
||||
g_StdOut << endl;
|
||||
fieldPrinter.PrintTitleLines();
|
||||
g_StdOut << endl;
|
||||
|
||||
// bool nameFirst = (fullPathMode && (mode != NListMode::kDefault)) || (mode == NListMode::kAll);
|
||||
|
||||
UINT64 numFiles = 0, totalPackSize = 0, totalUnPackSize = 0;
|
||||
UINT64 *totalPackSizePointer = 0, *totalUnPackSizePointer = 0;
|
||||
UINT32 numItems;
|
||||
RINOK(archive->GetNumberOfItems(&numItems));
|
||||
for(UINT32 i = 0; i < numItems; i++)
|
||||
UInt64 numFiles2 = 0, totalPackSize2 = 0, totalUnPackSize2 = 0;
|
||||
UInt64 *totalPackSizePointer2 = 0, *totalUnPackSizePointer2 = 0;
|
||||
int numErrors = 0;
|
||||
for (int i = 0; i < archivePaths.Size(); i++)
|
||||
{
|
||||
if (NConsoleClose::TestBreakSignal())
|
||||
return E_ABORT;
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(archive->GetProperty(i, kpidPath, &propVariant));
|
||||
UString filePath;
|
||||
if(propVariant.vt == VT_EMPTY)
|
||||
filePath = defaultItemName;
|
||||
else
|
||||
const UString &archiveName = archivePaths[i];
|
||||
NFile::NFind::CFileInfoW archiveFileInfo;
|
||||
if (!NFile::NFind::FindFile(archiveName, archiveFileInfo) || archiveFileInfo.IsDirectory())
|
||||
{
|
||||
if(propVariant.vt != VT_BSTR)
|
||||
return E_FAIL;
|
||||
filePath = propVariant.bstrVal;
|
||||
}
|
||||
if (!wildcardCensor.CheckName(filePath))
|
||||
g_StdOut << endl << "Error: " << archiveName << " is not archive" << endl;
|
||||
numErrors++;
|
||||
continue;
|
||||
}
|
||||
if (archiveFileInfo.IsDirectory())
|
||||
{
|
||||
g_StdOut << endl << "Error: " << archiveName << " is not file" << endl;
|
||||
numErrors++;
|
||||
continue;
|
||||
}
|
||||
|
||||
fieldPrinter.PrintItemInfo(archive, defaultItemName, archiveFileInfo, i);
|
||||
CArchiveLink archiveLink;
|
||||
|
||||
UINT64 packSize, unpackSize;
|
||||
if (!GetUINT64Value(archive, i, kpidSize, unpackSize))
|
||||
unpackSize = 0;
|
||||
else
|
||||
totalUnPackSizePointer = &totalUnPackSize;
|
||||
if (!GetUINT64Value(archive, i, kpidPackedSize, packSize))
|
||||
packSize = 0;
|
||||
else
|
||||
totalPackSizePointer = &totalPackSize;
|
||||
COpenCallbackConsole openCallback;
|
||||
openCallback.OutStream = &g_StdOut;
|
||||
openCallback.PasswordIsDefined = passwordEnabled;
|
||||
openCallback.Password = password;
|
||||
|
||||
g_StdOut << endl;
|
||||
HRESULT result = MyOpenArchive(archiveName, archiveLink, &openCallback);
|
||||
if (result != S_OK)
|
||||
{
|
||||
g_StdOut << endl << "Error: " << archiveName << " is not supported archive" << endl;
|
||||
numErrors++;
|
||||
continue;
|
||||
}
|
||||
|
||||
numFiles++;
|
||||
totalPackSize += packSize;
|
||||
totalUnPackSize += unpackSize;
|
||||
for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)
|
||||
{
|
||||
int index = archivePathsFull.FindInSorted(archiveLink.VolumePaths[v]);
|
||||
if (index >= 0 && index > i)
|
||||
{
|
||||
archivePaths.Delete(index);
|
||||
archivePathsFull.Delete(index);
|
||||
}
|
||||
}
|
||||
|
||||
IInArchive *archive = archiveLink.GetArchive();
|
||||
const UString defaultItemName = archiveLink.GetDefaultItemName();
|
||||
|
||||
if (enableHeaders)
|
||||
g_StdOut << endl << kListing << archiveName << endl << endl;
|
||||
|
||||
if (enableHeaders)
|
||||
{
|
||||
fieldPrinter.PrintTitle();
|
||||
g_StdOut << endl;
|
||||
fieldPrinter.PrintTitleLines();
|
||||
g_StdOut << endl;
|
||||
}
|
||||
|
||||
UInt64 numFiles = 0, totalPackSize = 0, totalUnPackSize = 0;
|
||||
UInt64 *totalPackSizePointer = 0, *totalUnPackSizePointer = 0;
|
||||
UInt32 numItems;
|
||||
RINOK(archive->GetNumberOfItems(&numItems));
|
||||
for(UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
if (NConsoleClose::TestBreakSignal())
|
||||
return E_ABORT;
|
||||
|
||||
UString filePath;
|
||||
RINOK(GetArchiveItemPath(archive, i, defaultItemName, filePath));
|
||||
|
||||
bool isFolder;
|
||||
RINOK(IsArchiveItemFolder(archive, i, isFolder));
|
||||
if (!wildcardCensor.CheckPath(filePath, !isFolder))
|
||||
continue;
|
||||
|
||||
fieldPrinter.PrintItemInfo(archive, defaultItemName, archiveFileInfo, i);
|
||||
|
||||
UInt64 packSize, unpackSize;
|
||||
if (!GetUInt64Value(archive, i, kpidSize, unpackSize))
|
||||
unpackSize = 0;
|
||||
else
|
||||
totalUnPackSizePointer = &totalUnPackSize;
|
||||
if (!GetUInt64Value(archive, i, kpidPackedSize, packSize))
|
||||
packSize = 0;
|
||||
else
|
||||
totalPackSizePointer = &totalPackSize;
|
||||
|
||||
g_StdOut << endl;
|
||||
|
||||
numFiles++;
|
||||
totalPackSize += packSize;
|
||||
totalUnPackSize += unpackSize;
|
||||
}
|
||||
if (enableHeaders)
|
||||
{
|
||||
fieldPrinter.PrintTitleLines();
|
||||
g_StdOut << endl;
|
||||
fieldPrinter.PrintSummaryInfo(numFiles, totalUnPackSizePointer, totalPackSizePointer);
|
||||
g_StdOut << endl;
|
||||
}
|
||||
if (totalPackSizePointer != 0)
|
||||
{
|
||||
totalPackSizePointer2 = &totalPackSize2;
|
||||
totalPackSize2 += totalPackSize;
|
||||
}
|
||||
if (totalUnPackSizePointer != 0)
|
||||
{
|
||||
totalUnPackSizePointer2 = &totalUnPackSize2;
|
||||
totalUnPackSize2 += totalUnPackSize;
|
||||
}
|
||||
numFiles2 += numFiles;
|
||||
}
|
||||
fieldPrinter.PrintTitleLines();
|
||||
g_StdOut << endl;
|
||||
/*
|
||||
if(numFiles == 0)
|
||||
g_StdOut << kNoFilesMessage);
|
||||
else
|
||||
*/
|
||||
fieldPrinter.PrintSummaryInfo(numFiles, totalUnPackSizePointer, totalPackSizePointer);
|
||||
g_StdOut << endl;
|
||||
if (enableHeaders && archivePaths.Size() > 1)
|
||||
{
|
||||
g_StdOut << endl;
|
||||
fieldPrinter.PrintTitleLines();
|
||||
g_StdOut << endl;
|
||||
fieldPrinter.PrintSummaryInfo(numFiles2, totalUnPackSizePointer2, totalPackSizePointer2);
|
||||
g_StdOut << endl;
|
||||
g_StdOut << "Archives: " << archivePaths.Size() << endl;
|
||||
}
|
||||
if (numErrors > 0)
|
||||
g_StdOut << endl << "Errors: " << numErrors;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,31 +1,13 @@
|
||||
// List.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __LIST_H
|
||||
#define __LIST_H
|
||||
|
||||
#include "../../Archive/IArchive.h"
|
||||
#include "Common/Wildcard.h"
|
||||
#include "Windows/FileFind.h"
|
||||
|
||||
/*
|
||||
namespace NListMode
|
||||
{
|
||||
enum EEnum
|
||||
{
|
||||
kDefault,
|
||||
kAdd,
|
||||
kAll
|
||||
};
|
||||
}
|
||||
*/
|
||||
|
||||
HRESULT ListArchive(IInArchive *archive,
|
||||
const UString &defaultItemName,
|
||||
const NWindows::NFile::NFind::CFileInfoW &srchiveFileInfo,
|
||||
const NWildcard::CCensor &wildcardCensor/*, bool fullPathMode,
|
||||
NListMode::EEnum mode*/);
|
||||
HRESULT ListArchives(UStringVector &archivePaths, UStringVector &archivePathsFull,
|
||||
const NWildcard::CCensorNode &wildcardCensor,
|
||||
bool enableHeaders, bool &passwordEnabled, UString &password);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,28 +4,34 @@
|
||||
|
||||
// #include <locale.h>
|
||||
|
||||
#include "Windows/COM.h"
|
||||
#include "Windows/Error.h"
|
||||
|
||||
#include "Common/StdOutStream.h"
|
||||
#include "Common/NewHandler.h"
|
||||
#include "Common/Exception.h"
|
||||
#include "Common/StringConvert.h"
|
||||
|
||||
#include "../Common/ExitCode.h"
|
||||
#include "ConsoleClose.h"
|
||||
#include "ArError.h"
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
// extern int Main2(int numArguments, const char *arguments[]);
|
||||
extern int Main2();
|
||||
CStdOutStream *g_StdStream = 0;
|
||||
|
||||
extern int Main2(
|
||||
#ifndef _WIN32
|
||||
int numArguments, const char *arguments[]
|
||||
#endif
|
||||
);
|
||||
|
||||
static const char *kExceptionErrorMessage = "\n\nError:\n";
|
||||
static const char *kUserBreak = "\nBreak signaled\n";
|
||||
|
||||
static const char *kMemoryExceptionMessage = "\n\nMemory Error! Can't allocate!\n";
|
||||
static const char *kMemoryExceptionMessage = "\n\nERROR: Can't allocate required memory!\n";
|
||||
static const char *kUnknownExceptionMessage = "\n\nUnknown Error\n";
|
||||
static const char *kInternalExceptionMessage = "\n\nInternal Error #";
|
||||
|
||||
#ifdef UNICODE
|
||||
static inline bool IsItWindowsNT()
|
||||
{
|
||||
OSVERSIONINFO versionInfo;
|
||||
@@ -34,81 +40,100 @@ static inline bool IsItWindowsNT()
|
||||
return false;
|
||||
return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
|
||||
}
|
||||
#endif
|
||||
|
||||
int __cdecl main()
|
||||
// int __cdecl main(int numArguments, const char *arguments[])
|
||||
int
|
||||
#ifdef _MSC_VER
|
||||
__cdecl
|
||||
#endif
|
||||
main
|
||||
(
|
||||
#ifndef _WIN32
|
||||
int numArguments, const char *arguments[]
|
||||
#endif
|
||||
)
|
||||
{
|
||||
g_StdStream = &g_StdOut;
|
||||
#ifdef UNICODE
|
||||
if (!IsItWindowsNT())
|
||||
{
|
||||
g_StdOut << "This program requires Windows NT/2000/XP";
|
||||
(*g_StdStream) << "This program requires Windows NT/2000/XP/2003";
|
||||
return NExitCode::kFatalError;
|
||||
}
|
||||
#endif
|
||||
// setlocale(LC_COLLATE, ".OCP");
|
||||
int result=1;
|
||||
NCOM::CComInitializer comInitializer;
|
||||
NConsoleClose::CCtrlHandlerSetter ctrlHandlerSetter;
|
||||
try
|
||||
{
|
||||
NConsoleClose::CCtrlHandlerSetter aCtrlHandlerSetter;
|
||||
try
|
||||
{
|
||||
// result = Main2(numArguments, arguments);
|
||||
result = Main2();
|
||||
}
|
||||
catch(const NConsoleClose::CCtrlBreakException &)
|
||||
{
|
||||
g_StdOut << endl << kUserBreak;
|
||||
return (NExitCode::kUserBreak);
|
||||
}
|
||||
return Main2(
|
||||
#ifndef _WIN32
|
||||
numArguments, arguments
|
||||
#endif
|
||||
);
|
||||
}
|
||||
catch(const CNewException)
|
||||
catch(const CNewException &)
|
||||
{
|
||||
g_StdOut << kMemoryExceptionMessage;
|
||||
(*g_StdStream) << kMemoryExceptionMessage;
|
||||
return (NExitCode::kMemoryError);
|
||||
}
|
||||
catch(const CSystemException &e)
|
||||
catch(const NConsoleClose::CCtrlBreakException &)
|
||||
{
|
||||
g_StdOut << "System Error: " << (UINT64)(e.ErrorCode);
|
||||
return (NExitCode::kFatalError);
|
||||
(*g_StdStream) << endl << kUserBreak;
|
||||
return (NExitCode::kUserBreak);
|
||||
}
|
||||
catch(NExitCode::EEnum &aExitCode)
|
||||
{
|
||||
g_StdOut << kInternalExceptionMessage << aExitCode << endl;
|
||||
return (aExitCode);
|
||||
}
|
||||
catch(const NExitCode::CSystemError &systemError)
|
||||
catch(const CSystemException &systemError)
|
||||
{
|
||||
if (systemError.ErrorCode == E_OUTOFMEMORY)
|
||||
{
|
||||
(*g_StdStream) << kMemoryExceptionMessage;
|
||||
return (NExitCode::kMemoryError);
|
||||
}
|
||||
if (systemError.ErrorCode == E_ABORT)
|
||||
{
|
||||
(*g_StdStream) << endl << kUserBreak;
|
||||
return (NExitCode::kUserBreak);
|
||||
}
|
||||
UString message;
|
||||
NError::MyFormatMessage(systemError.ErrorValue, message);
|
||||
g_StdOut << endl << endl << "System error:" << endl <<
|
||||
NError::MyFormatMessage(systemError.ErrorCode, message);
|
||||
(*g_StdStream) << endl << endl << "System error:" << endl <<
|
||||
message << endl;
|
||||
return (NExitCode::kFatalError);
|
||||
}
|
||||
catch(NExitCode::EEnum &exitCode)
|
||||
{
|
||||
(*g_StdStream) << kInternalExceptionMessage << exitCode << endl;
|
||||
return (exitCode);
|
||||
}
|
||||
/*
|
||||
catch(const NExitCode::CMultipleErrors &multipleErrors)
|
||||
{
|
||||
g_StdOut << endl << multipleErrors.NumErrors << " errors" << endl;
|
||||
(*g_StdStream) << endl << multipleErrors.NumErrors << " errors" << endl;
|
||||
return (NExitCode::kFatalError);
|
||||
}
|
||||
*/
|
||||
catch(const UString &s)
|
||||
{
|
||||
g_StdOut << kExceptionErrorMessage << s << endl;
|
||||
(*g_StdStream) << kExceptionErrorMessage << s << endl;
|
||||
return (NExitCode::kFatalError);
|
||||
}
|
||||
catch(const AString &s)
|
||||
{
|
||||
(*g_StdStream) << kExceptionErrorMessage << s << endl;
|
||||
return (NExitCode::kFatalError);
|
||||
}
|
||||
catch(const char *s)
|
||||
{
|
||||
g_StdOut << kExceptionErrorMessage << s << endl;
|
||||
(*g_StdStream) << kExceptionErrorMessage << s << endl;
|
||||
return (NExitCode::kFatalError);
|
||||
}
|
||||
catch(int t)
|
||||
{
|
||||
g_StdOut << kInternalExceptionMessage << t << endl;
|
||||
(*g_StdStream) << kInternalExceptionMessage << t << endl;
|
||||
return (NExitCode::kFatalError);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
g_StdOut << kUnknownExceptionMessage;
|
||||
(*g_StdStream) << kUnknownExceptionMessage;
|
||||
return (NExitCode::kFatalError);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
// OpenCallback.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "OpenCallback.h"
|
||||
|
||||
#include "Common/StdOutStream.h"
|
||||
#include "Common/StdInStream.h"
|
||||
#include "Common/StringConvert.h"
|
||||
|
||||
#include "../../Common/FileStreams.h"
|
||||
|
||||
#include "Windows/PropVariant.h"
|
||||
|
||||
#include "ConsoleClose.h"
|
||||
|
||||
STDMETHODIMP COpenCallbackImp::SetTotal(const UINT64 *files, const UINT64 *bytes)
|
||||
{
|
||||
if (NConsoleClose::TestBreakSignal())
|
||||
return E_ABORT;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP COpenCallbackImp::SetCompleted(const UINT64 *files, const UINT64 *bytes)
|
||||
{
|
||||
if (NConsoleClose::TestBreakSignal())
|
||||
return E_ABORT;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
switch(propID)
|
||||
{
|
||||
case kpidName:
|
||||
propVariant = _fileInfo.Name;
|
||||
break;
|
||||
case kpidIsFolder:
|
||||
propVariant = _fileInfo.IsDirectory();
|
||||
break;
|
||||
case kpidSize:
|
||||
propVariant = _fileInfo.Size;
|
||||
break;
|
||||
case kpidAttributes:
|
||||
propVariant = (UINT32)_fileInfo.Attributes;
|
||||
break;
|
||||
case kpidLastAccessTime:
|
||||
propVariant = _fileInfo.LastAccessTime;
|
||||
break;
|
||||
case kpidCreationTime:
|
||||
propVariant = _fileInfo.CreationTime;
|
||||
break;
|
||||
case kpidLastWriteTime:
|
||||
propVariant = _fileInfo.LastWriteTime;
|
||||
break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name,
|
||||
IInStream **inStream)
|
||||
{
|
||||
*inStream = NULL;
|
||||
UString fullPath = _folderPrefix + name;
|
||||
if (!NWindows::NFile::NFind::FindFile(fullPath, _fileInfo))
|
||||
return S_FALSE;
|
||||
if (_fileInfo.IsDirectory())
|
||||
return S_FALSE;
|
||||
CInFileStream *inFile = new CInFileStream;
|
||||
CMyComPtr<IInStream> inStreamTemp = inFile;
|
||||
if (!inFile->Open(fullPath))
|
||||
return ::GetLastError();
|
||||
*inStream = inStreamTemp.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP COpenCallbackImp::CryptoGetTextPassword(BSTR *password)
|
||||
{
|
||||
if (!PasswordIsDefined)
|
||||
{
|
||||
g_StdOut << "\nEnter password:";
|
||||
AString oemPassword = g_StdIn.ScanStringUntilNewLine();
|
||||
Password = MultiByteToUnicodeString(oemPassword, CP_OEMCP);
|
||||
PasswordIsDefined = true;
|
||||
}
|
||||
CMyComBSTR temp(Password);
|
||||
*password = temp.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
// OpenCallback.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __OPENCALLBACK_H
|
||||
#define __OPENCALLBACK_H
|
||||
|
||||
#include "Common/String.h"
|
||||
#include "Common/MyCom.h"
|
||||
#include "Windows/FileFind.h"
|
||||
|
||||
#include "../../Archive/IArchive.h"
|
||||
#include "../../IPassword.h"
|
||||
|
||||
class COpenCallbackImp:
|
||||
public IArchiveOpenCallback,
|
||||
public IArchiveOpenVolumeCallback,
|
||||
public ICryptoGetTextPassword,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP2(
|
||||
IArchiveOpenVolumeCallback,
|
||||
ICryptoGetTextPassword
|
||||
)
|
||||
|
||||
STDMETHOD(SetTotal)(const UINT64 *files, const UINT64 *bytes);
|
||||
STDMETHOD(SetCompleted)(const UINT64 *files, const UINT64 *bytes);
|
||||
|
||||
// IArchiveOpenVolumeCallback
|
||||
STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value);
|
||||
STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream);
|
||||
|
||||
// ICryptoGetTextPassword
|
||||
STDMETHOD(CryptoGetTextPassword)(BSTR *password);
|
||||
|
||||
private:
|
||||
UString _folderPrefix;
|
||||
NWindows::NFile::NFind::CFileInfoW _fileInfo;
|
||||
public:
|
||||
bool PasswordIsDefined;
|
||||
UString Password;
|
||||
COpenCallbackImp(): PasswordIsDefined(false) {}
|
||||
void LoadFileInfo(const UString &folderPrefix, const UString &fileName)
|
||||
{
|
||||
_folderPrefix = folderPrefix;
|
||||
if (!NWindows::NFile::NFind::FindFile(_folderPrefix + fileName, _fileInfo))
|
||||
throw 1;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
47
7zip/UI/Console/OpenCallbackConsole.cpp
Executable file
47
7zip/UI/Console/OpenCallbackConsole.cpp
Executable file
@@ -0,0 +1,47 @@
|
||||
// OpenCallbackConsole.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "OpenCallbackConsole.h"
|
||||
|
||||
#include "ConsoleClose.h"
|
||||
#include "UserInputUtils.h"
|
||||
|
||||
HRESULT COpenCallbackConsole::CheckBreak()
|
||||
{
|
||||
if (NConsoleClose::TestBreakSignal())
|
||||
return E_ABORT;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT COpenCallbackConsole::SetTotal(const UInt64 *files, const UInt64 *bytes)
|
||||
{
|
||||
return CheckBreak();
|
||||
}
|
||||
|
||||
HRESULT COpenCallbackConsole::SetCompleted(const UInt64 *files, const UInt64 *bytes)
|
||||
{
|
||||
return CheckBreak();
|
||||
}
|
||||
|
||||
HRESULT COpenCallbackConsole::CryptoGetTextPassword(BSTR *password)
|
||||
{
|
||||
RINOK(CheckBreak());
|
||||
if (!PasswordIsDefined)
|
||||
{
|
||||
Password = GetPassword(OutStream);
|
||||
PasswordIsDefined = true;
|
||||
}
|
||||
CMyComBSTR temp(Password);
|
||||
*password = temp.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT COpenCallbackConsole::GetPasswordIfAny(UString &password)
|
||||
{
|
||||
if (PasswordIsDefined)
|
||||
password = Password;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
24
7zip/UI/Console/OpenCallbackConsole.h
Executable file
24
7zip/UI/Console/OpenCallbackConsole.h
Executable file
@@ -0,0 +1,24 @@
|
||||
// OpenCallbackConsole.h
|
||||
|
||||
#ifndef __OPENCALLBACKCONSOLE_H
|
||||
#define __OPENCALLBACKCONSOLE_H
|
||||
|
||||
#include "Common/StdOutStream.h"
|
||||
#include "../Common/ArchiveOpenCallback.h"
|
||||
|
||||
class COpenCallbackConsole: public IOpenCallbackUI
|
||||
{
|
||||
public:
|
||||
HRESULT CheckBreak();
|
||||
HRESULT SetTotal(const UInt64 *files, const UInt64 *bytes);
|
||||
HRESULT SetCompleted(const UInt64 *files, const UInt64 *bytes);
|
||||
HRESULT CryptoGetTextPassword(BSTR *password);
|
||||
HRESULT GetPasswordIfAny(UString &password);
|
||||
|
||||
CStdOutStream *OutStream;
|
||||
bool PasswordIsDefined;
|
||||
UString Password;
|
||||
COpenCallbackConsole(): PasswordIsDefined(false) {}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/StdOutStream.h"
|
||||
#include "Common/IntToString.h"
|
||||
#include "Common/String.h"
|
||||
|
||||
@@ -14,7 +13,7 @@ static const char *kCloseString = "\b\b\b\b \b\b\b\b";
|
||||
static const char *kPercentFormatString1 = "\b\b\b\b";
|
||||
static const int kNumDigits = 3;
|
||||
|
||||
CPercentPrinter::CPercentPrinter(UINT64 minStepSize):
|
||||
CPercentPrinter::CPercentPrinter(UInt64 minStepSize):
|
||||
m_MinStepSize(minStepSize),
|
||||
m_ScreenPos(0),
|
||||
m_StringIsPrinted(false)
|
||||
@@ -27,53 +26,51 @@ CPercentPrinter::CPercentPrinter(UINT64 minStepSize):
|
||||
void CPercentPrinter::PreparePrint()
|
||||
{
|
||||
if (m_ScreenPos < kNumPercentSpaces)
|
||||
g_StdOut << (m_Spaces + m_ScreenPos);
|
||||
(*OutStream) << (m_Spaces + m_ScreenPos);
|
||||
m_ScreenPos = kNumPercentSpaces;
|
||||
g_StdOut << kPrepareString;
|
||||
(*OutStream) << kPrepareString;
|
||||
}
|
||||
|
||||
void CPercentPrinter::ClosePrint()
|
||||
{
|
||||
g_StdOut << kCloseString;
|
||||
(*OutStream) << kCloseString;
|
||||
m_StringIsPrinted = false;
|
||||
}
|
||||
|
||||
void CPercentPrinter::PrintString(const char *s)
|
||||
{
|
||||
m_ScreenPos += MyStringLen(s);
|
||||
g_StdOut << s;
|
||||
(*OutStream) << s;
|
||||
}
|
||||
|
||||
void CPercentPrinter::PrintString(const wchar_t *s)
|
||||
{
|
||||
m_ScreenPos += MyStringLen(s);
|
||||
g_StdOut << s;
|
||||
(*OutStream) << s;
|
||||
}
|
||||
|
||||
void CPercentPrinter::PrintNewLine()
|
||||
{
|
||||
m_ScreenPos = 0;
|
||||
g_StdOut << "\n";
|
||||
(*OutStream) << "\n";
|
||||
m_StringIsPrinted = false;
|
||||
}
|
||||
|
||||
void CPercentPrinter::SetRatio(UINT64 doneValue)
|
||||
void CPercentPrinter::SetRatio(UInt64 doneValue)
|
||||
{ m_CurValue = doneValue; }
|
||||
|
||||
void CPercentPrinter::RePrintRatio()
|
||||
{
|
||||
if (m_Total == 0)
|
||||
return;
|
||||
UINT64 ratio = m_CurValue * 100 / m_Total;
|
||||
// char temp[32];
|
||||
// sprintf(temp, kPercentFormatString, ratio);
|
||||
UInt64 ratio = m_CurValue * 100 / m_Total;
|
||||
char temp[32 + kNumDigits] = " "; // for 4 digits;
|
||||
ConvertUINT64ToString(ratio, temp + kNumDigits);
|
||||
int len = lstrlenA(temp + kNumDigits);
|
||||
lstrcatA(temp, "%");
|
||||
ConvertUInt64ToString(ratio, temp + kNumDigits);
|
||||
int len = strlen(temp + kNumDigits);
|
||||
strcat(temp, "%");
|
||||
int pos = (len > kNumDigits)? kNumDigits : len;
|
||||
g_StdOut << kPercentFormatString1;
|
||||
g_StdOut << (temp + pos);
|
||||
(*OutStream) << kPercentFormatString1;
|
||||
(*OutStream) << (temp + pos);
|
||||
m_PrevValue = m_CurValue;
|
||||
m_StringIsPrinted = true;
|
||||
}
|
||||
|
||||
@@ -1,25 +1,27 @@
|
||||
// PercentPrinter.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __PERCENTPRINTER_H
|
||||
#define __PERCENTPRINTER_H
|
||||
|
||||
#include "Common/Defs.h"
|
||||
#include "Common/Types.h"
|
||||
#include "Common/StdOutStream.h"
|
||||
|
||||
const int kNumPercentSpaces = 70;
|
||||
class CPercentPrinter
|
||||
{
|
||||
UINT64 m_MinStepSize;
|
||||
UINT64 m_PrevValue;
|
||||
UINT64 m_CurValue;
|
||||
UINT64 m_Total;
|
||||
UINT32 m_ScreenPos;
|
||||
UInt64 m_MinStepSize;
|
||||
UInt64 m_PrevValue;
|
||||
UInt64 m_CurValue;
|
||||
UInt64 m_Total;
|
||||
UInt32 m_ScreenPos;
|
||||
char m_Spaces[kNumPercentSpaces + 1];
|
||||
bool m_StringIsPrinted;
|
||||
public:
|
||||
CPercentPrinter(UINT64 minStepSize = 1);
|
||||
void SetTotal(UINT64 total)
|
||||
CStdOutStream *OutStream;
|
||||
|
||||
CPercentPrinter(UInt64 minStepSize = 1);
|
||||
void SetTotal(UInt64 total)
|
||||
{
|
||||
m_Total = total;
|
||||
m_PrevValue = 0;
|
||||
@@ -30,7 +32,7 @@ public:
|
||||
void PrintNewLine();
|
||||
void PreparePrint();
|
||||
void ClosePrint();
|
||||
void SetRatio(UINT64 doneValue);
|
||||
void SetRatio(UInt64 doneValue);
|
||||
void RePrintRatio();
|
||||
void PrintRatio();
|
||||
};
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
// StdAfx.cpp
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
// stdafx.h
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <vector>
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
// TempFiles.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "TempFiles.h"
|
||||
|
||||
#include "Windows/FileDir.h"
|
||||
#include "Windows/FileIO.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
|
||||
void CFileVectorBundle::DisableDeleting(int index)
|
||||
{
|
||||
m_FileNames.Delete(index);
|
||||
}
|
||||
|
||||
bool CFileVectorBundle::Add(const UString &filePath, bool tryToOpen)
|
||||
{
|
||||
if (tryToOpen)
|
||||
{
|
||||
NIO::COutFile file;
|
||||
if (!file.Open(filePath))
|
||||
return false;
|
||||
}
|
||||
m_FileNames.Add(filePath);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CFileVectorBundle::Clear()
|
||||
{
|
||||
while(!m_FileNames.IsEmpty())
|
||||
{
|
||||
NDirectory::DeleteFileAlways(m_FileNames.Back());
|
||||
m_FileNames.DeleteBack();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
// FileCreationUtils.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FILECREATIONUTILS_H
|
||||
#define __FILECREATIONUTILS_H
|
||||
|
||||
#include "Common/String.h"
|
||||
|
||||
class CFileVectorBundle
|
||||
{
|
||||
UStringVector m_FileNames;
|
||||
public:
|
||||
~CFileVectorBundle() { Clear(); }
|
||||
bool Add(const UString &filePath, bool tryToOpen = true);
|
||||
void DisableDeleting(int index);
|
||||
void Clear();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,503 +0,0 @@
|
||||
// Update.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Update.h"
|
||||
|
||||
#include "Common/StdOutStream.h"
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/MyCom.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
#include "Windows/Error.h"
|
||||
#include "Windows/FileDir.h"
|
||||
#include "Windows/FileFind.h"
|
||||
#include "Windows/FileName.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "Windows/PropVariantConversions.h"
|
||||
#include "Windows/Error.h"
|
||||
|
||||
#include "../../Common/FileStreams.h"
|
||||
#include "../../Compress/Copy/CopyCoder.h"
|
||||
|
||||
#include "../Common/DirItem.h"
|
||||
#include "../Common/EnumDirItems.h"
|
||||
#include "../Common/UpdateProduce.h"
|
||||
|
||||
#include "TempFiles.h"
|
||||
#include "ConsoleClose.h"
|
||||
#include "UpdateCallback.h"
|
||||
|
||||
#ifdef FORMAT_7Z
|
||||
#include "../../Archive/7z/7zHandler.h"
|
||||
#endif
|
||||
|
||||
#ifdef FORMAT_BZIP2
|
||||
#include "../../Archive/BZip2/BZip2Handler.h"
|
||||
#endif
|
||||
|
||||
#ifdef FORMAT_GZIP
|
||||
#include "../../Archive/GZip/GZipHandler.h"
|
||||
#endif
|
||||
|
||||
#ifdef FORMAT_TAR
|
||||
#include "../../Archive/Tar/TarHandler.h"
|
||||
#endif
|
||||
|
||||
#ifdef FORMAT_ZIP
|
||||
#include "../../Archive/Zip/ZipHandler.h"
|
||||
#endif
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
#include "../Common/HandlerLoader.h"
|
||||
#endif
|
||||
|
||||
static const char *kCreatingArchiveMessage = "Creating archive ";
|
||||
static const char *kUpdatingArchiveMessage = "Updating archive ";
|
||||
static const char *kScanningMessage = "Scanning";
|
||||
static const char *kNoFilesScannedMessage = "No files scanned";
|
||||
static const char *kTotalFilesAddedMessage = "Total files added to archive: ";
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NCOM;
|
||||
using namespace NFile;
|
||||
using namespace NName;
|
||||
|
||||
static wchar_t *kTempArchiveFilePrefixString = L"7zi";
|
||||
static const char *kEverythingIsOk = "Everything is Ok";
|
||||
|
||||
static const char *kIllegalFileNameMessage = "Illegal file name for temp archive";
|
||||
|
||||
using namespace NUpdateArchive;
|
||||
|
||||
static bool ParseNumberString(const UString &srcString, UINT32 &number)
|
||||
{
|
||||
wchar_t *anEndPtr;
|
||||
number = wcstoul(srcString, &anEndPtr, 10);
|
||||
return (anEndPtr - srcString == srcString.Length());
|
||||
}
|
||||
|
||||
|
||||
static HRESULT CopyBlock(ISequentialInStream *inStream, ISequentialOutStream *outStream)
|
||||
{
|
||||
CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
|
||||
return copyCoder->Code(inStream, outStream, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
HRESULT Compress(
|
||||
const CActionSet &actionSet,
|
||||
IInArchive *archive,
|
||||
const CCompressionMethodMode &compressionMethod,
|
||||
const UString &archiveName,
|
||||
const CObjectVector<CArchiveItem> &archiveItems,
|
||||
const CObjectVector<CDirItem> &dirItems,
|
||||
bool enablePercents,
|
||||
bool sfxMode,
|
||||
const UString &sfxModule)
|
||||
{
|
||||
#ifndef EXCLUDE_COM
|
||||
CHandlerLoader loader;
|
||||
#endif
|
||||
|
||||
CMyComPtr<IOutArchive> outArchive;
|
||||
if(archive != NULL)
|
||||
{
|
||||
CMyComPtr<IInArchive> archive2 = archive;
|
||||
HRESULT result = archive2.QueryInterface(IID_IOutArchive, &outArchive);
|
||||
if(result != S_OK)
|
||||
{
|
||||
throw "update operations are not supported for this archive";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef EXCLUDE_COM
|
||||
|
||||
HRESULT result = loader.CreateHandler(compressionMethod.FilePath,
|
||||
compressionMethod.ClassID1, (void **)&outArchive, true);
|
||||
|
||||
if (result != S_OK)
|
||||
{
|
||||
throw "update operations are not supported for this archive";
|
||||
return E_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FORMAT_7Z
|
||||
if (compressionMethod.Name.CompareNoCase(L"7z") == 0)
|
||||
outArchive = new NArchive::N7z::CHandler;
|
||||
#endif
|
||||
|
||||
#ifdef FORMAT_BZIP2
|
||||
if (compressionMethod.Name.CompareNoCase(L"BZip2") == 0)
|
||||
outArchive = new NArchive::NBZip2::CHandler;
|
||||
#endif
|
||||
|
||||
#ifdef FORMAT_GZIP
|
||||
if (compressionMethod.Name.CompareNoCase(L"GZip") == 0)
|
||||
outArchive = new NArchive::NGZip::CHandler;
|
||||
#endif
|
||||
|
||||
#ifdef FORMAT_TAR
|
||||
if (compressionMethod.Name.CompareNoCase(L"Tar") == 0)
|
||||
outArchive = new NArchive::NTar::CHandler;
|
||||
#endif
|
||||
|
||||
#ifdef FORMAT_ZIP
|
||||
if (compressionMethod.Name.CompareNoCase(L"Zip") == 0)
|
||||
outArchive = new NArchive::NZip::CHandler;
|
||||
#endif
|
||||
|
||||
|
||||
if (outArchive == 0)
|
||||
{
|
||||
throw "update operations are not supported for this archive";
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
NFileTimeType::EEnum fileTimeType;
|
||||
UINT32 value;
|
||||
RINOK(outArchive->GetFileTimeType(&value));
|
||||
|
||||
switch(value)
|
||||
{
|
||||
case NFileTimeType::kWindows:
|
||||
case NFileTimeType::kDOS:
|
||||
case NFileTimeType::kUnix:
|
||||
fileTimeType = NFileTimeType::EEnum(value);
|
||||
break;
|
||||
default:
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
CObjectVector<CUpdatePair> updatePairs;
|
||||
GetUpdatePairInfoList(dirItems, archiveItems, fileTimeType, updatePairs); // must be done only once!!!
|
||||
|
||||
CObjectVector<CUpdatePair2> operationChain;
|
||||
UpdateProduce(dirItems, archiveItems, updatePairs, actionSet,
|
||||
operationChain);
|
||||
|
||||
CUpdateCallbackImp *updateCallbackSpec = new CUpdateCallbackImp;
|
||||
CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec );
|
||||
|
||||
updateCallbackSpec->Init(&dirItems, &archiveItems, &operationChain, enablePercents,
|
||||
compressionMethod.PasswordIsDefined, compressionMethod.Password,
|
||||
compressionMethod.AskPassword);
|
||||
|
||||
COutFileStream *outStreamSpec = new COutFileStream;
|
||||
CMyComPtr<IOutStream> outStream(outStreamSpec);
|
||||
|
||||
{
|
||||
UString resultPath;
|
||||
int pos;
|
||||
if(! NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos))
|
||||
throw 141716;
|
||||
NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos));
|
||||
}
|
||||
if (!outStreamSpec->Open(archiveName))
|
||||
{
|
||||
UString message;
|
||||
NError::MyFormatMessage(::GetLastError(), message);
|
||||
g_StdOut << message << endl;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
CMyComPtr<ISetProperties> setProperties;
|
||||
if (outArchive.QueryInterface(IID_ISetProperties, &setProperties) == S_OK)
|
||||
{
|
||||
CObjectVector<CMyComBSTR> realNames;
|
||||
std::vector<CPropVariant> values;
|
||||
int i;
|
||||
for(i = 0; i < compressionMethod.Properties.Size(); i++)
|
||||
{
|
||||
const CProperty &property = compressionMethod.Properties[i];
|
||||
NCOM::CPropVariant propVariant;
|
||||
UINT32 number;
|
||||
if (!property.Value.IsEmpty())
|
||||
{
|
||||
if (ParseNumberString(property.Value, number))
|
||||
propVariant = number;
|
||||
else
|
||||
propVariant = property.Value;
|
||||
}
|
||||
CMyComBSTR comBSTR(property.Name);
|
||||
realNames.Add(comBSTR);
|
||||
values.push_back(propVariant);
|
||||
}
|
||||
std::vector<BSTR> names;
|
||||
for(i = 0; i < realNames.Size(); i++)
|
||||
names.push_back(realNames[i]);
|
||||
|
||||
RINOK(setProperties->SetProperties(&names.front(),
|
||||
&values.front(), names.size()));
|
||||
}
|
||||
|
||||
if (sfxMode)
|
||||
{
|
||||
CInFileStream *sfxStreamSpec = new CInFileStream;
|
||||
CMyComPtr<IInStream> sfxStream(sfxStreamSpec);
|
||||
if (!sfxStreamSpec->Open(sfxModule))
|
||||
throw "Can't open sfx module";
|
||||
RINOK(CopyBlock(sfxStream, outStream));
|
||||
}
|
||||
|
||||
return outArchive->UpdateItems(outStream, operationChain.Size(),
|
||||
updateCallback);
|
||||
}
|
||||
|
||||
static void EnumerateDirItems(const NWildcard::CCensorNode &curNode,
|
||||
const UString &directory,
|
||||
const UString &prefix,
|
||||
bool checkNameFull,
|
||||
CObjectVector<CDirItem> &dirItems,
|
||||
bool enterToSubFolders)
|
||||
{
|
||||
NConsoleClose::CheckCtrlBreak();
|
||||
|
||||
NFind::CEnumeratorW enumerator(directory + wchar_t(kAnyStringWildcard));
|
||||
NFind::CFileInfoW fileInfo;
|
||||
while (enumerator.Next(fileInfo))
|
||||
{
|
||||
NConsoleClose::CheckCtrlBreak();
|
||||
UString unicodeName = fileInfo.Name;
|
||||
if (checkNameFull)
|
||||
{
|
||||
if (curNode.CheckNameFull(unicodeName))
|
||||
AddDirFileInfo(prefix, directory + fileInfo.Name, fileInfo,
|
||||
dirItems);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (curNode.CheckNameRecursive(unicodeName))
|
||||
AddDirFileInfo(prefix, directory + fileInfo.Name, fileInfo,
|
||||
dirItems);
|
||||
}
|
||||
if (enterToSubFolders && fileInfo.IsDirectory())
|
||||
{
|
||||
const NWildcard::CCensorNode *nextNode = &curNode;
|
||||
if (checkNameFull)
|
||||
{
|
||||
nextNode = ((NWildcard::CCensorNode *)&curNode)->FindSubNode(unicodeName);
|
||||
if (nextNode == NULL)
|
||||
nextNode = &curNode;
|
||||
}
|
||||
EnumerateDirItems(*nextNode,
|
||||
directory + fileInfo.Name + wchar_t(kDirDelimiter),
|
||||
prefix + unicodeName + wchar_t(kDirDelimiter),
|
||||
nextNode != (&curNode), dirItems, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void EnumerateItems(const NWildcard::CCensorNode &curNode,
|
||||
const UString &directory,
|
||||
const UString &prefix,
|
||||
CObjectVector<CDirItem> &dirItems)
|
||||
{
|
||||
NConsoleClose::CheckCtrlBreak();
|
||||
if (!curNode.GetAllowedRecursedNamesVector(false).IsEmpty() ||
|
||||
!curNode.GetAllowedRecursedNamesVector(true).IsEmpty())
|
||||
{
|
||||
EnumerateDirItems(curNode, directory, prefix, true, dirItems,
|
||||
true);
|
||||
return;
|
||||
}
|
||||
if (!curNode.GetAllowedNamesVector(false, true).IsEmpty())
|
||||
{
|
||||
EnumerateDirItems(curNode, directory, prefix, true, dirItems,
|
||||
false);
|
||||
}
|
||||
else
|
||||
{
|
||||
const UStringVector &directNames = curNode.GetAllowedNamesVector(false, false);
|
||||
for (int i = 0; i < directNames.Size(); i++)
|
||||
{
|
||||
const UString &nameSpec = directNames[i];
|
||||
if (curNode.CheckName(nameSpec, false, false))
|
||||
continue;
|
||||
|
||||
NFind::CFileInfoW fileInfo;
|
||||
if (!NFind::FindFile(directory + nameSpec, fileInfo))
|
||||
continue;
|
||||
|
||||
AddDirFileInfo(prefix, directory + fileInfo.Name, fileInfo, dirItems);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < curNode.SubNodes.Size(); i++)
|
||||
{
|
||||
const NWildcard::CCensorNode &nextNode = curNode.SubNodes[i];
|
||||
EnumerateItems(nextNode,
|
||||
directory + nextNode.Name + wchar_t(kDirDelimiter),
|
||||
prefix + nextNode.Name + wchar_t(kDirDelimiter),
|
||||
dirItems);
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT GetFileTime(IInArchive *archive, UINT32 index,
|
||||
FILETIME &fileTime, const FILETIME &defaultFileTime)
|
||||
{
|
||||
CPropVariant property;
|
||||
RINOK(archive->GetProperty(index, kpidLastWriteTime, &property));
|
||||
if (property.vt == VT_FILETIME)
|
||||
fileTime = property.filetime;
|
||||
else if (property.vt == VT_EMPTY)
|
||||
fileTime = defaultFileTime;
|
||||
else
|
||||
throw 4190407;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT EnumerateInArchiveItems(const NWildcard::CCensor &censor,
|
||||
IInArchive *archive,
|
||||
const UString &defaultItemName,
|
||||
const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo,
|
||||
CObjectVector<CArchiveItem> &archiveItems)
|
||||
{
|
||||
archiveItems.Clear();
|
||||
UINT32 numItems;
|
||||
RINOK(archive->GetNumberOfItems(&numItems));
|
||||
archiveItems.Reserve(numItems);
|
||||
for(UINT32 i = 0; i < numItems; i++)
|
||||
{
|
||||
CArchiveItem archiveItem;
|
||||
NCOM::CPropVariant propVariantPath;
|
||||
RINOK(archive->GetProperty(i, kpidPath, &propVariantPath));
|
||||
UString filePath;
|
||||
if(propVariantPath.vt == VT_EMPTY)
|
||||
archiveItem.Name = defaultItemName;
|
||||
else
|
||||
{
|
||||
if(propVariantPath.vt != VT_BSTR)
|
||||
return E_FAIL;
|
||||
archiveItem.Name = propVariantPath.bstrVal;
|
||||
}
|
||||
archiveItem.Censored = censor.CheckName(archiveItem.Name);
|
||||
|
||||
RINOK(GetFileTime(archive, i, archiveItem.LastWriteTime,
|
||||
archiveFileInfo.LastWriteTime));
|
||||
|
||||
CPropVariant propertySize;
|
||||
RINOK(archive->GetProperty(i, kpidSize, &propertySize));
|
||||
if (archiveItem.SizeIsDefined = (propertySize.vt != VT_EMPTY))
|
||||
archiveItem.Size = ConvertPropVariantToUINT64(propertySize);
|
||||
|
||||
CPropVariant propertyIsFolder;
|
||||
RINOK(archive->GetProperty(i, kpidIsFolder, &propertyIsFolder));
|
||||
if(propertyIsFolder.vt != VT_BOOL)
|
||||
return E_FAIL;
|
||||
archiveItem.IsDirectory = VARIANT_BOOLToBool(propertyIsFolder.boolVal);
|
||||
|
||||
archiveItem.IndexInServer = i;
|
||||
archiveItems.Add(archiveItem);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
static HRESULT UpdateWithItemLists(
|
||||
const CUpdateArchiveOptions &options,
|
||||
IInArchive *archive,
|
||||
const CObjectVector<CArchiveItem> &archiveItems,
|
||||
const CObjectVector<CDirItem> &dirItems,
|
||||
bool enablePercents)
|
||||
{
|
||||
for(int i = 0; i < options.Commands.Size(); i++)
|
||||
{
|
||||
const CUpdateArchiveCommand &command = options.Commands[i];
|
||||
const UString &realArchivePath = command.ArchivePath;
|
||||
if (i == 0 && options.UpdateArchiveItself)
|
||||
{
|
||||
if(archive != 0)
|
||||
g_StdOut << kUpdatingArchiveMessage;
|
||||
else
|
||||
g_StdOut << kCreatingArchiveMessage;
|
||||
g_StdOut << options.ArchivePath;
|
||||
}
|
||||
else
|
||||
g_StdOut << kCreatingArchiveMessage << realArchivePath;
|
||||
|
||||
g_StdOut << endl << endl;
|
||||
|
||||
RINOK(Compress(command.ActionSet, archive,
|
||||
options.MethodMode, realArchivePath,
|
||||
archiveItems, dirItems, enablePercents,
|
||||
options.SfxMode, options.SfxModule));
|
||||
|
||||
g_StdOut << endl;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT UpdateArchiveStdMain(const NWildcard::CCensor &censor,
|
||||
CUpdateArchiveOptions &options, const UString &workingDir,
|
||||
IInArchive *archive,
|
||||
const UString *defaultItemName,
|
||||
const NWindows::NFile::NFind::CFileInfoW *archiveFileInfo,
|
||||
bool enablePercents)
|
||||
{
|
||||
CObjectVector<CDirItem> dirItems;
|
||||
g_StdOut << kScanningMessage;
|
||||
EnumerateItems(censor._head, L"", L"", dirItems);
|
||||
g_StdOut << endl;
|
||||
|
||||
CFileVectorBundle fileVectorBundle;
|
||||
if(options.UpdateArchiveItself)
|
||||
{
|
||||
if (!NDirectory::MyGetTempFileName(workingDir, kTempArchiveFilePrefixString,
|
||||
options.Commands[0].ArchivePath))
|
||||
throw "create temp file error";
|
||||
}
|
||||
|
||||
int i;
|
||||
for(i = 0; i < options.Commands.Size(); i++)
|
||||
{
|
||||
fileVectorBundle.Add(options.Commands[i].ArchivePath,
|
||||
i > 0 || !options.UpdateArchiveItself);
|
||||
// SetBanOnFile(censor,currentDir, options.Commands[i].ArchivePath);
|
||||
}
|
||||
g_StdOut << endl;
|
||||
|
||||
CObjectVector<CArchiveItem> archiveItems;
|
||||
if (archive != NULL)
|
||||
{
|
||||
RINOK(EnumerateInArchiveItems(censor,
|
||||
archive, *defaultItemName, *archiveFileInfo, archiveItems));
|
||||
}
|
||||
|
||||
RINOK(UpdateWithItemLists(options, archive, archiveItems, dirItems, enablePercents));
|
||||
|
||||
if (archive != NULL)
|
||||
{
|
||||
RINOK(archive->Close());
|
||||
}
|
||||
|
||||
int firstNotTempArchiveIndex = options.UpdateArchiveItself ? 1 : 0;
|
||||
for(i = options.Commands.Size() - 1; i >= firstNotTempArchiveIndex; i--)
|
||||
fileVectorBundle.DisableDeleting(i);
|
||||
if(options.UpdateArchiveItself)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (archive != NULL)
|
||||
if (!NDirectory::DeleteFileAlways(options.ArchivePath))
|
||||
throw "delete file error";
|
||||
|
||||
if (!NDirectory::MyMoveFile(options.Commands[0].ArchivePath, options.ArchivePath))
|
||||
{
|
||||
g_StdOut << endl << "Error: ";
|
||||
g_StdOut << NError::MyFormatMessage(::GetLastError()) << endl;
|
||||
g_StdOut << options.Commands[0].ArchivePath << endl;
|
||||
g_StdOut << options.ArchivePath << endl;
|
||||
throw "move file error";
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
fileVectorBundle.DisableDeleting(0);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
g_StdOut << kEverythingIsOk << endl;
|
||||
return S_OK;
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
// Update.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __UPDATE_H
|
||||
#define __UPDATE_H
|
||||
|
||||
#include "Common/Wildcard.h"
|
||||
#include "../Common/UpdateAction.h"
|
||||
// #include "ProxyHandler.h"
|
||||
#include "Windows/FileFind.h"
|
||||
#include "../../Archive/IArchive.h"
|
||||
#include "CompressionMode.h"
|
||||
|
||||
struct CUpdateArchiveCommand
|
||||
{
|
||||
UString ArchivePath;
|
||||
NUpdateArchive::CActionSet ActionSet;
|
||||
};
|
||||
|
||||
struct CUpdateArchiveOptions
|
||||
{
|
||||
CObjectVector<CUpdateArchiveCommand> Commands;
|
||||
bool UpdateArchiveItself;
|
||||
|
||||
bool SfxMode;
|
||||
UString SfxModule;
|
||||
|
||||
UString ArchivePath;
|
||||
CCompressionMethodMode MethodMode;
|
||||
};
|
||||
|
||||
|
||||
HRESULT UpdateArchiveStdMain(const NWildcard::CCensor &censor,
|
||||
CUpdateArchiveOptions &options, const UString &workingDir,
|
||||
IInArchive *archive,
|
||||
const UString *defaultItemName,
|
||||
const NWindows::NFile::NFind::CFileInfoW *archiveFileInfo,
|
||||
bool enablePercents);
|
||||
|
||||
#endif
|
||||
@@ -1,259 +0,0 @@
|
||||
// UpdateCallback.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "UpdateCallback.h"
|
||||
|
||||
#include "Common/StdInStream.h"
|
||||
#include "Common/StdOutStream.h"
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/Defs.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
|
||||
#include "../../Common/FileStreams.h"
|
||||
// #include "Interface/EnumStatProp.h"
|
||||
|
||||
#include "ConsoleClose.h"
|
||||
|
||||
CUpdateCallbackImp::CUpdateCallbackImp():
|
||||
m_PercentPrinter(1 << 16) {}
|
||||
|
||||
void CUpdateCallbackImp::Init(
|
||||
const CObjectVector<CDirItem> *dirItems,
|
||||
const CObjectVector<CArchiveItem> *archiveItems, // test CItemInfoExList
|
||||
CObjectVector<CUpdatePair2> *updatePairs,
|
||||
bool enablePercents,
|
||||
bool passwordIsDefined,
|
||||
const UString &password,
|
||||
bool askPassword)
|
||||
{
|
||||
_passwordIsDefined = passwordIsDefined;
|
||||
_password = password;
|
||||
_askPassword = askPassword;
|
||||
|
||||
m_EnablePercents = enablePercents;
|
||||
m_DirItems = dirItems;
|
||||
m_ArchiveItems = archiveItems;
|
||||
m_UpdatePairs = updatePairs;
|
||||
m_PercentCanBePrint = false;
|
||||
m_NeedBeClosed = false;
|
||||
}
|
||||
|
||||
void CUpdateCallbackImp::Finilize()
|
||||
{
|
||||
if (m_NeedBeClosed)
|
||||
{
|
||||
if (m_EnablePercents)
|
||||
{
|
||||
m_PercentPrinter.ClosePrint();
|
||||
m_PercentCanBePrint = false;
|
||||
m_NeedBeClosed = false;
|
||||
}
|
||||
m_PercentPrinter.PrintNewLine();
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP CUpdateCallbackImp::SetTotal(UINT64 size)
|
||||
{
|
||||
if (m_EnablePercents)
|
||||
m_PercentPrinter.SetTotal(size);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CUpdateCallbackImp::SetCompleted(const UINT64 *completeValue)
|
||||
{
|
||||
if (completeValue != NULL)
|
||||
{
|
||||
if (m_EnablePercents)
|
||||
{
|
||||
m_PercentPrinter.SetRatio(*completeValue);
|
||||
if (m_PercentCanBePrint)
|
||||
m_PercentPrinter.PrintRatio();
|
||||
}
|
||||
}
|
||||
|
||||
if (NConsoleClose::TestBreakSignal())
|
||||
return E_ABORT;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
STATPROPSTG kProperties[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
{ NULL, kpidIsFolder, VT_BOOL},
|
||||
{ NULL, kpidSize, VT_UI8},
|
||||
{ NULL, kpidLastAccessTime, VT_FILETIME},
|
||||
{ NULL, kpidCreationTime, VT_FILETIME},
|
||||
{ NULL, kpidLastWriteTime, VT_FILETIME},
|
||||
{ NULL, kpidAttributes, VT_UI4},
|
||||
{ NULL, kpidIsAnti, VT_BOOL}
|
||||
};
|
||||
*/
|
||||
|
||||
STDMETHODIMP CUpdateCallbackImp::EnumProperties(IEnumSTATPROPSTG **enumerator)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
|
||||
/*
|
||||
return CStatPropEnumerator::CreateEnumerator(kProperties,
|
||||
sizeof(kProperties) / sizeof(kProperties[0]), enumerator);
|
||||
*/
|
||||
}
|
||||
|
||||
STDMETHODIMP CUpdateCallbackImp::GetUpdateItemInfo(UINT32 index,
|
||||
INT32 *newData, INT32 *newProperties, UINT32 *indexInArchive)
|
||||
{
|
||||
if (NConsoleClose::TestBreakSignal())
|
||||
return E_ABORT;
|
||||
const CUpdatePair2 &updatePair = (*m_UpdatePairs)[index];
|
||||
if(newData != NULL)
|
||||
*newData = BoolToInt(updatePair.NewData);
|
||||
if(newProperties != NULL)
|
||||
*newProperties = BoolToInt(updatePair.NewProperties);
|
||||
if(indexInArchive != NULL)
|
||||
{
|
||||
if (updatePair.ExistInArchive)
|
||||
*indexInArchive = (*m_ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer;
|
||||
else
|
||||
*indexInArchive = UINT32(-1);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CUpdateCallbackImp::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
const CUpdatePair2 &updatePair = (*m_UpdatePairs)[index];
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
|
||||
if (propID == kpidIsAnti)
|
||||
{
|
||||
propVariant = updatePair.IsAnti;
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (updatePair.IsAnti)
|
||||
{
|
||||
switch(propID)
|
||||
{
|
||||
case kpidIsFolder:
|
||||
case kpidPath:
|
||||
break;
|
||||
case kpidSize:
|
||||
propVariant = (UINT64)0;
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
default:
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if(updatePair.ExistOnDisk)
|
||||
{
|
||||
const CDirItem &dirItem =
|
||||
(*m_DirItems)[updatePair.DirItemIndex];
|
||||
switch(propID)
|
||||
{
|
||||
case kpidPath:
|
||||
propVariant = dirItem.Name;
|
||||
break;
|
||||
case kpidIsFolder:
|
||||
propVariant = dirItem.IsDirectory();
|
||||
break;
|
||||
case kpidSize:
|
||||
propVariant = dirItem.Size;
|
||||
break;
|
||||
case kpidAttributes:
|
||||
propVariant = dirItem.Attributes;
|
||||
break;
|
||||
case kpidLastAccessTime:
|
||||
propVariant = dirItem.LastAccessTime;
|
||||
break;
|
||||
case kpidCreationTime:
|
||||
propVariant = dirItem.CreationTime;
|
||||
break;
|
||||
case kpidLastWriteTime:
|
||||
propVariant = dirItem.LastWriteTime;
|
||||
break;
|
||||
}
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CUpdateCallbackImp::GetStream(UINT32 index,
|
||||
IInStream **inStream)
|
||||
{
|
||||
const CUpdatePair2 &updatePair = (*m_UpdatePairs)[index];
|
||||
if(!updatePair.NewData)
|
||||
return E_FAIL;
|
||||
|
||||
if (NConsoleClose::TestBreakSignal())
|
||||
return E_ABORT;
|
||||
|
||||
Finilize();
|
||||
|
||||
if(updatePair.IsAnti)
|
||||
{
|
||||
m_PercentPrinter.PrintString("Anti item ");
|
||||
m_PercentPrinter.PrintString(
|
||||
(*m_ArchiveItems)[updatePair.ArchiveItemIndex].Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
const CDirItem &dirItem =
|
||||
(*m_DirItems)[updatePair.DirItemIndex];
|
||||
|
||||
m_PercentPrinter.PrintString("Compressing ");
|
||||
m_PercentPrinter.PrintString(dirItem.Name);
|
||||
}
|
||||
if (m_EnablePercents)
|
||||
{
|
||||
m_PercentCanBePrint = true;
|
||||
m_PercentPrinter.PreparePrint();
|
||||
m_PercentPrinter.RePrintRatio();
|
||||
}
|
||||
|
||||
if(updatePair.IsAnti)
|
||||
return S_OK;
|
||||
|
||||
const CDirItem &dirItem =
|
||||
(*m_DirItems)[updatePair.DirItemIndex];
|
||||
|
||||
if(dirItem.IsDirectory())
|
||||
return S_OK;
|
||||
|
||||
CInFileStream *inStreamSpec = new CInFileStream;
|
||||
CMyComPtr<IInStream> inStreamLoc(inStreamSpec);
|
||||
if(!inStreamSpec->Open(dirItem.FullPath))
|
||||
return ::GetLastError();
|
||||
*inStream = inStreamLoc.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CUpdateCallbackImp::SetOperationResult(INT32 operationResult)
|
||||
{
|
||||
m_NeedBeClosed = true;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CUpdateCallbackImp::CryptoGetTextPassword2(INT32 *passwordIsDefined, BSTR *password)
|
||||
{
|
||||
if (!_passwordIsDefined)
|
||||
{
|
||||
if (_askPassword)
|
||||
{
|
||||
g_StdOut << "\nEnter password:";
|
||||
AString oemPassword = g_StdIn.ScanStringUntilNewLine();
|
||||
_password = MultiByteToUnicodeString(oemPassword, CP_OEMCP);
|
||||
_passwordIsDefined = true;
|
||||
}
|
||||
}
|
||||
*passwordIsDefined = BoolToInt(_passwordIsDefined);
|
||||
CMyComBSTR tempName(_password);
|
||||
*password = tempName.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
// UpdateCallback.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __UPDATECALLBACK_H
|
||||
#define __UPDATECALLBACK_H
|
||||
|
||||
// #include "../Format/Common/ArchiveInterface.h"
|
||||
#include "Common/MyCom.h"
|
||||
#include "Common/String.h"
|
||||
|
||||
#include "../../IPassword.h"
|
||||
|
||||
#include "../Common/UpdatePair.h"
|
||||
#include "../Common/UpdateProduce.h"
|
||||
|
||||
#include "PercentPrinter.h"
|
||||
|
||||
class CUpdateCallbackImp:
|
||||
public IArchiveUpdateCallback,
|
||||
public ICryptoGetTextPassword2,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP1(ICryptoGetTextPassword2)
|
||||
|
||||
// IProfress
|
||||
|
||||
STDMETHOD(SetTotal)(UINT64 size);
|
||||
STDMETHOD(SetCompleted)(const UINT64 *completeValue);
|
||||
|
||||
// IUpdateCallback
|
||||
STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator);
|
||||
STDMETHOD(GetUpdateItemInfo)(UINT32 index,
|
||||
INT32 *newData, INT32 *newProperties, UINT32 *indexInArchive);
|
||||
|
||||
STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value);
|
||||
|
||||
STDMETHOD(GetStream)(UINT32 index, IInStream **inStream);
|
||||
|
||||
STDMETHOD(SetOperationResult)(INT32 operationResult);
|
||||
|
||||
STDMETHOD(CryptoGetTextPassword2)(INT32 *passwordIsDefined, BSTR *password);
|
||||
|
||||
private:
|
||||
const CObjectVector<CDirItem> *m_DirItems;
|
||||
const CObjectVector<CArchiveItem> *m_ArchiveItems;
|
||||
const CObjectVector<CUpdatePair2> *m_UpdatePairs;
|
||||
|
||||
CPercentPrinter m_PercentPrinter;
|
||||
|
||||
bool m_EnablePercents;
|
||||
bool m_PercentCanBePrint;
|
||||
bool m_NeedBeClosed;
|
||||
|
||||
bool _passwordIsDefined;
|
||||
UString _password;
|
||||
bool _askPassword;
|
||||
|
||||
public:
|
||||
CUpdateCallbackImp();
|
||||
~CUpdateCallbackImp()
|
||||
{ Finilize(); }
|
||||
void Init(
|
||||
const CObjectVector<CDirItem> *dirItems,
|
||||
const CObjectVector<CArchiveItem> *archiveItems, // test CItemInfoExList
|
||||
CObjectVector<CUpdatePair2> *updatePairs,
|
||||
bool enablePercents,
|
||||
bool passwordIsDefined,
|
||||
const UString &password,
|
||||
bool askPassword);
|
||||
void Finilize();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
159
7zip/UI/Console/UpdateCallbackConsole.cpp
Executable file
159
7zip/UI/Console/UpdateCallbackConsole.cpp
Executable file
@@ -0,0 +1,159 @@
|
||||
// UpdateCallbackConsole.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "UpdateCallbackConsole.h"
|
||||
|
||||
#include "Windows/Error.h"
|
||||
|
||||
#include "ConsoleClose.h"
|
||||
#include "UserInputUtils.h"
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
static const char *kCreatingArchiveMessage = "Creating archive ";
|
||||
static const char *kUpdatingArchiveMessage = "Updating archive ";
|
||||
static const char *kScanningMessage = "Scanning";
|
||||
static const char *kNoFilesScannedMessage = "No files scanned";
|
||||
static const char *kTotalFilesAddedMessage = "Total files added to archive: ";
|
||||
|
||||
HRESULT CUpdateCallbackConsole::OpenResult(const wchar_t *name, HRESULT result)
|
||||
{
|
||||
(*OutStream) << endl;
|
||||
if (result != S_OK)
|
||||
(*OutStream) << "Error: " << name << " is not supported archive" << endl;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackConsole::StartScanning()
|
||||
{
|
||||
(*OutStream) << kScanningMessage;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackConsole::FinishScanning()
|
||||
{
|
||||
(*OutStream) << endl << endl;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackConsole::StartArchive(const wchar_t *name, bool updating)
|
||||
{
|
||||
if(updating)
|
||||
(*OutStream) << kUpdatingArchiveMessage;
|
||||
else
|
||||
(*OutStream) << kCreatingArchiveMessage;
|
||||
if (name != 0)
|
||||
(*OutStream) << name;
|
||||
else
|
||||
(*OutStream) << "StdOut";
|
||||
(*OutStream) << endl << endl;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackConsole::FinishArchive()
|
||||
{
|
||||
(*OutStream) << endl;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackConsole::CheckBreak()
|
||||
{
|
||||
if (NConsoleClose::TestBreakSignal())
|
||||
return E_ABORT;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackConsole::Finilize()
|
||||
{
|
||||
if (m_NeedBeClosed)
|
||||
{
|
||||
if (EnablePercents)
|
||||
{
|
||||
m_PercentPrinter.ClosePrint();
|
||||
m_PercentCanBePrint = false;
|
||||
}
|
||||
if (!StdOutMode)
|
||||
m_PercentPrinter.PrintNewLine();
|
||||
m_NeedBeClosed = false;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackConsole::SetTotal(UInt64 size)
|
||||
{
|
||||
if (EnablePercents)
|
||||
m_PercentPrinter.SetTotal(size);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackConsole::SetCompleted(const UInt64 *completeValue)
|
||||
{
|
||||
if (completeValue != NULL)
|
||||
{
|
||||
if (EnablePercents)
|
||||
{
|
||||
m_PercentPrinter.SetRatio(*completeValue);
|
||||
if (m_PercentCanBePrint)
|
||||
m_PercentPrinter.PrintRatio();
|
||||
}
|
||||
}
|
||||
if (NConsoleClose::TestBreakSignal())
|
||||
return E_ABORT;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackConsole::GetStream(const wchar_t *name, bool isAnti)
|
||||
{
|
||||
if (StdOutMode)
|
||||
return S_OK;
|
||||
if(isAnti)
|
||||
m_PercentPrinter.PrintString("Anti item ");
|
||||
else
|
||||
m_PercentPrinter.PrintString("Compressing ");
|
||||
m_PercentPrinter.PrintString(name);
|
||||
if (EnablePercents)
|
||||
{
|
||||
m_PercentCanBePrint = true;
|
||||
m_PercentPrinter.PreparePrint();
|
||||
m_PercentPrinter.RePrintRatio();
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackConsole::OpenFileError(const wchar_t *name, DWORD systemError)
|
||||
{
|
||||
FailedCodes.Add(systemError);
|
||||
FailedFiles.Add(name);
|
||||
// if (systemError == ERROR_SHARING_VIOLATION)
|
||||
{
|
||||
m_PercentPrinter.ClosePrint();
|
||||
m_PercentPrinter.PrintNewLine();
|
||||
m_PercentPrinter.PrintString("WARNING: ");
|
||||
m_PercentPrinter.PrintString(NError::MyFormatMessageW(systemError));
|
||||
return S_FALSE;
|
||||
}
|
||||
return systemError;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackConsole::SetOperationResult(Int32 operationResult)
|
||||
{
|
||||
m_NeedBeClosed = true;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallbackConsole::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
|
||||
{
|
||||
if (!PasswordIsDefined)
|
||||
{
|
||||
if (AskPassword)
|
||||
{
|
||||
Password = GetPassword(OutStream);
|
||||
PasswordIsDefined = true;
|
||||
}
|
||||
}
|
||||
*passwordIsDefined = BoolToInt(PasswordIsDefined);
|
||||
CMyComBSTR tempName(Password);
|
||||
*password = tempName.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
68
7zip/UI/Console/UpdateCallbackConsole.h
Executable file
68
7zip/UI/Console/UpdateCallbackConsole.h
Executable file
@@ -0,0 +1,68 @@
|
||||
// UpdateCallbackConsole.h
|
||||
|
||||
#ifndef __UPDATECALLBACKCONSOLE_H
|
||||
#define __UPDATECALLBACKCONSOLE_H
|
||||
|
||||
#include "Common/String.h"
|
||||
#include "Common/StdOutStream.h"
|
||||
#include "PercentPrinter.h"
|
||||
#include "../Common/Update.h"
|
||||
|
||||
class CUpdateCallbackConsole: public IUpdateCallbackUI2
|
||||
{
|
||||
CPercentPrinter m_PercentPrinter;
|
||||
bool m_PercentCanBePrint;
|
||||
bool m_NeedBeClosed;
|
||||
|
||||
CStdOutStream *OutStream;
|
||||
public:
|
||||
bool EnablePercents;
|
||||
bool StdOutMode;
|
||||
|
||||
bool PasswordIsDefined;
|
||||
UString Password;
|
||||
bool AskPassword;
|
||||
|
||||
|
||||
CUpdateCallbackConsole():
|
||||
m_PercentPrinter(1 << 16),
|
||||
PasswordIsDefined(false),
|
||||
AskPassword(false),
|
||||
StdOutMode(false),
|
||||
EnablePercents(true)
|
||||
{}
|
||||
|
||||
~CUpdateCallbackConsole() { Finilize(); }
|
||||
void Init(CStdOutStream *outStream)
|
||||
{
|
||||
m_PercentCanBePrint = false;
|
||||
m_NeedBeClosed = false;
|
||||
FailedFiles.Clear();
|
||||
FailedCodes.Clear();
|
||||
OutStream = outStream;
|
||||
m_PercentPrinter.OutStream = outStream;
|
||||
}
|
||||
|
||||
HRESULT OpenResult(const wchar_t *name, HRESULT result);
|
||||
|
||||
HRESULT StartScanning();
|
||||
HRESULT FinishScanning();
|
||||
|
||||
HRESULT StartArchive(const wchar_t *name, bool updating);
|
||||
HRESULT FinishArchive();
|
||||
|
||||
HRESULT CheckBreak();
|
||||
HRESULT Finilize();
|
||||
HRESULT SetTotal(UInt64 size);
|
||||
HRESULT SetCompleted(const UInt64 *completeValue);
|
||||
|
||||
HRESULT GetStream(const wchar_t *name, bool isAnti);
|
||||
HRESULT OpenFileError(const wchar_t *name, DWORD systemError);
|
||||
HRESULT SetOperationResult(Int32 operationResult);
|
||||
HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password);
|
||||
|
||||
UStringVector FailedFiles;
|
||||
CRecordVector<HRESULT> FailedCodes;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -3,16 +3,16 @@
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/StdInStream.h"
|
||||
#include "Common/StdOutStream.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 kAutoRename = '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 kAutoRename = 'U';
|
||||
static const char kQuit = 'Q';
|
||||
|
||||
static const char *kFirstQuestionMessage = "?\n";
|
||||
static const char *kHelpQuestionMessage =
|
||||
@@ -22,12 +22,12 @@ static const char *kHelpQuestionMessage =
|
||||
// in: anAll
|
||||
// out: anAll, anYes;
|
||||
|
||||
NUserAnswerMode::EEnum ScanUserYesNoAllQuit()
|
||||
NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream)
|
||||
{
|
||||
g_StdOut << kFirstQuestionMessage;
|
||||
(*outStream) << kFirstQuestionMessage;
|
||||
do
|
||||
{
|
||||
g_StdOut << kHelpQuestionMessage;
|
||||
(*outStream) << kHelpQuestionMessage;
|
||||
AString scannedString = g_StdIn.ScanStringUntilNewLine();
|
||||
scannedString.Trim();
|
||||
if(!scannedString.IsEmpty())
|
||||
@@ -49,3 +49,10 @@ NUserAnswerMode::EEnum ScanUserYesNoAllQuit()
|
||||
}
|
||||
while(true);
|
||||
}
|
||||
|
||||
UString GetPassword(CStdOutStream *outStream)
|
||||
{
|
||||
(*outStream) << "\nEnter password:";
|
||||
AString oemPassword = g_StdIn.ScanStringUntilNewLine();
|
||||
return MultiByteToUnicodeString(oemPassword, CP_OEMCP);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// UserInputUtils.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __USERINPUTUTILS_H
|
||||
#define __USERINPUTUTILS_H
|
||||
|
||||
#include "Common/StdOutStream.h"
|
||||
|
||||
namespace NUserAnswerMode {
|
||||
|
||||
enum EEnum
|
||||
@@ -18,6 +18,7 @@ enum EEnum
|
||||
};
|
||||
}
|
||||
|
||||
NUserAnswerMode::EEnum ScanUserYesNoAllQuit();
|
||||
NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream);
|
||||
UString GetPassword(CStdOutStream *outStream);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,12,0,0
|
||||
PRODUCTVERSION 3,12,0,0
|
||||
FILEVERSION 4,20,0,0
|
||||
PRODUCTVERSION 4,20,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -85,14 +85,14 @@ BEGIN
|
||||
VALUE "Comments", "\0"
|
||||
VALUE "CompanyName", "Igor Pavlov\0"
|
||||
VALUE "FileDescription", "7-Zip Console version\0"
|
||||
VALUE "FileVersion", "3, 12, 0, 0\0"
|
||||
VALUE "FileVersion", "4, 20, 0, 0\0"
|
||||
VALUE "InternalName", "7z\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "7z.exe\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "7-Zip\0"
|
||||
VALUE "ProductVersion", "3, 12, 0, 0\0"
|
||||
VALUE "ProductVersion", "4, 20, 0, 0\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "Windows/FileFind.h"
|
||||
#include "Windows/FileDir.h"
|
||||
#include "Windows/FileName.h"
|
||||
#include "Windows/System.h"
|
||||
#include "Windows/Thread.h"
|
||||
#include "Windows/Window.h"
|
||||
|
||||
@@ -260,13 +259,18 @@ static UString GetSubFolderNameForExtract(const UString &archiveName)
|
||||
{
|
||||
int dotPos = archiveName.ReverseFind('.');
|
||||
if (dotPos >= 0)
|
||||
return archiveName.Left(dotPos);
|
||||
{
|
||||
UString res = archiveName.Left(dotPos);
|
||||
res.TrimRight();
|
||||
return res;
|
||||
}
|
||||
return archiveName + UString(L"~");
|
||||
}
|
||||
|
||||
STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
UINT commandIDFirst, UINT commandIDLast, UINT flags)
|
||||
{
|
||||
LoadLangOneTime();
|
||||
if(_fileNames.Size() == 0)
|
||||
return E_FAIL;
|
||||
UINT currentCommandID = commandIDFirst;
|
||||
@@ -311,7 +315,6 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
if(_fileNames.Size() == 1 && currentCommandID + 6 <= commandIDLast)
|
||||
{
|
||||
const UString &fileName = _fileNames.Front();
|
||||
|
||||
UString folderPrefix;
|
||||
NFile::NDirectory::GetOnlyDirPrefix(fileName, folderPrefix);
|
||||
|
||||
@@ -328,7 +331,28 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, GetSystemString(mainString));
|
||||
_commandMap.push_back(commandMapItem);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(_fileNames.Size() > 0 && currentCommandID + 10 <= commandIDLast)
|
||||
{
|
||||
bool thereAreFolders = false;
|
||||
for(int i = 0; i < _fileNames.Size(); i++)
|
||||
{
|
||||
NFile::NFind::CFileInfoW fileInfo;
|
||||
if (!NFile::NFind::FindFile(_fileNames[i], fileInfo))
|
||||
return E_FAIL;
|
||||
if (fileInfo.IsDirectory())
|
||||
thereAreFolders = true;
|
||||
}
|
||||
const UString &fileName = _fileNames.Front();
|
||||
if (!thereAreFolders)
|
||||
{
|
||||
UString folderPrefix;
|
||||
NFile::NDirectory::GetOnlyDirPrefix(fileName, folderPrefix);
|
||||
NFile::NFind::CFileInfoW fileInfo;
|
||||
if (!NFile::NFind::FindFile(fileName, fileInfo))
|
||||
return E_FAIL;
|
||||
// Extract
|
||||
if ((contextMenuFlags & NContextMenuFlags::kExtract) != 0)
|
||||
{
|
||||
@@ -357,14 +381,17 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
CCommandMapItem commandMapItem;
|
||||
UString s;
|
||||
FillCommand2(kExtractTo, s, commandMapItem);
|
||||
UString folder = GetSubFolderNameForExtract(fileInfo.Name) +
|
||||
UString(L'\\');
|
||||
UString folder;
|
||||
if (_fileNames.Size() == 1)
|
||||
folder = GetSubFolderNameForExtract(fileInfo.Name);
|
||||
else
|
||||
folder = L'*';
|
||||
folder += L'\\';
|
||||
commandMapItem.Folder = folderPrefix + folder;
|
||||
s = MyFormatNew(s, folder);
|
||||
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, GetSystemString(s));
|
||||
_commandMap.push_back(commandMapItem);
|
||||
}
|
||||
|
||||
// Test
|
||||
if ((contextMenuFlags & NContextMenuFlags::kTest) != 0)
|
||||
{
|
||||
@@ -374,11 +401,6 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
_commandMap.push_back(commandMapItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(_fileNames.Size() > 0 && currentCommandID + 6 <= commandIDLast)
|
||||
{
|
||||
const UString &fileName = _fileNames.Front();
|
||||
UString archiveName = CreateArchiveName(fileName, _fileNames.Size() > 1, false);
|
||||
UString archiveName7z = archiveName + L".7z";
|
||||
UString archivePathPrefix;
|
||||
@@ -388,7 +410,8 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
if ((contextMenuFlags & NContextMenuFlags::kCompress) != 0)
|
||||
{
|
||||
CCommandMapItem commandMapItem;
|
||||
commandMapItem.Archive = archivePathPrefix + archiveName;
|
||||
commandMapItem.Folder = archivePathPrefix;
|
||||
commandMapItem.Archive = archiveName;
|
||||
FillCommand(kCompress, mainString, commandMapItem);
|
||||
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, GetSystemString(mainString));
|
||||
_commandMap.push_back(commandMapItem);
|
||||
@@ -401,7 +424,8 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
|
||||
CCommandMapItem commandMapItem;
|
||||
UString s;
|
||||
FillCommand2(kCompressTo, s, commandMapItem);
|
||||
commandMapItem.Archive = archivePathPrefix + archiveName7z;
|
||||
commandMapItem.Folder = archivePathPrefix;
|
||||
commandMapItem.Archive = archiveName7z;
|
||||
UString t = UString(L"\"") + archiveName7z + UString(L"\"");
|
||||
s = MyFormatNew(s, t);
|
||||
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, GetSystemString(s));
|
||||
@@ -609,20 +633,20 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
|
||||
params += L" \"";
|
||||
params += _fileNames[0];
|
||||
params += L"\"";
|
||||
MyCreateProcess(params);
|
||||
MyCreateProcess(params, 0);
|
||||
break;
|
||||
}
|
||||
case kExtract:
|
||||
case kExtractHere:
|
||||
case kExtractTo:
|
||||
{
|
||||
ExtractArchive(_fileNames[0], commandMapItem.Folder,
|
||||
ExtractArchives(_fileNames, commandMapItem.Folder,
|
||||
(commandInternalID == kExtract));
|
||||
break;
|
||||
}
|
||||
case kTest:
|
||||
{
|
||||
TestArchive(_fileNames[0]);
|
||||
TestArchives(_fileNames);
|
||||
break;
|
||||
}
|
||||
case kCompress:
|
||||
@@ -634,7 +658,8 @@ STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
|
||||
(commandInternalID == kCompressToEmail);
|
||||
bool showDialog = (commandInternalID == kCompress) ||
|
||||
(commandInternalID == kCompressEmail);
|
||||
CompressFiles(commandMapItem.Archive, _fileNames, email, showDialog);
|
||||
CompressFiles(commandMapItem.Folder, commandMapItem.Archive,
|
||||
_fileNames, email, showDialog);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// ContextMenu.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __CONTEXTMENU_H
|
||||
#define __CONTEXTMENU_H
|
||||
|
||||
@@ -9,10 +7,14 @@
|
||||
DEFINE_GUID(CLSID_CZipContextMenu,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00);
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "Common/String.h"
|
||||
|
||||
#include "../../FileManager/PluginInterface.h"
|
||||
|
||||
|
||||
|
||||
class CZipContextMenu:
|
||||
public IContextMenu,
|
||||
public IShellExtInit,
|
||||
@@ -89,4 +91,4 @@ private:
|
||||
CCommandMapItem &commandMapItem);
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// ContextMenuFlags.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __SEVENZIP_CONTEXTMENUFLAGS_H
|
||||
#define __SEVENZIP_CONTEXTMENUFLAGS_H
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// DLLExports.cpp : Implementation of DLL Exports.
|
||||
// DLLExports.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
#include <ShlGuid.h>
|
||||
#include <windows.h>
|
||||
|
||||
// #include "../../Compress/Interface/CompressInterface.h"
|
||||
#include "../../IPassword.h"
|
||||
#include "../Agent/Agent.h"
|
||||
#include "../../FileManager/LangUtils.h"
|
||||
#include "Common/ComTry.h"
|
||||
|
||||
#include "ContextMenu.h"
|
||||
@@ -44,9 +44,9 @@ extern "C"
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID)
|
||||
{
|
||||
// setlocale(LC_COLLATE, ".ACP");
|
||||
g_hInstance = hInstance;
|
||||
if (dwReason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
g_hInstance = hInstance;
|
||||
#ifdef UNICODE
|
||||
if (!IsItWindowsNT())
|
||||
return FALSE;
|
||||
@@ -56,7 +56,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID)
|
||||
}
|
||||
else if (dwReason == DLL_PROCESS_DETACH)
|
||||
_Module.Term();
|
||||
return TRUE; // ok
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
@@ -93,6 +93,7 @@ STDAPI CreateObject(
|
||||
const GUID *interfaceID,
|
||||
void **outObject)
|
||||
{
|
||||
LoadLangOneTime();
|
||||
COM_TRY_BEGIN
|
||||
*outObject = 0;
|
||||
if (*classID == CLSID_CAgentArchiveHandler)
|
||||
|
||||
@@ -182,6 +182,14 @@ SOURCE=.\StdAfx.h
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ArchiveExtractCallback.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ArchiveExtractCallback.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ArchiveName.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -190,6 +198,14 @@ SOURCE=..\Common\ArchiveName.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ArchiveOpenCallback.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ArchiveOpenCallback.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ArchiverInfo.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -266,6 +282,14 @@ SOURCE=..\Common\UpdateAction.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\UpdateCallback.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\UpdateCallback.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\UpdatePair.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -396,14 +420,6 @@ SOURCE=..\Agent\AgentProxy.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Agent\ArchiveExtractCallback.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Agent\ArchiveExtractCallback.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Agent\ArchiveFolder.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -416,39 +432,19 @@ SOURCE=..\Agent\ArchiveFolderOut.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Agent\ArchiveUpdateCallback.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Agent\ArchiveUpdateCallback.h
|
||||
SOURCE=..\Agent\IFileExtractCallback.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Agent\IFolderArchive.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Spec Interfaces"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Format\Common\ArchiveInterface.h
|
||||
SOURCE=..\Agent\UpdateCallbackAgent.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\ArchiveStyleDirItemInfo.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Compress\Interface\CompressInterface.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Common\FolderArchiveInterface.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Format\Common\FormatCryptoInterface.h
|
||||
SOURCE=..\Agent\UpdateCallbackAgent.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "FileManager"
|
||||
@@ -507,6 +503,14 @@ SOURCE=..\..\FileManager\RegistryUtils.h
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Alloc.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Alloc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\IntToString.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -731,14 +735,6 @@ SOURCE=..\..\..\Windows\Synchronization.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\System.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\System.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Windows\Window.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -797,7 +793,7 @@ SOURCE=.\OptionsDialog.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\RegistryContextMenu..cpp
|
||||
SOURCE=.\RegistryContextMenu.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user