diff options
Diffstat (limited to '7zip/UI/Agent/AgentOut.cpp')
-rwxr-xr-x | 7zip/UI/Agent/AgentOut.cpp | 169 |
1 files changed, 103 insertions, 66 deletions
diff --git a/7zip/UI/Agent/AgentOut.cpp b/7zip/UI/Agent/AgentOut.cpp index 7f1f8e77..7368550f 100755 --- a/7zip/UI/Agent/AgentOut.cpp +++ b/7zip/UI/Agent/AgentOut.cpp @@ -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(); |