Upload 2.0.2
[physicsfs] / lzma / CPP / 7zip / UI / Common / UpdateCallback.cpp
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 }