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