1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// Update.cpp
2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h"
4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Update.h"
6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
7cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Common/IntToString.h"
8cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Common/StringConvert.h"
9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
10cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Windows/DLL.h"
11cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Windows/FileDir.h"
12cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Windows/FileFind.h"
13cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Windows/FileName.h"
14cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Windows/PropVariant.h"
15cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Windows/PropVariantConv.h"
16cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Windows/TimeUtils.h"
17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/FileStreams.h"
19cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../Common/LimitedStreams.h"
20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Compress/CopyCoder.h"
22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../Common/DirItem.h"
24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../Common/EnumDirItems.h"
25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../Common/OpenArchive.h"
26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../Common/UpdateProduce.h"
27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
28baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "EnumDirItems.h"
29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "SetProperties.h"
30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "TempFiles.h"
31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "UpdateCallback.h"
32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
33baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const char *kUpdateIsNotSupoorted =
34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  "update operations are not supported for this archive";
35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
36baa3858d3f5d128a5c8466b700098109edcad5f2repo syncusing namespace NWindows;
37baa3858d3f5d128a5c8466b700098109edcad5f2repo syncusing namespace NCOM;
38baa3858d3f5d128a5c8466b700098109edcad5f2repo syncusing namespace NFile;
39cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyusing namespace NDir;
40baa3858d3f5d128a5c8466b700098109edcad5f2repo syncusing namespace NName;
41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
42cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic CFSTR kTempFolderPrefix = FTEXT("7zE");
43cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
44cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
45cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic bool DeleteEmptyFolderAndEmptySubFolders(const FString &path)
46cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
47cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  NFind::CFileInfo fileInfo;
48cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  FString pathPrefix = path + FCHAR_PATH_SEPARATOR;
49cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
50cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    NFind::CEnumerator enumerator(pathPrefix + FCHAR_ANY_MASK);
51cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    while (enumerator.Next(fileInfo))
52cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
53cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (fileInfo.IsDir())
54cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (!DeleteEmptyFolderAndEmptySubFolders(pathPrefix + fileInfo.Name))
55cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          return false;
56cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
57cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
58cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  /*
59cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  // we don't need clear read-only for folders
60cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!MySetFileAttributes(path, 0))
61cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return false;
62cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  */
63cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return RemoveDir(path);
64cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
65cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
67baa3858d3f5d128a5c8466b700098109edcad5f2repo syncusing namespace NUpdateArchive;
68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
69baa3858d3f5d128a5c8466b700098109edcad5f2repo syncclass COutMultiVolStream:
70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  public IOutStream,
71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  public CMyUnknownImp
72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
73cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  unsigned _streamIndex; // required stream
74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 _offsetPos; // offset from start of _streamIndex index
75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 _absPos;
76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 _length;
77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
78cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  struct CAltStreamInfo
79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    COutFileStream *StreamSpec;
81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComPtr<IOutStream> Stream;
82cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    FString Name;
83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 Pos;
84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 RealSize;
85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  };
86cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CObjectVector<CAltStreamInfo> Streams;
87baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic:
88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  // CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CRecordVector<UInt64> Sizes;
90cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  FString Prefix;
91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CTempFiles *TempFiles;
92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  void Init()
94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _streamIndex = 0;
96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _offsetPos = 0;
97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _absPos = 0;
98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _length = 0;
99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
101cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool SetMTime(const FILETIME *mTime);
102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  HRESULT Close();
103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MY_UNKNOWN_IMP1(IOutStream)
105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  STDMETHOD(SetSize)(UInt64 newSize);
109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// static NSynchronization::CCriticalSection g_TempPathsCS;
112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
113baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT COutMultiVolStream::Close()
114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  HRESULT res = S_OK;
116cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  FOR_VECTOR (i, Streams)
117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
118cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    COutFileStream *s = Streams[i].StreamSpec;
119cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (s)
120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
121cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      HRESULT res2 = s->Close();
122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (res2 != S_OK)
123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        res = res2;
124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return res;
127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
129cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckybool COutMultiVolStream::SetMTime(const FILETIME *mTime)
130cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
131cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool res = true;
132cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  FOR_VECTOR (i, Streams)
133cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
134cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    COutFileStream *s = Streams[i].StreamSpec;
135cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (s)
136cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (!s->SetMTime(mTime))
137cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        res = false;
138cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
139cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return res;
140cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
141cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
142baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
143baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (processedSize != NULL)
145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *processedSize = 0;
146cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  while (size > 0)
147baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (_streamIndex >= Streams.Size())
149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
150cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      CAltStreamInfo altStream;
151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
152cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      FChar temp[16];
153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      ConvertUInt32ToString(_streamIndex + 1, temp);
154cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      FString res = temp;
155cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      while (res.Len() < 3)
156cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        res = FString(FTEXT('0')) + res;
157cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      FString name = Prefix + res;
158cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      altStream.StreamSpec = new COutFileStream;
159cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      altStream.Stream = altStream.StreamSpec;
160cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (!altStream.StreamSpec->Create(name, false))
161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return ::GetLastError();
162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
163baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        // NSynchronization::CCriticalSectionLock lock(g_TempPathsCS);
164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        TempFiles->Paths.Add(name);
165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
167cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      altStream.Pos = 0;
168cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      altStream.RealSize = 0;
169cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      altStream.Name = name;
170cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      Streams.Add(altStream);
171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      continue;
172baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
173cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CAltStreamInfo &altStream = Streams[_streamIndex];
174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
175cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    unsigned index = _streamIndex;
176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (index >= Sizes.Size())
177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      index = Sizes.Size() - 1;
178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 volSize = Sizes[index];
179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (_offsetPos >= volSize)
181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _offsetPos -= volSize;
183baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _streamIndex++;
184baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      continue;
185baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
186cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (_offsetPos != altStream.Pos)
187baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      // CMyComPtr<IOutStream> outStream;
189cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      // RINOK(altStream.Stream.QueryInterface(IID_IOutStream, &outStream));
190cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(altStream.Stream->Seek(_offsetPos, STREAM_SEEK_SET, NULL));
191cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      altStream.Pos = _offsetPos;
192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
194cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt32 curSize = (UInt32)MyMin((UInt64)size, volSize - altStream.Pos);
195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 realProcessed;
196cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RINOK(altStream.Stream->Write(data, curSize, &realProcessed));
197baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    data = (void *)((Byte *)data + realProcessed);
198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    size -= realProcessed;
199cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    altStream.Pos += realProcessed;
200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _offsetPos += realProcessed;
201baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _absPos += realProcessed;
202baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (_absPos > _length)
203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _length = _absPos;
204cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (_offsetPos > altStream.RealSize)
205cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      altStream.RealSize = _offsetPos;
206baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (processedSize != NULL)
207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      *processedSize += realProcessed;
208cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (altStream.Pos == volSize)
209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
210baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _streamIndex++;
211baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _offsetPos = 0;
212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (realProcessed == 0 && curSize != 0)
214baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return E_FAIL;
215baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    break;
216baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
220baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP COutMultiVolStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (seekOrigin >= 3)
223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return STG_E_INVALIDFUNCTION;
224cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  switch (seekOrigin)
225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
226cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    case STREAM_SEEK_SET: _absPos = offset; break;
227cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    case STREAM_SEEK_CUR: _absPos += offset; break;
228cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    case STREAM_SEEK_END: _absPos = _length + offset; break;
229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _offsetPos = _absPos;
231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (newPosition != NULL)
232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *newPosition = _absPos;
233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _streamIndex = 0;
234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
237baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP COutMultiVolStream::SetSize(UInt64 newSize)
238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (newSize < 0)
240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return E_INVALIDARG;
241cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  unsigned i = 0;
242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  while (i < Streams.Size())
243baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
244cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CAltStreamInfo &altStream = Streams[i++];
245cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if ((UInt64)newSize < altStream.RealSize)
246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
247cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(altStream.Stream->SetSize(newSize));
248cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      altStream.RealSize = newSize;
249baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
251cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    newSize -= altStream.RealSize;
252baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  while (i < Streams.Size())
254baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
255baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
256cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      CAltStreamInfo &altStream = Streams.Back();
257cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      altStream.Stream.Release();
258cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      DeleteFileAlways(altStream.Name);
259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
260baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Streams.DeleteBack();
261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
262baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _offsetPos = _absPos;
263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _streamIndex = 0;
264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _length = newSize;
265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
266baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
267baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
268cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CArchivePath::ParseFromPath(const UString &path, EArcNameMode mode)
269cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
270cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  OriginalPath = path;
271cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
272cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  SplitPathToParts_2(path, Prefix, Name);
273cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
274cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (mode == k_ArcNameMode_Add)
275cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return;
276cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (mode == k_ArcNameMode_Exact)
277cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
278cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    BaseExtension.Empty();
279cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return;
280cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
281cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
282cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  int dotPos = Name.ReverseFind(L'.');
283cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (dotPos < 0)
284cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return;
285cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if ((unsigned)dotPos == Name.Len() - 1)
286cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
287cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    Name.DeleteBack();
288cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    BaseExtension.Empty();
289cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return;
290cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
291cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  const UString ext = Name.Ptr(dotPos + 1);
292cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (BaseExtension.IsEqualToNoCase(ext))
293cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
294cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    BaseExtension = ext;
295cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    Name.DeleteFrom(dotPos);
296cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
297cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  else
298cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    BaseExtension.Empty();
299cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
300cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
301cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyUString CArchivePath::GetFinalPath() const
302cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
303cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UString path = GetPathWithoutExt();
304cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!BaseExtension.IsEmpty())
305cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    path += UString(L'.') + BaseExtension;
306cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return path;
307cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
308cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
309cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyUString CArchivePath::GetFinalVolPath() const
310cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
311cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UString path = GetPathWithoutExt();
312cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!BaseExtension.IsEmpty())
313cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    path += UString(L'.') + VolExtension;
314cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return path;
315cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
316cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
317cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyFString CArchivePath::GetTempPath() const
318cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
319cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  FString path = TempPrefix + us2fs(Name);
320cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!BaseExtension.IsEmpty())
321cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    path += FString(FTEXT('.')) + us2fs(BaseExtension);
322cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  path += FTEXT(".tmp");
323cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  path += TempPostfix;
324cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return path;
325cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
326cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
327cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic const wchar_t *kDefaultArcType = L"7z";
328cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic const wchar_t *kDefaultArcExt = L"7z";
329baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const wchar_t *kSFXExtension =
330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef _WIN32
331baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    L"exe";
332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #else
333baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    L"";
334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
335baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
336cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckybool CUpdateOptions::InitFormatIndex(const CCodecs *codecs,
337cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const CObjectVector<COpenType> &types, const UString &arcPath)
338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
339cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (types.Size() > 1)
340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return false;
341cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  // int arcTypeIndex = -1;
342cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (types.Size() != 0)
343cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
344cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    MethodMode.Type = types[0];
345cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    MethodMode.Type_Defined = true;
346cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
347cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (MethodMode.Type.FormatIndex < 0)
348cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
349cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    // MethodMode.Type = -1;
350cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    MethodMode.Type = COpenType();
351cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (ArcNameMode != k_ArcNameMode_Add)
352cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
353cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      MethodMode.Type.FormatIndex = codecs->FindFormatForArchiveName(arcPath);
354cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (MethodMode.Type.FormatIndex >= 0)
355cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        MethodMode.Type_Defined = true;
356cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
357cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
358cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return true;
359cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
360cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
361cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckybool CUpdateOptions::SetArcPath(const CCodecs *codecs, const UString &arcPath)
362cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
363cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UString typeExt;
364cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  int formatIndex = MethodMode.Type.FormatIndex;
365cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (formatIndex < 0)
366cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
367cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    typeExt = kDefaultArcExt;
368cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
369baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
371cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const CArcInfoEx &arcInfo = codecs->Formats[formatIndex];
372cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!arcInfo.UpdateEnabled)
373cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return false;
374cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    typeExt = arcInfo.GetMainExt();
375baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString ext = typeExt;
377baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (SfxMode)
378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ext = kSFXExtension;
379baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  ArchivePath.BaseExtension = ext;
380baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  ArchivePath.VolExtension = typeExt;
381cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  ArchivePath.ParseFromPath(arcPath, ArcNameMode);
382cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  FOR_VECTOR (i, Commands)
383baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CUpdateArchiveCommand &uc = Commands[i];
385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    uc.ArchivePath.BaseExtension = ext;
386baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    uc.ArchivePath.VolExtension = typeExt;
387cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    uc.ArchivePath.ParseFromPath(uc.UserArchivePath, ArcNameMode);
388baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return true;
390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
391baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync/*
393baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstruct CUpdateProduceCallbackImp: public IUpdateProduceCallback
394baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
395baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  const CObjectVector<CArcItem> *_arcItems;
396baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IUpdateCallbackUI *_callback;
397baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
398baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CUpdateProduceCallbackImp(const CObjectVector<CArcItem> *a,
399baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      IUpdateCallbackUI *callback): _arcItems(a), _callback(callback) {}
400baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  virtual HRESULT ShowDeleteFile(int arcIndex);
401baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
402baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
403baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CUpdateProduceCallbackImp::ShowDeleteFile(int arcIndex)
404baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
405baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return _callback->ShowDeleteFile((*_arcItems)[arcIndex].Name);
406baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
407baa3858d3f5d128a5c8466b700098109edcad5f2repo sync*/
408baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
409cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckybool CRenamePair::Prepare()
410cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
411cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (RecursedType != NRecursedType::kNonRecursed)
412cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return false;
413cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!WildcardParsing)
414cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return true;
415cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return !DoesNameContainWildcard(OldName);
416cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
417cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
418cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyextern bool g_CaseSensitive;
419cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
420cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic int CompareTwoNames(const wchar_t *s1, const wchar_t *s2)
421cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
422cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (int i = 0;; i++)
423cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
424cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    wchar_t c1 = s1[i];
425cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    wchar_t c2 = s2[i];
426cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (c1 == 0 || c2 == 0)
427cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return i;
428cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (c1 == c2)
429cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      continue;
430cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!g_CaseSensitive && (MyCharUpper(c1) == MyCharUpper(c2)))
431cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      continue;
432cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (IsCharDirLimiter(c1) && IsCharDirLimiter(c2))
433cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      continue;
434cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return i;
435cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
436cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
437cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
438cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckybool CRenamePair::GetNewPath(bool isFolder, const UString &src, UString &dest) const
439cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
440cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  int num = CompareTwoNames(OldName, src);
441cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (OldName[num] == 0)
442cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
443cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (src[num] != 0 && !IsCharDirLimiter(src[num]) && num != 0 && !IsCharDirLimiter(src[num - 1]))
444cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return false;
445cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
446cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  else
447cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
448cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    // OldName[num] != 0
449cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    // OldName = "1\1a.txt"
450cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    // src = "1"
451cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
452cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!isFolder ||
453cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        src[num] != 0 ||
454cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        !IsCharDirLimiter(OldName[num]) ||
455cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        OldName[num + 1] != 0)
456cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return false;
457cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
458cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  dest = NewName + src.Ptr(num);
459cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return true;
460cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
461cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
462cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic int GetReverseSlashPos(const UString &name)
463cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
464cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  int slashPos = name.ReverseFind(L'/');
465cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  #ifdef _WIN32
466cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  int slash1Pos = name.ReverseFind(L'\\');
467cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  slashPos = MyMax(slashPos, slash1Pos);
468cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  #endif
469cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return slashPos;
470cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
471cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
472baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic HRESULT Compress(
473cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const CUpdateOptions &options,
474baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CCodecs *codecs,
475baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CActionSet &actionSet,
476cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const CArc *arc,
477baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CArchivePath &archivePath,
478baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CObjectVector<CArcItem> &arcItems,
479cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    Byte *processedItemsStatuses,
480baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CDirItems &dirItems,
481cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const CDirItem *parentDirItem,
482baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CTempFiles &tempFiles,
483baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CUpdateErrorInfo &errorInfo,
484baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    IUpdateCallbackUI *callback)
485baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
486baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CMyComPtr<IOutArchive> outArchive;
487cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  int formatIndex = options.MethodMode.Type.FormatIndex;
488cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (arc)
489baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
490cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    formatIndex = arc->FormatIndex;
491cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (formatIndex < 0)
492cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return E_NOTIMPL;
493cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CMyComPtr<IInArchive> archive2 = arc->Archive;
494baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    HRESULT result = archive2.QueryInterface(IID_IOutArchive, &outArchive);
495baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (result != S_OK)
496baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      throw kUpdateIsNotSupoorted;
497baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
498baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
499baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
500cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RINOK(codecs->CreateOutArchive(formatIndex, outArchive));
501baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
502baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #ifdef EXTERNAL_CODECS
503baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
504baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
505baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      outArchive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
506baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (setCompressCodecsInfo)
507baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
508baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs));
509baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
510baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
511baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #endif
512baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
513baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (outArchive == 0)
514baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    throw kUpdateIsNotSupoorted;
515baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
516baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NFileTimeType::EEnum fileTimeType;
517baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 value;
518baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(outArchive->GetFileTimeType(&value));
519baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
520cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  switch (value)
521baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
522baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case NFileTimeType::kWindows:
523baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case NFileTimeType::kUnix:
524baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case NFileTimeType::kDOS:
525baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      fileTimeType = (NFileTimeType::EEnum)value;
526baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
527baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    default:
528baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return E_FAIL;
529baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
530baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
531cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
532cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const CArcInfoEx &arcInfo = codecs->Formats[formatIndex];
533cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (options.AltStreams.Val && !arcInfo.Flags_AltStreams())
534cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return E_NOTIMPL;
535cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (options.NtSecurity.Val && !arcInfo.Flags_NtSecure())
536cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return E_NOTIMPL;
537cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
538cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
539baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CRecordVector<CUpdatePair2> updatePairs2;
540baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
541cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UStringVector newNames;
542cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
543cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (options.RenamePairs.Size() != 0)
544cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
545cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    FOR_VECTOR (i, arcItems)
546cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
547cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      const CArcItem &ai = arcItems[i];
548cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      bool needRename = false;
549cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      UString dest;
550cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (ai.Censored)
551cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
552cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        FOR_VECTOR (j, options.RenamePairs)
553cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        {
554cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          const CRenamePair &rp = options.RenamePairs[j];
555cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          if (rp.GetNewPath(ai.IsDir, ai.Name, dest))
556cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          {
557cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            needRename = true;
558cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            break;
559cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          }
560cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          if (ai.IsAltStream)
561cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          {
562cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            int colonPos = ai.Name.ReverseFind(':');
563cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            int slashPosPos = GetReverseSlashPos(ai.Name);
564cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            if (colonPos > slashPosPos)
565cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            {
566cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky              UString mainName = ai.Name.Left(colonPos);
567cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky              /*
568cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky              actually we must improve that code to support cases
569cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky              with folder renaming like: rn arc dir1\ dir2\
570cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky              */
571cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky              if (rp.GetNewPath(false, mainName, dest))
572cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky              {
573cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky                needRename = true;
574cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky                dest += ':';
575cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky                dest += ai.Name.Ptr(colonPos + 1);
576cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky                break;
577cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky              }
578cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            }
579cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          }
580cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        }
581cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
582cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      CUpdatePair2 up2;
583cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      up2.SetAs_NoChangeArcItem(ai.IndexInServer);
584cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (needRename)
585cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
586cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        up2.NewProps = true;
587cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        RINOK(arc->IsItemAnti(i, up2.IsAnti));
588cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        up2.NewNameIndex = newNames.Add(dest);
589cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
590cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      updatePairs2.Add(up2);
591cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
592cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
593cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  else
594baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
595baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CRecordVector<CUpdatePair> updatePairs;
596baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    GetUpdatePairInfoList(dirItems, arcItems, fileTimeType, updatePairs); // must be done only once!!!
597baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // CUpdateProduceCallbackImp upCallback(&arcItems, callback);
598baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UpdateProduce(updatePairs, actionSet, updatePairs2, NULL /* &upCallback */);
599baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
600baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
601baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 numFiles = 0;
602cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  FOR_VECTOR (i, updatePairs2)
603baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (updatePairs2[i].NewData)
604baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      numFiles++;
605baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
606baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(callback->SetNumFiles(numFiles));
607baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
608baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
609baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);
610baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
611cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  updateCallbackSpec->ShareForWrite = options.OpenShareForWrite;
612cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  updateCallbackSpec->StdInMode = options.StdInMode;
613baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  updateCallbackSpec->Callback = callback;
614cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
615cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (arc)
616cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
617cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    // we set Archive to allow to transfer GetProperty requests back to DLL.
618cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    updateCallbackSpec->Archive = arc->Archive;
619cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    updateCallbackSpec->GetRawProps = arc->GetRawProps;
620cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    updateCallbackSpec->GetRootProps = arc->GetRootProps;
621cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
622cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
623baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  updateCallbackSpec->DirItems = &dirItems;
624cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  updateCallbackSpec->ParentDirItem = parentDirItem;
625cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
626cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  updateCallbackSpec->StoreNtSecurity = options.NtSecurity.Val;
627cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  updateCallbackSpec->StoreHardLinks = options.HardLinks.Val;
628cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  updateCallbackSpec->StoreSymLinks = options.SymLinks.Val;
629cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
630baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  updateCallbackSpec->ArcItems = &arcItems;
631baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  updateCallbackSpec->UpdatePairs = &updatePairs2;
632baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
633cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  updateCallbackSpec->ProcessedItemsStatuses = processedItemsStatuses;
634cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
635cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (options.RenamePairs.Size() != 0)
636cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    updateCallbackSpec->NewNames = &newNames;
637cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
638cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CMyComPtr<IOutStream> outSeekStream;
639baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CMyComPtr<ISequentialOutStream> outStream;
640baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
641cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!options.StdOutMode)
642baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
643cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    FString dirPrefix;
644cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!GetOnlyDirPrefix(us2fs(archivePath.GetFinalPath()), dirPrefix))
645baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      throw 1417161;
646cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CreateComplexDir(dirPrefix);
647baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
648baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
649baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COutFileStream *outStreamSpec = NULL;
650baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COutMultiVolStream *volStreamSpec = NULL;
651baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
652cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (options.VolumesSizes.Size() == 0)
653baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
654cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (options.StdOutMode)
655baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      outStream = new CStdOutFileStream;
656baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    else
657baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
658baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      outStreamSpec = new COutFileStream;
659cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      outSeekStream = outStreamSpec;
660cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      outStream = outSeekStream;
661baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      bool isOK = false;
662cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      FString realPath;
663baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      for (int i = 0; i < (1 << 16); i++)
664baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
665baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (archivePath.Temp)
666baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
667baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          if (i > 0)
668baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          {
669cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            FChar s[16];
670baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            ConvertUInt32ToString(i, s);
671baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            archivePath.TempPostfix = s;
672baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          }
673baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          realPath = archivePath.GetTempPath();
674baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
675baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        else
676cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          realPath = us2fs(archivePath.GetFinalPath());
677baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (outStreamSpec->Create(realPath, false))
678baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
679baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          tempFiles.Paths.Add(realPath);
680baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          isOK = true;
681baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          break;
682baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
683baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (::GetLastError() != ERROR_FILE_EXISTS)
684baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          break;
685baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (!archivePath.Temp)
686baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          break;
687baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
688baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (!isOK)
689baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
690baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        errorInfo.SystemError = ::GetLastError();
691baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        errorInfo.FileName = realPath;
692baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        errorInfo.Message = L"7-Zip cannot open file";
693baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return E_FAIL;
694baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
695baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
696baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
697baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
698baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
699cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (options.StdOutMode)
700baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return E_FAIL;
701cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (arc && arc->GetGlobalOffset() > 0)
702cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return E_NOTIMPL;
703cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
704baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    volStreamSpec = new COutMultiVolStream;
705cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    outSeekStream = volStreamSpec;
706cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    outStream = outSeekStream;
707cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    volStreamSpec->Sizes = options.VolumesSizes;
708cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    volStreamSpec->Prefix = us2fs(archivePath.GetFinalVolPath() + L".");
709baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    volStreamSpec->TempFiles = &tempFiles;
710baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    volStreamSpec->Init();
711baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
712baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    /*
713baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    updateCallbackSpec->VolumesSizes = volumesSizes;
714baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    updateCallbackSpec->VolName = archivePath.Prefix + archivePath.Name;
715baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (!archivePath.VolExtension.IsEmpty())
716baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      updateCallbackSpec->VolExt = UString(L'.') + archivePath.VolExtension;
717baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    */
718baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
719baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
720cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  RINOK(SetProperties(outArchive, options.MethodMode.Properties));
721baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
722cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (options.SfxMode)
723baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
724baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CInFileStream *sfxStreamSpec = new CInFileStream;
725baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComPtr<IInStream> sfxStream(sfxStreamSpec);
726cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!sfxStreamSpec->Open(options.SfxModule))
727baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
728baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      errorInfo.SystemError = ::GetLastError();
729baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      errorInfo.Message = L"7-Zip cannot open SFX module";
730cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      errorInfo.FileName = options.SfxModule;
731baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return E_FAIL;
732baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
733baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
734baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComPtr<ISequentialOutStream> sfxOutStream;
735baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    COutFileStream *outStreamSpec = NULL;
736cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (options.VolumesSizes.Size() == 0)
737baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      sfxOutStream = outStream;
738baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    else
739baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
740baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      outStreamSpec = new COutFileStream;
741baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      sfxOutStream = outStreamSpec;
742cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      FString realPath = us2fs(archivePath.GetFinalPath());
743baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (!outStreamSpec->Create(realPath, false))
744baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
745baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        errorInfo.SystemError = ::GetLastError();
746baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        errorInfo.FileName = realPath;
747baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        errorInfo.Message = L"7-Zip cannot open file";
748baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return E_FAIL;
749baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
750baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
751baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(NCompress::CopyStream(sfxStream, sfxOutStream, NULL));
752baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (outStreamSpec)
753baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
754baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(outStreamSpec->Close());
755baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
756baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
757baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
758cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CMyComPtr<ISequentialOutStream> tailStream;
759cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
760cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (options.SfxMode || !arc || arc->ArcStreamOffset == 0)
761cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    tailStream = outStream;
762cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  else
763cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
764cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    // Int64 globalOffset = arc->GetGlobalOffset();
765cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RINOK(arc->InStream->Seek(0, STREAM_SEEK_SET, NULL));
766cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RINOK(NCompress::CopyStream_ExactSize(arc->InStream, outStream, arc->ArcStreamOffset, NULL));
767cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (options.StdOutMode)
768cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      tailStream = outStream;
769cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    else
770cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
771cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      CTailOutStream *tailStreamSpec = new CTailOutStream;
772cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      tailStream = tailStreamSpec;
773cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      tailStreamSpec->Stream = outSeekStream;
774cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      tailStreamSpec->Offset = arc->ArcStreamOffset;
775cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      tailStreamSpec->Init();
776cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
777cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
778cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
779cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
780cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  HRESULT result = outArchive->UpdateItems(tailStream, updatePairs2.Size(), updateCallback);
781baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  callback->Finilize();
782baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(result);
783cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
784cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
785cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (options.SetArcMTime)
786cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
787cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    FILETIME ft;
788cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    ft.dwLowDateTime = 0;
789cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    ft.dwHighDateTime = 0;
790cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    FOR_VECTOR (i, updatePairs2)
791cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
792cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      CUpdatePair2 &pair2 = updatePairs2[i];
793cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      const FILETIME *ft2 = NULL;
794cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (pair2.NewProps && pair2.DirIndex >= 0)
795cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        ft2 = &dirItems.Items[pair2.DirIndex].MTime;
796cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      else if (pair2.UseArcProps && pair2.ArcIndex >= 0)
797cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        ft2 = &arcItems[pair2.ArcIndex].MTime;
798cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (ft2)
799cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
800cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (::CompareFileTime(&ft, ft2) < 0)
801cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          ft = *ft2;
802cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
803cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
804cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (ft.dwLowDateTime != 0 || ft.dwHighDateTime != 0)
805cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
806cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (outStreamSpec)
807cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        outStreamSpec->SetMTime(&ft);
808cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      else if (volStreamSpec)
809cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        volStreamSpec->SetMTime(&ft);;
810cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
811cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
812cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
813baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (outStreamSpec)
814baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    result = outStreamSpec->Close();
815baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else if (volStreamSpec)
816baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    result = volStreamSpec->Close();
817baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return result;
818baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
819baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
820cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic HRESULT EnumerateInArchiveItems(
821cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    // bool storeStreamsMode,
822cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const NWildcard::CCensor &censor,
823baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CArc &arc,
824baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CObjectVector<CArcItem> &arcItems)
825baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
826baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  arcItems.Clear();
827baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 numItems;
828baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IInArchive *archive = arc.Archive;
829baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(archive->GetNumberOfItems(&numItems));
830cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  arcItems.ClearAndReserve(numItems);
831baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (UInt32 i = 0; i < numItems; i++)
832baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
833baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CArcItem ai;
834baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
835baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(arc.GetItemPath(i, ai.Name));
836cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RINOK(Archive_IsItem_Folder(archive, i, ai.IsDir));
837cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RINOK(Archive_IsItem_AltStream(archive, i, ai.IsAltStream));
838cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    /*
839cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!storeStreamsMode && ai.IsAltStream)
840cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      continue;
841cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    */
842cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    ai.Censored = censor.CheckPath(ai.IsAltStream, ai.Name, !ai.IsDir);
843baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(arc.GetItemMTime(i, ai.MTime, ai.MTimeDefined));
844cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RINOK(arc.GetItemSize(i, ai.Size, ai.SizeDefined));
845baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
846baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
847baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CPropVariant prop;
848baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(archive->GetProperty(i, kpidTimeType, &prop));
849baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (prop.vt == VT_UI4)
850baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
851baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        ai.TimeType = (int)(NFileTimeType::EEnum)prop.ulVal;
852cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        switch (ai.TimeType)
853baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
854baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          case NFileTimeType::kWindows:
855baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          case NFileTimeType::kUnix:
856baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          case NFileTimeType::kDOS:
857baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            break;
858baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          default:
859baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            return E_FAIL;
860baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
861baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
862baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
863baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
864baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ai.IndexInServer = i;
865cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    arcItems.AddInReserved(ai);
866baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
867baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
868baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
869baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
870cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystruct CEnumDirItemUpdateCallback: public IEnumDirItemCallback
871baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
872cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  IUpdateCallbackUI2 *Callback;
873cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  HRESULT ScanProgress(UInt64 numFolders, UInt64 numFiles, UInt64 totalSize, const wchar_t *path, bool isDir)
874baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
875cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return Callback->ScanProgress(numFolders, numFiles, totalSize, path, isDir);
876baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
877cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky};
878baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
879baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#if defined(_WIN32) && !defined(UNDER_CE)
880cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
881cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include <mapi.h>
882cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
883cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#endif
884cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
885cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystruct CRefSortPair
886baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
887cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  int Len;
888cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  int Index;
889baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
890baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
891cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
892cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
893cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic int CompareRefSortPair(const CRefSortPair *a1, const CRefSortPair *a2, void *)
894baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
895cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  RINOZ(-MyCompare(a1->Len, a2->Len));
896cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return MyCompare(a1->Index, a2->Index);
897cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
898cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
899cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic int GetNumSlashes(const FChar *s)
900cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
901cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (int numSlashes = 0;;)
902baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
903cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    FChar c = *s++;
904cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (c == 0)
905cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return numSlashes;
906cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (
907cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        #ifdef _WIN32
908cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        c == FTEXT('\\') ||
909cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        #endif
910cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        c == FTEXT('/'))
911cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      numSlashes++;
912baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
913cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
914baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
915baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifdef _WIN32
916cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid ConvertToLongNames(NWildcard::CCensor &censor);
917baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
918baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
919baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT UpdateArchive(
920baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CCodecs *codecs,
921cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const CObjectVector<COpenType> &types,
922cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const UString &cmdArcPath2,
923cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    NWildcard::CCensor &censor,
924baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CUpdateOptions &options,
925baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CUpdateErrorInfo &errorInfo,
926baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    IOpenCallbackUI *openCallback,
927cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    IUpdateCallbackUI2 *callback,
928cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    bool needSetPath)
929baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
930baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (options.StdOutMode && options.EMailMode)
931baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return E_FAIL;
932baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
933cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (types.Size() > 1)
934cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return E_NOTIMPL;
935cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
936cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool renameMode = !options.RenamePairs.IsEmpty();
937cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (renameMode)
938cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
939cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (options.Commands.Size() != 1)
940cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return E_FAIL;
941cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
942cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
943cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (options.DeleteAfterCompressing)
944cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
945cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (options.Commands.Size() != 1)
946cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return E_NOTIMPL;
947cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const CActionSet &as = options.Commands[0].ActionSet;
948cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (int i = 2; i < NPairState::kNumValues; i++)
949cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (as.StateActions[i] != NPairAction::kCompress)
950cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        return E_NOTIMPL;
951cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
952cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
953cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  censor.AddPathsToCensor(options.PathMode);
954cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  #ifdef _WIN32
955cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  ConvertToLongNames(censor);
956cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  #endif
957cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  censor.ExtendExclude();
958cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
959cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
960cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (options.VolumesSizes.Size() > 0 && (options.EMailMode /* || options.SfxMode */))
961baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return E_NOTIMPL;
962baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
963baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (options.SfxMode)
964baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
965baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CProperty property;
966baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    property.Name = L"rsfx";
967baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    property.Value = L"on";
968baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    options.MethodMode.Properties.Add(property);
969baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (options.SfxModule.IsEmpty())
970baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
971baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      errorInfo.Message = L"SFX file is not specified";
972baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return E_FAIL;
973baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
974cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    bool found = false;
975cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (options.SfxModule.Find(FCHAR_PATH_SEPARATOR) < 0)
976baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
977cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      const FString fullName = NDLL::GetModuleDirPrefix() + options.SfxModule;
978cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (NFind::DoesFileExist(fullName))
979cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
980cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        options.SfxModule = fullName;
981cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        found = true;
982cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
983cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
984cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!found)
985cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
986cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (!NFind::DoesFileExist(options.SfxModule))
987cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
988cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        errorInfo.SystemError = ::GetLastError();
989cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        errorInfo.Message = L"7-Zip cannot find specified SFX module";
990cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        errorInfo.FileName = options.SfxModule;
991cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        return E_FAIL;
992cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
993baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
994baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
995baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
996baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CArchiveLink arcLink;
997baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
998cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
999cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (needSetPath)
1000cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1001cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!options.InitFormatIndex(codecs, types, cmdArcPath2) ||
1002cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        !options.SetArcPath(codecs, cmdArcPath2))
1003cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return E_NOTIMPL;
1004cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1005cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UString arcPath = options.ArchivePath.GetFinalPath();
1006cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1007cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (cmdArcPath2.IsEmpty())
1008cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1009cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (options.MethodMode.Type.FormatIndex < 0)
1010cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      throw "type of archive is not specified";
1011cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1012cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  else
1013baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1014cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    NFind::CFileInfo fi;
1015cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!fi.Find(us2fs(arcPath)))
1016cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
1017cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (renameMode)
1018cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        throw "can't find archive";;
1019cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (options.MethodMode.Type.FormatIndex < 0)
1020cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
1021cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (!options.SetArcPath(codecs, cmdArcPath2))
1022cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          return E_NOTIMPL;
1023cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
1024cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
1025cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    else
1026baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1027baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (fi.IsDir())
1028baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        throw "there is no such archive";
1029cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (fi.IsDevice)
1030cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        return E_NOTIMPL;
1031baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (options.VolumesSizes.Size() > 0)
1032baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return E_NOTIMPL;
1033cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      CObjectVector<COpenType> types;
1034cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      // change it.
1035cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (options.MethodMode.Type_Defined)
1036cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        types.Add(options.MethodMode.Type);
1037cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      // We need to set Properties to open archive only in some cases (WIM archives).
1038cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1039cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      CIntVector excl;
1040cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      COpenOptions op;
1041cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      #ifndef _SFX
1042cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      op.props = &options.MethodMode.Properties;
1043cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      #endif
1044cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      op.codecs = codecs;
1045cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      op.types = &types;
1046cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      op.excludedFormats = &excl;
1047cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      op.stdInMode = false;
1048cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      op.stream = NULL;
1049cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      op.filePath = arcPath;
1050cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1051cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      HRESULT result = arcLink.Open2(op, openCallback);
1052cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1053baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (result == E_ABORT)
1054baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return result;
1055cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1056cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      const wchar_t *errorArcType = NULL;
1057cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex > 0)
1058cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        errorArcType = codecs->Formats[arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name;
1059cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(callback->OpenResult(arcPath, result, errorArcType));
1060cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      /*
1061cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (result == S_FALSE)
1062cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        return E_FAIL;
1063cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      */
1064baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(result);
1065baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (arcLink.VolumePaths.Size() > 1)
1066baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
1067baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        errorInfo.SystemError = (DWORD)E_NOTIMPL;
1068baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        errorInfo.Message = L"Updating for multivolume archives is not implemented";
1069baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return E_NOTIMPL;
1070baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
1071baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1072baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CArc &arc = arcLink.Arcs.Back();
1073baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      arc.MTimeDefined = !fi.IsDevice;
1074baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      arc.MTime = fi.MTime;
1075cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1076cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (arc.ErrorInfo.ThereIsTail)
1077cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
1078cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        errorInfo.SystemError = (DWORD)E_NOTIMPL;
1079cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        errorInfo.Message = L"There is some data block after the end of the archive";
1080cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        return E_NOTIMPL;
1081cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
1082cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (options.MethodMode.Type.FormatIndex < 0)
1083cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
1084cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        options.MethodMode.Type.FormatIndex = arcLink.GetArc()->FormatIndex;
1085cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (!options.SetArcPath(codecs, cmdArcPath2))
1086cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          return E_NOTIMPL;
1087cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
1088baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1089baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1090cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1091cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (options.MethodMode.Type.FormatIndex < 0)
1092baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1093cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    options.MethodMode.Type.FormatIndex = codecs->FindFormatForArchiveType(kDefaultArcType);
1094cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (options.MethodMode.Type.FormatIndex < 0)
1095cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return E_NOTIMPL;
1096baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1097baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1098cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool thereIsInArchive = arcLink.IsOpen;
1099cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!thereIsInArchive && renameMode)
1100cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return E_FAIL;
1101cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CDirItems dirItems;
1103cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CDirItem parentDirItem;
1104cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CDirItem *parentDirItem_Ptr = NULL;
1105cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1106cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  /*
1107cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  FStringVector requestedPaths;
1108cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  FStringVector *requestedPaths_Ptr = NULL;
1109cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (options.DeleteAfterCompressing)
1110cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    requestedPaths_Ptr = &requestedPaths;
1111cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  */
1112cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (options.StdInMode)
1114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CDirItem di;
1116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    di.Name = options.StdInFileName;
1117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    di.Size = (UInt64)(Int64)-1;
1118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    di.Attrib = 0;
1119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    NTime::GetCurUtcFileTime(di.MTime);
1120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    di.CTime = di.ATime = di.MTime;
1121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    dirItems.Items.Add(di);
1122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
1124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    bool needScanning = false;
1126cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!renameMode)
1127cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    FOR_VECTOR (i, options.Commands)
1128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (options.Commands[i].ActionSet.NeedScanning())
1129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        needScanning = true;
1130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (needScanning)
1131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CEnumDirItemUpdateCallback enumCallback;
1133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      enumCallback.Callback = callback;
1134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(callback->StartScanning());
1135cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1136cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      dirItems.SymLinks = options.SymLinks.Val;
1137cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1138cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      #if defined(_WIN32) && !defined(UNDER_CE)
1139cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      dirItems.ReadSecure = options.NtSecurity.Val;
1140cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      #endif
1141cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1142cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      dirItems.ScanAltStreams = options.AltStreams.Val;
1143cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      HRESULT res = EnumerateItems(censor,
1144cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          options.PathMode,
1145cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          options.AddPathPrefix,
1146cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          dirItems, &enumCallback);
1147cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      FOR_VECTOR (i, dirItems.ErrorPaths)
1148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
1149cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        RINOK(callback->CanNotFindError(fs2us(dirItems.ErrorPaths[i]), dirItems.ErrorCodes[i]));
1150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
1151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (res != S_OK)
1152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
1153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (res != E_ABORT)
1154baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          errorInfo.Message = L"Scanning error";
1155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return res;
1156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
1157baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(callback->FinishScanning());
1158cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1159cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (censor.Pairs.Size() == 1)
1160cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
1161cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        NFind::CFileInfo fi;
1162cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        FString prefix = us2fs(censor.Pairs[0].Prefix) + FTEXT(".");
1163cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        // UString prefix = censor.Pairs[0].Prefix;
1164cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        /*
1165cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (prefix.Back() == WCHAR_PATH_SEPARATOR)
1166cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        {
1167cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          prefix.DeleteBack();
1168cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        }
1169cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        */
1170cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (fi.Find(prefix))
1171cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          if (fi.IsDir())
1172cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          {
1173cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            parentDirItem.Size = fi.Size;
1174cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            parentDirItem.CTime = fi.CTime;
1175cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            parentDirItem.ATime = fi.ATime;
1176cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            parentDirItem.MTime = fi.MTime;
1177cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            parentDirItem.Attrib = fi.Attrib;
1178cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            parentDirItem_Ptr = &parentDirItem;
1179cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1180cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            int secureIndex = -1;
1181cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            #if defined(_WIN32) && !defined(UNDER_CE)
1182cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            if (options.NtSecurity.Val)
1183cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky              dirItems.AddSecurityItem(prefix, secureIndex);
1184cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            #endif
1185cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            parentDirItem.SecureIndex = secureIndex;
1186cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1187cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            parentDirItem_Ptr = &parentDirItem;
1188cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          }
1189cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
1190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1191baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1193cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  FString tempDirPrefix;
1194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  bool usesTempDir = false;
1195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef _WIN32
1197cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CTempDir tempDirectory;
1198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (options.EMailMode && options.EMailRemoveAfter)
1199baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    tempDirectory.Create(kTempFolderPrefix);
1201baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    tempDirPrefix = tempDirectory.GetPath();
1202baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    NormalizeDirPathPrefix(tempDirPrefix);
1203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    usesTempDir = true;
1204baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1205baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
1206baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CTempFiles tempFiles;
1208baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  bool createTempFile = false;
1210baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1211baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!options.StdOutMode && options.UpdateArchiveItself)
1212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CArchivePath &ap = options.Commands[0].ArchivePath;
1214baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ap = options.ArchivePath;
1215baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // if ((archive != 0 && !usesTempDir) || !options.WorkingDir.IsEmpty())
1216baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if ((thereIsInArchive || !options.WorkingDir.IsEmpty()) && !usesTempDir && options.VolumesSizes.Size() == 0)
1217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      createTempFile = true;
1219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      ap.Temp = true;
1220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (!options.WorkingDir.IsEmpty())
1221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        ap.TempPrefix = options.WorkingDir;
1222cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      else
1223cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        ap.TempPrefix = us2fs(ap.Prefix);
1224cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      NormalizeDirPathPrefix(ap.TempPrefix);
1225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1228cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  unsigned i;
1229cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (i = 0; i < options.Commands.Size(); i++)
1230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CArchivePath &ap = options.Commands[i].ArchivePath;
1232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (usesTempDir)
1233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      // Check it
1235cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      ap.Prefix = fs2us(tempDirPrefix);
1236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      // ap.Temp = true;
1237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      // ap.TempPrefix = tempDirPrefix;
1238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (!options.StdOutMode &&
1240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        (i > 0 || !createTempFile))
1241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1242cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      const FString path = us2fs(ap.GetFinalPath());
1243baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (NFind::DoesFileOrDirExist(path))
1244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
1245baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        errorInfo.SystemError = 0;
1246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        errorInfo.Message = L"The file already exists";
1247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        errorInfo.FileName = path;
1248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return E_FAIL;
1249baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
1250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1251baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1252baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CObjectVector<CArcItem> arcItems;
1254baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (thereIsInArchive)
1255baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1256cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RINOK(EnumerateInArchiveItems(
1257cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      // options.StoreAltStreams,
1258cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      censor, arcLink.Arcs.Back(), arcItems));
1259cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1260cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1261cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  /*
1262cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  FStringVector processedFilePaths;
1263cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  FStringVector *processedFilePaths_Ptr = NULL;
1264cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (options.DeleteAfterCompressing)
1265cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    processedFilePaths_Ptr = &processedFilePaths;
1266cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  */
1267cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1268cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CByteBuffer processedItems;
1269cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (options.DeleteAfterCompressing)
1270cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1271cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    unsigned num = dirItems.Items.Size();
1272cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    processedItems.Alloc(num);
1273cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (i = 0; i < num; i++)
1274cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      processedItems[i] = 0;
1275cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1276cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1277cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (i = 0; i < options.Commands.Size(); i++)
1278cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1279cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const CArc *arc = thereIsInArchive ? arcLink.GetArc() : 0;
1280cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    // IInArchiveExtra *archiveExtra = thereIsInArchive ? arcLink.GetArchiveExtra() : 0;
1281cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    // IArchiveGetRootProps *archiveGetRootProps = thereIsInArchive ? arcLink.GetArchiveGetRootProps() : 0;
1282cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CUpdateArchiveCommand &command = options.Commands[i];
1283cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UString name;
1284cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    bool isUpdating;
1285cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (options.StdOutMode)
1286cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
1287cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      name = L"stdout";
1288cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      isUpdating = arc != 0;
1289cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
1290cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    else
1291cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
1292cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      name = command.ArchivePath.GetFinalPath();
1293cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      isUpdating = (i == 0 && options.UpdateArchiveItself && arc != 0);
1294cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
1295cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RINOK(callback->StartArchive(name, isUpdating))
1296cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1297cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RINOK(Compress(options,
1298cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        codecs,
1299cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        command.ActionSet,
1300cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        arc,
1301cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        command.ArchivePath,
1302cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        arcItems,
1303cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        options.DeleteAfterCompressing ? (Byte *)processedItems : NULL,
1304cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1305cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        dirItems,
1306cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        parentDirItem_Ptr,
1307cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1308cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        tempFiles,
1309cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        errorInfo, callback));
1310cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1311cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RINOK(callback->FinishArchive());
1312baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1313baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1314baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1315baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (thereIsInArchive)
1316baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(arcLink.Close());
1318baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    arcLink.Release();
1319baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1320baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1321baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  tempFiles.Paths.Clear();
1322baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (createTempFile)
1323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    try
1325baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CArchivePath &ap = options.Commands[0].ArchivePath;
1327cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      const FString &tempPath = ap.GetTempPath();
1328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (thereIsInArchive)
1329cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (!DeleteFileAlways(us2fs(arcPath)))
1330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
1331baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          errorInfo.SystemError = ::GetLastError();
1332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          errorInfo.Message = L"7-Zip cannot delete the file";
1333cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          errorInfo.FileName = us2fs(arcPath);
1334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          return E_FAIL;
1335baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
1336cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (!MyMoveFile(tempPath, us2fs(arcPath)))
1337baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
1338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        errorInfo.SystemError = ::GetLastError();
1339baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        errorInfo.Message = L"7-Zip cannot move the file";
1340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        errorInfo.FileName = tempPath;
1341cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        errorInfo.FileName2 = us2fs(arcPath);
1342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return E_FAIL;
1343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
1344baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1345baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    catch(...)
1346baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1347baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      throw;
1348baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1349baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1350baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1351cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #if defined(_WIN32) && !defined(UNDER_CE)
1353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (options.EMailMode)
1354baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1355baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    NDLL::CLibrary mapiLib;
1356cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!mapiLib.Load(FTEXT("Mapi32.dll")))
1357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1358baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      errorInfo.SystemError = ::GetLastError();
1359baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      errorInfo.Message = L"7-Zip cannot load Mapi32.dll";
1360baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return E_FAIL;
1361baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1362cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1363cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    /*
1364cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    LPMAPISENDDOCUMENTS fnSend = (LPMAPISENDDOCUMENTS)mapiLib.GetProc("MAPISendDocuments");
1365baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (fnSend == 0)
1366baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1367baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      errorInfo.SystemError = ::GetLastError();
1368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      errorInfo.Message = L"7-Zip cannot find MAPISendDocuments function";
1369baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return E_FAIL;
1370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1371cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    */
1372cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    LPMAPISENDMAIL sendMail = (LPMAPISENDMAIL)mapiLib.GetProc("MAPISendMail");
1373cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (sendMail == 0)
1374cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
1375cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      errorInfo.SystemError = ::GetLastError();
1376cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      errorInfo.Message = L"7-Zip cannot find MAPISendMail function";
1377cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return E_FAIL;
1378cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
1379cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1380cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    FStringVector fullPaths;
1381cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    unsigned i;
1382cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (i = 0; i < options.Commands.Size(); i++)
1383baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CArchivePath &ap = options.Commands[i].ArchivePath;
1385cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      FString arcPath;
1386cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (!MyGetFullPathName(us2fs(ap.GetFinalPath()), arcPath))
1387baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
1388baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        errorInfo.SystemError = ::GetLastError();
1389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        errorInfo.Message = L"GetFullPathName error";
1390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return E_FAIL;
1391baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
1392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      fullPaths.Add(arcPath);
1393baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1394baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CCurrentDirRestorer curDirRestorer;
1395cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (i = 0; i < fullPaths.Size(); i++)
1396baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1397cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      UString arcPath = fs2us(fullPaths[i]);
1398baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      UString fileName = ExtractFileNameFromPath(arcPath);
1399baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      AString path = GetAnsiString(arcPath);
1400baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      AString name = GetAnsiString(fileName);
1401baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      // Warning!!! MAPISendDocuments function changes Current directory
1402cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      // fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0);
1403cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1404cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      MapiFileDesc f;
1405cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      memset(&f, 0, sizeof(f));
1406cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      f.nPosition = 0xFFFFFFFF;
1407cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      f.lpszPathName = (char *)(const char *)path;
1408cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      f.lpszFileName = (char *)(const char *)name;
1409cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1410cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      MapiMessage m;
1411cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      memset(&m, 0, sizeof(m));
1412cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      m.nFileCount = 1;
1413cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      m.lpFiles = &f;
1414cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1415cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      const AString addr = GetAnsiString(options.EMailAddress);
1416cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      MapiRecipDesc rec;
1417cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (!addr.IsEmpty())
1418cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
1419cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        memset(&rec, 0, sizeof(rec));
1420cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        rec.ulRecipClass = MAPI_TO;
1421cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        rec.lpszAddress = (char *)(const char *)addr;
1422cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        m.nRecipCount = 1;
1423cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        m.lpRecips = &rec;
1424cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
1425cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1426cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      sendMail((LHANDLE)0, 0, &m, MAPI_DIALOG, 0);
1427baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1428baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1429baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
1430cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1431cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (options.DeleteAfterCompressing)
1432cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1433cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CRecordVector<CRefSortPair> pairs;
1434cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    FStringVector foldersNames;
1435cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (i = 0; i < dirItems.Items.Size(); i++)
1436cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
1437cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      const CDirItem &dirItem = dirItems.Items[i];
1438cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      FString phyPath = us2fs(dirItems.GetPhyPath(i));
1439cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (dirItem.IsDir())
1440cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
1441cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        CRefSortPair pair;
1442cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        pair.Index = i;
1443cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        pair.Len = GetNumSlashes(phyPath);
1444cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        pairs.Add(pair);
1445cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
1446cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      else
1447cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
1448cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (processedItems[i] != 0 || dirItem.Size == 0)
1449cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        {
1450cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          DeleteFileAlways(phyPath);
1451cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        }
1452cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        else
1453cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        {
1454cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          // file was skipped
1455cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          /*
1456cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          errorInfo.SystemError = 0;
1457cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          errorInfo.Message = L"file was not processed";
1458cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          errorInfo.FileName = phyPath;
1459cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          return E_FAIL;
1460cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          */
1461cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        }
1462cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
1463cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
1464cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1465cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    pairs.Sort(CompareRefSortPair, NULL);
1466cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (i = 0; i < pairs.Size(); i++)
1467cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
1468cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      FString phyPath = us2fs(dirItems.GetPhyPath(pairs[i].Index));
1469cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (NFind::DoesDirExist(phyPath))
1470cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
1471cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        // printf("delete %S\n", phyPath);
1472cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        RemoveDir(phyPath);
1473cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
1474cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
1475cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1476baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
1477baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1478