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 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 29 STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size) 30 { 31 COM_TRY_BEGIN 32 return Callback->SetTotal(size); 33 COM_TRY_END 34 } 35 36 STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue) 37 { 38 COM_TRY_BEGIN 39 return Callback->SetCompleted(completeValue); 40 COM_TRY_END 41 } 42 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 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 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 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 199 STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 operationResult) 200 { 201 COM_TRY_BEGIN 202 return Callback->SetOperationResult(operationResult); 203 COM_TRY_END 204 } 205 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 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 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 244 STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword(BSTR *password) 245 { 246 COM_TRY_BEGIN 247 return Callback->CryptoGetTextPassword(password); 248 COM_TRY_END 249 } 250