// Update.cpp

#include "StdAfx.h"

#include "Update.h"

#include "../../../Common/StringConvert.h"

#include "../../../Windows/DLL.h"
#include "../../../Windows/FileDir.h"
#include "../../../Windows/FileFind.h"
#include "../../../Windows/FileName.h"
#include "../../../Windows/PropVariant.h"
#include "../../../Windows/PropVariantConv.h"
#include "../../../Windows/TimeUtils.h"

#include "../../Common/FileStreams.h"
#include "../../Common/LimitedStreams.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 * const kUpdateIsNotSupoorted =
  "update operations are not supported for this archive";

static const char * const kUpdateIsNotSupoorted_MultiVol =
  "Updating for multivolume archives is not implemented";

using namespace NWindows;
using namespace NCOM;
using namespace NFile;
using namespace NDir;
using namespace NName;

static CFSTR const kTempFolderPrefix = FTEXT("7zE");


void CUpdateErrorInfo::SetFromLastError(const char *message)
{
  SystemError = ::GetLastError();
  Message = message;
}

HRESULT CUpdateErrorInfo::SetFromLastError(const char *message, const FString &fileName)
{
  SetFromLastError(message);
  FileNames.Add(fileName);
  return Get_HRESULT_Error();
}

static bool DeleteEmptyFolderAndEmptySubFolders(const FString &path)
{
  NFind::CFileInfo fileInfo;
  FString pathPrefix = path + FCHAR_PATH_SEPARATOR;
  {
    NFind::CEnumerator enumerator;
    enumerator.SetDirPrefix(pathPrefix);
    while (enumerator.Next(fileInfo))
    {
      if (fileInfo.IsDir())
        if (!DeleteEmptyFolderAndEmptySubFolders(pathPrefix + fileInfo.Name))
          return false;
    }
  }
  /*
  // we don't need clear read-only for folders
  if (!MySetFileAttributes(path, 0))
    return false;
  */
  return RemoveDir(path);
}


using namespace NUpdateArchive;

class COutMultiVolStream:
  public IOutStream,
  public CMyUnknownImp
{
  unsigned _streamIndex; // required stream
  UInt64 _offsetPos; // offset from start of _streamIndex index
  UInt64 _absPos;
  UInt64 _length;

  struct CAltStreamInfo
  {
    COutFileStream *StreamSpec;
    CMyComPtr<IOutStream> Stream;
    FString Name;
    UInt64 Pos;
    UInt64 RealSize;
  };
  CObjectVector<CAltStreamInfo> Streams;
public:
  // CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
  CRecordVector<UInt64> Sizes;
  FString Prefix;
  CTempFiles *TempFiles;

  void Init()
  {
    _streamIndex = 0;
    _offsetPos = 0;
    _absPos = 0;
    _length = 0;
  }

  bool SetMTime(const FILETIME *mTime);
  HRESULT Close();

  UInt64 GetSize() const { return _length; }

  MY_UNKNOWN_IMP1(IOutStream)

  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
  STDMETHOD(SetSize)(UInt64 newSize);
};

// static NSynchronization::CCriticalSection g_TempPathsCS;

HRESULT COutMultiVolStream::Close()
{
  HRESULT res = S_OK;
  FOR_VECTOR (i, Streams)
  {
    COutFileStream *s = Streams[i].StreamSpec;
    if (s)
    {
      HRESULT res2 = s->Close();
      if (res2 != S_OK)
        res = res2;
    }
  }
  return res;
}

bool COutMultiVolStream::SetMTime(const FILETIME *mTime)
{
  bool res = true;
  FOR_VECTOR (i, Streams)
  {
    COutFileStream *s = Streams[i].StreamSpec;
    if (s)
      if (!s->SetMTime(mTime))
        res = false;
  }
  return res;
}

STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
  if (processedSize)
    *processedSize = 0;
  while (size > 0)
  {
    if (_streamIndex >= Streams.Size())
    {
      CAltStreamInfo altStream;

      FString name;
      name.Add_UInt32(_streamIndex + 1);
      while (name.Len() < 3)
        name.InsertAtFront(FTEXT('0'));
      name.Insert(0, Prefix);
      altStream.StreamSpec = new COutFileStream;
      altStream.Stream = altStream.StreamSpec;
      if (!altStream.StreamSpec->Create(name, false))
        return ::GetLastError();
      {
        // NSynchronization::CCriticalSectionLock lock(g_TempPathsCS);
        TempFiles->Paths.Add(name);
      }

      altStream.Pos = 0;
      altStream.RealSize = 0;
      altStream.Name = name;
      Streams.Add(altStream);
      continue;
    }
    CAltStreamInfo &altStream = Streams[_streamIndex];

    unsigned index = _streamIndex;
    if (index >= Sizes.Size())
      index = Sizes.Size() - 1;
    UInt64 volSize = Sizes[index];

    if (_offsetPos >= volSize)
    {
      _offsetPos -= volSize;
      _streamIndex++;
      continue;
    }
    if (_offsetPos != altStream.Pos)
    {
      // CMyComPtr<IOutStream> outStream;
      // RINOK(altStream.Stream.QueryInterface(IID_IOutStream, &outStream));
      RINOK(altStream.Stream->Seek(_offsetPos, STREAM_SEEK_SET, NULL));
      altStream.Pos = _offsetPos;
    }

    UInt32 curSize = (UInt32)MyMin((UInt64)size, volSize - altStream.Pos);
    UInt32 realProcessed;
    RINOK(altStream.Stream->Write(data, curSize, &realProcessed));
    data = (void *)((Byte *)data + realProcessed);
    size -= realProcessed;
    altStream.Pos += realProcessed;
    _offsetPos += realProcessed;
    _absPos += realProcessed;
    if (_absPos > _length)
      _length = _absPos;
    if (_offsetPos > altStream.RealSize)
      altStream.RealSize = _offsetPos;
    if (processedSize)
      *processedSize += realProcessed;
    if (altStream.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)
    *newPosition = _absPos;
  _streamIndex = 0;
  return S_OK;
}

STDMETHODIMP COutMultiVolStream::SetSize(UInt64 newSize)
{
  unsigned i = 0;
  while (i < Streams.Size())
  {
    CAltStreamInfo &altStream = Streams[i++];
    if ((UInt64)newSize < altStream.RealSize)
    {
      RINOK(altStream.Stream->SetSize(newSize));
      altStream.RealSize = newSize;
      break;
    }
    newSize -= altStream.RealSize;
  }
  while (i < Streams.Size())
  {
    {
      CAltStreamInfo &altStream = Streams.Back();
      altStream.Stream.Release();
      DeleteFileAlways(altStream.Name);
    }
    Streams.DeleteBack();
  }
  _offsetPos = _absPos;
  _streamIndex = 0;
  _length = newSize;
  return S_OK;
}

void CArchivePath::ParseFromPath(const UString &path, EArcNameMode mode)
{
  OriginalPath = path;
  
  SplitPathToParts_2(path, Prefix, Name);
  
  if (mode == k_ArcNameMode_Add)
    return;
  
  if (mode != k_ArcNameMode_Exact)
  {
    int dotPos = Name.ReverseFind_Dot();
    if (dotPos < 0)
      return;
    if ((unsigned)dotPos == Name.Len() - 1)
      Name.DeleteBack();
    else
    {
      const UString ext = Name.Ptr(dotPos + 1);
      if (BaseExtension.IsEqualTo_NoCase(ext))
      {
        BaseExtension = ext;
        Name.DeleteFrom(dotPos);
        return;
      }
    }
  }

  BaseExtension.Empty();
}

UString CArchivePath::GetFinalPath() const
{
  UString path = GetPathWithoutExt();
  if (!BaseExtension.IsEmpty())
  {
    path += '.';
    path += BaseExtension;
  }
  return path;
}

UString CArchivePath::GetFinalVolPath() const
{
  UString path = GetPathWithoutExt();
  // if BaseExtension is empty, we must ignore VolExtension also.
  if (!BaseExtension.IsEmpty())
  {
    path += '.';
    path += VolExtension;
  }
  return path;
}

FString CArchivePath::GetTempPath() const
{
  FString path = TempPrefix;
  path += us2fs(Name);
  if (!BaseExtension.IsEmpty())
  {
    path += '.';
    path += us2fs(BaseExtension);
  }
  path += ".tmp";
  path += TempPostfix;
  return path;
}

static const char * const kDefaultArcType = "7z";
static const char * const kDefaultArcExt = "7z";
static const char * const kSFXExtension =
  #ifdef _WIN32
    "exe";
  #else
    "";
  #endif

bool CUpdateOptions::InitFormatIndex(const CCodecs *codecs,
    const CObjectVector<COpenType> &types, const UString &arcPath)
{
  if (types.Size() > 1)
    return false;
  // int arcTypeIndex = -1;
  if (types.Size() != 0)
  {
    MethodMode.Type = types[0];
    MethodMode.Type_Defined = true;
  }
  if (MethodMode.Type.FormatIndex < 0)
  {
    // MethodMode.Type = -1;
    MethodMode.Type = COpenType();
    if (ArcNameMode != k_ArcNameMode_Add)
    {
      MethodMode.Type.FormatIndex = codecs->FindFormatForArchiveName(arcPath);
      if (MethodMode.Type.FormatIndex >= 0)
        MethodMode.Type_Defined = true;
    }
  }
  return true;
}

bool CUpdateOptions::SetArcPath(const CCodecs *codecs, const UString &arcPath)
{
  UString typeExt;
  int formatIndex = MethodMode.Type.FormatIndex;
  if (formatIndex < 0)
  {
    typeExt = kDefaultArcExt;
  }
  else
  {
    const CArcInfoEx &arcInfo = codecs->Formats[formatIndex];
    if (!arcInfo.UpdateEnabled)
      return false;
    typeExt = arcInfo.GetMainExt();
  }
  UString ext = typeExt;
  if (SfxMode)
    ext = kSFXExtension;
  ArchivePath.BaseExtension = ext;
  ArchivePath.VolExtension = typeExt;
  ArchivePath.ParseFromPath(arcPath, ArcNameMode);
  FOR_VECTOR (i, Commands)
  {
    CUpdateArchiveCommand &uc = Commands[i];
    uc.ArchivePath.BaseExtension = ext;
    uc.ArchivePath.VolExtension = typeExt;
    uc.ArchivePath.ParseFromPath(uc.UserArchivePath, ArcNameMode);
  }
  return true;
}


struct CUpdateProduceCallbackImp: public IUpdateProduceCallback
{
  const CObjectVector<CArcItem> *_arcItems;
  IUpdateCallbackUI *_callback;
  CDirItemsStat *_stat;
  
  CUpdateProduceCallbackImp(
      const CObjectVector<CArcItem> *a,
      CDirItemsStat *stat,
      IUpdateCallbackUI *callback):
    _arcItems(a),
    _stat(stat),
    _callback(callback) {}
  
  virtual HRESULT ShowDeleteFile(unsigned arcIndex);
};


HRESULT CUpdateProduceCallbackImp::ShowDeleteFile(unsigned arcIndex)
{
  const CArcItem &ai = (*_arcItems)[arcIndex];
  {
    CDirItemsStat &stat = *_stat;
    if (ai.IsDir)
      stat.NumDirs++;
    else if (ai.IsAltStream)
    {
      stat.NumAltStreams++;
      stat.AltStreamsSize += ai.Size;
    }
    else
    {
      stat.NumFiles++;
      stat.FilesSize += ai.Size;
    }
  }
  return _callback->ShowDeleteFile(ai.Name, ai.IsDir);
}

bool CRenamePair::Prepare()
{
  if (RecursedType != NRecursedType::kNonRecursed)
    return false;
  if (!WildcardParsing)
    return true;
  return !DoesNameContainWildcard(OldName);
}

extern bool g_CaseSensitive;

static unsigned CompareTwoNames(const wchar_t *s1, const wchar_t *s2)
{
  for (unsigned i = 0;; i++)
  {
    wchar_t c1 = s1[i];
    wchar_t c2 = s2[i];
    if (c1 == 0 || c2 == 0)
      return i;
    if (c1 == c2)
      continue;
    if (!g_CaseSensitive && (MyCharUpper(c1) == MyCharUpper(c2)))
      continue;
    if (IsPathSepar(c1) && IsPathSepar(c2))
      continue;
    return i;
  }
}

bool CRenamePair::GetNewPath(bool isFolder, const UString &src, UString &dest) const
{
  unsigned num = CompareTwoNames(OldName, src);
  if (OldName[num] == 0)
  {
    if (src[num] != 0 && !IsPathSepar(src[num]) && num != 0 && !IsPathSepar(src[num - 1]))
      return false;
  }
  else
  {
    // OldName[num] != 0
    // OldName = "1\1a.txt"
    // src = "1"

    if (!isFolder
        || src[num] != 0
        || !IsPathSepar(OldName[num])
        || OldName[num + 1] != 0)
      return false;
  }
  dest = NewName + src.Ptr(num);
  return true;
}

#ifdef SUPPORT_ALT_STREAMS
int FindAltStreamColon_in_Path(const wchar_t *path);
#endif

static HRESULT Compress(
    const CUpdateOptions &options,
    bool isUpdatingItself,
    CCodecs *codecs,
    const CActionSet &actionSet,
    const CArc *arc,
    CArchivePath &archivePath,
    const CObjectVector<CArcItem> &arcItems,
    Byte *processedItemsStatuses,
    const CDirItems &dirItems,
    const CDirItem *parentDirItem,
    CTempFiles &tempFiles,
    CUpdateErrorInfo &errorInfo,
    IUpdateCallbackUI *callback,
    CFinishArchiveStat &st)
{
  CMyComPtr<IOutArchive> outArchive;
  int formatIndex = options.MethodMode.Type.FormatIndex;
  
  if (arc)
  {
    formatIndex = arc->FormatIndex;
    if (formatIndex < 0)
      return E_NOTIMPL;
    CMyComPtr<IInArchive> archive2 = arc->Archive;
    HRESULT result = archive2.QueryInterface(IID_IOutArchive, &outArchive);
    if (result != S_OK)
      throw kUpdateIsNotSupoorted;
  }
  else
  {
    RINOK(codecs->CreateOutArchive(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;
    }
  }

  {
    const CArcInfoEx &arcInfo = codecs->Formats[formatIndex];
    if (options.AltStreams.Val && !arcInfo.Flags_AltStreams())
      return E_NOTIMPL;
    if (options.NtSecurity.Val && !arcInfo.Flags_NtSecure())
      return E_NOTIMPL;
  }

  CRecordVector<CUpdatePair2> updatePairs2;

  UStringVector newNames;

  CArcToDoStat stat2;

  if (options.RenamePairs.Size() != 0)
  {
    FOR_VECTOR (i, arcItems)
    {
      const CArcItem &ai = arcItems[i];
      bool needRename = false;
      UString dest;
      
      if (ai.Censored)
      {
        FOR_VECTOR (j, options.RenamePairs)
        {
          const CRenamePair &rp = options.RenamePairs[j];
          if (rp.GetNewPath(ai.IsDir, ai.Name, dest))
          {
            needRename = true;
            break;
          }
          
          #ifdef SUPPORT_ALT_STREAMS
          if (ai.IsAltStream)
          {
            int colonPos = FindAltStreamColon_in_Path(ai.Name);
            if (colonPos >= 0)
            {
              UString mainName = ai.Name.Left(colonPos);
              /*
              actually we must improve that code to support cases
              with folder renaming like: rn arc dir1\ dir2\
              */
              if (rp.GetNewPath(false, mainName, dest))
              {
                needRename = true;
                dest += ':';
                dest += ai.Name.Ptr(colonPos + 1);
                break;
              }
            }
          }
          #endif
        }
      }
      
      CUpdatePair2 up2;
      up2.SetAs_NoChangeArcItem(ai.IndexInServer);
      if (needRename)
      {
        up2.NewProps = true;
        RINOK(arc->IsItemAnti(i, up2.IsAnti));
        up2.NewNameIndex = newNames.Add(dest);
      }
      updatePairs2.Add(up2);
    }
  }
  else
  {
    CRecordVector<CUpdatePair> updatePairs;
    GetUpdatePairInfoList(dirItems, arcItems, fileTimeType, updatePairs); // must be done only once!!!
    CUpdateProduceCallbackImp upCallback(&arcItems, &stat2.DeleteData, callback);
    
    UpdateProduce(updatePairs, actionSet, updatePairs2, isUpdatingItself ? &upCallback : NULL);
  }

  {
    FOR_VECTOR (i, updatePairs2)
    {
      const CUpdatePair2 &up = updatePairs2[i];

      // 17.01: anti-item is (up.NewData && (p.UseArcProps in most cases))

      if (up.NewData && !up.UseArcProps)
      {
        if (up.ExistOnDisk())
        {
          CDirItemsStat2 &stat = stat2.NewData;
          const CDirItem &di = dirItems.Items[up.DirIndex];
          if (di.IsDir())
          {
            if (up.IsAnti)
              stat.Anti_NumDirs++;
            else
              stat.NumDirs++;
          }
          else if (di.IsAltStream)
          {
            if (up.IsAnti)
              stat.Anti_NumAltStreams++;
            else
            {
              stat.NumAltStreams++;
              stat.AltStreamsSize += di.Size;
            }
          }
          else
          {
            if (up.IsAnti)
              stat.Anti_NumFiles++;
            else
            {
              stat.NumFiles++;
              stat.FilesSize += di.Size;
            }
          }
        }
      }
      else if (up.ArcIndex >= 0)
      {
        CDirItemsStat2 &stat = *(up.NewData ? &stat2.NewData : &stat2.OldData);
        const CArcItem &ai = arcItems[up.ArcIndex];
        if (ai.IsDir)
        {
          if (up.IsAnti)
            stat.Anti_NumDirs++;
          else
            stat.NumDirs++;
        }
        else if (ai.IsAltStream)
        {
          if (up.IsAnti)
            stat.Anti_NumAltStreams++;
          else
          {
            stat.NumAltStreams++;
            stat.AltStreamsSize += ai.Size;
          }
        }
        else
        {
          if (up.IsAnti)
            stat.Anti_NumFiles++;
          else
          {
            stat.NumFiles++;
            stat.FilesSize += ai.Size;
          }
        }
      }
    }
    RINOK(callback->SetNumItems(stat2));
  }
  
  CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
  CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);
  
  updateCallbackSpec->ShareForWrite = options.OpenShareForWrite;
  updateCallbackSpec->StopAfterOpenError = options.StopAfterOpenError;
  updateCallbackSpec->StdInMode = options.StdInMode;
  updateCallbackSpec->Callback = callback;

  if (arc)
  {
    // we set Archive to allow to transfer GetProperty requests back to DLL.
    updateCallbackSpec->Archive = arc->Archive;
  }
  
  updateCallbackSpec->DirItems = &dirItems;
  updateCallbackSpec->ParentDirItem = parentDirItem;

  updateCallbackSpec->StoreNtSecurity = options.NtSecurity.Val;
  updateCallbackSpec->StoreHardLinks = options.HardLinks.Val;
  updateCallbackSpec->StoreSymLinks = options.SymLinks.Val;

  updateCallbackSpec->Arc = arc;
  updateCallbackSpec->ArcItems = &arcItems;
  updateCallbackSpec->UpdatePairs = &updatePairs2;

  updateCallbackSpec->ProcessedItemsStatuses = processedItemsStatuses;

  if (options.RenamePairs.Size() != 0)
    updateCallbackSpec->NewNames = &newNames;

  CMyComPtr<IOutStream> outSeekStream;
  CMyComPtr<ISequentialOutStream> outStream;

  if (!options.StdOutMode)
  {
    FString dirPrefix;
    if (!GetOnlyDirPrefix(us2fs(archivePath.GetFinalPath()), dirPrefix))
      throw 1417161;
    CreateComplexDir(dirPrefix);
  }

  COutFileStream *outStreamSpec = NULL;
  CStdOutFileStream *stdOutFileStreamSpec = NULL;
  COutMultiVolStream *volStreamSpec = NULL;

  if (options.VolumesSizes.Size() == 0)
  {
    if (options.StdOutMode)
    {
      stdOutFileStreamSpec = new CStdOutFileStream;
      outStream = stdOutFileStreamSpec;
    }
    else
    {
      outStreamSpec = new COutFileStream;
      outSeekStream = outStreamSpec;
      outStream = outSeekStream;
      bool isOK = false;
      FString realPath;
      
      for (unsigned i = 0; i < (1 << 16); i++)
      {
        if (archivePath.Temp)
        {
          if (i > 0)
          {
            archivePath.TempPostfix.Empty();
            archivePath.TempPostfix.Add_UInt32(i);
          }
          realPath = archivePath.GetTempPath();
        }
        else
          realPath = us2fs(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)
        return errorInfo.SetFromLastError("cannot open file", realPath);
    }
  }
  else
  {
    if (options.StdOutMode)
      return E_FAIL;
    if (arc && arc->GetGlobalOffset() > 0)
      return E_NOTIMPL;
      
    volStreamSpec = new COutMultiVolStream;
    outSeekStream = volStreamSpec;
    outStream = outSeekStream;
    volStreamSpec->Sizes = options.VolumesSizes;
    volStreamSpec->Prefix = us2fs(archivePath.GetFinalVolPath());
    volStreamSpec->Prefix += '.';
    volStreamSpec->TempFiles = &tempFiles;
    volStreamSpec->Init();

    /*
    updateCallbackSpec->VolumesSizes = volumesSizes;
    updateCallbackSpec->VolName = archivePath.Prefix + archivePath.Name;
    if (!archivePath.VolExtension.IsEmpty())
      updateCallbackSpec->VolExt = UString('.') + archivePath.VolExtension;
    */
  }

  RINOK(SetProperties(outArchive, options.MethodMode.Properties));

  if (options.SfxMode)
  {
    CInFileStream *sfxStreamSpec = new CInFileStream;
    CMyComPtr<IInStream> sfxStream(sfxStreamSpec);
    if (!sfxStreamSpec->Open(options.SfxModule))
      return errorInfo.SetFromLastError("cannot open SFX module", options.SfxModule);

    CMyComPtr<ISequentialOutStream> sfxOutStream;
    COutFileStream *outStreamSpec2 = NULL;
    if (options.VolumesSizes.Size() == 0)
      sfxOutStream = outStream;
    else
    {
      outStreamSpec2 = new COutFileStream;
      sfxOutStream = outStreamSpec2;
      FString realPath = us2fs(archivePath.GetFinalPath());
      if (!outStreamSpec2->Create(realPath, false))
        return errorInfo.SetFromLastError("cannot open file", realPath);
    }

    {
      UInt64 sfxSize;
      RINOK(sfxStreamSpec->GetSize(&sfxSize));
      RINOK(callback->WriteSfx(fs2us(options.SfxModule), sfxSize));
    }

    RINOK(NCompress::CopyStream(sfxStream, sfxOutStream, NULL));
    
    if (outStreamSpec2)
    {
      RINOK(outStreamSpec2->Close());
    }
  }

  CMyComPtr<ISequentialOutStream> tailStream;

  if (options.SfxMode || !arc || arc->ArcStreamOffset == 0)
    tailStream = outStream;
  else
  {
    // Int64 globalOffset = arc->GetGlobalOffset();
    RINOK(arc->InStream->Seek(0, STREAM_SEEK_SET, NULL));
    RINOK(NCompress::CopyStream_ExactSize(arc->InStream, outStream, arc->ArcStreamOffset, NULL));
    if (options.StdOutMode)
      tailStream = outStream;
    else
    {
      CTailOutStream *tailStreamSpec = new CTailOutStream;
      tailStream = tailStreamSpec;
      tailStreamSpec->Stream = outSeekStream;
      tailStreamSpec->Offset = arc->ArcStreamOffset;
      tailStreamSpec->Init();
    }
  }


  HRESULT result = outArchive->UpdateItems(tailStream, updatePairs2.Size(), updateCallback);
  // callback->Finalize();
  RINOK(result);

  if (!updateCallbackSpec->AreAllFilesClosed())
  {
    errorInfo.Message = "There are unclosed input file:";
    errorInfo.FileNames = updateCallbackSpec->_openFiles_Paths;
    return E_FAIL;
  }

  if (options.SetArcMTime)
  {
    FILETIME ft;
    ft.dwLowDateTime = 0;
    ft.dwHighDateTime = 0;
    FOR_VECTOR (i, updatePairs2)
    {
      CUpdatePair2 &pair2 = updatePairs2[i];
      const FILETIME *ft2 = NULL;
      if (pair2.NewProps && pair2.DirIndex >= 0)
        ft2 = &dirItems.Items[pair2.DirIndex].MTime;
      else if (pair2.UseArcProps && pair2.ArcIndex >= 0)
        ft2 = &arcItems[pair2.ArcIndex].MTime;
      if (ft2)
      {
        if (::CompareFileTime(&ft, ft2) < 0)
          ft = *ft2;
      }
    }
    if (ft.dwLowDateTime != 0 || ft.dwHighDateTime != 0)
    {
      if (outStreamSpec)
        outStreamSpec->SetMTime(&ft);
      else if (volStreamSpec)
        volStreamSpec->SetMTime(&ft);;
    }
  }

  if (callback)
  {
    UInt64 size = 0;
    if (outStreamSpec)
      outStreamSpec->GetSize(&size);
    else if (stdOutFileStreamSpec)
      size = stdOutFileStreamSpec->GetSize();
    else
      size = volStreamSpec->GetSize();

    st.OutArcFileSize = size;
  }

  if (outStreamSpec)
    result = outStreamSpec->Close();
  else if (volStreamSpec)
    result = volStreamSpec->Close();
  return result;
}

bool CensorNode_CheckPath2(const NWildcard::CCensorNode &node, const CReadArcItem &item, bool &include);

static bool Censor_CheckPath(const NWildcard::CCensor &censor, const CReadArcItem &item)
{
  bool finded = false;
  FOR_VECTOR (i, censor.Pairs)
  {
    bool include;
    if (CensorNode_CheckPath2(censor.Pairs[i].Head, item, include))
    {
      if (!include)
        return false;
      finded = true;
    }
  }
  return finded;
}

static HRESULT EnumerateInArchiveItems(
    // bool storeStreamsMode,
    const NWildcard::CCensor &censor,
    const CArc &arc,
    CObjectVector<CArcItem> &arcItems)
{
  arcItems.Clear();
  UInt32 numItems;
  IInArchive *archive = arc.Archive;
  RINOK(archive->GetNumberOfItems(&numItems));
  arcItems.ClearAndReserve(numItems);

  CReadArcItem item;

  for (UInt32 i = 0; i < numItems; i++)
  {
    CArcItem ai;

    RINOK(arc.GetItem(i, item));
    ai.Name = item.Path;
    ai.IsDir = item.IsDir;
    ai.IsAltStream =
        #ifdef SUPPORT_ALT_STREAMS
          item.IsAltStream;
        #else
          false;
        #endif

    /*
    if (!storeStreamsMode && ai.IsAltStream)
      continue;
    */
    ai.Censored = Censor_CheckPath(censor, item);

    RINOK(arc.GetItemMTime(i, ai.MTime, ai.MTimeDefined));
    RINOK(arc.GetItemSize(i, ai.Size, ai.SizeDefined));

    {
      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.AddInReserved(ai);
  }
  return S_OK;
}

#if defined(_WIN32) && !defined(UNDER_CE)

#include <mapi.h>

#endif

HRESULT UpdateArchive(
    CCodecs *codecs,
    const CObjectVector<COpenType> &types,
    const UString &cmdArcPath2,
    NWildcard::CCensor &censor,
    CUpdateOptions &options,
    CUpdateErrorInfo &errorInfo,
    IOpenCallbackUI *openCallback,
    IUpdateCallbackUI2 *callback,
    bool needSetPath)
{
  if (options.StdOutMode && options.EMailMode)
    return E_FAIL;

  if (types.Size() > 1)
    return E_NOTIMPL;

  bool renameMode = !options.RenamePairs.IsEmpty();
  if (renameMode)
  {
    if (options.Commands.Size() != 1)
      return E_FAIL;
  }

  if (options.DeleteAfterCompressing)
  {
    if (options.Commands.Size() != 1)
      return E_NOTIMPL;
    const CActionSet &as = options.Commands[0].ActionSet;
    for (int i = 2; i < NPairState::kNumValues; i++)
      if (as.StateActions[i] != NPairAction::kCompress)
        return E_NOTIMPL;
  }

  censor.AddPathsToCensor(options.PathMode);
  #ifdef _WIN32
  ConvertToLongNames(censor);
  #endif
  censor.ExtendExclude();

  
  if (options.VolumesSizes.Size() > 0 && (options.EMailMode /* || options.SfxMode */))
    return E_NOTIMPL;

  if (options.SfxMode)
  {
    CProperty property;
    property.Name = "rsfx";
    options.MethodMode.Properties.Add(property);
    if (options.SfxModule.IsEmpty())
    {
      errorInfo.Message = "SFX file is not specified";
      return E_FAIL;
    }
    bool found = false;
    if (options.SfxModule.Find(FCHAR_PATH_SEPARATOR) < 0)
    {
      const FString fullName = NDLL::GetModuleDirPrefix() + options.SfxModule;
      if (NFind::DoesFileExist(fullName))
      {
        options.SfxModule = fullName;
        found = true;
      }
    }
    if (!found)
    {
      if (!NFind::DoesFileExist(options.SfxModule))
        return errorInfo.SetFromLastError("cannot find specified SFX module", options.SfxModule);
    }
  }

  CArchiveLink arcLink;

  
  if (needSetPath)
  {
    if (!options.InitFormatIndex(codecs, types, cmdArcPath2) ||
        !options.SetArcPath(codecs, cmdArcPath2))
      return E_NOTIMPL;
  }
  
  UString arcPath = options.ArchivePath.GetFinalPath();

  if (!options.VolumesSizes.IsEmpty())
  {
    arcPath = options.ArchivePath.GetFinalVolPath();
    arcPath += '.';
    arcPath += "001";
  }

  if (cmdArcPath2.IsEmpty())
  {
    if (options.MethodMode.Type.FormatIndex < 0)
      throw "type of archive is not specified";
  }
  else
  {
    NFind::CFileInfo fi;
    if (!fi.Find(us2fs(arcPath)))
    {
      if (renameMode)
        throw "can't find archive";;
      if (options.MethodMode.Type.FormatIndex < 0)
      {
        if (!options.SetArcPath(codecs, cmdArcPath2))
          return E_NOTIMPL;
      }
    }
    else
    {
      if (fi.IsDir())
        throw "there is no such archive";
      if (fi.IsDevice)
        return E_NOTIMPL;

      if (!options.StdOutMode && options.UpdateArchiveItself)
        if (fi.IsReadOnly())
        {
          errorInfo.SystemError = ERROR_ACCESS_DENIED;
          errorInfo.Message = "The file is read-only";
          errorInfo.FileNames.Add(us2fs(arcPath));
          return errorInfo.Get_HRESULT_Error();
        }

      if (options.VolumesSizes.Size() > 0)
      {
        errorInfo.FileNames.Add(us2fs(arcPath));
        errorInfo.SystemError = (DWORD)E_NOTIMPL;
        errorInfo.Message = kUpdateIsNotSupoorted_MultiVol;
        return E_NOTIMPL;
      }
      CObjectVector<COpenType> types2;
      // change it.
      if (options.MethodMode.Type_Defined)
        types2.Add(options.MethodMode.Type);
      // We need to set Properties to open archive only in some cases (WIM archives).

      CIntVector excl;
      COpenOptions op;
      #ifndef _SFX
      op.props = &options.MethodMode.Properties;
      #endif
      op.codecs = codecs;
      op.types = &types2;
      op.excludedFormats = &excl;
      op.stdInMode = false;
      op.stream = NULL;
      op.filePath = arcPath;

      RINOK(callback->StartOpenArchive(arcPath));

      HRESULT result = arcLink.Open_Strict(op, openCallback);

      if (result == E_ABORT)
        return result;
      
      HRESULT res2 = callback->OpenResult(codecs, arcLink, arcPath, result);
      /*
      if (result == S_FALSE)
        return E_FAIL;
      */
      RINOK(res2);
      RINOK(result);

      if (arcLink.VolumePaths.Size() > 1)
      {
        errorInfo.SystemError = (DWORD)E_NOTIMPL;
        errorInfo.Message = kUpdateIsNotSupoorted_MultiVol;
        return E_NOTIMPL;
      }
      
      CArc &arc = arcLink.Arcs.Back();
      arc.MTimeDefined = !fi.IsDevice;
      arc.MTime = fi.MTime;

      if (arc.ErrorInfo.ThereIsTail)
      {
        errorInfo.SystemError = (DWORD)E_NOTIMPL;
        errorInfo.Message = "There is some data block after the end of the archive";
        return E_NOTIMPL;
      }
      if (options.MethodMode.Type.FormatIndex < 0)
      {
        options.MethodMode.Type.FormatIndex = arcLink.GetArc()->FormatIndex;
        if (!options.SetArcPath(codecs, cmdArcPath2))
          return E_NOTIMPL;
      }
    }
  }

  if (options.MethodMode.Type.FormatIndex < 0)
  {
    options.MethodMode.Type.FormatIndex = codecs->FindFormatForArchiveType((UString)kDefaultArcType);
    if (options.MethodMode.Type.FormatIndex < 0)
      return E_NOTIMPL;
  }

  bool thereIsInArchive = arcLink.IsOpen;
  if (!thereIsInArchive && renameMode)
    return E_FAIL;
  
  CDirItems dirItems;
  dirItems.Callback = callback;

  CDirItem parentDirItem;
  CDirItem *parentDirItem_Ptr = NULL;
  
  /*
  FStringVector requestedPaths;
  FStringVector *requestedPaths_Ptr = NULL;
  if (options.DeleteAfterCompressing)
    requestedPaths_Ptr = &requestedPaths;
  */

  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;
    
    if (!renameMode)
    FOR_VECTOR (i, options.Commands)
      if (options.Commands[i].ActionSet.NeedScanning())
        needScanning = true;

    if (needScanning)
    {
      RINOK(callback->StartScanning());

      dirItems.SymLinks = options.SymLinks.Val;

      #if defined(_WIN32) && !defined(UNDER_CE)
      dirItems.ReadSecure = options.NtSecurity.Val;
      #endif

      dirItems.ScanAltStreams = options.AltStreams.Val;

      HRESULT res = EnumerateItems(censor,
          options.PathMode,
          options.AddPathPrefix,
          dirItems);

      if (res != S_OK)
      {
        if (res != E_ABORT)
          errorInfo.Message = "Scanning error";
        return res;
      }
      
      RINOK(callback->FinishScanning(dirItems.Stat));

      if (censor.Pairs.Size() == 1)
      {
        NFind::CFileInfo fi;
        FString prefix = us2fs(censor.Pairs[0].Prefix);
        prefix += '.';
        // UString prefix = censor.Pairs[0].Prefix;
        /*
        if (prefix.Back() == WCHAR_PATH_SEPARATOR)
        {
          prefix.DeleteBack();
        }
        */
        if (fi.Find(prefix))
          if (fi.IsDir())
          {
            parentDirItem.Size = fi.Size;
            parentDirItem.CTime = fi.CTime;
            parentDirItem.ATime = fi.ATime;
            parentDirItem.MTime = fi.MTime;
            parentDirItem.Attrib = fi.Attrib;
            parentDirItem_Ptr = &parentDirItem;

            int secureIndex = -1;
            #if defined(_WIN32) && !defined(UNDER_CE)
            if (options.NtSecurity.Val)
              dirItems.AddSecurityItem(prefix, secureIndex);
            #endif
            parentDirItem.SecureIndex = secureIndex;

            parentDirItem_Ptr = &parentDirItem;
          }
      }
    }
  }

  FString tempDirPrefix;
  bool usesTempDir = false;
  
  #ifdef _WIN32
  CTempDir 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 ((thereIsInArchive || !options.WorkingDir.IsEmpty()) && !usesTempDir && options.VolumesSizes.Size() == 0)
    {
      createTempFile = true;
      ap.Temp = true;
      if (!options.WorkingDir.IsEmpty())
        ap.TempPrefix = options.WorkingDir;
      else
        ap.TempPrefix = us2fs(ap.Prefix);
      NormalizeDirPathPrefix(ap.TempPrefix);
    }
  }

  unsigned ci;


  // self including protection
  if (options.DeleteAfterCompressing)
  {
    for (ci = 0; ci < options.Commands.Size(); ci++)
    {
      CArchivePath &ap = options.Commands[ci].ArchivePath;
      const FString path = us2fs(ap.GetFinalPath());
      // maybe we must compare absolute paths path here
      FOR_VECTOR (i, dirItems.Items)
      {
        const FString phyPath = dirItems.GetPhyPath(i);
        if (phyPath == path)
        {
          UString s;
          s = "It is not allowed to include archive to itself";
          s.Add_LF();
          s += path;
          throw s;
        }
      }
    }
  }


  for (ci = 0; ci < options.Commands.Size(); ci++)
  {
    CArchivePath &ap = options.Commands[ci].ArchivePath;
    if (usesTempDir)
    {
      // Check it
      ap.Prefix = fs2us(tempDirPrefix);
      // ap.Temp = true;
      // ap.TempPrefix = tempDirPrefix;
    }
    if (!options.StdOutMode &&
        (ci > 0 || !createTempFile))
    {
      const FString path = us2fs(ap.GetFinalPath());
      if (NFind::DoesFileOrDirExist(path))
      {
        errorInfo.SystemError = ERROR_FILE_EXISTS;
        errorInfo.Message = "The file already exists";
        errorInfo.FileNames.Add(path);
        return errorInfo.Get_HRESULT_Error();
      }
    }
  }

  CObjectVector<CArcItem> arcItems;
  if (thereIsInArchive)
  {
    RINOK(EnumerateInArchiveItems(
      // options.StoreAltStreams,
      censor, arcLink.Arcs.Back(), arcItems));
  }

  /*
  FStringVector processedFilePaths;
  FStringVector *processedFilePaths_Ptr = NULL;
  if (options.DeleteAfterCompressing)
    processedFilePaths_Ptr = &processedFilePaths;
  */

  CByteBuffer processedItems;
  if (options.DeleteAfterCompressing)
  {
    unsigned num = dirItems.Items.Size();
    processedItems.Alloc(num);
    for (unsigned i = 0; i < num; i++)
      processedItems[i] = 0;
  }

  /*
  #ifndef _NO_CRYPTO
  if (arcLink.PasswordWasAsked)
  {
    // We set password, if open have requested password
    RINOK(callback->SetPassword(arcLink.Password));
  }
  #endif
  */

  for (ci = 0; ci < options.Commands.Size(); ci++)
  {
    const CArc *arc = thereIsInArchive ? arcLink.GetArc() : NULL;
    CUpdateArchiveCommand &command = options.Commands[ci];
    UString name;
    bool isUpdating;
    
    if (options.StdOutMode)
    {
      name = "stdout";
      isUpdating = thereIsInArchive;
    }
    else
    {
      name = command.ArchivePath.GetFinalPath();
      isUpdating = (ci == 0 && options.UpdateArchiveItself && thereIsInArchive);
    }
    
    RINOK(callback->StartArchive(name, isUpdating))

    CFinishArchiveStat st;

    RINOK(Compress(options,
        isUpdating,
        codecs,
        command.ActionSet,
        arc,
        command.ArchivePath,
        arcItems,
        options.DeleteAfterCompressing ? (Byte *)processedItems : NULL,

        dirItems,
        parentDirItem_Ptr,

        tempFiles,
        errorInfo, callback, st));

    RINOK(callback->FinishArchive(st));
  }


  if (thereIsInArchive)
  {
    RINOK(arcLink.Close());
    arcLink.Release();
  }

  tempFiles.Paths.Clear();
  if (createTempFile)
  {
    try
    {
      CArchivePath &ap = options.Commands[0].ArchivePath;
      const FString &tempPath = ap.GetTempPath();
      
      // DWORD attrib = 0;
      if (thereIsInArchive)
      {
        // attrib = NFind::GetFileAttrib(us2fs(arcPath));
        if (!DeleteFileAlways(us2fs(arcPath)))
          return errorInfo.SetFromLastError("cannot delete the file", us2fs(arcPath));
      }
      
      if (!MyMoveFile(tempPath, us2fs(arcPath)))
      {
        errorInfo.SetFromLastError("cannot move the file", tempPath);
        errorInfo.FileNames.Add(us2fs(arcPath));
        return errorInfo.Get_HRESULT_Error();
      }
      
      /*
      if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_READONLY))
      {
        DWORD attrib2 = NFind::GetFileAttrib(us2fs(arcPath));
        if (attrib2 != INVALID_FILE_ATTRIBUTES)
          NDir::SetFileAttrib(us2fs(arcPath), attrib2 | FILE_ATTRIBUTE_READONLY);
      }
      */
    }
    catch(...)
    {
      throw;
    }
  }


  #if defined(_WIN32) && !defined(UNDER_CE)
  
  if (options.EMailMode)
  {
    NDLL::CLibrary mapiLib;
    if (!mapiLib.Load(FTEXT("Mapi32.dll")))
    {
      errorInfo.SetFromLastError("cannot load Mapi32.dll");
      return errorInfo.Get_HRESULT_Error();
    }

    /*
    LPMAPISENDDOCUMENTS fnSend = (LPMAPISENDDOCUMENTS)mapiLib.GetProc("MAPISendDocuments");
    if (fnSend == 0)
    {
      errorInfo.SetFromLastError)("7-Zip cannot find MAPISendDocuments function");
      return errorInfo.Get_HRESULT_Error();
    }
    */
    
    LPMAPISENDMAIL sendMail = (LPMAPISENDMAIL)mapiLib.GetProc("MAPISendMail");
    if (sendMail == 0)
    {
      errorInfo.SetFromLastError("7-Zip cannot find MAPISendMail function");
      return errorInfo.Get_HRESULT_Error();;
    }

    FStringVector fullPaths;
    unsigned i;
    
    for (i = 0; i < options.Commands.Size(); i++)
    {
      CArchivePath &ap = options.Commands[i].ArchivePath;
      FString finalPath = us2fs(ap.GetFinalPath());
      FString arcPath2;
      if (!MyGetFullPathName(finalPath, arcPath2))
        return errorInfo.SetFromLastError("GetFullPathName error", finalPath);
      fullPaths.Add(arcPath2);
    }

    CCurrentDirRestorer curDirRestorer;

    AStringVector paths;
    AStringVector names;
    
    for (i = 0; i < fullPaths.Size(); i++)
    {
      const UString arcPath2 = fs2us(fullPaths[i]);
      const UString fileName = ExtractFileNameFromPath(arcPath2);
      paths.Add(GetAnsiString(arcPath2));
      names.Add(GetAnsiString(fileName));
      // const AString path (GetAnsiString(arcPath2));
      // const AString name (GetAnsiString(fileName));
      // Warning!!! MAPISendDocuments function changes Current directory
      // fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0);
    }

    CRecordVector<MapiFileDesc> files;
    files.ClearAndSetSize(paths.Size());
    
    for (i = 0; i < paths.Size(); i++)
    {
      MapiFileDesc &f = files[i];
      memset(&f, 0, sizeof(f));
      f.nPosition = 0xFFFFFFFF;
      f.lpszPathName = (char *)(const char *)paths[i];
      f.lpszFileName = (char *)(const char *)names[i];
    }

    {
      MapiMessage m;
      memset(&m, 0, sizeof(m));
      m.nFileCount = files.Size();
      m.lpFiles = &files.Front();
      
      const AString addr (GetAnsiString(options.EMailAddress));
      MapiRecipDesc rec;
      if (!addr.IsEmpty())
      {
        memset(&rec, 0, sizeof(rec));
        rec.ulRecipClass = MAPI_TO;
        rec.lpszAddress = (char *)(const char *)addr;
        m.nRecipCount = 1;
        m.lpRecips = &rec;
      }
      
      sendMail((LHANDLE)0, 0, &m, MAPI_DIALOG, 0);
    }
  }
  
  #endif

  if (options.DeleteAfterCompressing)
  {
    CRecordVector<CDirPathSortPair> pairs;
    FStringVector foldersNames;

    unsigned i;

    for (i = 0; i < dirItems.Items.Size(); i++)
    {
      const CDirItem &dirItem = dirItems.Items[i];
      const FString phyPath = dirItems.GetPhyPath(i);
      if (dirItem.IsDir())
      {
        CDirPathSortPair pair;
        pair.Index = i;
        pair.SetNumSlashes(phyPath);
        pairs.Add(pair);
      }
      else
      {
        if (processedItems[i] != 0 || dirItem.Size == 0)
        {
          NFind::CFileInfo fileInfo;
          if (fileInfo.Find(phyPath))
          {
            // maybe we must exclude also files with archive name: "a a.7z * -sdel"
            if (fileInfo.Size == dirItem.Size
                && CompareFileTime(&fileInfo.MTime, &dirItem.MTime) == 0
                && CompareFileTime(&fileInfo.CTime, &dirItem.CTime) == 0)
            {
              RINOK(callback->DeletingAfterArchiving(phyPath, false));
              DeleteFileAlways(phyPath);
            }
          }
        }
        else
        {
          // file was skipped
          /*
          errorInfo.SystemError = 0;
          errorInfo.Message = "file was not processed";
          errorInfo.FileName = phyPath;
          return E_FAIL;
          */
        }
      }
    }

    pairs.Sort2();
    
    for (i = 0; i < pairs.Size(); i++)
    {
      const FString phyPath = dirItems.GetPhyPath(pairs[i].Index);
      if (NFind::DoesDirExist(phyPath))
      {
        RINOK(callback->DeletingAfterArchiving(phyPath, true));
        RemoveDir(phyPath);
      }
    }

    RINOK(callback->FinishDeletingAfterArchiving());
  }

  return S_OK;
}
