diff options
Diffstat (limited to 'installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/Agent/Agent.cpp')
-rw-r--r-- | installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/Agent/Agent.cpp | 615 |
1 files changed, 615 insertions, 0 deletions
diff --git a/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/Agent/Agent.cpp b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/Agent/Agent.cpp new file mode 100644 index 000000000..0b8f7c370 --- /dev/null +++ b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/Agent/Agent.cpp @@ -0,0 +1,615 @@ +// Agent.cpp + +#include "StdAfx.h" + +#include "../../../../C/Sort.h" + +#include "Common/ComTry.h" + +#include "../Common/ArchiveExtractCallback.h" + +#include "Agent.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() +{ + if (!_agentSpec->_archiveLink.IsOpen) + return E_FAIL; + _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; +} + +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(WCHAR_PATH_SEPARATOR) + path; + folder = folder->Parent; + } + return path; +} + +UString CAgentFolder::GetFullPathPrefixPlusPrefix(UInt32 index) const +{ + return _proxyFolderItem->GetFullPathPrefix() + GetPrefix(index); +} + +void CAgentFolder::GetPrefixIfAny(UInt32 index, NCOM::CPropVariant &prop) const +{ + if (!_flatMode) + return; + prop = GetPrefix(index); +} + + +STDMETHODIMP CAgentFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value) +{ + NCOM::CPropVariant prop; + 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]; + if (!_flatMode && propID == kpidSize) + prop = item.Size; + else if (!_flatMode && propID == kpidPackSize) + prop = item.PackSize; + else + switch(propID) + { + case kpidIsDir: prop = true; break; + case kpidNumSubDirs: prop = item.NumSubFolders; break; + case kpidNumSubFiles: prop = item.NumSubFiles; break; + case kpidName: prop = item.Name; break; + case kpidCRC: + { + if (item.IsLeaf) + { + RINOK(_agentSpec->GetArchive()->GetProperty(item.Index, propID, value)); + } + if (item.CrcIsDefined && value->vt == VT_EMPTY) + prop = item.Crc; + break; + } + case kpidPrefix: GetPrefixIfAny(itemIndex, prop); 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 kpidIsDir: prop = false; break; + case kpidName: prop = item.Name; break; + case kpidPrefix: GetPrefixIfAny(itemIndex, prop); break; + default: + return _agentSpec->GetArchive()->GetProperty(item.Index, propID, value); + } + } + prop.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::GetStream(UInt32 index, ISequentialInStream **stream) +{ + CMyComPtr<IInArchiveGetStream> getStream; + _agentSpec->GetArchive()->QueryInterface(IID_IInArchiveGetStream, (void **)&getStream); + if (!getStream) + return S_OK; + + const CProxyFolder *folder; + UInt32 realIndex; + if (_flatMode) + { + const CProxyItem &item = _items[index]; + folder = item.Folder; + realIndex = item.Index; + } + else + { + folder = _proxyFolderItem; + realIndex = index; + } + + UInt32 indexInArchive; + if (realIndex < (UInt32)folder->Folders.Size()) + { + const CProxyFolder &item = folder->Folders[realIndex]; + if (!item.IsLeaf) + return S_OK; + indexInArchive = item.Index; + } + else + indexInArchive = folder->Files[realIndex - folder->Folders.Size()].Index; + return getStream->GetStream(indexInArchive, stream); +} + +STATPROPSTG kProperties[] = +{ + { NULL, kpidNumSubDirs, VT_UI4}, + { NULL, kpidNumSubFiles, VT_UI4}, + { NULL, kpidPrefix, VT_BSTR} +}; + +static const UInt32 kNumProperties = sizeof(kProperties) / sizeof(kProperties[0]); + +struct CArchiveItemPropertyTemp +{ + UString Name; + PROPID ID; + VARTYPE Type; +}; + +STDMETHODIMP CAgentFolder::GetNumberOfProperties(UInt32 *numProperties) +{ + COM_TRY_BEGIN + RINOK(_agentSpec->GetArchive()->GetNumberOfProperties(numProperties)); + *numProperties += kNumProperties; + if (!_flatMode) + (*numProperties)--; + if (!_agentSpec->_proxyArchive->ThereIsPathProp) + (*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 (!_agentSpec->_proxyArchive->ThereIsPathProp) + { + if (index == 0) + { + *propID = kpidName; + *varType = VT_BSTR; + *name = 0; + return S_OK; + } + index--; + } + + if (index < numProperties) + { + RINOK(_agentSpec->GetArchive()->GetPropertyInfo(index, name, propID, varType)); + if (*propID == kpidPath) + *propID = kpidName; + } + else + { + const STATPROPSTG &srcItem = kProperties[index - numProperties]; + *propID = srcItem.propid; + *varType = srcItem.vt; + *name = 0; + } + return S_OK; + COM_TRY_END +} + +STATPROPSTG kFolderProps[] = +{ + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidNumSubDirs, VT_UI4}, + { NULL, kpidNumSubFiles, VT_UI4}, + { NULL, kpidCRC, VT_UI4} +}; + +static const UInt32 kNumFolderProps = sizeof(kFolderProps) / sizeof(kFolderProps[0]); + +STDMETHODIMP CAgentFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch(propID) + { + case kpidSize: prop = _proxyFolderItem->Size; break; + case kpidPackSize: prop = _proxyFolderItem->PackSize; break; + case kpidNumSubDirs: prop = _proxyFolderItem->NumSubFolders; break; + case kpidNumSubFiles: prop = _proxyFolderItem->NumSubFiles; break; + case kpidName: prop = _proxyFolderItem->Name; break; + case kpidPath: prop = _proxyFolderItem->GetFullPathPrefix(); break; + case kpidType: prop = UString(L"7-Zip.") + _agentSpec->ArchiveType; break; + case kpidCRC: if (_proxyFolderItem->CrcIsDefined) prop = _proxyFolderItem->Crc; break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CAgentFolder::GetNumberOfFolderProperties(UInt32 *numProperties) +{ + *numProperties = kNumFolderProps; + return S_OK; +} + +STDMETHODIMP CAgentFolder::GetFolderPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) +{ + // if (index < kNumFolderProps) + { + const STATPROPSTG &srcItem = kFolderProps[index]; + *propID = srcItem.propid; + *varType = srcItem.vt; + *name = 0; + return S_OK; + } +} + +STDMETHODIMP CAgentFolder::GetFolderArchiveProperties(IFolderArchiveProperties **object) +{ + CMyComPtr<IFolderArchiveProperties> temp = _agentSpec; + *object = temp.Detach(); + return S_OK; +} + +#ifdef NEW_FOLDER_INTERFACE + +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->InitForMulti(false, pathMode, overwriteMode); + + extractCallbackSpec->Init(NULL, &_agentSpec->GetArc(), + extractCallback2, + false, testMode ? true : false, false, + (path ? path : L""), + pathParts, + (UInt64)(Int64)-1); + CUIntVector realIndices; + GetRealIndices(indices, numItems, realIndices); + return _agentSpec->GetArchive()->Extract(&realIndices.Front(), + realIndices.Size(), testMode, extractCallback); + COM_TRY_END +} + +///////////////////////////////////////// +// CAgent + +CAgent::CAgent(): + _proxyArchive(NULL), + _codecs(0) +{ +} + +CAgent::~CAgent() +{ + if (_proxyArchive != NULL) + delete _proxyArchive; +} + +STDMETHODIMP CAgent::Open( + IInStream *inStream, + const wchar_t *filePath, + BSTR *archiveType, + IArchiveOpenCallback *openArchiveCallback) +{ + COM_TRY_BEGIN + _archiveFilePath = filePath; + NFile::NFind::CFileInfoW fi; + if (!inStream) + { + if (!fi.Find(_archiveFilePath)) + return ::GetLastError(); + if (fi.IsDir()) + return E_FAIL; + } + CArcInfoEx archiverInfo0, archiverInfo1; + + _compressCodecsInfo.Release(); + _codecs = new CCodecs; + _compressCodecsInfo = _codecs; + RINOK(_codecs->Load()); + + RINOK(_archiveLink.Open(_codecs, CIntVector(), false, inStream, _archiveFilePath, openArchiveCallback)); + + CArc &arc = _archiveLink.Arcs.Back(); + if (!inStream) + { + arc.MTimeDefined = !fi.IsDevice; + arc.MTime = fi.MTime; + } + + ArchiveType = _codecs->Formats[arc.FormatIndex].Name; + if (archiveType == 0) + return S_OK; + return StringToBstr(ArchiveType, archiveType); + COM_TRY_END +} + +STDMETHODIMP CAgent::ReOpen(IArchiveOpenCallback *openArchiveCallback) +{ + COM_TRY_BEGIN + if (_proxyArchive != NULL) + { + delete _proxyArchive; + _proxyArchive = NULL; + } + RINOK(_archiveLink.ReOpen(_codecs, _archiveFilePath, openArchiveCallback)); + return ReadItems(); + COM_TRY_END +} + +STDMETHODIMP CAgent::Close() +{ + COM_TRY_BEGIN + return _archiveLink.Close(); + 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(GetArc(), 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->InitForMulti(false, pathMode, overwriteMode); + extractCallbackSpec->Init(NULL, &GetArc(), + extractCallback2, + false, testMode ? true : false, false, + path, + UStringVector(), + (UInt64)(Int64)-1); + 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 +} |