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