mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-07 03:15:00 -06:00
4.44 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
804edc5756
commit
d9666cf046
578
CPP/7zip/UI/Agent/Agent.cpp
Executable file
578
CPP/7zip/UI/Agent/Agent.cpp
Executable file
@@ -0,0 +1,578 @@
|
||||
// Agent.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/ComTry.h"
|
||||
#include "Windows/Defs.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "Windows/FileFind.h"
|
||||
|
||||
#include "../Common/DefaultName.h"
|
||||
#include "../Common/ArchiveExtractCallback.h"
|
||||
|
||||
#include "Agent.h"
|
||||
|
||||
#ifdef FORMAT_7Z
|
||||
#include "../../Archive/7z/7zHandler.h"
|
||||
#endif
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/Sort.h"
|
||||
}
|
||||
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
STDMETHODIMP CAgentFolder::GetAgentFolder(CAgentFolder **agentFolder)
|
||||
{
|
||||
*agentFolder = this;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CAgentFolder::LoadFolder(CProxyFolder *folder)
|
||||
{
|
||||
int i;
|
||||
CProxyItem item;
|
||||
item.Folder = folder;
|
||||
for (i = 0; i < folder->Folders.Size(); i++)
|
||||
{
|
||||
item.Index = i;
|
||||
_items.Add(item);
|
||||
LoadFolder(&folder->Folders[i]);
|
||||
}
|
||||
int start = folder->Folders.Size();
|
||||
for (i = 0; i < folder->Files.Size(); i++)
|
||||
{
|
||||
item.Index = start + i;
|
||||
_items.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CAgentFolder::LoadItems()
|
||||
{
|
||||
_items.Clear();
|
||||
if (_flatMode)
|
||||
LoadFolder(_proxyFolderItem);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgentFolder::GetNumberOfItems(UINT32 *numItems)
|
||||
{
|
||||
if (_flatMode)
|
||||
*numItems = _items.Size();
|
||||
else
|
||||
*numItems = _proxyFolderItem->Folders.Size() +_proxyFolderItem->Files.Size();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
STDMETHODIMP CAgentFolder::GetNumberOfSubFolders(UINT32 *aNumSubFolders)
|
||||
{
|
||||
*aNumSubFolders = _proxyFolderItem->Folders.Size();
|
||||
return S_OK;
|
||||
}
|
||||
*/
|
||||
|
||||
UString CAgentFolder::GetName(UInt32 index) const
|
||||
{
|
||||
UInt32 realIndex;
|
||||
const CProxyFolder *folder;
|
||||
if (_flatMode)
|
||||
{
|
||||
const CProxyItem &item = _items[index];
|
||||
folder = item.Folder;
|
||||
realIndex = item.Index;
|
||||
}
|
||||
else
|
||||
{
|
||||
folder = _proxyFolderItem;
|
||||
realIndex = index;
|
||||
}
|
||||
|
||||
if (realIndex < (UINT32)folder->Folders.Size())
|
||||
return folder->Folders[realIndex].Name;
|
||||
return folder->Files[realIndex - folder->Folders.Size()].Name;
|
||||
}
|
||||
|
||||
UString CAgentFolder::GetPrefix(UInt32 index) const
|
||||
{
|
||||
if (!_flatMode)
|
||||
return UString();
|
||||
const CProxyItem &item = _items[index];
|
||||
const CProxyFolder *folder = item.Folder;
|
||||
UString path;
|
||||
while(folder != _proxyFolderItem)
|
||||
{
|
||||
path = folder->Name + UString(L"\\") + path;
|
||||
folder = folder->Parent;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
UString CAgentFolder::GetFullPathPrefixPlusPrefix(UInt32 index) const
|
||||
{
|
||||
return _proxyFolderItem->GetFullPathPrefix() + GetPrefix(index);
|
||||
}
|
||||
|
||||
void CAgentFolder::GetPrefixIfAny(UInt32 index, NCOM::CPropVariant &propVariant) const
|
||||
{
|
||||
if (!_flatMode)
|
||||
return;
|
||||
propVariant = GetPrefix(index);
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CAgentFolder::GetProperty(UINT32 itemIndex, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
const CProxyFolder *folder;
|
||||
UInt32 realIndex;
|
||||
if (_flatMode)
|
||||
{
|
||||
const CProxyItem &item = _items[itemIndex];
|
||||
folder = item.Folder;
|
||||
realIndex = item.Index;
|
||||
}
|
||||
else
|
||||
{
|
||||
folder = _proxyFolderItem;
|
||||
realIndex = itemIndex;
|
||||
}
|
||||
|
||||
if (realIndex < (UINT32)folder->Folders.Size())
|
||||
{
|
||||
const CProxyFolder &item = folder->Folders[realIndex];
|
||||
switch(propID)
|
||||
{
|
||||
case kpidIsFolder:
|
||||
propVariant = true;
|
||||
break;
|
||||
case kpidName:
|
||||
propVariant = item.Name;
|
||||
break;
|
||||
case kpidPrefix:
|
||||
GetPrefixIfAny(itemIndex, propVariant);
|
||||
break;
|
||||
default:
|
||||
if (item.IsLeaf)
|
||||
return _agentSpec->GetArchive()->GetProperty(item.Index, propID, value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
realIndex -= folder->Folders.Size();
|
||||
const CProxyFile &item = folder->Files[realIndex];
|
||||
switch(propID)
|
||||
{
|
||||
case kpidIsFolder:
|
||||
propVariant = false;
|
||||
break;
|
||||
case kpidName:
|
||||
propVariant = item.Name;
|
||||
break;
|
||||
case kpidPrefix:
|
||||
GetPrefixIfAny(itemIndex, propVariant);
|
||||
break;
|
||||
default:
|
||||
return _agentSpec->GetArchive()->GetProperty(item.Index, propID, value);
|
||||
}
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CAgentFolder::BindToFolder(CProxyFolder *folder, IFolderFolder **resultFolder)
|
||||
{
|
||||
CMyComPtr<IFolderFolder> parentFolder;
|
||||
if (folder->Parent != _proxyFolderItem)
|
||||
{
|
||||
RINOK(BindToFolder(folder->Parent, &parentFolder));
|
||||
}
|
||||
else
|
||||
parentFolder = this;
|
||||
CAgentFolder *folderSpec = new CAgentFolder;
|
||||
CMyComPtr<IFolderFolder> agentFolder = folderSpec;
|
||||
folderSpec->Init(_proxyArchive, folder, parentFolder, _agentSpec);
|
||||
*resultFolder = agentFolder.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgentFolder::BindToFolder(UINT32 index, IFolderFolder **resultFolder)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
|
||||
CProxyFolder *folder;
|
||||
UInt32 realIndex;
|
||||
if (_flatMode)
|
||||
{
|
||||
const CProxyItem &item = _items[index];
|
||||
folder = item.Folder;
|
||||
realIndex = item.Index;
|
||||
}
|
||||
else
|
||||
{
|
||||
folder = _proxyFolderItem;
|
||||
realIndex = index;
|
||||
}
|
||||
if (realIndex >= (UINT32)folder->Folders.Size())
|
||||
return E_INVALIDARG;
|
||||
return BindToFolder(&folder->Folders[realIndex], resultFolder);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgentFolder::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
int index = _proxyFolderItem->FindDirSubItemIndex(name);
|
||||
if (index < 0)
|
||||
return E_INVALIDARG;
|
||||
return BindToFolder(index, resultFolder);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgentFolder::BindToParentFolder(IFolderFolder **resultFolder)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
CMyComPtr<IFolderFolder> parentFolder = _parentFolder;
|
||||
*resultFolder = parentFolder.Detach();
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgentFolder::GetName(BSTR *name)
|
||||
{
|
||||
CMyComBSTR temp = _proxyFolderItem->Name;
|
||||
*name = temp.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
#ifdef NEW_FOLDER_INTERFACE
|
||||
|
||||
struct CArchiveItemPropertyTemp
|
||||
{
|
||||
UString Name;
|
||||
PROPID ID;
|
||||
VARTYPE Type;
|
||||
};
|
||||
|
||||
STDMETHODIMP CAgentFolder::GetNumberOfProperties(UINT32 *numProperties)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
RINOK(_agentSpec->GetArchive()->GetNumberOfProperties(numProperties));
|
||||
if (_flatMode)
|
||||
(*numProperties)++;
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgentFolder::GetPropertyInfo(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
UINT32 numProperties;
|
||||
_agentSpec->GetArchive()->GetNumberOfProperties(&numProperties);
|
||||
if (index < numProperties)
|
||||
{
|
||||
RINOK(_agentSpec->GetArchive()->GetPropertyInfo(index, name, propID, varType));
|
||||
if (*propID == kpidPath)
|
||||
*propID = kpidName;
|
||||
}
|
||||
else
|
||||
{
|
||||
*name = NULL;
|
||||
*propID = kpidPrefix;
|
||||
*varType = VT_BSTR;
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgentFolder::GetTypeID(BSTR *name)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
UString temp = UString(L"7-Zip.") + _agentSpec->ArchiveType;
|
||||
CMyComBSTR bstrTemp = temp;
|
||||
*name = bstrTemp.Detach();
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgentFolder::GetPath(BSTR *path)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
UStringVector pathParts;
|
||||
pathParts.Clear();
|
||||
CMyComPtr<IFolderFolder> currentFolder = this;
|
||||
for (;;)
|
||||
{
|
||||
CMyComPtr<IFolderFolder> newFolder;
|
||||
currentFolder->BindToParentFolder(&newFolder);
|
||||
if (newFolder == NULL)
|
||||
break;
|
||||
CMyComBSTR aName;
|
||||
currentFolder->GetName(&aName);
|
||||
pathParts.Insert(0, (const wchar_t *)aName);
|
||||
currentFolder = newFolder;
|
||||
}
|
||||
|
||||
UString prefix;
|
||||
for(int i = 0; i < pathParts.Size(); i++)
|
||||
{
|
||||
prefix += pathParts[i];
|
||||
prefix += L'\\';
|
||||
}
|
||||
|
||||
CMyComBSTR tempPath = prefix;
|
||||
*path = tempPath.Detach();
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgentFolder::SetFlatMode(Int32 flatMode)
|
||||
{
|
||||
_flatMode = IntToBool(flatMode);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void CAgentFolder::GetRealIndices(const UINT32 *indices, UINT32 numItems, CUIntVector &realIndices) const
|
||||
{
|
||||
if (!_flatMode)
|
||||
{
|
||||
_proxyFolderItem->GetRealIndices(indices, numItems, realIndices);
|
||||
return;
|
||||
}
|
||||
realIndices.Clear();
|
||||
for(UINT32 i = 0; i < numItems; i++)
|
||||
{
|
||||
const CProxyItem &item = _items[indices[i]];
|
||||
const CProxyFolder *folder = item.Folder;
|
||||
UInt32 realIndex = item.Index;
|
||||
if (realIndex < (UINT32)folder->Folders.Size())
|
||||
continue;
|
||||
realIndices.Add(folder->Files[realIndex - folder->Folders.Size()].Index);
|
||||
}
|
||||
HeapSort(&realIndices.Front(), realIndices.Size());
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgentFolder::Extract(const UINT32 *indices,
|
||||
UINT32 numItems,
|
||||
NExtract::NPathMode::EEnum pathMode,
|
||||
NExtract::NOverwriteMode::EEnum overwriteMode,
|
||||
const wchar_t *path,
|
||||
INT32 testMode,
|
||||
IFolderArchiveExtractCallback *extractCallback2)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
|
||||
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
|
||||
UStringVector pathParts;
|
||||
CProxyFolder *currentProxyFolder = _proxyFolderItem;
|
||||
while (currentProxyFolder->Parent)
|
||||
{
|
||||
pathParts.Insert(0, currentProxyFolder->Name);
|
||||
currentProxyFolder = currentProxyFolder->Parent;
|
||||
}
|
||||
|
||||
/*
|
||||
if (_flatMode)
|
||||
pathMode = NExtract::NPathMode::kNoPathnames;
|
||||
*/
|
||||
|
||||
extractCallbackSpec->Init(_agentSpec->GetArchive(),
|
||||
extractCallback2,
|
||||
false,
|
||||
path,
|
||||
pathMode,
|
||||
overwriteMode,
|
||||
pathParts,
|
||||
_agentSpec->DefaultName,
|
||||
_agentSpec->DefaultTime,
|
||||
_agentSpec->DefaultAttributes
|
||||
// ,_agentSpec->_srcDirectoryPrefix
|
||||
);
|
||||
CUIntVector realIndices;
|
||||
GetRealIndices(indices, numItems, realIndices);
|
||||
return _agentSpec->GetArchive()->Extract(&realIndices.Front(),
|
||||
realIndices.Size(), testMode, extractCallback);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
// CAgent
|
||||
|
||||
CAgent::CAgent():
|
||||
_proxyArchive(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
CAgent::~CAgent()
|
||||
{
|
||||
if (_proxyArchive != NULL)
|
||||
delete _proxyArchive;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgent::Open(
|
||||
const wchar_t *filePath,
|
||||
BSTR *archiveType,
|
||||
// CLSID *clsIDResult,
|
||||
IArchiveOpenCallback *openArchiveCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
_archiveFilePath = filePath;
|
||||
NFile::NFind::CFileInfoW fileInfo;
|
||||
if (!NFile::NFind::FindFile(_archiveFilePath, fileInfo))
|
||||
return ::GetLastError();
|
||||
if (fileInfo.IsDirectory())
|
||||
return E_FAIL;
|
||||
CArchiverInfo archiverInfo0, archiverInfo1;
|
||||
HRESULT res = OpenArchive(_archiveFilePath, _archiveLink, openArchiveCallback);
|
||||
// _archive = _archiveLink.GetArchive();
|
||||
DefaultName = _archiveLink.GetDefaultItemName();
|
||||
const CArchiverInfo &ai = _archiveLink.GetArchiverInfo();
|
||||
|
||||
RINOK(res);
|
||||
DefaultTime = fileInfo.LastWriteTime;
|
||||
DefaultAttributes = fileInfo.Attributes;
|
||||
ArchiveType = ai.Name;
|
||||
if (archiveType != 0)
|
||||
{
|
||||
CMyComBSTR name = ArchiveType;
|
||||
*archiveType = name.Detach();
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgent::ReOpen(
|
||||
// const wchar_t *filePath,
|
||||
IArchiveOpenCallback * /* openArchiveCallback */)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
if (_proxyArchive != NULL)
|
||||
{
|
||||
delete _proxyArchive;
|
||||
_proxyArchive = NULL;
|
||||
}
|
||||
RINOK(ReOpenArchive(_archiveLink, _archiveFilePath));
|
||||
return ReadItems();
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgent::Close()
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
RINOK(_archiveLink.Close());
|
||||
if (_archiveLink.GetNumLevels() > 1)
|
||||
{
|
||||
// return S_OK;
|
||||
}
|
||||
// _archive->Close();
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
/*
|
||||
STDMETHODIMP CAgent::EnumProperties(IEnumSTATPROPSTG **EnumProperties)
|
||||
{
|
||||
return _archive->EnumProperties(EnumProperties);
|
||||
}
|
||||
*/
|
||||
|
||||
HRESULT CAgent::ReadItems()
|
||||
{
|
||||
if (_proxyArchive != NULL)
|
||||
return S_OK;
|
||||
_proxyArchive = new CProxyArchive();
|
||||
return _proxyArchive->Load(GetArchive(),
|
||||
DefaultName,
|
||||
// _defaultTime,
|
||||
// _defaultAttributes,
|
||||
NULL);
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgent::BindToRootFolder(IFolderFolder **resultFolder)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
RINOK(ReadItems());
|
||||
CAgentFolder *folderSpec = new CAgentFolder;
|
||||
CMyComPtr<IFolderFolder> rootFolder = folderSpec;
|
||||
folderSpec->Init(_proxyArchive, &_proxyArchive->RootFolder, NULL, this);
|
||||
*resultFolder = rootFolder.Detach();
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CAgent::Extract(
|
||||
NExtract::NPathMode::EEnum pathMode,
|
||||
NExtract::NOverwriteMode::EEnum overwriteMode,
|
||||
const wchar_t *path,
|
||||
INT32 testMode,
|
||||
IFolderArchiveExtractCallback *extractCallback2)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
|
||||
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
|
||||
extractCallbackSpec->Init(GetArchive(),
|
||||
extractCallback2,
|
||||
false,
|
||||
path,
|
||||
pathMode,
|
||||
overwriteMode,
|
||||
UStringVector(),
|
||||
DefaultName,
|
||||
DefaultTime,
|
||||
DefaultAttributes
|
||||
// ,_srcDirectoryPrefix
|
||||
);
|
||||
return GetArchive()->Extract(0, (UInt32)(Int32)-1, testMode, extractCallback);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgent::GetNumberOfProperties(UINT32 *numProperties)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
return GetArchive()->GetNumberOfProperties(numProperties);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgent::GetPropertyInfo(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
RINOK(GetArchive()->GetPropertyInfo(index, name, propID, varType));
|
||||
if (*propID == kpidPath)
|
||||
*propID = kpidName;
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgent::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
return GetArchive()->GetArchiveProperty(propID, value);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgent::GetNumberOfArchiveProperties(UINT32 *numProperties)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
return GetArchive()->GetNumberOfArchiveProperties(numProperties);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgent::GetArchivePropertyInfo(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
return GetArchive()->GetArchivePropertyInfo(index,
|
||||
name, propID, varType);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
314
CPP/7zip/UI/Agent/Agent.h
Executable file
314
CPP/7zip/UI/Agent/Agent.h
Executable file
@@ -0,0 +1,314 @@
|
||||
// Agent/Agent.h
|
||||
|
||||
#ifndef __AGENT_AGENT_H
|
||||
#define __AGENT_AGENT_H
|
||||
|
||||
#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"
|
||||
|
||||
#ifndef EXCLUDE_COM
|
||||
#include "Windows/DLL.h"
|
||||
#endif
|
||||
#ifdef NEW_FOLDER_INTERFACE
|
||||
#include "../../FileManager/IFolder.h"
|
||||
#endif
|
||||
|
||||
class CAgentFolder;
|
||||
|
||||
// {23170F69-40C1-278A-0000-000100050001}
|
||||
DEFINE_GUID(IID_IArchiveFolderInternal,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000100050001")
|
||||
IArchiveFolderInternal: public IUnknown
|
||||
{
|
||||
public:
|
||||
STDMETHOD(GetAgentFolder)(CAgentFolder **agentFolder) PURE;
|
||||
};
|
||||
|
||||
struct CProxyItem
|
||||
{
|
||||
CProxyFolder *Folder;
|
||||
UInt32 Index;
|
||||
};
|
||||
|
||||
class CAgent;
|
||||
|
||||
class CAgentFolder:
|
||||
public IFolderFolder,
|
||||
public IArchiveFolder,
|
||||
public IArchiveFolderInternal,
|
||||
#ifdef NEW_FOLDER_INTERFACE
|
||||
public IEnumProperties,
|
||||
public IFolderGetTypeID,
|
||||
public IFolderGetPath,
|
||||
public IFolderOperations,
|
||||
public IFolderSetFlatMode,
|
||||
#endif
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
|
||||
MY_QUERYINTERFACE_BEGIN
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderFolder)
|
||||
MY_QUERYINTERFACE_ENTRY(IArchiveFolder)
|
||||
MY_QUERYINTERFACE_ENTRY(IArchiveFolderInternal)
|
||||
#ifdef NEW_FOLDER_INTERFACE
|
||||
MY_QUERYINTERFACE_ENTRY(IEnumProperties)
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderGetTypeID)
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderGetPath)
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderOperations)
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderSetFlatMode)
|
||||
#endif
|
||||
MY_QUERYINTERFACE_END
|
||||
MY_ADDREF_RELEASE
|
||||
|
||||
// IFolderFolder
|
||||
|
||||
void LoadFolder(CProxyFolder *folder);
|
||||
HRESULT BindToFolder(CProxyFolder *folder, IFolderFolder **resultFolder);
|
||||
void GetRealIndices(const UINT32 *indices, UINT32 numItems, CUIntVector &realIndices) const;
|
||||
|
||||
STDMETHOD(LoadItems)();
|
||||
STDMETHOD(GetNumberOfItems)(UINT32 *numItems);
|
||||
STDMETHOD(GetProperty)(UINT32 itemIndex, PROPID propID, PROPVARIANT *value);
|
||||
STDMETHOD(BindToFolder)(UINT32 index, IFolderFolder **resultFolder);
|
||||
STDMETHOD(BindToFolder)(const wchar_t *name, IFolderFolder **resultFolder);
|
||||
STDMETHOD(BindToParentFolder)(IFolderFolder **resultFolder);
|
||||
STDMETHOD(GetName)(BSTR *name);
|
||||
|
||||
// IArchiveFolder
|
||||
STDMETHOD(Extract)(const UINT32 *indices, UINT32 numItems,
|
||||
NExtract::NPathMode::EEnum pathMode,
|
||||
NExtract::NOverwriteMode::EEnum overwriteMode,
|
||||
const wchar_t *path,
|
||||
INT32 testMode,
|
||||
IFolderArchiveExtractCallback *extractCallback);
|
||||
|
||||
STDMETHOD(GetAgentFolder)(CAgentFolder **agentFolder);
|
||||
|
||||
#ifdef NEW_FOLDER_INTERFACE
|
||||
STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties);
|
||||
STDMETHOD(GetPropertyInfo)(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
||||
STDMETHOD(GetTypeID)(BSTR *name);
|
||||
STDMETHOD(GetPath)(BSTR *path);
|
||||
|
||||
|
||||
// IFolderOperations
|
||||
STDMETHOD(CreateFolder)(const wchar_t *name, IProgress *progress);
|
||||
STDMETHOD(CreateFile)(const wchar_t *name, IProgress *progress);
|
||||
STDMETHOD(Rename)(UINT32 index, const wchar_t *newName, IProgress *progress);
|
||||
STDMETHOD(Delete)(const UINT32 *indices, UINT32 numItems, IProgress *progress);
|
||||
STDMETHOD(CopyTo)(const UINT32 *indices, UINT32 numItems,
|
||||
const wchar_t *path, IFolderOperationsExtractCallback *callback);
|
||||
STDMETHOD(MoveTo)(const UINT32 *indices, UINT32 numItems,
|
||||
const wchar_t *path, IFolderOperationsExtractCallback *callback);
|
||||
STDMETHOD(CopyFrom)(const wchar_t *fromFolderPath,
|
||||
const wchar_t **itemsPaths, UINT32 numItems, IProgress *progress);
|
||||
STDMETHOD(SetProperty)(UINT32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress);
|
||||
|
||||
STDMETHOD(SetFlatMode)(Int32 flatMode);
|
||||
#endif
|
||||
|
||||
CAgentFolder(): _proxyFolderItem(NULL), _flatMode(0) {}
|
||||
|
||||
void Init(CProxyArchive *proxyHandler,
|
||||
CProxyFolder *proxyFolderItem,
|
||||
IFolderFolder *parentFolder,
|
||||
CAgent *agent)
|
||||
{
|
||||
_proxyArchive = proxyHandler;
|
||||
_proxyFolderItem = proxyFolderItem;
|
||||
_parentFolder = parentFolder;
|
||||
_agent = (IInFolderArchive *)agent;
|
||||
_agentSpec = agent;
|
||||
}
|
||||
|
||||
void GetPathParts(UStringVector &pathParts);
|
||||
HRESULT CommonUpdateOperation(
|
||||
bool deleteOperation,
|
||||
bool createFolderOperation,
|
||||
bool renameOperation,
|
||||
const wchar_t *newItemName,
|
||||
const NUpdateArchive::CActionSet *actionSet,
|
||||
const UINT32 *indices, UINT32 numItems,
|
||||
IFolderArchiveUpdateCallback *updateCallback100);
|
||||
|
||||
|
||||
UString GetPrefix(UInt32 index) const;
|
||||
UString GetName(UInt32 index) const;
|
||||
UString GetFullPathPrefixPlusPrefix(UInt32 index) const;
|
||||
void GetPrefixIfAny(UInt32 index, NWindows::NCOM::CPropVariant &propVariant) const;
|
||||
|
||||
public:
|
||||
CProxyArchive *_proxyArchive;
|
||||
CProxyFolder *_proxyFolderItem;
|
||||
CMyComPtr<IFolderFolder> _parentFolder;
|
||||
CMyComPtr<IInFolderArchive> _agent;
|
||||
CAgent *_agentSpec;
|
||||
|
||||
CRecordVector<CProxyItem> _items;
|
||||
bool _flatMode;
|
||||
private:
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-1000-000100030000}
|
||||
DEFINE_GUID(CLSID_CAgentArchiveHandler,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00);
|
||||
|
||||
class CAgent:
|
||||
public IInFolderArchive,
|
||||
#ifndef EXTRACT_ONLY
|
||||
public IOutFolderArchive,
|
||||
public ISetProperties,
|
||||
#endif
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
|
||||
MY_QUERYINTERFACE_BEGIN
|
||||
MY_QUERYINTERFACE_ENTRY(IInFolderArchive)
|
||||
#ifndef EXTRACT_ONLY
|
||||
MY_QUERYINTERFACE_ENTRY(IOutFolderArchive)
|
||||
MY_QUERYINTERFACE_ENTRY(ISetProperties)
|
||||
#endif
|
||||
MY_QUERYINTERFACE_END
|
||||
MY_ADDREF_RELEASE
|
||||
|
||||
STDMETHOD(Open)(
|
||||
const wchar_t *filePath,
|
||||
// CLSID *clsIDResult,
|
||||
BSTR *archiveType,
|
||||
IArchiveOpenCallback *openArchiveCallback);
|
||||
|
||||
STDMETHOD(ReOpen)(
|
||||
// const wchar_t *filePath,
|
||||
IArchiveOpenCallback *openArchiveCallback);
|
||||
/*
|
||||
STDMETHOD(ReOpen)(IInStream *stream,
|
||||
const wchar_t *defaultName,
|
||||
const FILETIME *defaultTime,
|
||||
UINT32 defaultAttributes,
|
||||
const UINT64 *maxCheckStartPosition,
|
||||
IArchiveOpenCallback *openArchiveCallback);
|
||||
*/
|
||||
STDMETHOD(Close)();
|
||||
STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value);
|
||||
STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties);
|
||||
STDMETHOD(GetPropertyInfo)(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
||||
STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties);
|
||||
STDMETHOD(GetArchivePropertyInfo)(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
||||
STDMETHOD(BindToRootFolder)(IFolderFolder **resultFolder);
|
||||
STDMETHOD(Extract)(
|
||||
NExtract::NPathMode::EEnum pathMode,
|
||||
NExtract::NOverwriteMode::EEnum overwriteMode,
|
||||
const wchar_t *path,
|
||||
INT32 testMode,
|
||||
IFolderArchiveExtractCallback *extractCallback2);
|
||||
|
||||
#ifndef EXTRACT_ONLY
|
||||
STDMETHOD(SetFolder)(IFolderFolder *folder);
|
||||
STDMETHOD(SetFiles)(const wchar_t *folderPrefix, const wchar_t **names, UINT32 numNames);
|
||||
STDMETHOD(DeleteItems)(const wchar_t *newArchiveName, const UINT32 *indices,
|
||||
UINT32 numItems, IFolderArchiveUpdateCallback *updateCallback);
|
||||
STDMETHOD(DoOperation)(
|
||||
const wchar_t *filePath,
|
||||
const CLSID *clsID,
|
||||
const wchar_t *newArchiveName,
|
||||
const Byte *stateActions,
|
||||
const wchar_t *sfxModule,
|
||||
IFolderArchiveUpdateCallback *updateCallback);
|
||||
|
||||
HRESULT CommonUpdate(
|
||||
const wchar_t *newArchiveName,
|
||||
int numUpdateItems,
|
||||
IArchiveUpdateCallback *updateCallback);
|
||||
|
||||
HRESULT CreateFolder(
|
||||
const wchar_t *newArchiveName,
|
||||
const wchar_t *folderName,
|
||||
IFolderArchiveUpdateCallback *updateCallback100);
|
||||
|
||||
HRESULT RenameItem(
|
||||
const wchar_t *newArchiveName,
|
||||
const UINT32 *indices, UINT32 numItems,
|
||||
const wchar_t *newItemName,
|
||||
IFolderArchiveUpdateCallback *updateCallback100);
|
||||
|
||||
// ISetProperties
|
||||
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, INT32 numProperties);
|
||||
#endif
|
||||
|
||||
CAgent();
|
||||
~CAgent();
|
||||
private:
|
||||
HRESULT ReadItems();
|
||||
public:
|
||||
CProxyArchive *_proxyArchive;
|
||||
|
||||
CArchiveLink _archiveLink;
|
||||
// IInArchive *_archive2;
|
||||
|
||||
// CLSID _CLSID;
|
||||
// CMyComPtr<IArchiveFolder> m_RootFolder;
|
||||
|
||||
UString DefaultName;
|
||||
|
||||
FILETIME DefaultTime;
|
||||
UINT32 DefaultAttributes;
|
||||
|
||||
UString ArchiveType;
|
||||
|
||||
UStringVector _names;
|
||||
UString _folderPrefix;
|
||||
|
||||
UString _archiveNamePrefix;
|
||||
CAgentFolder *_agentFolder;
|
||||
|
||||
UString _archiveFilePath;
|
||||
|
||||
#ifndef EXTRACT_ONLY
|
||||
CObjectVector<UString> m_PropNames;
|
||||
CObjectVector<NWindows::NCOM::CPropVariant> m_PropValues;
|
||||
#endif
|
||||
|
||||
IInArchive *GetArchive() { return _archiveLink.GetArchive(); }
|
||||
bool CanUpdate() const { return _archiveLink.GetNumLevels() <= 1; }
|
||||
};
|
||||
|
||||
#ifdef NEW_FOLDER_INTERFACE
|
||||
class CArchiveFolderManager:
|
||||
public IFolderManager,
|
||||
public IFolderManagerGetIconPath,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP2(
|
||||
IFolderManager,
|
||||
IFolderManagerGetIconPath
|
||||
)
|
||||
// IFolderManager
|
||||
STDMETHOD(OpenFolderFile)(const wchar_t *filePath, IFolderFolder **resultFolder, IProgress *progress);
|
||||
STDMETHOD(GetTypes)(BSTR *types);
|
||||
STDMETHOD(GetExtension)(const wchar_t *type, BSTR *extension);
|
||||
STDMETHOD(CreateFolderFile)(const wchar_t *type, const wchar_t *filePath, IProgress *progress);
|
||||
STDMETHOD(GetIconPath)(const wchar_t *type, BSTR *iconPath);
|
||||
CArchiveFolderManager(): _formatsLoaded(false) {}
|
||||
private:
|
||||
void LoadFormats();
|
||||
int FindFormat(const UString &type);
|
||||
bool _formatsLoaded;
|
||||
CObjectVector<CArchiverInfo> _formats;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
518
CPP/7zip/UI/Agent/AgentOut.cpp
Executable file
518
CPP/7zip/UI/Agent/AgentOut.cpp
Executable file
@@ -0,0 +1,518 @@
|
||||
// AgentOut.cpp
|
||||
|
||||
#include "StdAfx.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 "UpdateCallbackAgent.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NCOM;
|
||||
|
||||
static HRESULT CopyBlock(ISequentialInStream *inStream, ISequentialOutStream *outStream)
|
||||
{
|
||||
CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
|
||||
return copyCoder->Code(inStream, outStream, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgent::SetFolder(IFolderFolder *folder)
|
||||
{
|
||||
_archiveNamePrefix.Empty();
|
||||
if (folder == NULL)
|
||||
{
|
||||
_agentFolder = NULL;
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
CMyComPtr<IFolderFolder> archiveFolder = folder;
|
||||
CMyComPtr<IArchiveFolderInternal> archiveFolderInternal;
|
||||
RINOK(archiveFolder.QueryInterface(IID_IArchiveFolderInternal, &archiveFolderInternal));
|
||||
RINOK(archiveFolderInternal->GetAgentFolder(&_agentFolder));
|
||||
}
|
||||
|
||||
UStringVector pathParts;
|
||||
pathParts.Clear();
|
||||
CMyComPtr<IFolderFolder> folderItem = folder;
|
||||
if (folderItem != NULL)
|
||||
for (;;)
|
||||
{
|
||||
CMyComPtr<IFolderFolder> newFolder;
|
||||
folderItem->BindToParentFolder(&newFolder);
|
||||
if (newFolder == NULL)
|
||||
break;
|
||||
CMyComBSTR name;
|
||||
folderItem->GetName(&name);
|
||||
pathParts.Insert(0, (const wchar_t *)name);
|
||||
folderItem = newFolder;
|
||||
}
|
||||
|
||||
for(int i = 0; i < pathParts.Size(); i++)
|
||||
{
|
||||
_archiveNamePrefix += pathParts[i];
|
||||
_archiveNamePrefix += L'\\';
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgent::SetFiles(const wchar_t *folderPrefix,
|
||||
const wchar_t **names, UINT32 numNames)
|
||||
{
|
||||
_folderPrefix = folderPrefix;
|
||||
_names.Clear();
|
||||
_names.Reserve(numNames);
|
||||
for (UINT32 i = 0; i < numNames; i++)
|
||||
_names.Add(names[i]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
static HRESULT GetFileTime(CAgent *agent, UINT32 itemIndex, FILETIME &fileTime)
|
||||
{
|
||||
CPropVariant property;
|
||||
RINOK(agent->GetArchive()->GetProperty(itemIndex, kpidLastWriteTime, &property));
|
||||
if (property.vt == VT_FILETIME)
|
||||
fileTime = property.filetime;
|
||||
else if (property.vt == VT_EMPTY)
|
||||
fileTime = agent->DefaultTime;
|
||||
else
|
||||
throw 4190407;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT EnumerateArchiveItems(CAgent *agent,
|
||||
const CProxyFolder &item,
|
||||
const UString &prefix,
|
||||
CObjectVector<CArchiveItem> &archiveItems)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < item.Files.Size(); i++)
|
||||
{
|
||||
const CProxyFile &fileItem = item.Files[i];
|
||||
CArchiveItem archiveItem;
|
||||
|
||||
RINOK(::GetFileTime(agent, fileItem.Index, archiveItem.LastWriteTime));
|
||||
|
||||
CPropVariant property;
|
||||
agent->GetArchive()->GetProperty(fileItem.Index, kpidSize, &property);
|
||||
archiveItem.SizeIsDefined = (property.vt != VT_EMPTY);
|
||||
if (archiveItem.SizeIsDefined)
|
||||
archiveItem.Size = ConvertPropVariantToUInt64(property);
|
||||
archiveItem.IsDirectory = false;
|
||||
archiveItem.Name = prefix + fileItem.Name;
|
||||
archiveItem.Censored = true; // test it
|
||||
archiveItem.IndexInServer = fileItem.Index;
|
||||
archiveItems.Add(archiveItem);
|
||||
}
|
||||
for(i = 0; i < item.Folders.Size(); i++)
|
||||
{
|
||||
const CProxyFolder &dirItem = item.Folders[i];
|
||||
UString fullName = prefix + dirItem.Name;
|
||||
if(dirItem.IsLeaf)
|
||||
{
|
||||
CArchiveItem archiveItem;
|
||||
RINOK(::GetFileTime(agent, dirItem.Index, archiveItem.LastWriteTime));
|
||||
archiveItem.IsDirectory = true;
|
||||
archiveItem.SizeIsDefined = false;
|
||||
archiveItem.Name = fullName;
|
||||
archiveItem.Censored = true; // test it
|
||||
archiveItem.IndexInServer = dirItem.Index;
|
||||
archiveItems.Add(archiveItem);
|
||||
}
|
||||
RINOK(EnumerateArchiveItems(agent, dirItem, fullName + UString(L'\\'), archiveItems));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgent::DoOperation(
|
||||
const wchar_t *filePath,
|
||||
const CLSID *clsID,
|
||||
const wchar_t *newArchiveName,
|
||||
const Byte *stateActions,
|
||||
const wchar_t *sfxModule,
|
||||
IFolderArchiveUpdateCallback *updateCallback100)
|
||||
{
|
||||
if (!CanUpdate())
|
||||
return E_NOTIMPL;
|
||||
NUpdateArchive::CActionSet actionSet;
|
||||
int i;
|
||||
for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
|
||||
actionSet.StateActions[i] = (NUpdateArchive::NPairAction::EEnum)stateActions[i];
|
||||
|
||||
CObjectVector<CDirItem> dirItems;
|
||||
|
||||
UString folderPrefix = _folderPrefix;
|
||||
NFile::NName::NormalizeDirPathPrefix(folderPrefix);
|
||||
UStringVector errorPaths;
|
||||
CRecordVector<DWORD> errorCodes;
|
||||
::EnumerateDirItems(folderPrefix, _names, _archiveNamePrefix, dirItems, errorPaths, errorCodes);
|
||||
if (errorCodes.Size() > 0)
|
||||
{
|
||||
return errorCodes.Front();
|
||||
}
|
||||
|
||||
NWindows::NDLL::CLibrary library;
|
||||
|
||||
CMyComPtr<IOutArchive> outArchive;
|
||||
if (GetArchive())
|
||||
{
|
||||
RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive));
|
||||
}
|
||||
else
|
||||
{
|
||||
CHandlerLoader loader;
|
||||
RINOK(loader.CreateHandler(filePath, *clsID, (void **)&outArchive, true));
|
||||
library.Attach(loader.Detach());
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
CObjectVector<CArchiveItem> archiveItems;
|
||||
if (GetArchive())
|
||||
{
|
||||
RINOK(ReadItems());
|
||||
EnumerateArchiveItems(this, _proxyArchive->RootFolder, L"", archiveItems);
|
||||
}
|
||||
|
||||
GetUpdatePairInfoList(dirItems, archiveItems, fileTimeType, updatePairs);
|
||||
|
||||
CObjectVector<CUpdatePair2> updatePairs2;
|
||||
UpdateProduce(updatePairs, actionSet, updatePairs2);
|
||||
|
||||
CUpdateCallbackAgent updateCallbackAgent;
|
||||
updateCallbackAgent.Callback = updateCallback100;
|
||||
CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
|
||||
CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec );
|
||||
|
||||
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;
|
||||
{
|
||||
UString resultPath;
|
||||
int pos;
|
||||
if(!NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos))
|
||||
throw 141716;
|
||||
NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos));
|
||||
}
|
||||
if (!outStreamSpec->Create(archiveName, true))
|
||||
{
|
||||
// ShowLastErrorMessage();
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
CMyComPtr<ISetProperties> setProperties;
|
||||
if (outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties) == S_OK)
|
||||
{
|
||||
if (m_PropNames.Size() == 0)
|
||||
{
|
||||
RINOK(setProperties->SetProperties(0, 0, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
CRecordVector<const wchar_t *> names;
|
||||
for(i = 0; i < m_PropNames.Size(); i++)
|
||||
names.Add((const wchar_t *)m_PropNames[i]);
|
||||
|
||||
NWindows::NCOM::CPropVariant *propValues = new NWindows::NCOM::CPropVariant[m_PropValues.Size()];
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < m_PropValues.Size(); i++)
|
||||
propValues[i] = m_PropValues[i];
|
||||
RINOK(setProperties->SetProperties(&names.Front(), propValues, names.Size()));
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
delete []propValues;
|
||||
throw;
|
||||
}
|
||||
delete []propValues;
|
||||
}
|
||||
}
|
||||
m_PropNames.Clear();
|
||||
m_PropValues.Clear();
|
||||
|
||||
if (sfxModule != NULL)
|
||||
{
|
||||
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, updatePairs2.Size(),updateCallback);
|
||||
}
|
||||
|
||||
|
||||
HRESULT CAgent::CommonUpdate(
|
||||
const wchar_t *newArchiveName,
|
||||
int numUpdateItems,
|
||||
IArchiveUpdateCallback *updateCallback)
|
||||
{
|
||||
if (!CanUpdate())
|
||||
return E_NOTIMPL;
|
||||
CMyComPtr<IOutArchive> outArchive;
|
||||
RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive));
|
||||
|
||||
COutFileStream *outStreamSpec = new COutFileStream;
|
||||
CMyComPtr<IOutStream> outStream(outStreamSpec);
|
||||
|
||||
UString archiveName = newArchiveName;
|
||||
{
|
||||
UString resultPath;
|
||||
int pos;
|
||||
if(!NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos))
|
||||
throw 141716;
|
||||
NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos));
|
||||
}
|
||||
|
||||
/*
|
||||
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;
|
||||
}
|
||||
|
||||
return outArchive->UpdateItems(outStream, numUpdateItems, updateCallback);
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CAgent::DeleteItems(
|
||||
const wchar_t *newArchiveName,
|
||||
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);
|
||||
|
||||
CUIntVector realIndices;
|
||||
_agentFolder->GetRealIndices(indices, numItems, realIndices);
|
||||
CObjectVector<CUpdatePair2> updatePairs;
|
||||
int curIndex = 0;
|
||||
UInt32 numItemsInArchive;
|
||||
RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive));
|
||||
for (UInt32 i = 0; i < numItemsInArchive; i++)
|
||||
{
|
||||
if (curIndex < realIndices.Size())
|
||||
if (realIndices[curIndex] == i)
|
||||
{
|
||||
curIndex++;
|
||||
continue;
|
||||
}
|
||||
CUpdatePair2 updatePair;
|
||||
updatePair.NewData = updatePair.NewProperties = false;
|
||||
updatePair.ExistInArchive = true;
|
||||
updatePair.ExistOnDisk = false;
|
||||
updatePair.IsAnti = false; // check it. Maybe it can be undefined
|
||||
updatePair.ArchiveItemIndex = i;
|
||||
updatePairs.Add(updatePair);
|
||||
}
|
||||
updateCallbackSpec->UpdatePairs = &updatePairs;
|
||||
updateCallbackSpec->Archive = GetArchive();
|
||||
updateCallbackSpec->Callback = &updateCallbackAgent;
|
||||
return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback);
|
||||
}
|
||||
|
||||
HRESULT CAgent::CreateFolder(
|
||||
const wchar_t *newArchiveName,
|
||||
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(GetArchive()->GetNumberOfItems(&numItemsInArchive));
|
||||
for (UInt32 i = 0; i < numItemsInArchive; i++)
|
||||
{
|
||||
CUpdatePair2 updatePair;
|
||||
updatePair.NewData = updatePair.NewProperties = false;
|
||||
updatePair.ExistInArchive = true;
|
||||
updatePair.ExistOnDisk = false;
|
||||
updatePair.IsAnti = false; // check it.
|
||||
updatePair.ArchiveItemIndex = i;
|
||||
updatePairs.Add(updatePair);
|
||||
}
|
||||
CUpdatePair2 updatePair;
|
||||
updatePair.NewData = updatePair.NewProperties = true;
|
||||
updatePair.ExistInArchive = false;
|
||||
updatePair.ExistOnDisk = true;
|
||||
updatePair.IsAnti = false;
|
||||
updatePair.ArchiveItemIndex = -1;
|
||||
updatePair.DirItemIndex = 0;
|
||||
|
||||
updatePairs.Add(updatePair);
|
||||
|
||||
CObjectVector<CDirItem> dirItems;
|
||||
CDirItem dirItem;
|
||||
|
||||
dirItem.Attributes = FILE_ATTRIBUTE_DIRECTORY;
|
||||
dirItem.Size = 0;
|
||||
dirItem.Name = _agentFolder->_proxyFolderItem->GetFullPathPrefix() + folderName;
|
||||
|
||||
SYSTEMTIME systemTime;
|
||||
FILETIME fileTime;
|
||||
::GetSystemTime(&systemTime);
|
||||
::SystemTimeToFileTime(&systemTime, &fileTime);
|
||||
dirItem.LastAccessTime = dirItem.LastWriteTime =
|
||||
dirItem.CreationTime = fileTime;
|
||||
|
||||
dirItems.Add(dirItem);
|
||||
|
||||
updateCallbackSpec->Callback = &updateCallbackAgent;
|
||||
updateCallbackSpec->DirItems = &dirItems;
|
||||
updateCallbackSpec->UpdatePairs = &updatePairs;
|
||||
updateCallbackSpec->Archive = GetArchive();
|
||||
return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback);
|
||||
}
|
||||
|
||||
|
||||
HRESULT CAgent::RenameItem(
|
||||
const wchar_t *newArchiveName,
|
||||
const UINT32 *indices, UINT32 numItems,
|
||||
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);
|
||||
|
||||
CUIntVector realIndices;
|
||||
_agentFolder->GetRealIndices(indices, numItems, realIndices);
|
||||
|
||||
UString fullPrefix = _agentFolder->GetFullPathPrefixPlusPrefix(indices[0]);
|
||||
UString oldItemPath = fullPrefix + _agentFolder->GetName(indices[0]);
|
||||
UString newItemPath = fullPrefix + newItemName;
|
||||
|
||||
CObjectVector<CUpdatePair2> updatePairs;
|
||||
int curIndex = 0;
|
||||
UINT32 numItemsInArchive;
|
||||
RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive));
|
||||
for (UInt32 i = 0; i < numItemsInArchive; i++)
|
||||
{
|
||||
if (curIndex < realIndices.Size())
|
||||
if (realIndices[curIndex] == i)
|
||||
{
|
||||
CUpdatePair2 updatePair;
|
||||
updatePair.NewData = false;
|
||||
updatePair.NewProperties = true;
|
||||
updatePair.ExistInArchive = true;
|
||||
updatePair.ExistOnDisk = false;
|
||||
RINOK(IsArchiveItemAnti(GetArchive(), i, updatePair.IsAnti));
|
||||
updatePair.ArchiveItemIndex = i;
|
||||
updatePair.NewNameIsDefined = true;
|
||||
|
||||
updatePair.NewName = newItemName;
|
||||
|
||||
UString oldFullPath;
|
||||
RINOK(GetArchiveItemPath(GetArchive(), i, DefaultName, oldFullPath));
|
||||
|
||||
if (oldItemPath.CompareNoCase(oldFullPath.Left(oldItemPath.Length())) != 0)
|
||||
return E_INVALIDARG;
|
||||
|
||||
updatePair.NewName = newItemPath + oldFullPath.Mid(oldItemPath.Length());
|
||||
updatePairs.Add(updatePair);
|
||||
curIndex++;
|
||||
continue;
|
||||
}
|
||||
CUpdatePair2 updatePair;
|
||||
updatePair.NewData = updatePair.NewProperties = false;
|
||||
updatePair.ExistInArchive = true;
|
||||
updatePair.ExistOnDisk = false;
|
||||
updatePair.IsAnti = false;
|
||||
updatePair.ArchiveItemIndex = i;
|
||||
updatePairs.Add(updatePair);
|
||||
}
|
||||
updateCallbackSpec->Callback = &updateCallbackAgent;
|
||||
updateCallbackSpec->UpdatePairs = &updatePairs;
|
||||
updateCallbackSpec->Archive = GetArchive();
|
||||
return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback);
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgent::SetProperties(const wchar_t **names,
|
||||
const PROPVARIANT *values, INT32 numProperties)
|
||||
{
|
||||
m_PropNames.Clear();
|
||||
m_PropValues.Clear();
|
||||
for (int i = 0; i < numProperties; i++)
|
||||
{
|
||||
m_PropNames.Add(names[i]);
|
||||
m_PropValues.Add(values[i]);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
203
CPP/7zip/UI/Agent/AgentProxy.cpp
Executable file
203
CPP/7zip/UI/Agent/AgentProxy.cpp
Executable file
@@ -0,0 +1,203 @@
|
||||
// AgentProxy.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "AgentProxy.h"
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "Windows/Defs.h"
|
||||
#include "../Common/OpenArchive.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/Sort.h"
|
||||
}
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
int CProxyFolder::FindDirSubItemIndex(const UString &name, int &insertPos) const
|
||||
{
|
||||
int left = 0, right = Folders.Size();
|
||||
for (;;)
|
||||
{
|
||||
if (left == right)
|
||||
{
|
||||
insertPos = left;
|
||||
return -1;
|
||||
}
|
||||
int mid = (left + right) / 2;
|
||||
int compare = name.CompareNoCase(Folders[mid].Name);
|
||||
if (compare == 0)
|
||||
return mid;
|
||||
if (compare < 0)
|
||||
right = mid;
|
||||
else
|
||||
left = mid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
int CProxyFolder::FindDirSubItemIndex(const UString &name) const
|
||||
{
|
||||
int insertPos;
|
||||
return FindDirSubItemIndex(name, insertPos);
|
||||
}
|
||||
|
||||
void CProxyFolder::AddFileSubItem(UINT32 index, const UString &name)
|
||||
{
|
||||
Files.Add(CProxyFile());
|
||||
Files.Back().Name = name;
|
||||
Files.Back().Index = index;
|
||||
}
|
||||
|
||||
CProxyFolder* CProxyFolder::AddDirSubItem(UINT32 index, bool leaf,
|
||||
const UString &name)
|
||||
{
|
||||
int insertPos;
|
||||
int folderIndex = FindDirSubItemIndex(name, insertPos);
|
||||
if (folderIndex >= 0)
|
||||
{
|
||||
CProxyFolder *item = &Folders[folderIndex];
|
||||
if(leaf)
|
||||
{
|
||||
item->Index = index;
|
||||
item->IsLeaf = true;
|
||||
}
|
||||
return item;
|
||||
}
|
||||
Folders.Insert(insertPos, CProxyFolder());
|
||||
CProxyFolder *item = &Folders[insertPos];
|
||||
item->Name = name;
|
||||
item->Index = index;
|
||||
item->Parent = this;
|
||||
item->IsLeaf = leaf;
|
||||
return item;
|
||||
}
|
||||
|
||||
void CProxyFolder::Clear()
|
||||
{
|
||||
Folders.Clear();
|
||||
Files.Clear();
|
||||
}
|
||||
|
||||
UString CProxyFolder::GetFullPathPrefix() const
|
||||
{
|
||||
UString result;
|
||||
const CProxyFolder *current = this;
|
||||
while (current->Parent != NULL)
|
||||
{
|
||||
result = current->Name + UString(L'\\') + result;
|
||||
current = current->Parent;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
UString CProxyFolder::GetItemName(UINT32 index) const
|
||||
{
|
||||
if (index < (UINT32)Folders.Size())
|
||||
return Folders[index].Name;
|
||||
return Files[index - Folders.Size()].Name;
|
||||
}
|
||||
|
||||
void CProxyFolder::AddRealIndices(CUIntVector &realIndices) const
|
||||
{
|
||||
if (IsLeaf)
|
||||
realIndices.Add(Index);
|
||||
int i;
|
||||
for(i = 0; i < Folders.Size(); i++)
|
||||
Folders[i].AddRealIndices(realIndices);
|
||||
for(i = 0; i < Files.Size(); i++)
|
||||
realIndices.Add(Files[i].Index);
|
||||
}
|
||||
|
||||
void CProxyFolder::GetRealIndices(const UINT32 *indices,
|
||||
UINT32 numItems, CUIntVector &realIndices) const
|
||||
{
|
||||
realIndices.Clear();
|
||||
for(UINT32 i = 0; i < numItems; i++)
|
||||
{
|
||||
int index = indices[i];
|
||||
int numDirItems = Folders.Size();
|
||||
if (index < numDirItems)
|
||||
Folders[index].AddRealIndices(realIndices);
|
||||
else
|
||||
realIndices.Add(Files[index - numDirItems].Index);
|
||||
}
|
||||
HeapSort(&realIndices.Front(), realIndices.Size());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// CProxyArchive
|
||||
|
||||
HRESULT CProxyArchive::Reload(IInArchive *archive, IProgress *progress)
|
||||
{
|
||||
RootFolder.Clear();
|
||||
return ReadObjects(archive, progress);
|
||||
}
|
||||
|
||||
HRESULT CProxyArchive::Load(IInArchive *archive,
|
||||
const UString &defaultName,
|
||||
// const FILETIME &defaultTime,
|
||||
// UINT32 defaultAttributes,
|
||||
IProgress *progress)
|
||||
{
|
||||
DefaultName = defaultName;
|
||||
// DefaultTime = defaultTime;
|
||||
// DefaultAttributes = defaultAttributes;
|
||||
return Reload(archive, progress);
|
||||
}
|
||||
|
||||
|
||||
HRESULT CProxyArchive::ReadObjects(IInArchive *archiveHandler, IProgress *progress)
|
||||
{
|
||||
UINT32 numItems;
|
||||
RINOK(archiveHandler->GetNumberOfItems(&numItems));
|
||||
if (progress != NULL)
|
||||
{
|
||||
UINT64 totalItems = numItems;
|
||||
RINOK(progress->SetTotal(totalItems));
|
||||
}
|
||||
for(UINT32 i = 0; i < numItems; i++)
|
||||
{
|
||||
if (progress != NULL)
|
||||
{
|
||||
UINT64 currentItemIndex = i;
|
||||
RINOK(progress->SetCompleted(¤tItemIndex));
|
||||
}
|
||||
NCOM::CPropVariant propVariantPath;
|
||||
RINOK(archiveHandler->GetProperty(i, kpidPath, &propVariantPath));
|
||||
CProxyFolder *currentItem = &RootFolder;
|
||||
UString fileName;
|
||||
if(propVariantPath.vt == VT_EMPTY)
|
||||
fileName = DefaultName;
|
||||
else
|
||||
{
|
||||
if(propVariantPath.vt != VT_BSTR)
|
||||
return E_FAIL;
|
||||
UString filePath = propVariantPath.bstrVal;
|
||||
|
||||
int len = filePath.Length();
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
wchar_t c = filePath[i];
|
||||
if (c == '\\' || c == '/')
|
||||
{
|
||||
currentItem = currentItem->AddDirSubItem((UInt32)(Int32)-1, false, fileName);
|
||||
fileName.Empty();
|
||||
}
|
||||
else
|
||||
fileName += c;
|
||||
}
|
||||
}
|
||||
|
||||
NCOM::CPropVariant propVariantIsFolder;
|
||||
bool isFolder;
|
||||
RINOK(IsArchiveItemFolder(archiveHandler, i, isFolder));
|
||||
if(isFolder)
|
||||
currentItem->AddDirSubItem(i, true, fileName);
|
||||
else
|
||||
currentItem->AddFileSubItem(i, fileName);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
56
CPP/7zip/UI/Agent/AgentProxy.h
Executable file
56
CPP/7zip/UI/Agent/AgentProxy.h
Executable file
@@ -0,0 +1,56 @@
|
||||
// AgentProxy.h
|
||||
|
||||
#ifndef __AGENT_PROXY_H
|
||||
#define __AGENT_PROXY_H
|
||||
|
||||
#include "Common/String.h"
|
||||
|
||||
#include "../../Archive/IArchive.h"
|
||||
|
||||
class CProxyFile
|
||||
{
|
||||
public:
|
||||
UINT32 Index;
|
||||
UString Name;
|
||||
};
|
||||
|
||||
class CProxyFolder: public CProxyFile
|
||||
{
|
||||
public:
|
||||
CProxyFolder *Parent;
|
||||
CObjectVector<CProxyFolder> Folders;
|
||||
CObjectVector<CProxyFile> Files;
|
||||
bool IsLeaf;
|
||||
|
||||
CProxyFolder(): Parent(NULL) {};
|
||||
int FindDirSubItemIndex(const UString &name, int &insertPos) const;
|
||||
int FindDirSubItemIndex(const UString &name) const;
|
||||
CProxyFolder* AddDirSubItem(UINT32 index,
|
||||
bool leaf, const UString &name);
|
||||
void AddFileSubItem(UINT32 index, const UString &name);
|
||||
void Clear();
|
||||
|
||||
UString GetFullPathPrefix() const;
|
||||
UString GetItemName(UINT32 index) const;
|
||||
void AddRealIndices(CUIntVector &realIndices) const;
|
||||
void GetRealIndices(const UINT32 *indices, UINT32 numItems,
|
||||
CUIntVector &realIndices) const;
|
||||
};
|
||||
|
||||
class CProxyArchive
|
||||
{
|
||||
HRESULT ReadObjects(IInArchive *inArchive, IProgress *progress);
|
||||
public:
|
||||
UString DefaultName;
|
||||
// FILETIME DefaultTime;
|
||||
// UINT32 DefaultAttributes;
|
||||
CProxyFolder RootFolder;
|
||||
HRESULT Reload(IInArchive *archive, IProgress *progress);
|
||||
HRESULT Load(IInArchive *archive,
|
||||
const UString &defaultName,
|
||||
// const FILETIME &defaultTime,
|
||||
// UINT32 defaultAttributes,
|
||||
IProgress *progress);
|
||||
};
|
||||
|
||||
#endif
|
||||
72
CPP/7zip/UI/Agent/ArchiveFolder.cpp
Executable file
72
CPP/7zip/UI/Agent/ArchiveFolder.cpp
Executable file
@@ -0,0 +1,72 @@
|
||||
// Zip/ArchiveFolder.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/ComTry.h"
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Windows/Defs.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "Windows/PropVariantConversions.h"
|
||||
#include "Windows/FileDir.h"
|
||||
|
||||
#include "../../Common/FileStreams.h"
|
||||
|
||||
#include "../Common/UpdatePair.h"
|
||||
#include "../Common/ArchiveExtractCallback.h"
|
||||
|
||||
#include "Agent.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NCOM;
|
||||
|
||||
STDMETHODIMP CAgentFolder::CopyTo(const UINT32 *indices, UINT32 numItems,
|
||||
const wchar_t *path, IFolderOperationsExtractCallback *callback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
CArchiveExtractCallback *extractCallbackSpec = new
|
||||
CArchiveExtractCallback;
|
||||
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
|
||||
UStringVector pathParts;
|
||||
CProxyFolder *currentProxyFolder = _proxyFolderItem;
|
||||
while (currentProxyFolder->Parent)
|
||||
{
|
||||
pathParts.Insert(0, currentProxyFolder->Name);
|
||||
currentProxyFolder = currentProxyFolder->Parent;
|
||||
}
|
||||
|
||||
CMyComPtr<IFolderArchiveExtractCallback> extractCallback2;
|
||||
{
|
||||
CMyComPtr<IFolderOperationsExtractCallback> callbackWrap = callback;
|
||||
RINOK(callbackWrap.QueryInterface(
|
||||
IID_IFolderArchiveExtractCallback, &extractCallback2));
|
||||
}
|
||||
|
||||
NExtract::NPathMode::EEnum pathMode = _flatMode ?
|
||||
NExtract::NPathMode::kNoPathnames :
|
||||
NExtract::NPathMode::kCurrentPathnames;
|
||||
|
||||
extractCallbackSpec->Init(_agentSpec->GetArchive(),
|
||||
extractCallback2,
|
||||
false,
|
||||
path,
|
||||
pathMode,
|
||||
NExtract::NOverwriteMode::kAskBefore,
|
||||
pathParts,
|
||||
_agentSpec->DefaultName,
|
||||
_agentSpec->DefaultTime,
|
||||
_agentSpec->DefaultAttributes
|
||||
// ,_agentSpec->_srcDirectoryPrefix
|
||||
);
|
||||
CUIntVector realIndices;
|
||||
GetRealIndices(indices, numItems, realIndices);
|
||||
return _agentSpec->GetArchive()->Extract(&realIndices.Front(),
|
||||
realIndices.Size(), BoolToInt(false), extractCallback);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgentFolder::MoveTo(const UINT32 * /* indices */, UINT32 /* numItems */,
|
||||
const wchar_t * /* path */, IFolderOperationsExtractCallback * /* callback */)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
98
CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp
Executable file
98
CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp
Executable file
@@ -0,0 +1,98 @@
|
||||
// Zip/ArchiveFolder.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Agent.h"
|
||||
|
||||
#include "Common/StringConvert.h"
|
||||
|
||||
#include "../Common/OpenArchive.h"
|
||||
|
||||
static const UInt64 kMaxCheckStartPosition = 1 << 20;
|
||||
|
||||
static inline UINT GetCurrentFileCodePage()
|
||||
{ return AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
|
||||
|
||||
void CArchiveFolderManager::LoadFormats()
|
||||
{
|
||||
if (!_formatsLoaded)
|
||||
ReadArchiverInfoList(_formats);
|
||||
}
|
||||
|
||||
int CArchiveFolderManager::FindFormat(const UString &type)
|
||||
{
|
||||
// LoadFormats();
|
||||
for (int i = 0; i < _formats.Size(); i++)
|
||||
if (type.CompareNoCase(_formats[i].Name) == 0)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveFolderManager::OpenFolderFile(const wchar_t *filePath,
|
||||
IFolderFolder **resultFolder, IProgress *progress)
|
||||
{
|
||||
CMyComPtr<IArchiveOpenCallback> openArchiveCallback;
|
||||
if (progress != 0)
|
||||
{
|
||||
CMyComPtr<IProgress> progressWrapper = progress;
|
||||
progressWrapper.QueryInterface(IID_IArchiveOpenCallback, &openArchiveCallback);
|
||||
}
|
||||
CAgent *agent = new CAgent();
|
||||
CMyComPtr<IInFolderArchive> archive = agent;
|
||||
RINOK(agent->Open(filePath, NULL, openArchiveCallback));
|
||||
return agent->BindToRootFolder(resultFolder);
|
||||
}
|
||||
|
||||
/*
|
||||
HRESULT CAgent::FolderReOpen(
|
||||
IArchiveOpenCallback *openArchiveCallback)
|
||||
{
|
||||
return ReOpenArchive(_archive, _archiveFilePath);
|
||||
}
|
||||
*/
|
||||
|
||||
STDMETHODIMP CArchiveFolderManager::GetTypes(BSTR *types)
|
||||
{
|
||||
LoadFormats();
|
||||
UString typesStrings;
|
||||
for(int i = 0; i < _formats.Size(); i++)
|
||||
{
|
||||
const CArchiverInfo &ai = _formats[i];
|
||||
if (!ai.Associate)
|
||||
continue;
|
||||
if (i != 0)
|
||||
typesStrings += L' ';
|
||||
typesStrings += ai.Name;
|
||||
}
|
||||
CMyComBSTR valueTemp = typesStrings;
|
||||
*types = valueTemp.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveFolderManager::GetExtension(const wchar_t *type, BSTR *extension)
|
||||
{
|
||||
*extension = 0;
|
||||
int formatIndex = FindFormat(type);
|
||||
if (formatIndex < 0)
|
||||
return E_INVALIDARG;
|
||||
CMyComBSTR valueTemp = _formats[formatIndex].Extensions[0].Ext;
|
||||
*extension = valueTemp.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveFolderManager::GetIconPath(const wchar_t *type, BSTR *iconPath)
|
||||
{
|
||||
*iconPath = 0;
|
||||
int formatIndex = FindFormat(type);
|
||||
if (formatIndex < 0)
|
||||
return E_INVALIDARG;
|
||||
CMyComBSTR iconPathTemp = _formats[formatIndex].FilePath;
|
||||
*iconPath = iconPathTemp.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CArchiveFolderManager::CreateFolderFile(const wchar_t * /* type */,
|
||||
const wchar_t * /* filePath */, IProgress * /* progress */)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
215
CPP/7zip/UI/Agent/ArchiveFolderOut.cpp
Executable file
215
CPP/7zip/UI/Agent/ArchiveFolderOut.cpp
Executable file
@@ -0,0 +1,215 @@
|
||||
// FolderOut.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "Agent.h"
|
||||
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/ComTry.h"
|
||||
#include "Windows/FileDir.h"
|
||||
|
||||
// #include "../Common/CompressEngineCommon.h"
|
||||
#include "../Common/ZipRegistry.h"
|
||||
#include "../Common/UpdateAction.h"
|
||||
#include "../Common/WorkDir.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
using namespace NDirectory;
|
||||
|
||||
static LPCWSTR kTempArcivePrefix = L"7zA";
|
||||
|
||||
void CAgentFolder::GetPathParts(UStringVector &pathParts)
|
||||
{
|
||||
pathParts.Clear();
|
||||
CMyComPtr<IFolderFolder> folder = this;
|
||||
for (;;)
|
||||
{
|
||||
CMyComPtr<IFolderFolder> newFolder;
|
||||
folder->BindToParentFolder(&newFolder);
|
||||
if (newFolder == NULL)
|
||||
break;
|
||||
CMyComBSTR name;
|
||||
folder->GetName(&name);
|
||||
pathParts.Insert(0, (const wchar_t *)name);
|
||||
folder = newFolder;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CAgentFolder::CommonUpdateOperation(
|
||||
bool deleteOperation,
|
||||
bool createFolderOperation,
|
||||
bool renameOperation,
|
||||
const wchar_t *newItemName,
|
||||
const NUpdateArchive::CActionSet *actionSet,
|
||||
const UINT32 *indices, UINT32 numItems,
|
||||
IFolderArchiveUpdateCallback *updateCallback100)
|
||||
{
|
||||
NWorkDir::CInfo workDirInfo;
|
||||
ReadWorkDirInfo(workDirInfo);
|
||||
UString archiveFilePath = _agentSpec->_archiveFilePath;
|
||||
UString workDir = GetWorkDir(workDirInfo, archiveFilePath );
|
||||
CreateComplexDirectory(workDir);
|
||||
|
||||
CTempFileW tempFile;
|
||||
UString tempFileName;
|
||||
if (tempFile.Create(workDir, kTempArcivePrefix, tempFileName) == 0)
|
||||
return E_FAIL;
|
||||
|
||||
/*
|
||||
if (SetOutProperties(anOutArchive, aCompressionInfo.Method) != S_OK)
|
||||
return NFileOperationReturnCode::kError;
|
||||
*/
|
||||
|
||||
////////////////////////////
|
||||
// Save FolderItem;
|
||||
|
||||
UStringVector pathParts;
|
||||
GetPathParts(pathParts);
|
||||
|
||||
HRESULT result;
|
||||
if (deleteOperation)
|
||||
result = _agentSpec->DeleteItems(tempFileName,
|
||||
indices, numItems, updateCallback100);
|
||||
else if (createFolderOperation)
|
||||
{
|
||||
result = _agentSpec->CreateFolder(tempFileName,
|
||||
newItemName, updateCallback100);
|
||||
}
|
||||
else if (renameOperation)
|
||||
{
|
||||
result = _agentSpec->RenameItem(
|
||||
tempFileName,
|
||||
indices, numItems,
|
||||
newItemName,
|
||||
updateCallback100);
|
||||
}
|
||||
else
|
||||
{
|
||||
Byte actionSetByte[NUpdateArchive::NPairState::kNumValues];
|
||||
for (int i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
|
||||
actionSetByte[i] = (Byte)actionSet->StateActions[i];
|
||||
result = _agentSpec->DoOperation(NULL, NULL,
|
||||
tempFileName, actionSetByte, NULL, updateCallback100);
|
||||
}
|
||||
|
||||
if (result != S_OK)
|
||||
return result;
|
||||
|
||||
_agentSpec->Close();
|
||||
|
||||
// m_FolderItem = NULL;
|
||||
|
||||
if (!DeleteFileAlways(archiveFilePath ))
|
||||
return GetLastError();
|
||||
|
||||
tempFile.DisableDeleting();
|
||||
if (!MyMoveFile(tempFileName, archiveFilePath ))
|
||||
return GetLastError();
|
||||
|
||||
RINOK(_agentSpec->ReOpen(NULL));
|
||||
|
||||
////////////////////////////
|
||||
// Restore FolderItem;
|
||||
|
||||
CMyComPtr<IFolderFolder> archiveFolder;
|
||||
RINOK(_agentSpec->BindToRootFolder(&archiveFolder));
|
||||
for (int i = 0; i < pathParts.Size(); i++)
|
||||
{
|
||||
CMyComPtr<IFolderFolder> newFolder;
|
||||
archiveFolder->BindToFolder(pathParts[i], &newFolder);
|
||||
if(!newFolder)
|
||||
break;
|
||||
archiveFolder = newFolder;
|
||||
}
|
||||
|
||||
CMyComPtr<IArchiveFolderInternal> archiveFolderInternal;
|
||||
RINOK(archiveFolder.QueryInterface(IID_IArchiveFolderInternal, &archiveFolderInternal));
|
||||
CAgentFolder *agentFolder;
|
||||
RINOK(archiveFolderInternal->GetAgentFolder(&agentFolder));
|
||||
_proxyFolderItem = agentFolder->_proxyFolderItem;
|
||||
_proxyArchive = agentFolder->_proxyArchive;
|
||||
_parentFolder = agentFolder->_parentFolder;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgentFolder::CopyFrom(
|
||||
const wchar_t *fromFolderPath, // test it
|
||||
const wchar_t **itemsPaths,
|
||||
UINT32 numItems,
|
||||
IProgress *progress)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
RINOK(_agentSpec->SetFiles(fromFolderPath, itemsPaths, numItems));
|
||||
RINOK(_agentSpec->SetFolder(this));
|
||||
CMyComPtr<IFolderArchiveUpdateCallback> updateCallback100;
|
||||
if (progress != 0)
|
||||
{
|
||||
CMyComPtr<IProgress> progressWrapper = progress;
|
||||
RINOK(progressWrapper.QueryInterface(
|
||||
IID_IFolderArchiveUpdateCallback, &updateCallback100));
|
||||
}
|
||||
return CommonUpdateOperation(false, false, false, NULL,
|
||||
&NUpdateArchive::kAddActionSet, 0, 0, updateCallback100);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgentFolder::Delete(const UINT32 *indices, UINT32 numItems, IProgress *progress)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
RINOK(_agentSpec->SetFolder(this));
|
||||
CMyComPtr<IFolderArchiveUpdateCallback> updateCallback100;
|
||||
if (progress != 0)
|
||||
{
|
||||
CMyComPtr<IProgress> progressWrapper = progress;
|
||||
RINOK(progressWrapper.QueryInterface(
|
||||
IID_IFolderArchiveUpdateCallback, &updateCallback100));
|
||||
}
|
||||
return CommonUpdateOperation(true, false, false, NULL,
|
||||
&NUpdateArchive::kDeleteActionSet, indices, numItems, updateCallback100);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgentFolder::CreateFolder(const wchar_t *name, IProgress *progress)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
if (_proxyFolderItem->FindDirSubItemIndex(name) >= 0)
|
||||
return ERROR_ALREADY_EXISTS;
|
||||
RINOK(_agentSpec->SetFolder(this));
|
||||
CMyComPtr<IFolderArchiveUpdateCallback> updateCallback100;
|
||||
if (progress != 0)
|
||||
{
|
||||
CMyComPtr<IProgress> progressWrapper = progress;
|
||||
RINOK(progressWrapper.QueryInterface(IID_IFolderArchiveUpdateCallback, &updateCallback100));
|
||||
}
|
||||
return CommonUpdateOperation(false, true, false, name, NULL, NULL, 0, updateCallback100);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgentFolder::Rename(UINT32 index, const wchar_t *newName, IProgress *progress)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
CUIntVector indices;
|
||||
indices.Add(index);
|
||||
RINOK(_agentSpec->SetFolder(this));
|
||||
CMyComPtr<IFolderArchiveUpdateCallback> updateCallback100;
|
||||
if (progress != 0)
|
||||
{
|
||||
CMyComPtr<IProgress> progressWrapper = progress;
|
||||
RINOK(progressWrapper.QueryInterface(IID_IFolderArchiveUpdateCallback, &updateCallback100));
|
||||
}
|
||||
return CommonUpdateOperation(false, false, true, newName, NULL, &indices.Front(),
|
||||
indices.Size(), updateCallback100);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgentFolder::CreateFile(const wchar_t * /* name */, IProgress * /* progress */)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAgentFolder::SetProperty(UINT32 /* index */, PROPID /* propID */,
|
||||
const PROPVARIANT * /* value */, IProgress * /* progress */)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
90
CPP/7zip/UI/Agent/IFolderArchive.h
Executable file
90
CPP/7zip/UI/Agent/IFolderArchive.h
Executable file
@@ -0,0 +1,90 @@
|
||||
// IFolderArchive.h
|
||||
|
||||
#ifndef __IFOLDER_ARCHIVE_H
|
||||
#define __IFOLDER_ARCHIVE_H
|
||||
|
||||
#include "../../Archive/IArchive.h"
|
||||
// #include "../Format/Common/ArchiveInterface.h"
|
||||
#include "../../FileManager/IFolder.h"
|
||||
#include "../Common/IFileExtractCallback.h"
|
||||
#include "../Common/ExtractMode.h"
|
||||
|
||||
// {23170F69-40C1-278A-0000-000100050000}
|
||||
DEFINE_GUID(IID_IArchiveFolder,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000100050000")
|
||||
IArchiveFolder: public IUnknown
|
||||
{
|
||||
public:
|
||||
STDMETHOD(Extract)(const UINT32 *indices, UINT32 numItems,
|
||||
NExtract::NPathMode::EEnum pathMode,
|
||||
NExtract::NOverwriteMode::EEnum overwriteMode,
|
||||
const wchar_t *path,
|
||||
INT32 testMode,
|
||||
IFolderArchiveExtractCallback *extractCallback2) PURE;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-000100060000}
|
||||
DEFINE_GUID(IID_IInFolderArchive,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-000100060000")
|
||||
IInFolderArchive: public IUnknown
|
||||
{
|
||||
public:
|
||||
STDMETHOD(Open)(const wchar_t *filePath,
|
||||
// CLSID *clsIDResult,
|
||||
BSTR *archiveType,
|
||||
IArchiveOpenCallback *openArchiveCallback) PURE;
|
||||
STDMETHOD(ReOpen)(
|
||||
// const wchar_t *filePath,
|
||||
IArchiveOpenCallback *openArchiveCallback) PURE;
|
||||
STDMETHOD(Close)() PURE;
|
||||
STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) PURE;
|
||||
STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties) PURE;
|
||||
STDMETHOD(GetPropertyInfo)(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType) PURE;
|
||||
STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties) PURE;
|
||||
STDMETHOD(GetArchivePropertyInfo)(UINT32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType) PURE;
|
||||
STDMETHOD(BindToRootFolder)(IFolderFolder **resultFolder) PURE;
|
||||
STDMETHOD(Extract)(
|
||||
NExtract::NPathMode::EEnum pathMode,
|
||||
NExtract::NOverwriteMode::EEnum overwriteMode,
|
||||
const wchar_t *path,
|
||||
INT32 testMode,
|
||||
IFolderArchiveExtractCallback *extractCallback2) PURE;
|
||||
};
|
||||
|
||||
// {23170F69-40C1-278A-0000-0001000B0000}
|
||||
DEFINE_GUID(IID_IFolderArchiveUpdateCallback,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-0001000B0000")
|
||||
IFolderArchiveUpdateCallback: public IProgress
|
||||
{
|
||||
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}
|
||||
DEFINE_GUID(IID_IOutFolderArchive,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x00);
|
||||
MIDL_INTERFACE("23170F69-40C1-278A-0000-0001000A0000")
|
||||
IOutFolderArchive: public IUnknown
|
||||
{
|
||||
STDMETHOD(SetFolder)(IFolderFolder *folder) PURE;
|
||||
STDMETHOD(SetFiles)(const wchar_t *folderPrefix, const wchar_t **names, UINT32 numNames) PURE;
|
||||
STDMETHOD(DeleteItems)(const wchar_t *newArchiveName,
|
||||
const UINT32 *indices, UINT32 numItems, IFolderArchiveUpdateCallback *updateCallback) PURE;
|
||||
STDMETHOD(DoOperation)(
|
||||
const wchar_t *filePath,
|
||||
const CLSID *clsID,
|
||||
const wchar_t *newArchiveName,
|
||||
const Byte *stateActions,
|
||||
const wchar_t *sfxModule,
|
||||
IFolderArchiveUpdateCallback *updateCallback) PURE;
|
||||
};
|
||||
|
||||
#endif
|
||||
80
CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp
Executable file
80
CPP/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
CPP/7zip/UI/Agent/UpdateCallbackAgent.h
Executable file
24
CPP/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
|
||||
Reference in New Issue
Block a user