• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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