misc/libphysfs/lzma/CPP/7zip/UI/Common/Update.cpp
branchui-scaling
changeset 15283 c4fd2813b127
parent 13390 0135e64c6c66
parent 15279 7ab5cf405686
child 15663 d92eeb468dad
--- a/misc/libphysfs/lzma/CPP/7zip/UI/Common/Update.cpp	Wed May 16 18:22:28 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,852 +0,0 @@
-// Update.cpp
-
-#include "StdAfx.h"
-
-#ifdef _WIN32
-#include <mapi.h>
-#endif
-
-#include "Update.h"
-
-#include "Common/IntToString.h"
-#include "Common/StringConvert.h"
-#include "Common/CommandLineParser.h"
-
-#ifdef _WIN32
-#include "Windows/DLL.h"
-#endif
-
-#include "Windows/Defs.h"
-#include "Windows/FileDir.h"
-#include "Windows/FileFind.h"
-#include "Windows/FileName.h"
-#include "Windows/PropVariant.h"
-#include "Windows/PropVariantConversions.h"
-// #include "Windows/Synchronization.h"
-
-#include "../../Common/FileStreams.h"
-#include "../../Compress/Copy/CopyCoder.h"
-
-#include "../Common/DirItem.h"
-#include "../Common/EnumDirItems.h"
-#include "../Common/UpdateProduce.h"
-#include "../Common/OpenArchive.h"
-
-#include "TempFiles.h"
-#include "UpdateCallback.h"
-#include "EnumDirItems.h"
-#include "SetProperties.h"
-
-static const char *kUpdateIsNotSupoorted = 
-  "update operations are not supported for this archive";
-
-using namespace NCommandLineParser;
-using namespace NWindows;
-using namespace NCOM;
-using namespace NFile;
-using namespace NName;
-
-static const wchar_t *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 UString &arcPath, const UString &arcType)
-{
-  if (!arcType.IsEmpty())
-    MethodMode.FormatIndex = codecs->FindFormatForArchiveType(arcType);
-  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];
-  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;
-}
-
-
-static HRESULT Compress(
-    CCodecs *codecs,
-    const CActionSet &actionSet, 
-    IInArchive *archive,
-    const CCompressionMethodMode &compressionMethod,
-    CArchivePath &archivePath, 
-    const CObjectVector<CArchiveItem> &archiveItems,
-    bool shareForWrite,
-    bool stdInMode,
-    /* const UString & stdInFileName, */
-    bool stdOutMode,
-    const CObjectVector<CDirItem> &dirItems,
-    bool sfxMode,
-    const UString &sfxModule,
-    const CRecordVector<UInt64> &volumesSizes,
-    CTempFiles &tempFiles,
-    CUpdateErrorInfo &errorInfo,
-    IUpdateCallbackUI *callback)
-{
-  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::kDOS:
-    case NFileTimeType::kUnix:
-      fileTimeType = NFileTimeType::EEnum(value);
-      break;
-    default:
-      return E_FAIL;
-  }
-
-  CObjectVector<CUpdatePair> updatePairs;
-  GetUpdatePairInfoList(dirItems, archiveItems, fileTimeType, updatePairs); // must be done only once!!!
-  
-  CObjectVector<CUpdatePair2> updatePairs2;
-  UpdateProduce(updatePairs, actionSet, updatePairs2);
-
-  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->ArchiveItems = &archiveItems;
-  updateCallbackSpec->UpdatePairs = &updatePairs2;
-
-  CMyComPtr<ISequentialOutStream> outStream;
-
-  const UString &archiveName = archivePath.GetFinalPath();
-  if (!stdOutMode)
-  {
-    UString resultPath;
-    int pos;
-    if(!NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos))
-      throw 1417161;
-    NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos));
-  }
-
-  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<CArchiveItem> &archiveItems)
-{
-  archiveItems.Clear();
-  UInt32 numItems;
-  RINOK(archive->GetNumberOfItems(&numItems));
-  archiveItems.Reserve(numItems);
-  for(UInt32 i = 0; i < numItems; i++)
-  {
-    CArchiveItem ai;
-
-    RINOK(GetArchiveItemPath(archive, i, ai.Name));
-    RINOK(IsArchiveItemFolder(archive, i, ai.IsDirectory));
-    ai.Censored = censor.CheckPath(ai.Name.IsEmpty() ? defaultItemName : ai.Name, !ai.IsDirectory);
-    RINOK(GetArchiveItemFileTime(archive, i, 
-        archiveFileInfo.LastWriteTime, ai.LastWriteTime));
-
-    CPropVariant propertySize;
-    RINOK(archive->GetProperty(i, kpidSize, &propertySize));
-    ai.SizeIsDefined = (propertySize.vt != VT_EMPTY);
-    if (ai.SizeIsDefined)
-      ai.Size = ConvertPropVariantToUInt64(propertySize);
-
-    ai.IndexInServer = i;
-    archiveItems.Add(ai);
-  }
-  return S_OK;
-}
-
-
-static HRESULT UpdateWithItemLists(
-    CCodecs *codecs,
-    CUpdateOptions &options,
-    IInArchive *archive, 
-    const CObjectVector<CArchiveItem> &archiveItems,
-    const CObjectVector<CDirItem> &dirItems,
-    CTempFiles &tempFiles,
-    CUpdateErrorInfo &errorInfo,
-    IUpdateCallbackUI2 *callback)
-{
-  for(int i = 0; i < options.Commands.Size(); i++)
-  {
-    CUpdateArchiveCommand &command = options.Commands[i];
-    if (options.StdOutMode)
-    {
-      RINOK(callback->StartArchive(0, archive != 0));
-    }
-    else
-    {
-      RINOK(callback->StartArchive(command.ArchivePath.GetFinalPath(), 
-          i == 0 && options.UpdateArchiveItself && archive != 0));
-    }
-
-    RINOK(Compress(
-        codecs,
-        command.ActionSet, archive,
-        options.MethodMode, 
-        command.ArchivePath, 
-        archiveItems, 
-        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 CheckBreak() { return Callback->CheckBreak(); }
-};
-
-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.IsDirectory())
-      throw "there is no such archive";
-    if (options.VolumesSizes.Size() > 0)
-      return E_NOTIMPL;
-    HRESULT result = MyOpenArchive(codecs, archiveName, archiveLink, openCallback);
-    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";
-    */
-  }
-
-  CObjectVector<CDirItem> dirItems;
-  if (options.StdInMode)
-  {
-    CDirItem item;
-    item.FullPath = item.Name = options.StdInFileName;
-    item.Size = (UInt64)(Int64)-1;
-    item.Attributes = 0;
-    SYSTEMTIME st;
-    FILETIME ft;
-    GetSystemTime(&st);
-    SystemTimeToFileTime(&st, &ft);
-    item.CreationTime = item.LastAccessTime = item.LastWriteTime = ft;
-    dirItems.Add(item);
-  }
-  else
-  {
-    bool needScanning = false;
-    for(int i = 0; i < options.Commands.Size(); i++)
-      if (options.Commands[i].ActionSet.NeedScanning())
-        needScanning = true;
-    if (needScanning)
-    {
-      CEnumDirItemUpdateCallback enumCallback;
-      enumCallback.Callback = callback;
-      RINOK(callback->StartScanning());
-      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) 
-      {
-        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<CArchiveItem> archiveItems;
-  if (archive != NULL)
-  {
-    RINOK(EnumerateInArchiveItems(censor, 
-        archive, defaultItemName, archiveFileInfo, archiveItems));
-  }
-
-  RINOK(UpdateWithItemLists(codecs, options, archive, archiveItems, dirItems, 
-      tempFiles, errorInfo, callback));
-
-  if (archive != NULL)
-  {
-    RINOK(archiveLink.Close());
-    archiveLink.Release();
-  }
-
-  tempFiles.Paths.Clear();
-  if(createTempFile)
-  {
-    try
-    {
-      CArchivePath &ap = options.Commands[0].ArchivePath;
-      const UString &tempPath = ap.GetTempPath();
-      if (archive != NULL)
-        if (!NDirectory::DeleteFileAlways(archiveName))
-        {
-          errorInfo.SystemError = ::GetLastError();
-          errorInfo.Message = L"delete file error";
-          errorInfo.FileName = archiveName;
-          return E_FAIL;
-        }
-      if (!NDirectory::MyMoveFile(tempPath, archiveName))
-      {
-        errorInfo.SystemError = ::GetLastError();
-        errorInfo.Message = L"move file error";
-        errorInfo.FileName = tempPath;
-        errorInfo.FileName2 = archiveName;
-        return E_FAIL;
-      }
-    }
-    catch(...)
-    {
-      throw;
-    }
-  }
-
-  #ifdef _WIN32
-  if (options.EMailMode)
-  {
-    NDLL::CLibrary mapiLib;
-    if (!mapiLib.Load(TEXT("Mapi32.dll")))
-    {
-      errorInfo.SystemError = ::GetLastError();
-      errorInfo.Message = L"can not load Mapi32.dll";
-      return E_FAIL;
-    }
-    LPMAPISENDDOCUMENTS fnSend = (LPMAPISENDDOCUMENTS)
-        mapiLib.GetProcAddress("MAPISendDocuments");
-    if (fnSend == 0)
-    {
-      errorInfo.SystemError = ::GetLastError();
-      errorInfo.Message = L"can not find MAPISendDocuments function";
-      return E_FAIL;
-    }
-    UStringVector fullPaths;
-    int i;
-    for(i = 0; i < options.Commands.Size(); i++)
-    {
-      CArchivePath &ap = options.Commands[i].ArchivePath;
-      UString arcPath;
-      if(!NFile::NDirectory::MyGetFullPathName(ap.GetFinalPath(), arcPath))
-      {
-        errorInfo.SystemError = ::GetLastError();
-        return E_FAIL;
-      }
-      fullPaths.Add(arcPath);
-    }
-    CCurrentDirRestorer curDirRestorer;
-    for(i = 0; i < fullPaths.Size(); i++)
-    {
-      UString arcPath = fullPaths[i];
-      UString fileName = ExtractFileNameFromPath(arcPath);
-      AString path = GetAnsiString(arcPath);
-      AString name = GetAnsiString(fileName);
-      // Warning!!! MAPISendDocuments function changes Current directory
-      fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0); 
-    }
-  }
-  #endif
-  return S_OK;
-}
-