5 #include "UpdateCallback.h"
7 #include "Common/StringConvert.h"
8 #include "Common/IntToString.h"
9 #include "Common/Defs.h"
10 #include "Common/ComTry.h"
12 #include "Windows/PropVariant.h"
14 #include "../../Common/FileStreams.h"
16 using namespace NWindows;
18 CArchiveUpdateCallback::CArchiveUpdateCallback():
28 STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size)
31 return Callback->SetTotal(size);
35 STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue)
38 return Callback->SetCompleted(completeValue);
42 STDMETHODIMP CArchiveUpdateCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
45 return Callback->SetRatioInfo(inSize, outSize);
51 STATPROPSTG kProperties[] =
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}
64 STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **)
68 return CStatPropEnumerator::CreateEnumerator(kProperties,
69 sizeof(kProperties) / sizeof(kProperties[0]), enumerator);
73 STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index,
74 Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive)
77 RINOK(Callback->CheckBreak());
78 const CUpdatePair2 &updatePair = (*UpdatePairs)[index];
80 *newData = BoolToInt(updatePair.NewData);
81 if(newProperties != NULL)
82 *newProperties = BoolToInt(updatePair.NewProperties);
83 if(indexInArchive != NULL)
85 if (updatePair.ExistInArchive)
87 if (ArchiveItems == 0)
88 *indexInArchive = updatePair.ArchiveItemIndex;
90 *indexInArchive = (*ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer;
93 *indexInArchive = UInt32(-1);
99 STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
102 const CUpdatePair2 &updatePair = (*UpdatePairs)[index];
103 NWindows::NCOM::CPropVariant propVariant;
105 if (propID == kpidIsAnti)
107 propVariant = updatePair.IsAnti;
108 propVariant.Detach(value);
112 if (updatePair.IsAnti)
120 propVariant = (UInt64)0;
121 propVariant.Detach(value);
124 propVariant.Detach(value);
129 if(updatePair.ExistOnDisk)
131 const CDirItem &dirItem = (*DirItems)[updatePair.DirItemIndex];
135 propVariant = dirItem.Name;
138 propVariant = dirItem.IsDirectory();
141 propVariant = dirItem.Size;
144 propVariant = dirItem.Attributes;
146 case kpidLastAccessTime:
147 propVariant = dirItem.LastAccessTime;
149 case kpidCreationTime:
150 propVariant = dirItem.CreationTime;
152 case kpidLastWriteTime:
153 propVariant = dirItem.LastWriteTime;
159 if (propID == kpidPath)
161 if (updatePair.NewNameIsDefined)
163 propVariant = updatePair.NewName;
164 propVariant.Detach(value);
168 if (updatePair.ExistInArchive && Archive)
170 UInt32 indexInArchive;
171 if (ArchiveItems == 0)
172 indexInArchive = updatePair.ArchiveItemIndex;
174 indexInArchive = (*ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer;
175 return Archive->GetProperty(indexInArchive, propID, value);
178 propVariant.Detach(value);
183 STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)
186 const CUpdatePair2 &updatePair = (*UpdatePairs)[index];
187 if(!updatePair.NewData)
190 RINOK(Callback->CheckBreak());
191 RINOK(Callback->Finilize());
193 if(updatePair.IsAnti)
195 return Callback->GetStream((*ArchiveItems)[updatePair.ArchiveItemIndex].Name, true);
197 const CDirItem &dirItem = (*DirItems)[updatePair.DirItemIndex];
198 RINOK(Callback->GetStream(dirItem.Name, false));
200 if(dirItem.IsDirectory())
205 CStdInFileStream *inStreamSpec = new CStdInFileStream;
206 CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
207 *inStream = inStreamLoc.Detach();
211 CInFileStream *inStreamSpec = new CInFileStream;
212 CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
213 UString path = DirPrefix + dirItem.FullPath;
214 if(!inStreamSpec->OpenShared(path, ShareForWrite))
216 return Callback->OpenFileError(path, ::GetLastError());
218 *inStream = inStreamLoc.Detach();
224 STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 operationResult)
227 return Callback->SetOperationResult(operationResult);
231 STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)
233 if (VolumesSizes.Size() == 0)
235 if (index >= (UInt32)VolumesSizes.Size())
236 index = VolumesSizes.Size() - 1;
237 *size = VolumesSizes[index];
241 STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)
245 ConvertUInt64ToString(index + 1, temp);
247 while (res.Length() < 2)
248 res = UString(L'0') + res;
249 UString fileName = VolName;
253 COutFileStream *streamSpec = new COutFileStream;
254 CMyComPtr<ISequentialOutStream> streamLoc(streamSpec);
255 if(!streamSpec->Create(fileName, false))
256 return ::GetLastError();
257 *volumeStream = streamLoc.Detach();
262 STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
265 return Callback->CryptoGetTextPassword2(passwordIsDefined, password);