| Index: third_party/lzma/v4_65/files/CPP/7zip/UI/Common/Update.cpp
|
| diff --git a/third_party/lzma/v4_65/files/CPP/7zip/UI/Common/Update.cpp b/third_party/lzma/v4_65/files/CPP/7zip/UI/Common/Update.cpp
|
| deleted file mode 100644
|
| index d8fee28ba3fade4a3dbe477c14528a45f3109f01..0000000000000000000000000000000000000000
|
| --- a/third_party/lzma/v4_65/files/CPP/7zip/UI/Common/Update.cpp
|
| +++ /dev/null
|
| @@ -1,911 +0,0 @@
|
| -// Update.cpp
|
| -
|
| -#include "StdAfx.h"
|
| -
|
| -#include "Update.h"
|
| -
|
| -#include "Common/IntToString.h"
|
| -#include "Common/StringConvert.h"
|
| -
|
| -#ifdef _WIN32
|
| -#include "Windows/DLL.h"
|
| -#endif
|
| -
|
| -#include "Windows/FileDir.h"
|
| -#include "Windows/FileFind.h"
|
| -#include "Windows/FileName.h"
|
| -#include "Windows/PropVariant.h"
|
| -#include "Windows/PropVariantConversions.h"
|
| -#include "Windows/Time.h"
|
| -
|
| -#include "../../Common/FileStreams.h"
|
| -
|
| -#include "../../Compress/CopyCoder.h"
|
| -
|
| -#include "../Common/DirItem.h"
|
| -#include "../Common/EnumDirItems.h"
|
| -#include "../Common/OpenArchive.h"
|
| -#include "../Common/UpdateProduce.h"
|
| -
|
| -#include "EnumDirItems.h"
|
| -#include "SetProperties.h"
|
| -#include "TempFiles.h"
|
| -#include "UpdateCallback.h"
|
| -
|
| -static const char *kUpdateIsNotSupoorted =
|
| - "update operations are not supported for this archive";
|
| -
|
| -using namespace NWindows;
|
| -using namespace NCOM;
|
| -using namespace NFile;
|
| -using namespace NName;
|
| -
|
| -static const wchar_t *kTempFolderPrefix = L"7zE";
|
| -
|
| -using namespace NUpdateArchive;
|
| -
|
| -static HRESULT CopyBlock(ISequentialInStream *inStream, ISequentialOutStream *outStream)
|
| -{
|
| - CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
|
| - return copyCoder->Code(inStream, outStream, NULL, NULL, NULL);
|
| -}
|
| -
|
| -class COutMultiVolStream:
|
| - public IOutStream,
|
| - public CMyUnknownImp
|
| -{
|
| - int _streamIndex; // required stream
|
| - UInt64 _offsetPos; // offset from start of _streamIndex index
|
| - UInt64 _absPos;
|
| - UInt64 _length;
|
| -
|
| - struct CSubStreamInfo
|
| - {
|
| - COutFileStream *StreamSpec;
|
| - CMyComPtr<IOutStream> Stream;
|
| - UString Name;
|
| - UInt64 Pos;
|
| - UInt64 RealSize;
|
| - };
|
| - CObjectVector<CSubStreamInfo> Streams;
|
| -public:
|
| - // CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
|
| - CRecordVector<UInt64> Sizes;
|
| - UString Prefix;
|
| - CTempFiles *TempFiles;
|
| -
|
| - void Init()
|
| - {
|
| - _streamIndex = 0;
|
| - _offsetPos = 0;
|
| - _absPos = 0;
|
| - _length = 0;
|
| - }
|
| -
|
| - HRESULT Close();
|
| -
|
| - MY_UNKNOWN_IMP1(IOutStream)
|
| -
|
| - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
| - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
|
| - STDMETHOD(SetSize)(Int64 newSize);
|
| -};
|
| -
|
| -// static NSynchronization::CCriticalSection g_TempPathsCS;
|
| -
|
| -HRESULT COutMultiVolStream::Close()
|
| -{
|
| - HRESULT res = S_OK;
|
| - for (int i = 0; i < Streams.Size(); i++)
|
| - {
|
| - CSubStreamInfo &s = Streams[i];
|
| - if (s.StreamSpec)
|
| - {
|
| - HRESULT res2 = s.StreamSpec->Close();
|
| - if (res2 != S_OK)
|
| - res = res2;
|
| - }
|
| - }
|
| - return res;
|
| -}
|
| -
|
| -STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
| -{
|
| - if(processedSize != NULL)
|
| - *processedSize = 0;
|
| - while(size > 0)
|
| - {
|
| - if (_streamIndex >= Streams.Size())
|
| - {
|
| - CSubStreamInfo subStream;
|
| -
|
| - wchar_t temp[32];
|
| - ConvertUInt64ToString(_streamIndex + 1, temp);
|
| - UString res = temp;
|
| - while (res.Length() < 3)
|
| - res = UString(L'0') + res;
|
| - UString name = Prefix + res;
|
| - subStream.StreamSpec = new COutFileStream;
|
| - subStream.Stream = subStream.StreamSpec;
|
| - if(!subStream.StreamSpec->Create(name, false))
|
| - return ::GetLastError();
|
| - {
|
| - // NSynchronization::CCriticalSectionLock lock(g_TempPathsCS);
|
| - TempFiles->Paths.Add(name);
|
| - }
|
| -
|
| - subStream.Pos = 0;
|
| - subStream.RealSize = 0;
|
| - subStream.Name = name;
|
| - Streams.Add(subStream);
|
| - continue;
|
| - }
|
| - CSubStreamInfo &subStream = Streams[_streamIndex];
|
| -
|
| - int index = _streamIndex;
|
| - if (index >= Sizes.Size())
|
| - index = Sizes.Size() - 1;
|
| - UInt64 volSize = Sizes[index];
|
| -
|
| - if (_offsetPos >= volSize)
|
| - {
|
| - _offsetPos -= volSize;
|
| - _streamIndex++;
|
| - continue;
|
| - }
|
| - if (_offsetPos != subStream.Pos)
|
| - {
|
| - // CMyComPtr<IOutStream> outStream;
|
| - // RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream));
|
| - RINOK(subStream.Stream->Seek(_offsetPos, STREAM_SEEK_SET, NULL));
|
| - subStream.Pos = _offsetPos;
|
| - }
|
| -
|
| - UInt32 curSize = (UInt32)MyMin((UInt64)size, volSize - subStream.Pos);
|
| - UInt32 realProcessed;
|
| - RINOK(subStream.Stream->Write(data, curSize, &realProcessed));
|
| - data = (void *)((Byte *)data + realProcessed);
|
| - size -= realProcessed;
|
| - subStream.Pos += realProcessed;
|
| - _offsetPos += realProcessed;
|
| - _absPos += realProcessed;
|
| - if (_absPos > _length)
|
| - _length = _absPos;
|
| - if (_offsetPos > subStream.RealSize)
|
| - subStream.RealSize = _offsetPos;
|
| - if(processedSize != NULL)
|
| - *processedSize += realProcessed;
|
| - if (subStream.Pos == volSize)
|
| - {
|
| - _streamIndex++;
|
| - _offsetPos = 0;
|
| - }
|
| - if (realProcessed == 0 && curSize != 0)
|
| - return E_FAIL;
|
| - break;
|
| - }
|
| - return S_OK;
|
| -}
|
| -
|
| -STDMETHODIMP COutMultiVolStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
|
| -{
|
| - if(seekOrigin >= 3)
|
| - return STG_E_INVALIDFUNCTION;
|
| - switch(seekOrigin)
|
| - {
|
| - case STREAM_SEEK_SET:
|
| - _absPos = offset;
|
| - break;
|
| - case STREAM_SEEK_CUR:
|
| - _absPos += offset;
|
| - break;
|
| - case STREAM_SEEK_END:
|
| - _absPos = _length + offset;
|
| - break;
|
| - }
|
| - _offsetPos = _absPos;
|
| - if (newPosition != NULL)
|
| - *newPosition = _absPos;
|
| - _streamIndex = 0;
|
| - return S_OK;
|
| -}
|
| -
|
| -STDMETHODIMP COutMultiVolStream::SetSize(Int64 newSize)
|
| -{
|
| - if (newSize < 0)
|
| - return E_INVALIDARG;
|
| - int i = 0;
|
| - while (i < Streams.Size())
|
| - {
|
| - CSubStreamInfo &subStream = Streams[i++];
|
| - if ((UInt64)newSize < subStream.RealSize)
|
| - {
|
| - RINOK(subStream.Stream->SetSize(newSize));
|
| - subStream.RealSize = newSize;
|
| - break;
|
| - }
|
| - newSize -= subStream.RealSize;
|
| - }
|
| - while (i < Streams.Size())
|
| - {
|
| - {
|
| - CSubStreamInfo &subStream = Streams.Back();
|
| - subStream.Stream.Release();
|
| - NDirectory::DeleteFileAlways(subStream.Name);
|
| - }
|
| - Streams.DeleteBack();
|
| - }
|
| - _offsetPos = _absPos;
|
| - _streamIndex = 0;
|
| - _length = newSize;
|
| - return S_OK;
|
| -}
|
| -
|
| -static const wchar_t *kDefaultArchiveType = L"7z";
|
| -static const wchar_t *kSFXExtension =
|
| - #ifdef _WIN32
|
| - L"exe";
|
| - #else
|
| - L"";
|
| - #endif
|
| -
|
| -bool CUpdateOptions::Init(const CCodecs *codecs, const CIntVector &formatIndices, const UString &arcPath)
|
| -{
|
| - if (formatIndices.Size() > 1)
|
| - return false;
|
| - int arcTypeIndex = -1;
|
| - if (formatIndices.Size() != 0)
|
| - arcTypeIndex = formatIndices[0];
|
| - if (arcTypeIndex >= 0)
|
| - MethodMode.FormatIndex = arcTypeIndex;
|
| - else
|
| - {
|
| - MethodMode.FormatIndex = codecs->FindFormatForArchiveName(arcPath);
|
| - if (MethodMode.FormatIndex < 0)
|
| - MethodMode.FormatIndex = codecs->FindFormatForArchiveType(kDefaultArchiveType);
|
| - }
|
| - if (MethodMode.FormatIndex < 0)
|
| - return false;
|
| - const CArcInfoEx &arcInfo = codecs->Formats[MethodMode.FormatIndex];
|
| - if (!arcInfo.UpdateEnabled)
|
| - return false;
|
| - UString typeExt = arcInfo.GetMainExt();
|
| - UString ext = typeExt;
|
| - if (SfxMode)
|
| - ext = kSFXExtension;
|
| - ArchivePath.BaseExtension = ext;
|
| - ArchivePath.VolExtension = typeExt;
|
| - ArchivePath.ParseFromPath(arcPath);
|
| - for (int i = 0; i < Commands.Size(); i++)
|
| - {
|
| - CUpdateArchiveCommand &uc = Commands[i];
|
| - uc.ArchivePath.BaseExtension = ext;
|
| - uc.ArchivePath.VolExtension = typeExt;
|
| - uc.ArchivePath.ParseFromPath(uc.UserArchivePath);
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -/*
|
| -struct CUpdateProduceCallbackImp: public IUpdateProduceCallback
|
| -{
|
| - const CObjectVector<CArcItem> *_arcItems;
|
| - IUpdateCallbackUI *_callback;
|
| -
|
| - CUpdateProduceCallbackImp(const CObjectVector<CArcItem> *a,
|
| - IUpdateCallbackUI *callback): _arcItems(a), _callback(callback) {}
|
| - virtual HRESULT ShowDeleteFile(int arcIndex);
|
| -};
|
| -
|
| -HRESULT CUpdateProduceCallbackImp::ShowDeleteFile(int arcIndex)
|
| -{
|
| - return _callback->ShowDeleteFile((*_arcItems)[arcIndex].Name);
|
| -}
|
| -*/
|
| -
|
| -static HRESULT Compress(
|
| - CCodecs *codecs,
|
| - const CActionSet &actionSet,
|
| - IInArchive *archive,
|
| - const CCompressionMethodMode &compressionMethod,
|
| - CArchivePath &archivePath,
|
| - const CObjectVector<CArcItem> &arcItems,
|
| - bool shareForWrite,
|
| - bool stdInMode,
|
| - /* const UString & stdInFileName, */
|
| - bool stdOutMode,
|
| - const CDirItems &dirItems,
|
| - bool sfxMode,
|
| - const UString &sfxModule,
|
| - const CRecordVector<UInt64> &volumesSizes,
|
| - CTempFiles &tempFiles,
|
| - CUpdateErrorInfo &errorInfo,
|
| - IUpdateCallbackUI *callback)
|
| -{
|
| - CMyComPtr<IOutArchive> outArchive;
|
| - if(archive != NULL)
|
| - {
|
| - CMyComPtr<IInArchive> archive2 = archive;
|
| - HRESULT result = archive2.QueryInterface(IID_IOutArchive, &outArchive);
|
| - if(result != S_OK)
|
| - throw kUpdateIsNotSupoorted;
|
| - }
|
| - else
|
| - {
|
| - RINOK(codecs->CreateOutArchive(compressionMethod.FormatIndex, outArchive));
|
| -
|
| - #ifdef EXTERNAL_CODECS
|
| - {
|
| - CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
|
| - outArchive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
|
| - if (setCompressCodecsInfo)
|
| - {
|
| - RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs));
|
| - }
|
| - }
|
| - #endif
|
| - }
|
| - if (outArchive == 0)
|
| - throw kUpdateIsNotSupoorted;
|
| -
|
| - NFileTimeType::EEnum fileTimeType;
|
| - UInt32 value;
|
| - RINOK(outArchive->GetFileTimeType(&value));
|
| -
|
| - switch(value)
|
| - {
|
| - case NFileTimeType::kWindows:
|
| - case NFileTimeType::kUnix:
|
| - case NFileTimeType::kDOS:
|
| - fileTimeType = (NFileTimeType::EEnum)value;
|
| - break;
|
| - default:
|
| - return E_FAIL;
|
| - }
|
| -
|
| - CRecordVector<CUpdatePair2> updatePairs2;
|
| -
|
| - {
|
| - CRecordVector<CUpdatePair> updatePairs;
|
| - GetUpdatePairInfoList(dirItems, arcItems, fileTimeType, updatePairs); // must be done only once!!!
|
| - // CUpdateProduceCallbackImp upCallback(&arcItems, callback);
|
| - UpdateProduce(updatePairs, actionSet, updatePairs2, NULL /* &upCallback */);
|
| - }
|
| -
|
| - UInt32 numFiles = 0;
|
| - for (int i = 0; i < updatePairs2.Size(); i++)
|
| - if (updatePairs2[i].NewData)
|
| - numFiles++;
|
| -
|
| - RINOK(callback->SetNumFiles(numFiles));
|
| -
|
| -
|
| - CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
|
| - CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);
|
| -
|
| - updateCallbackSpec->ShareForWrite = shareForWrite;
|
| - updateCallbackSpec->StdInMode = stdInMode;
|
| - updateCallbackSpec->Callback = callback;
|
| - updateCallbackSpec->DirItems = &dirItems;
|
| - updateCallbackSpec->ArcItems = &arcItems;
|
| - updateCallbackSpec->UpdatePairs = &updatePairs2;
|
| -
|
| - CMyComPtr<ISequentialOutStream> outStream;
|
| -
|
| - const UString &archiveName = archivePath.GetFinalPath();
|
| - if (!stdOutMode)
|
| - {
|
| - UString resultPath;
|
| - int pos;
|
| - if(!NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos))
|
| - throw 1417161;
|
| - NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos));
|
| - }
|
| -
|
| - COutFileStream *outStreamSpec = NULL;
|
| - COutMultiVolStream *volStreamSpec = NULL;
|
| -
|
| - if (volumesSizes.Size() == 0)
|
| - {
|
| - if (stdOutMode)
|
| - outStream = new CStdOutFileStream;
|
| - else
|
| - {
|
| - outStreamSpec = new COutFileStream;
|
| - outStream = outStreamSpec;
|
| - bool isOK = false;
|
| - UString realPath;
|
| - for (int i = 0; i < (1 << 16); i++)
|
| - {
|
| - if (archivePath.Temp)
|
| - {
|
| - if (i > 0)
|
| - {
|
| - wchar_t s[32];
|
| - ConvertUInt64ToString(i, s);
|
| - archivePath.TempPostfix = s;
|
| - }
|
| - realPath = archivePath.GetTempPath();
|
| - }
|
| - else
|
| - realPath = archivePath.GetFinalPath();
|
| - if (outStreamSpec->Create(realPath, false))
|
| - {
|
| - tempFiles.Paths.Add(realPath);
|
| - isOK = true;
|
| - break;
|
| - }
|
| - if (::GetLastError() != ERROR_FILE_EXISTS)
|
| - break;
|
| - if (!archivePath.Temp)
|
| - break;
|
| - }
|
| - if (!isOK)
|
| - {
|
| - errorInfo.SystemError = ::GetLastError();
|
| - errorInfo.FileName = realPath;
|
| - errorInfo.Message = L"Can not open file";
|
| - return E_FAIL;
|
| - }
|
| - }
|
| - }
|
| - else
|
| - {
|
| - if (stdOutMode)
|
| - return E_FAIL;
|
| - volStreamSpec = new COutMultiVolStream;
|
| - outStream = volStreamSpec;
|
| - volStreamSpec->Sizes = volumesSizes;
|
| - volStreamSpec->Prefix = archivePath.GetFinalPath() + UString(L".");
|
| - volStreamSpec->TempFiles = &tempFiles;
|
| - volStreamSpec->Init();
|
| -
|
| - /*
|
| - updateCallbackSpec->VolumesSizes = volumesSizes;
|
| - updateCallbackSpec->VolName = archivePath.Prefix + archivePath.Name;
|
| - if (!archivePath.VolExtension.IsEmpty())
|
| - updateCallbackSpec->VolExt = UString(L'.') + archivePath.VolExtension;
|
| - */
|
| - }
|
| -
|
| - RINOK(SetProperties(outArchive, compressionMethod.Properties));
|
| -
|
| - if (sfxMode)
|
| - {
|
| - CInFileStream *sfxStreamSpec = new CInFileStream;
|
| - CMyComPtr<IInStream> sfxStream(sfxStreamSpec);
|
| - if (!sfxStreamSpec->Open(sfxModule))
|
| - {
|
| - errorInfo.SystemError = ::GetLastError();
|
| - errorInfo.Message = L"Can't open sfx module";
|
| - errorInfo.FileName = sfxModule;
|
| - return E_FAIL;
|
| - }
|
| -
|
| - CMyComPtr<ISequentialOutStream> sfxOutStream;
|
| - COutFileStream *outStreamSpec = NULL;
|
| - if (volumesSizes.Size() == 0)
|
| - sfxOutStream = outStream;
|
| - else
|
| - {
|
| - outStreamSpec = new COutFileStream;
|
| - sfxOutStream = outStreamSpec;
|
| - UString realPath = archivePath.GetFinalPath();
|
| - if (!outStreamSpec->Create(realPath, false))
|
| - {
|
| - errorInfo.SystemError = ::GetLastError();
|
| - errorInfo.FileName = realPath;
|
| - errorInfo.Message = L"Can not open file";
|
| - return E_FAIL;
|
| - }
|
| - }
|
| - RINOK(CopyBlock(sfxStream, sfxOutStream));
|
| - if (outStreamSpec)
|
| - {
|
| - RINOK(outStreamSpec->Close());
|
| - }
|
| - }
|
| -
|
| - HRESULT result = outArchive->UpdateItems(outStream, updatePairs2.Size(), updateCallback);
|
| - callback->Finilize();
|
| - RINOK(result);
|
| - if (outStreamSpec)
|
| - result = outStreamSpec->Close();
|
| - else if (volStreamSpec)
|
| - result = volStreamSpec->Close();
|
| - return result;
|
| -}
|
| -
|
| -HRESULT EnumerateInArchiveItems(const NWildcard::CCensor &censor,
|
| - IInArchive *archive,
|
| - const UString &defaultItemName,
|
| - const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo,
|
| - CObjectVector<CArcItem> &arcItems)
|
| -{
|
| - arcItems.Clear();
|
| - UInt32 numItems;
|
| - RINOK(archive->GetNumberOfItems(&numItems));
|
| - arcItems.Reserve(numItems);
|
| - for (UInt32 i = 0; i < numItems; i++)
|
| - {
|
| - CArcItem ai;
|
| -
|
| - RINOK(GetArchiveItemPath(archive, i, ai.Name));
|
| - // check it: defaultItemName !!!
|
| - if (ai.Name.IsEmpty())
|
| - ai.Name = defaultItemName;
|
| - RINOK(IsArchiveItemFolder(archive, i, ai.IsDir));
|
| - ai.Censored = censor.CheckPath(ai.Name, !ai.IsDir);
|
| - RINOK(GetArchiveItemFileTime(archive, i, archiveFileInfo.MTime, ai.MTime));
|
| -
|
| - {
|
| - CPropVariant prop;
|
| - RINOK(archive->GetProperty(i, kpidSize, &prop));
|
| - ai.SizeDefined = (prop.vt != VT_EMPTY);
|
| - if (ai.SizeDefined)
|
| - ai.Size = ConvertPropVariantToUInt64(prop);
|
| - }
|
| -
|
| - {
|
| - CPropVariant prop;
|
| - RINOK(archive->GetProperty(i, kpidTimeType, &prop));
|
| - if (prop.vt == VT_UI4)
|
| - {
|
| - ai.TimeType = (int)(NFileTimeType::EEnum)prop.ulVal;
|
| - switch(ai.TimeType)
|
| - {
|
| - case NFileTimeType::kWindows:
|
| - case NFileTimeType::kUnix:
|
| - case NFileTimeType::kDOS:
|
| - break;
|
| - default:
|
| - return E_FAIL;
|
| - }
|
| - }
|
| - }
|
| -
|
| - ai.IndexInServer = i;
|
| - arcItems.Add(ai);
|
| - }
|
| - return S_OK;
|
| -}
|
| -
|
| -
|
| -static HRESULT UpdateWithItemLists(
|
| - CCodecs *codecs,
|
| - CUpdateOptions &options,
|
| - IInArchive *archive,
|
| - const CObjectVector<CArcItem> &arcItems,
|
| - CDirItems &dirItems,
|
| - CTempFiles &tempFiles,
|
| - CUpdateErrorInfo &errorInfo,
|
| - IUpdateCallbackUI2 *callback)
|
| -{
|
| - for(int i = 0; i < options.Commands.Size(); i++)
|
| - {
|
| - CUpdateArchiveCommand &command = options.Commands[i];
|
| - if (options.StdOutMode)
|
| - {
|
| - RINOK(callback->StartArchive(0, archive != 0));
|
| - }
|
| - else
|
| - {
|
| - RINOK(callback->StartArchive(command.ArchivePath.GetFinalPath(),
|
| - i == 0 && options.UpdateArchiveItself && archive != 0));
|
| - }
|
| -
|
| - RINOK(Compress(
|
| - codecs,
|
| - command.ActionSet, archive,
|
| - options.MethodMode,
|
| - command.ArchivePath,
|
| - arcItems,
|
| - options.OpenShareForWrite,
|
| - options.StdInMode,
|
| - /* options.StdInFileName, */
|
| - options.StdOutMode,
|
| - dirItems,
|
| - options.SfxMode, options.SfxModule,
|
| - options.VolumesSizes,
|
| - tempFiles,
|
| - errorInfo, callback));
|
| -
|
| - RINOK(callback->FinishArchive());
|
| - }
|
| - return S_OK;
|
| -}
|
| -
|
| -#ifdef _WIN32
|
| -class CCurrentDirRestorer
|
| -{
|
| - UString m_CurrentDirectory;
|
| -public:
|
| - CCurrentDirRestorer()
|
| - { NFile::NDirectory::MyGetCurrentDirectory(m_CurrentDirectory); }
|
| - ~CCurrentDirRestorer()
|
| - { RestoreDirectory();}
|
| - bool RestoreDirectory()
|
| - { return BOOLToBool(NFile::NDirectory::MySetCurrentDirectory(m_CurrentDirectory)); }
|
| -};
|
| -#endif
|
| -
|
| -struct CEnumDirItemUpdateCallback: public IEnumDirItemCallback
|
| -{
|
| - IUpdateCallbackUI2 *Callback;
|
| - HRESULT ScanProgress(UInt64 numFolders, UInt64 numFiles, const wchar_t *path)
|
| - {
|
| - return Callback->ScanProgress(numFolders, numFiles, path);
|
| - }
|
| -};
|
| -
|
| -#ifdef _WIN32
|
| -typedef ULONG (FAR PASCAL MY_MAPISENDDOCUMENTS)(
|
| - ULONG_PTR ulUIParam,
|
| - LPSTR lpszDelimChar,
|
| - LPSTR lpszFilePaths,
|
| - LPSTR lpszFileNames,
|
| - ULONG ulReserved
|
| -);
|
| -typedef MY_MAPISENDDOCUMENTS FAR *MY_LPMAPISENDDOCUMENTS;
|
| -#endif
|
| -
|
| -HRESULT UpdateArchive(
|
| - CCodecs *codecs,
|
| - const NWildcard::CCensor &censor,
|
| - CUpdateOptions &options,
|
| - CUpdateErrorInfo &errorInfo,
|
| - IOpenCallbackUI *openCallback,
|
| - IUpdateCallbackUI2 *callback)
|
| -{
|
| - if (options.StdOutMode && options.EMailMode)
|
| - return E_FAIL;
|
| -
|
| - if (options.VolumesSizes.Size() > 0 && (options.EMailMode || options.SfxMode))
|
| - return E_NOTIMPL;
|
| -
|
| - if (options.SfxMode)
|
| - {
|
| - CProperty property;
|
| - property.Name = L"rsfx";
|
| - property.Value = L"on";
|
| - options.MethodMode.Properties.Add(property);
|
| - if (options.SfxModule.IsEmpty())
|
| - {
|
| - errorInfo.Message = L"sfx file is not specified";
|
| - return E_FAIL;
|
| - }
|
| - UString name = options.SfxModule;
|
| - if (!NDirectory::MySearchPath(NULL, name, NULL, options.SfxModule))
|
| - {
|
| - errorInfo.Message = L"can't find specified sfx module";
|
| - return E_FAIL;
|
| - }
|
| - }
|
| -
|
| - const UString archiveName = options.ArchivePath.GetFinalPath();
|
| -
|
| - UString defaultItemName;
|
| - NFind::CFileInfoW archiveFileInfo;
|
| -
|
| - CArchiveLink archiveLink;
|
| - IInArchive *archive = 0;
|
| - if (NFind::FindFile(archiveName, archiveFileInfo))
|
| - {
|
| - if (archiveFileInfo.IsDir())
|
| - throw "there is no such archive";
|
| - if (options.VolumesSizes.Size() > 0)
|
| - return E_NOTIMPL;
|
| - CIntVector formatIndices;
|
| - if (options.MethodMode.FormatIndex >= 0)
|
| - formatIndices.Add(options.MethodMode.FormatIndex);
|
| - HRESULT result = MyOpenArchive(codecs, formatIndices, archiveName, archiveLink, openCallback);
|
| - if (result == E_ABORT)
|
| - return result;
|
| - RINOK(callback->OpenResult(archiveName, result));
|
| - RINOK(result);
|
| - if (archiveLink.VolumePaths.Size() > 1)
|
| - {
|
| - errorInfo.SystemError = (DWORD)E_NOTIMPL;
|
| - errorInfo.Message = L"Updating for multivolume archives is not implemented";
|
| - return E_NOTIMPL;
|
| - }
|
| - archive = archiveLink.GetArchive();
|
| - defaultItemName = archiveLink.GetDefaultItemName();
|
| - }
|
| - else
|
| - {
|
| - /*
|
| - if (archiveType.IsEmpty())
|
| - throw "type of archive is not specified";
|
| - */
|
| - }
|
| -
|
| - CDirItems dirItems;
|
| - if (options.StdInMode)
|
| - {
|
| - CDirItem di;
|
| - di.Name = options.StdInFileName;
|
| - di.Size = (UInt64)(Int64)-1;
|
| - di.Attrib = 0;
|
| - NTime::GetCurUtcFileTime(di.MTime);
|
| - di.CTime = di.ATime = di.MTime;
|
| - dirItems.Items.Add(di);
|
| - }
|
| - else
|
| - {
|
| - bool needScanning = false;
|
| - for(int i = 0; i < options.Commands.Size(); i++)
|
| - if (options.Commands[i].ActionSet.NeedScanning())
|
| - needScanning = true;
|
| - if (needScanning)
|
| - {
|
| - CEnumDirItemUpdateCallback enumCallback;
|
| - enumCallback.Callback = callback;
|
| - RINOK(callback->StartScanning());
|
| - UStringVector errorPaths;
|
| - CRecordVector<DWORD> errorCodes;
|
| - HRESULT res = EnumerateItems(censor, dirItems, &enumCallback, errorPaths, errorCodes);
|
| - for (int i = 0; i < errorPaths.Size(); i++)
|
| - {
|
| - RINOK(callback->CanNotFindError(errorPaths[i], errorCodes[i]));
|
| - }
|
| - if (res != S_OK)
|
| - {
|
| - if (res != E_ABORT)
|
| - errorInfo.Message = L"Scanning error";
|
| - // errorInfo.FileName = errorPath;
|
| - return res;
|
| - }
|
| - RINOK(callback->FinishScanning());
|
| - }
|
| - }
|
| -
|
| - UString tempDirPrefix;
|
| - bool usesTempDir = false;
|
| -
|
| - #ifdef _WIN32
|
| - NDirectory::CTempDirectoryW tempDirectory;
|
| - if (options.EMailMode && options.EMailRemoveAfter)
|
| - {
|
| - tempDirectory.Create(kTempFolderPrefix);
|
| - tempDirPrefix = tempDirectory.GetPath();
|
| - NormalizeDirPathPrefix(tempDirPrefix);
|
| - usesTempDir = true;
|
| - }
|
| - #endif
|
| -
|
| - CTempFiles tempFiles;
|
| -
|
| - bool createTempFile = false;
|
| - if(!options.StdOutMode && options.UpdateArchiveItself)
|
| - {
|
| - CArchivePath &ap = options.Commands[0].ArchivePath;
|
| - ap = options.ArchivePath;
|
| - // if ((archive != 0 && !usesTempDir) || !options.WorkingDir.IsEmpty())
|
| - if ((archive != 0 || !options.WorkingDir.IsEmpty()) && !usesTempDir && options.VolumesSizes.Size() == 0)
|
| - {
|
| - createTempFile = true;
|
| - ap.Temp = true;
|
| - if (!options.WorkingDir.IsEmpty())
|
| - {
|
| - ap.TempPrefix = options.WorkingDir;
|
| - NormalizeDirPathPrefix(ap.TempPrefix);
|
| - }
|
| - }
|
| - }
|
| -
|
| - for(int i = 0; i < options.Commands.Size(); i++)
|
| - {
|
| - CArchivePath &ap = options.Commands[i].ArchivePath;
|
| - if (usesTempDir)
|
| - {
|
| - // Check it
|
| - ap.Prefix = tempDirPrefix;
|
| - // ap.Temp = true;
|
| - // ap.TempPrefix = tempDirPrefix;
|
| - }
|
| - if (i > 0 || !createTempFile)
|
| - {
|
| - const UString &path = ap.GetFinalPath();
|
| - if (NFind::DoesFileExist(path))
|
| - {
|
| - errorInfo.SystemError = 0;
|
| - errorInfo.Message = L"File already exists";
|
| - errorInfo.FileName = path;
|
| - return E_FAIL;
|
| - }
|
| - }
|
| - }
|
| -
|
| - CObjectVector<CArcItem> arcItems;
|
| - if (archive != NULL)
|
| - {
|
| - RINOK(EnumerateInArchiveItems(censor,
|
| - archive, defaultItemName, archiveFileInfo, arcItems));
|
| - }
|
| -
|
| - RINOK(UpdateWithItemLists(codecs, options, archive, arcItems, dirItems,
|
| - tempFiles, errorInfo, callback));
|
| -
|
| - if (archive != NULL)
|
| - {
|
| - RINOK(archiveLink.Close());
|
| - archiveLink.Release();
|
| - }
|
| -
|
| - tempFiles.Paths.Clear();
|
| - if(createTempFile)
|
| - {
|
| - try
|
| - {
|
| - CArchivePath &ap = options.Commands[0].ArchivePath;
|
| - const UString &tempPath = ap.GetTempPath();
|
| - if (archive != NULL)
|
| - if (!NDirectory::DeleteFileAlways(archiveName))
|
| - {
|
| - errorInfo.SystemError = ::GetLastError();
|
| - errorInfo.Message = L"delete file error";
|
| - errorInfo.FileName = archiveName;
|
| - return E_FAIL;
|
| - }
|
| - if (!NDirectory::MyMoveFile(tempPath, archiveName))
|
| - {
|
| - errorInfo.SystemError = ::GetLastError();
|
| - errorInfo.Message = L"move file error";
|
| - errorInfo.FileName = tempPath;
|
| - errorInfo.FileName2 = archiveName;
|
| - return E_FAIL;
|
| - }
|
| - }
|
| - catch(...)
|
| - {
|
| - throw;
|
| - }
|
| - }
|
| -
|
| - #ifdef _WIN32
|
| - if (options.EMailMode)
|
| - {
|
| - NDLL::CLibrary mapiLib;
|
| - if (!mapiLib.Load(TEXT("Mapi32.dll")))
|
| - {
|
| - errorInfo.SystemError = ::GetLastError();
|
| - errorInfo.Message = L"can not load Mapi32.dll";
|
| - return E_FAIL;
|
| - }
|
| - MY_LPMAPISENDDOCUMENTS fnSend = (MY_LPMAPISENDDOCUMENTS)
|
| - mapiLib.GetProcAddress("MAPISendDocuments");
|
| - if (fnSend == 0)
|
| - {
|
| - errorInfo.SystemError = ::GetLastError();
|
| - errorInfo.Message = L"can not find MAPISendDocuments function";
|
| - return E_FAIL;
|
| - }
|
| - UStringVector fullPaths;
|
| - int i;
|
| - for(i = 0; i < options.Commands.Size(); i++)
|
| - {
|
| - CArchivePath &ap = options.Commands[i].ArchivePath;
|
| - UString arcPath;
|
| - if(!NFile::NDirectory::MyGetFullPathName(ap.GetFinalPath(), arcPath))
|
| - {
|
| - errorInfo.SystemError = ::GetLastError();
|
| - return E_FAIL;
|
| - }
|
| - fullPaths.Add(arcPath);
|
| - }
|
| - CCurrentDirRestorer curDirRestorer;
|
| - for(i = 0; i < fullPaths.Size(); i++)
|
| - {
|
| - UString arcPath = fullPaths[i];
|
| - UString fileName = ExtractFileNameFromPath(arcPath);
|
| - AString path = GetAnsiString(arcPath);
|
| - AString name = GetAnsiString(fileName);
|
| - // Warning!!! MAPISendDocuments function changes Current directory
|
| - fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0);
|
| - }
|
| - }
|
| - #endif
|
| - return S_OK;
|
| -}
|
| -
|
|
|