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
16 using namespace NWindows;
17
CArchiveUpdateCallback()18 CArchiveUpdateCallback::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
SetTotal(UInt64 size)29 STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size)
30 {
31 COM_TRY_BEGIN
32 return Callback->SetTotal(size);
33 COM_TRY_END
34 }
35
SetCompleted(const UInt64 * completeValue)36 STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue)
37 {
38 COM_TRY_BEGIN
39 return Callback->SetCompleted(completeValue);
40 COM_TRY_END
41 }
42
SetRatioInfo(const UInt64 * inSize,const UInt64 * outSize)43 STDMETHODIMP 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 /*
52 STATPROPSTG 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
64 STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **)
65 {
66 return CStatPropEnumerator::CreateEnumerator(kProperties, sizeof(kProperties) / sizeof(kProperties[0]), enumerator);
67 }
68 */
69
GetUpdateItemInfo(UInt32 index,Int32 * newData,Int32 * newProps,UInt32 * indexInArchive)70 STDMETHODIMP 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
GetProperty(UInt32 index,PROPID propID,PROPVARIANT * value)88 STDMETHODIMP 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
GetStream(UInt32 index,ISequentialInStream ** inStream)158 STDMETHODIMP 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
SetOperationResult(Int32 operationResult)199 STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 operationResult)
200 {
201 COM_TRY_BEGIN
202 return Callback->SetOperationResult(operationResult);
203 COM_TRY_END
204 }
205
GetVolumeSize(UInt32 index,UInt64 * size)206 STDMETHODIMP 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
GetVolumeStream(UInt32 index,ISequentialOutStream ** volumeStream)216 STDMETHODIMP 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
CryptoGetTextPassword2(Int32 * passwordIsDefined,BSTR * password)237 STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
238 {
239 COM_TRY_BEGIN
240 return Callback->CryptoGetTextPassword2(passwordIsDefined, password);
241 COM_TRY_END
242 }
243
CryptoGetTextPassword(BSTR * password)244 STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword(BSTR *password)
245 {
246 COM_TRY_BEGIN
247 return Callback->CryptoGetTextPassword(password);
248 COM_TRY_END
249 }
250