1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// 7zHandlerOut.cpp
2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h"
4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../Common/ComTry.h"
6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../Common/StringToInt.h"
7cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Common/Wildcard.h"
8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../Common/ItemNameUtils.h"
10baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../Common/ParseProperties.h"
11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
12baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "7zHandler.h"
13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "7zOut.h"
14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "7zUpdate.h"
15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
16baa3858d3f5d128a5c8466b700098109edcad5f2repo syncusing namespace NWindows;
17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
18baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NArchive {
19baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace N7z {
20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
21cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic const wchar_t *k_LZMA_Name = L"LZMA";
22cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic const wchar_t *kDefaultMethodName = L"LZMA2";
23cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic const wchar_t *k_Copy_Name = L"Copy";
24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
25cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic const wchar_t *k_MatchFinder_ForHeaders = L"BT2";
26cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic const UInt32 k_NumFastBytes_ForHeaders = 273;
27cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic const UInt32 k_Level_ForHeaders = 5;
28cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic const UInt32 k_Dictionary_ForHeaders =
29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef UNDER_CE
30cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  1 << 18;
31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #else
32cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  1 << 20;
33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
35baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  *type = NFileTimeType::kWindows;
38baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
41cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyHRESULT CHandler::PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m)
42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
43cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!FindMethod(
44cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      EXTERNAL_CODECS_VARS
45cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      m.MethodName, dest.Id, dest.NumInStreams, dest.NumOutStreams))
46cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return E_INVALIDARG;
47cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  (CProps &)dest = (CProps &)m;
48cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return S_OK;
49cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
51cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyHRESULT CHandler::SetHeaderMethod(CCompressionMethodMode &headerMethod)
52cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
53cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!_compressHeaders)
54cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return S_OK;
55cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  COneMethodInfo m;
56cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  m.MethodName = k_LZMA_Name;
57cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  m.AddPropString(NCoderPropID::kMatchFinder, k_MatchFinder_ForHeaders);
58cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  m.AddProp32(NCoderPropID::kLevel, k_Level_ForHeaders);
59cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  m.AddProp32(NCoderPropID::kNumFastBytes, k_NumFastBytes_ForHeaders);
60cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  m.AddProp32(NCoderPropID::kDictionarySize, k_Dictionary_ForHeaders);
61cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  m.AddNumThreadsProp(1);
62cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
63cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CMethodFull methodFull;
64cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  RINOK(PropsMethod_To_FullMethod(methodFull, m));
65cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  headerMethod.Methods.Add(methodFull);
66cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return S_OK;
67cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
69cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CHandler::AddDefaultMethod()
70cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
71cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  FOR_VECTOR (i, _methods)
72cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
73cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UString &methodName = _methods[i].MethodName;
74cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (methodName.IsEmpty())
75cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      methodName = kDefaultMethodName;
76cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
77cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (_methods.IsEmpty())
78cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
79cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    COneMethodInfo m;
80cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    m.MethodName = (GetLevel() == 0 ? k_Copy_Name : kDefaultMethodName);
81cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    _methods.Add(m);
82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
85cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyHRESULT CHandler::SetMainMethod(
86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CCompressionMethodMode &methodMode,
87cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CObjectVector<COneMethodInfo> &methods
88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #ifndef _7ZIP_ST
89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    , UInt32 numThreads
90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #endif
91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    )
92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
93cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  AddDefaultMethod();
94cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
95cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  const UInt64 kSolidBytes_Min = (1 << 24);
96cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  const UInt64 kSolidBytes_Max = ((UInt64)1 << 32) - 1;
97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  bool needSolid = false;
99cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  FOR_VECTOR (i, methods)
100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
101cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    COneMethodInfo &oneMethodInfo = methods[i];
102cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    SetGlobalLevelAndThreads(oneMethodInfo
103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      #ifndef _7ZIP_ST
104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      , numThreads
105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      #endif
106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      );
107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMethodFull methodFull;
109cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo));
110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    methodMode.Methods.Add(methodFull);
111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
112cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (methodFull.Id != k_Copy)
113cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      needSolid = true;
114cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
115cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (_numSolidBytesDefined)
116cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      continue;
117cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
118cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt32 dicSize;
119cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    switch (methodFull.Id)
120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
121cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      case k_LZMA:
122cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      case k_LZMA2: dicSize = oneMethodInfo.Get_Lzma_DicSize(); break;
123cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      case k_PPMD: dicSize = oneMethodInfo.Get_Ppmd_MemSize(); break;
124cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      case k_Deflate: dicSize = (UInt32)1 << 15; break;
125cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      case k_BZip2: dicSize = oneMethodInfo.Get_BZip2_BlockSize(); break;
126cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      default: continue;
127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
128cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    _numSolidBytes = (UInt64)dicSize << 7;
129cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (_numSolidBytes < kSolidBytes_Min) _numSolidBytes = kSolidBytes_Min;
130cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (_numSolidBytes > kSolidBytes_Max) _numSolidBytes = kSolidBytes_Max;
131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _numSolidBytesDefined = true;
132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
133cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
134cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!_numSolidBytesDefined)
135cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (needSolid)
136cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      _numSolidBytes = kSolidBytes_Max;
137cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    else
138cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      _numSolidBytes = 0;
139cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  _numSolidBytesDefined = true;
140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
143cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, PROPID propID, UInt64 &ft, bool &ftDefined)
144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
145cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  // ft = 0;
146cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  // ftDefined = false;
147baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NCOM::CPropVariant prop;
148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(updateCallback->GetProperty(index, propID, &prop));
149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (prop.vt == VT_FILETIME)
150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ft = prop.filetime.dwLowDateTime | ((UInt64)prop.filetime.dwHighDateTime << 32);
152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ftDefined = true;
153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
154baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else if (prop.vt != VT_EMPTY)
155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return E_INVALIDARG;
156cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  else
157cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
158cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    ft = 0;
159cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    ftDefined = false;
160cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
163baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
164cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky/*
165cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
166cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#ifdef _WIN32
167cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic const wchar_t kDirDelimiter1 = L'\\';
168cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#endif
169cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic const wchar_t kDirDelimiter2 = L'/';
170cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
171cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic inline bool IsCharDirLimiter(wchar_t c)
172cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
173cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return (
174cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    #ifdef _WIN32
175cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    c == kDirDelimiter1 ||
176cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    #endif
177cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    c == kDirDelimiter2);
178cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
179cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
180cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic int FillSortIndex(CObjectVector<CTreeFolder> &treeFolders, int cur, int curSortIndex)
181cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
182cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CTreeFolder &tf = treeFolders[cur];
183cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  tf.SortIndex = curSortIndex++;
184cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (int i = 0; i < tf.SubFolders.Size(); i++)
185cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    curSortIndex = FillSortIndex(treeFolders, tf.SubFolders[i], curSortIndex);
186cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  tf.SortIndexEnd = curSortIndex;
187cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return curSortIndex;
188cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
189cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
190cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic int FindSubFolder(const CObjectVector<CTreeFolder> &treeFolders, int cur, const UString &name, int &insertPos)
191cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
192cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  const CIntVector &subFolders = treeFolders[cur].SubFolders;
193cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  int left = 0, right = subFolders.Size();
194cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  insertPos = -1;
195cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (;;)
196cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
197cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (left == right)
198cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
199cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      insertPos = left;
200cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return -1;
201cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
202cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    int mid = (left + right) / 2;
203cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    int midFolder = subFolders[mid];
204cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    int compare = CompareFileNames(name, treeFolders[midFolder].Name);
205cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (compare == 0)
206cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return midFolder;
207cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (compare < 0)
208cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      right = mid;
209cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    else
210cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      left = mid + 1;
211cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
212cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
213cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
214cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic int AddFolder(CObjectVector<CTreeFolder> &treeFolders, int cur, const UString &name)
215cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
216cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  int insertPos;
217cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  int folderIndex = FindSubFolder(treeFolders, cur, name, insertPos);
218cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (folderIndex < 0)
219cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
220cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    folderIndex = treeFolders.Size();
221cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CTreeFolder &newFolder = treeFolders.AddNew();
222cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    newFolder.Parent = cur;
223cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    newFolder.Name = name;
224cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    treeFolders[cur].SubFolders.Insert(insertPos, folderIndex);
225cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
226cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  // else if (treeFolders[folderIndex].IsAltStreamFolder != isAltStreamFolder) throw 1123234234;
227cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return folderIndex;
228cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
229cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky*/
230cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
231baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    IArchiveUpdateCallback *updateCallback)
233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_BEGIN
235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
236cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  const CDbEx *db = 0;
237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef _7Z_VOL
238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_volumes.Size() > 1)
239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return E_FAIL;
240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  const CVolume *volume = 0;
241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_volumes.Size() == 1)
242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
243baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    volume = &_volumes.Front();
244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    db = &volume->Database;
245baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #else
247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_inStream != 0)
248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    db = &_db;
249baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
251cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  /*
252cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CMyComPtr<IArchiveGetRawProps> getRawProps;
253cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  updateCallback->QueryInterface(IID_IArchiveGetRawProps, (void **)&getRawProps);
254cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
255cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CUniqBlocks secureBlocks;
256cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  secureBlocks.AddUniq(NULL, 0);
257cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
258cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CObjectVector<CTreeFolder> treeFolders;
259cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
260cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CTreeFolder folder;
261cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    folder.Parent = -1;
262cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    treeFolders.Add(folder);
263cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
264cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  */
265cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
266baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CObjectVector<CUpdateItem> updateItems;
267cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
268cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool need_CTime = (Write_CTime.Def && Write_CTime.Val);
269cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool need_ATime = (Write_ATime.Def && Write_ATime.Val);
270cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool need_MTime = (Write_MTime.Def && Write_MTime.Val || !Write_MTime.Def);
271cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (db)
272cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
273cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!Write_CTime.Def) need_CTime = !db->CTime.Defs.IsEmpty();
274cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!Write_ATime.Def) need_ATime = !db->ATime.Defs.IsEmpty();
275cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!Write_MTime.Def) need_MTime = !db->MTime.Defs.IsEmpty();
276cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
277cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
278cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UString s;
279cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
280baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (UInt32 i = 0; i < numItems; i++)
281baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
282baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Int32 newData, newProps;
283baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 indexInArchive;
284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (!updateCallback)
285baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return E_FAIL;
286baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(updateCallback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive));
287baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CUpdateItem ui;
288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ui.NewProps = IntToBool(newProps);
289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ui.NewData = IntToBool(newData);
290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ui.IndexInArchive = indexInArchive;
291baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ui.IndexInClient = i;
292baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ui.IsAnti = false;
293baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ui.Size = 0;
294baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
295cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UString name;
296cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    // bool isAltStream = false;
297baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (ui.IndexInArchive != -1)
298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
299cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (db == 0 || (unsigned)ui.IndexInArchive >= db->Files.Size())
300baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return E_INVALIDARG;
301baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      const CFileItem &fi = db->Files[ui.IndexInArchive];
302cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (!ui.NewProps)
303cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
304cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        _db.GetPath(ui.IndexInArchive, name);
305cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
306baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      ui.IsDir = fi.IsDir;
307baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      ui.Size = fi.Size;
308cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      // isAltStream = fi.IsAltStream;
309baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      ui.IsAnti = db->IsItemAnti(ui.IndexInArchive);
310baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
311cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (!ui.NewProps)
312cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
313cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        ui.CTimeDefined = db->CTime.GetItem(ui.IndexInArchive, ui.CTime);
314cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        ui.ATimeDefined = db->ATime.GetItem(ui.IndexInArchive, ui.ATime);
315cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        ui.MTimeDefined = db->MTime.GetItem(ui.IndexInArchive, ui.MTime);
316cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
318baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
319baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (ui.NewProps)
320baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
321baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      bool folderStatusIsDefined;
322baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        NCOM::CPropVariant prop;
324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(updateCallback->GetProperty(i, kpidAttrib, &prop));
325baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (prop.vt == VT_EMPTY)
326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          ui.AttribDefined = false;
327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        else if (prop.vt != VT_UI4)
328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          return E_INVALIDARG;
329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        else
330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
331baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          ui.Attrib = prop.ulVal;
332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          ui.AttribDefined = true;
333baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
335baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      // we need MTime to sort files.
337cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (need_CTime) RINOK(GetTime(updateCallback, i, kpidCTime, ui.CTime, ui.CTimeDefined));
338cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (need_ATime) RINOK(GetTime(updateCallback, i, kpidATime, ui.ATime, ui.ATimeDefined));
339cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (need_MTime) RINOK(GetTime(updateCallback, i, kpidMTime, ui.MTime, ui.MTimeDefined));
340cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
341cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      /*
342cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (getRawProps)
343cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
344cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        const void *data;
345cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        UInt32 dataSize;
346cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        UInt32 propType;
347cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
348cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        getRawProps->GetRawProp(i, kpidNtSecure, &data, &dataSize, &propType);
349cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (dataSize != 0 && propType != NPropDataType::kRaw)
350cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          return E_FAIL;
351cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        ui.SecureIndex = secureBlocks.AddUniq((const Byte *)data, dataSize);
352cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
353cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      */
354baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
355baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
356baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        NCOM::CPropVariant prop;
357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(updateCallback->GetProperty(i, kpidPath, &prop));
358baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (prop.vt == VT_EMPTY)
359cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        {
360cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        }
361baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        else if (prop.vt != VT_BSTR)
362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          return E_INVALIDARG;
363baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        else
364baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
365cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          name = NItemName::MakeLegalName(prop.bstrVal);
366baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
367baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
369baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        NCOM::CPropVariant prop;
370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(updateCallback->GetProperty(i, kpidIsDir, &prop));
371baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (prop.vt == VT_EMPTY)
372baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          folderStatusIsDefined = false;
373baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        else if (prop.vt != VT_BOOL)
374baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          return E_INVALIDARG;
375baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        else
376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
377baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          ui.IsDir = (prop.boolVal != VARIANT_FALSE);
378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          folderStatusIsDefined = true;
379baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
380baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
381baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
382baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
383baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        NCOM::CPropVariant prop;
384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(updateCallback->GetProperty(i, kpidIsAnti, &prop));
385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (prop.vt == VT_EMPTY)
386baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          ui.IsAnti = false;
387baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        else if (prop.vt != VT_BOOL)
388baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          return E_INVALIDARG;
389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        else
390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          ui.IsAnti = (prop.boolVal != VARIANT_FALSE);
391baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
393cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      /*
394cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
395cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        NCOM::CPropVariant prop;
396cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        RINOK(updateCallback->GetProperty(i, kpidIsAltStream, &prop));
397cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (prop.vt == VT_EMPTY)
398cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          isAltStream = false;
399cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        else if (prop.vt != VT_BOOL)
400cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          return E_INVALIDARG;
401cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        else
402cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          isAltStream = (prop.boolVal != VARIANT_FALSE);
403cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
404cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      */
405cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
406baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (ui.IsAnti)
407baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
408baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        ui.AttribDefined = false;
409baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
410baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        ui.CTimeDefined = false;
411baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        ui.ATimeDefined = false;
412baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        ui.MTimeDefined = false;
413baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
414baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        ui.Size = 0;
415baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
416baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
417baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (!folderStatusIsDefined && ui.AttribDefined)
418baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        ui.SetDirStatusFromAttrib();
419baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
420cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    else
421cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
422cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      /*
423cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (_db.SecureIDs.IsEmpty())
424cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        ui.SecureIndex = secureBlocks.AddUniq(NULL, 0);
425cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      else
426cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
427cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        int id = _db.SecureIDs[ui.IndexInArchive];
428cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        size_t offs = _db.SecureOffsets[id];
429cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        size_t size = _db.SecureOffsets[id + 1] - offs;
430cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        ui.SecureIndex = secureBlocks.AddUniq(_db.SecureBuf + offs, size);
431cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
432cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      */
433cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
434cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
435cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    /*
436cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
437cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      int folderIndex = 0;
438cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (_useParents)
439cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
440cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        int j;
441cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        s.Empty();
442cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        for (j = 0; j < name.Len(); j++)
443cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        {
444cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          wchar_t c = name[j];
445cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          if (IsCharDirLimiter(c))
446cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          {
447cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            folderIndex = AddFolder(treeFolders, folderIndex, s);
448cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            s.Empty();
449cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            continue;
450cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          }
451cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          s += c;
452cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        }
453cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (isAltStream)
454cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        {
455cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          int colonPos = s.Find(':');
456cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          if (colonPos < 0)
457cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          {
458cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            // isAltStream = false;
459cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            return E_INVALIDARG;
460cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          }
461cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          UString mainName = s.Left(colonPos);
462cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          int newFolderIndex = AddFolder(treeFolders, folderIndex, mainName);
463cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          if (treeFolders[newFolderIndex].UpdateItemIndex < 0)
464cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          {
465cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            for (int j = updateItems.Size() - 1; j >= 0; j--)
466cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            {
467cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky              CUpdateItem &ui2 = updateItems[j];
468cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky              if (ui2.ParentFolderIndex == folderIndex
469cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky                  && ui2.Name == mainName)
470cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky              {
471cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky                ui2.TreeFolderIndex = newFolderIndex;
472cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky                treeFolders[newFolderIndex].UpdateItemIndex = j;
473cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky              }
474cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            }
475cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          }
476cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          folderIndex = newFolderIndex;
477cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          s.Delete(0, colonPos + 1);
478cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        }
479cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        ui.Name = s;
480cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
481cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      else
482cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        ui.Name = name;
483cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      ui.IsAltStream = isAltStream;
484cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      ui.ParentFolderIndex = folderIndex;
485cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      ui.TreeFolderIndex = -1;
486cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (ui.IsDir && !s.IsEmpty())
487cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
488cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        ui.TreeFolderIndex = AddFolder(treeFolders, folderIndex, s);
489cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        treeFolders[ui.TreeFolderIndex].UpdateItemIndex = updateItems.Size();
490cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
491cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
492cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    */
493cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    ui.Name = name;
494baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
495baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (ui.NewData)
496baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
497baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      NCOM::CPropVariant prop;
498baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(updateCallback->GetProperty(i, kpidSize, &prop));
499baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (prop.vt != VT_UI8)
500baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return E_INVALIDARG;
501baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      ui.Size = (UInt64)prop.uhVal.QuadPart;
502baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (ui.Size != 0 && ui.IsAnti)
503baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return E_INVALIDARG;
504baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
505baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    updateItems.Add(ui);
506baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
507baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
508cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  /*
509cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  FillSortIndex(treeFolders, 0, 0);
510cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (i = 0; i < (UInt32)updateItems.Size(); i++)
511cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
512cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CUpdateItem &ui = updateItems[i];
513cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    ui.ParentSortIndex = treeFolders[ui.ParentFolderIndex].SortIndex;
514cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    ui.ParentSortIndexEnd = treeFolders[ui.ParentFolderIndex].SortIndexEnd;
515cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
516cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  */
517cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
518baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CCompressionMethodMode methodMode, headerMethod;
519cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
520cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  HRESULT res = SetMainMethod(methodMode, _methods
521cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    #ifndef _7ZIP_ST
522cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    , _numThreads
523cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    #endif
524cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    );
525cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  RINOK(res);
526cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  methodMode.Binds = _binds;
527cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
528cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  RINOK(SetHeaderMethod(headerMethod));
529baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifndef _7ZIP_ST
530baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  methodMode.NumThreads = _numThreads;
531baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  headerMethod.NumThreads = 1;
532baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
533baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
534baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CMyComPtr<ICryptoGetTextPassword2> getPassword2;
535baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  updateCallback->QueryInterface(IID_ICryptoGetTextPassword2, (void **)&getPassword2);
536baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
537cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  methodMode.PasswordIsDefined = false;
538cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  methodMode.Password.Empty();
539baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (getPassword2)
540baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
541baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComBSTR password;
542baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Int32 passwordIsDefined;
543baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(getPassword2->CryptoGetTextPassword2(&passwordIsDefined, &password));
544baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    methodMode.PasswordIsDefined = IntToBool(passwordIsDefined);
545cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (methodMode.PasswordIsDefined && (BSTR)password)
546baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      methodMode.Password = password;
547baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
548baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
549baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  bool compressMainHeader = _compressHeaders;  // check it
550baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
551baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  bool encryptHeaders = false;
552baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
553baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (methodMode.PasswordIsDefined)
554baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
555baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (_encryptHeadersSpecified)
556baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      encryptHeaders = _encryptHeaders;
557baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #ifndef _NO_CRYPTO
558baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    else
559baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      encryptHeaders = _passwordIsDefined;
560baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #endif
561baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    compressMainHeader = true;
562baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (encryptHeaders)
563baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
564baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      headerMethod.PasswordIsDefined = methodMode.PasswordIsDefined;
565baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      headerMethod.Password = methodMode.Password;
566baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
567baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
568baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
569baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (numItems < 2)
570baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    compressMainHeader = false;
571baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
572baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CUpdateOptions options;
573baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  options.Method = &methodMode;
574baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : 0;
575cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  int level = GetLevel();
576cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  options.UseFilters = level != 0 && _autoFilter;
577cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  options.MaxFilter = level >= 8;
578baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
579baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  options.HeaderOptions.CompressMainHeader = compressMainHeader;
580cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  /*
581cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  options.HeaderOptions.WriteCTime = Write_CTime;
582cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  options.HeaderOptions.WriteATime = Write_ATime;
583cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  options.HeaderOptions.WriteMTime = Write_MTime;
584cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  */
585baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
586baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  options.NumSolidFiles = _numSolidFiles;
587baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  options.NumSolidBytes = _numSolidBytes;
588baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  options.SolidExtension = _solidExtension;
589baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  options.RemoveSfxBlock = _removeSfxBlock;
590baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  options.VolumeMode = _volumeMode;
591baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
592baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COutArchive archive;
593cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CArchiveDatabaseOut newDatabase;
594baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
595baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CMyComPtr<ICryptoGetTextPassword> getPassword;
596baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  updateCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getPassword);
597baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
598cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  /*
599cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (secureBlocks.Sorted.Size() > 1)
600cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
601cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    secureBlocks.GetReverseMap();
602cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (int i = 0; i < updateItems.Size(); i++)
603cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
604cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      int &secureIndex = updateItems[i].SecureIndex;
605cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      secureIndex = secureBlocks.BufIndexToSortedIndex[secureIndex];
606cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
607cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
608cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  */
609cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
610cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  res = Update(
611baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      EXTERNAL_CODECS_VARS
612baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      #ifdef _7Z_VOL
613baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      volume ? volume->Stream: 0,
614baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      volume ? db : 0,
615baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      #else
616baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _inStream,
617baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      db,
618baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      #endif
619baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      updateItems,
620cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      // treeFolders,
621cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      // secureBlocks,
622baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      archive, newDatabase, outStream, updateCallback, options
623baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      #ifndef _NO_CRYPTO
624baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      , getPassword
625baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      #endif
626baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      );
627baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
628baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(res);
629baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
630baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  updateItems.ClearAndFree();
631baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
632baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return archive.WriteDatabase(EXTERNAL_CODECS_VARS
633baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      newDatabase, options.HeaderMethod, options.HeaderOptions);
634baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
635baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_END
636baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
637baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
638baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream)
639baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
640baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  stream = 0;
641baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int index = ParseStringToUInt32(srcString, coder);
642baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (index == 0)
643baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return E_INVALIDARG;
644baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  srcString.Delete(0, index);
645cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (srcString[0] == 's')
646baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
647baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    srcString.Delete(0);
648baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    int index = ParseStringToUInt32(srcString, stream);
649baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (index == 0)
650baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return E_INVALIDARG;
651baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    srcString.Delete(0, index);
652baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
653baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
654baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
655baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
656cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid COutHandler::InitProps()
657baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
658cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CMultiMethodProps::Init();
659cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
660cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  _removeSfxBlock = false;
661cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  _compressHeaders = true;
662cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  _encryptHeadersSpecified = false;
663cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  _encryptHeaders = false;
664cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  // _useParents = false;
665cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
666cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  Write_CTime.Init();
667cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  Write_ATime.Init();
668cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  Write_MTime.Init();
669cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
670cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  _volumeMode = false;
671cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  InitSolid();
672cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
673cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
674cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyHRESULT COutHandler::SetSolidFromString(const UString &s)
675cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
676cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UString s2 = s;
677cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  s2.MakeLower_Ascii();
678cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (unsigned i = 0; i < s2.Len();)
679cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
680cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const wchar_t *start = ((const wchar_t *)s2) + i;
681cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const wchar_t *end;
682cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt64 v = ConvertStringToUInt64(start, &end);
683cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (start == end)
684cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
685cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (s2[i++] != 'e')
686cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        return E_INVALIDARG;
687cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      _solidExtension = true;
688cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      continue;
689cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
690cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    i += (int)(end - start);
691cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (i == s2.Len())
692cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return E_INVALIDARG;
693cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    wchar_t c = s2[i++];
694cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (c == 'f')
695cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
696cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (v < 1)
697cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        v = 1;
698cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      _numSolidFiles = v;
699cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
700cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    else
701cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
702cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      unsigned numBits;
703cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      switch (c)
704cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
705cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        case 'b': numBits =  0; break;
706cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        case 'k': numBits = 10; break;
707cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        case 'm': numBits = 20; break;
708cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        case 'g': numBits = 30; break;
709cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        case 't': numBits = 40; break;
710cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        default: return E_INVALIDARG;
711cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
712cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      _numSolidBytes = (v << numBits);
713cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      _numSolidBytesDefined = true;
714cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
715cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
716cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return S_OK;
717cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
718cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
719cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyHRESULT COutHandler::SetSolidFromPROPVARIANT(const PROPVARIANT &value)
720cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
721cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool isSolid;
722cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  switch (value.vt)
723cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
724cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    case VT_EMPTY: isSolid = true; break;
725cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    case VT_BOOL: isSolid = (value.boolVal != VARIANT_FALSE); break;
726cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    case VT_BSTR:
727cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (StringToBool(value.bstrVal, isSolid))
728cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        break;
729cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return SetSolidFromString(value.bstrVal);
730cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    default: return E_INVALIDARG;
731cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
732cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (isSolid)
733cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    InitSolid();
734cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  else
735cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    _numSolidFiles = 1;
736cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return S_OK;
737cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
738cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
739cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic HRESULT PROPVARIANT_to_BoolPair(const PROPVARIANT &prop, CBoolPair &dest)
740cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
741cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  RINOK(PROPVARIANT_to_bool(prop, dest.Val));
742cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  dest.Def = true;
743baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
744baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
745baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
746cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyHRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
747cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
748cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UString name = nameSpec;
749cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  name.MakeLower_Ascii();
750cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (name.IsEmpty())
751cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return E_INVALIDARG;
752cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
753cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (name[0] == L's')
754cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
755cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    name.Delete(0);
756cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (name.IsEmpty())
757cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return SetSolidFromPROPVARIANT(value);
758cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (value.vt != VT_EMPTY)
759cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return E_INVALIDARG;
760cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return SetSolidFromString(name);
761cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
762cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
763cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 number;
764cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  int index = ParseStringToUInt32(name, number);
765cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UString realName = name.Ptr(index);
766cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (index == 0)
767cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
768cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (name.IsEqualTo("rsfx")) return PROPVARIANT_to_bool(value, _removeSfxBlock);
769cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (name.IsEqualTo("hc")) return PROPVARIANT_to_bool(value, _compressHeaders);
770cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    // if (name.IsEqualToNoCase(L"HS")) return PROPVARIANT_to_bool(value, _useParents);
771cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
772cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (name.IsEqualTo("hcf"))
773cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
774cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      bool compressHeadersFull = true;
775cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(PROPVARIANT_to_bool(value, compressHeadersFull));
776cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return compressHeadersFull ? S_OK: E_INVALIDARG;
777cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
778cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
779cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (name.IsEqualTo("he"))
780cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
781cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(PROPVARIANT_to_bool(value, _encryptHeaders));
782cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      _encryptHeadersSpecified = true;
783cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return S_OK;
784cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
785cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
786cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (name.IsEqualTo("tc")) return PROPVARIANT_to_BoolPair(value, Write_CTime);
787cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (name.IsEqualTo("ta")) return PROPVARIANT_to_BoolPair(value, Write_ATime);
788cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (name.IsEqualTo("tm")) return PROPVARIANT_to_BoolPair(value, Write_MTime);
789cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
790cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (name.IsEqualTo("v"))  return PROPVARIANT_to_bool(value, _volumeMode);
791cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
792cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return CMultiMethodProps::SetProperty(name, value);
793cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
794cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
795cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckySTDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, UInt32 numProps)
796baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
797baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_BEGIN
798baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _binds.Clear();
799cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  InitProps();
800baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
801cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (UInt32 i = 0; i < numProps; i++)
802baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
803baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UString name = names[i];
804cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    name.MakeLower_Ascii();
805baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (name.IsEmpty())
806baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return E_INVALIDARG;
807baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
808baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const PROPVARIANT &value = values[i];
809baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
810cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (name[0] == 'b')
811baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
812cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (value.vt != VT_EMPTY)
813cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        return E_INVALIDARG;
814baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      name.Delete(0);
815baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CBind bind;
816cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(GetBindInfoPart(name, bind.OutCoder, bind.OutStream));
817cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (name[0] != ':')
818cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        return E_INVALIDARG;
819cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      name.Delete(0);
820cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      RINOK(GetBindInfoPart(name, bind.InCoder, bind.InStream));
821cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (!name.IsEmpty())
822cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        return E_INVALIDARG;
823baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _binds.Add(bind);
824baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      continue;
825baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
826baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
827baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SetProperty(name, value));
828baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
829baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
830cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  unsigned numEmptyMethods = GetNumEmptyMethods();
831cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (numEmptyMethods > 0)
832cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
833cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    unsigned k;
834cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (k = 0; k < _binds.Size(); k++)
835cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
836cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      const CBind &bind = _binds[k];
837cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (bind.InCoder < (UInt32)numEmptyMethods ||
838cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          bind.OutCoder < (UInt32)numEmptyMethods)
839cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        return E_INVALIDARG;
840cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
841cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (k = 0; k < _binds.Size(); k++)
842cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
843cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      CBind &bind = _binds[k];
844cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      bind.InCoder -= (UInt32)numEmptyMethods;
845cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      bind.OutCoder -= (UInt32)numEmptyMethods;
846cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
847cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    _methods.DeleteFrontal(numEmptyMethods);
848cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
849cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
850cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  AddDefaultMethod();
851cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
852cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!_filterMethod.MethodName.IsEmpty())
853cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
854cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    FOR_VECTOR (k, _binds)
855cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
856cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      CBind &bind = _binds[k];
857cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      bind.InCoder++;
858cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      bind.OutCoder++;
859cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
860cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    _methods.Insert(0, _filterMethod);
861cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
862cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
863cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  FOR_VECTOR (k, _binds)
864cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
865cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const CBind &bind = _binds[k];
866cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (bind.InCoder >= (UInt32)_methods.Size() ||
867cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        bind.OutCoder >= (UInt32)_methods.Size())
868cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return E_INVALIDARG;
869cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
870cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
871baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
872baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COM_TRY_END
873baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
874baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
875baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}}
876