UpdateCallback.cpp revision baa3858d3f5d128a5c8466b700098109edcad5f2
1// UpdateCallback.cpp
2
3#include "StdAfx.h"
4
5#include "Common/ComTry.h"
6#include "Common/Defs.h"
7#include "Common/IntToString.h"
8#include "Common/StringConvert.h"
9
10#include "Windows/PropVariant.h"
11
12#include "../../Common/FileStreams.h"
13
14#include "UpdateCallback.h"
15
16using namespace NWindows;
17
18CArchiveUpdateCallback::CArchiveUpdateCallback():
19  Callback(0),
20  ShareForWrite(false),
21  StdInMode(false),
22  DirItems(0),
23  ArcItems(0),
24  UpdatePairs(0),
25  NewNames(0)
26  {}
27
28
29STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size)
30{
31  COM_TRY_BEGIN
32  return Callback->SetTotal(size);
33  COM_TRY_END
34}
35
36STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue)
37{
38  COM_TRY_BEGIN
39  return Callback->SetCompleted(completeValue);
40  COM_TRY_END
41}
42
43STDMETHODIMP CArchiveUpdateCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
44{
45  COM_TRY_BEGIN
46  return Callback->SetRatioInfo(inSize, outSize);
47  COM_TRY_END
48}
49
50
51/*
52STATPROPSTG kProperties[] =
53{
54  { NULL, kpidPath, VT_BSTR},
55  { NULL, kpidIsDir, VT_BOOL},
56  { NULL, kpidSize, VT_UI8},
57  { NULL, kpidCTime, VT_FILETIME},
58  { NULL, kpidATime, VT_FILETIME},
59  { NULL, kpidMTime, VT_FILETIME},
60  { NULL, kpidAttrib, VT_UI4},
61  { NULL, kpidIsAnti, VT_BOOL}
62};
63
64STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **)
65{
66  return CStatPropEnumerator::CreateEnumerator(kProperties, sizeof(kProperties) / sizeof(kProperties[0]), enumerator);
67}
68*/
69
70STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index,
71      Int32 *newData, Int32 *newProps, UInt32 *indexInArchive)
72{
73  COM_TRY_BEGIN
74  RINOK(Callback->CheckBreak());
75  const CUpdatePair2 &up = (*UpdatePairs)[index];
76  if (newData != NULL) *newData = BoolToInt(up.NewData);
77  if (newProps != NULL) *newProps = BoolToInt(up.NewProps);
78  if (indexInArchive != NULL)
79  {
80    *indexInArchive = (UInt32)-1;
81    if (up.ExistInArchive())
82      *indexInArchive = (ArcItems == 0) ? up.ArcIndex : (*ArcItems)[up.ArcIndex].IndexInServer;
83  }
84  return S_OK;
85  COM_TRY_END
86}
87
88STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
89{
90  COM_TRY_BEGIN
91  const CUpdatePair2 &up = (*UpdatePairs)[index];
92  NWindows::NCOM::CPropVariant prop;
93
94  if (propID == kpidIsAnti)
95  {
96    prop = up.IsAnti;
97    prop.Detach(value);
98    return S_OK;
99  }
100
101  if (up.IsAnti)
102  {
103    switch(propID)
104    {
105      case kpidIsDir:
106      case kpidPath:
107        break;
108      case kpidSize:
109        prop = (UInt64)0;
110        prop.Detach(value);
111        return S_OK;
112      default:
113        prop.Detach(value);
114        return S_OK;
115    }
116  }
117
118  if (up.ExistOnDisk())
119  {
120    const CDirItem &di = DirItems->Items[up.DirIndex];
121    switch(propID)
122    {
123      case kpidPath:  prop = DirItems->GetLogPath(up.DirIndex); break;
124      case kpidIsDir:  prop = di.IsDir(); break;
125      case kpidSize:  prop = di.Size; break;
126      case kpidAttrib:  prop = di.Attrib; break;
127      case kpidCTime:  prop = di.CTime; break;
128      case kpidATime:  prop = di.ATime; break;
129      case kpidMTime:  prop = di.MTime; break;
130    }
131  }
132  else
133  {
134    if (propID == kpidPath)
135    {
136      if (up.NewNameIndex >= 0)
137      {
138        prop = (*NewNames)[up.NewNameIndex];
139        prop.Detach(value);
140        return S_OK;
141      }
142    }
143    if (up.ExistInArchive() && Archive)
144    {
145      UInt32 indexInArchive;
146      if (ArcItems == 0)
147        indexInArchive = up.ArcIndex;
148      else
149        indexInArchive = (*ArcItems)[up.ArcIndex].IndexInServer;
150      return Archive->GetProperty(indexInArchive, propID, value);
151    }
152  }
153  prop.Detach(value);
154  return S_OK;
155  COM_TRY_END
156}
157
158STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)
159{
160  COM_TRY_BEGIN
161  const CUpdatePair2 &up = (*UpdatePairs)[index];
162  if (!up.NewData)
163    return E_FAIL;
164
165  RINOK(Callback->CheckBreak());
166  RINOK(Callback->Finilize());
167
168  if (up.IsAnti)
169  {
170    return Callback->GetStream((*ArcItems)[up.ArcIndex].Name, true);
171  }
172  const CDirItem &di = DirItems->Items[up.DirIndex];
173  RINOK(Callback->GetStream(DirItems->GetLogPath(up.DirIndex), false));
174
175  if (di.IsDir())
176    return S_OK;
177
178  if (StdInMode)
179  {
180    CStdInFileStream *inStreamSpec = new CStdInFileStream;
181    CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
182    *inStream = inStreamLoc.Detach();
183  }
184  else
185  {
186    CInFileStream *inStreamSpec = new CInFileStream;
187    CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
188    const UString path = DirItems->GetPhyPath(up.DirIndex);
189    if (!inStreamSpec->OpenShared(path, ShareForWrite))
190    {
191      return Callback->OpenFileError(path, ::GetLastError());
192    }
193    *inStream = inStreamLoc.Detach();
194  }
195  return S_OK;
196  COM_TRY_END
197}
198
199STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 operationResult)
200{
201  COM_TRY_BEGIN
202  return Callback->SetOperationResult(operationResult);
203  COM_TRY_END
204}
205
206STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)
207{
208  if (VolumesSizes.Size() == 0)
209    return S_FALSE;
210  if (index >= (UInt32)VolumesSizes.Size())
211    index = VolumesSizes.Size() - 1;
212  *size = VolumesSizes[index];
213  return S_OK;
214}
215
216STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)
217{
218  COM_TRY_BEGIN
219  wchar_t temp[16];
220  ConvertUInt32ToString(index + 1, temp);
221  UString res = temp;
222  while (res.Length() < 2)
223    res = UString(L'0') + res;
224  UString fileName = VolName;
225  fileName += L'.';
226  fileName += res;
227  fileName += VolExt;
228  COutFileStream *streamSpec = new COutFileStream;
229  CMyComPtr<ISequentialOutStream> streamLoc(streamSpec);
230  if (!streamSpec->Create(fileName, false))
231    return ::GetLastError();
232  *volumeStream = streamLoc.Detach();
233  return S_OK;
234  COM_TRY_END
235}
236
237STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
238{
239  COM_TRY_BEGIN
240  return Callback->CryptoGetTextPassword2(passwordIsDefined, password);
241  COM_TRY_END
242}
243
244STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword(BSTR *password)
245{
246  COM_TRY_BEGIN
247  return Callback->CryptoGetTextPassword(password);
248  COM_TRY_END
249}
250