// UpdateCallback.cpp #include "StdAfx.h" #include "UpdateCallback.h" #include "Common/StringConvert.h" #include "Common/IntToString.h" #include "Common/Defs.h" #include "Common/ComTry.h" #include "Windows/PropVariant.h" #include "../../Common/FileStreams.h" using namespace NWindows; CArchiveUpdateCallback::CArchiveUpdateCallback(): Callback(0), StdInMode(false), DirItems(0), ArchiveItems(0), UpdatePairs(0) {} STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size) { COM_TRY_BEGIN return Callback->SetTotal(size); COM_TRY_END } STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue) { COM_TRY_BEGIN return Callback->SetCompleted(completeValue); COM_TRY_END } /* STATPROPSTG kProperties[] = { { NULL, kpidPath, VT_BSTR}, { NULL, kpidIsFolder, VT_BOOL}, { NULL, kpidSize, VT_UI8}, { NULL, kpidLastAccessTime, VT_FILETIME}, { NULL, kpidCreationTime, VT_FILETIME}, { NULL, kpidLastWriteTime, VT_FILETIME}, { NULL, kpidAttributes, VT_UI4}, { NULL, kpidIsAnti, VT_BOOL} }; */ STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **) { return E_NOTIMPL; /* return CStatPropEnumerator::CreateEnumerator(kProperties, sizeof(kProperties) / sizeof(kProperties[0]), enumerator); */ } STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index, Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive) { COM_TRY_BEGIN RINOK(Callback->CheckBreak()); const CUpdatePair2 &updatePair = (*UpdatePairs)[index]; if(newData != NULL) *newData = BoolToInt(updatePair.NewData); if(newProperties != NULL) *newProperties = BoolToInt(updatePair.NewProperties); if(indexInArchive != NULL) { if (updatePair.ExistInArchive) { if (ArchiveItems == 0) *indexInArchive = updatePair.ArchiveItemIndex; else *indexInArchive = (*ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer; } else *indexInArchive = UInt32(-1); } return S_OK; COM_TRY_END } STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN const CUpdatePair2 &updatePair = (*UpdatePairs)[index]; NWindows::NCOM::CPropVariant propVariant; if (propID == kpidIsAnti) { propVariant = updatePair.IsAnti; propVariant.Detach(value); return S_OK; } if (updatePair.IsAnti) { switch(propID) { case kpidIsFolder: case kpidPath: break; case kpidSize: propVariant = (UInt64)0; propVariant.Detach(value); return S_OK; default: propVariant.Detach(value); return S_OK; } } if(updatePair.ExistOnDisk) { const CDirItem &dirItem = (*DirItems)[updatePair.DirItemIndex]; switch(propID) { case kpidPath: propVariant = dirItem.Name; break; case kpidIsFolder: propVariant = dirItem.IsDirectory(); break; case kpidSize: propVariant = dirItem.Size; break; case kpidAttributes: propVariant = dirItem.Attributes; break; case kpidLastAccessTime: propVariant = dirItem.LastAccessTime; break; case kpidCreationTime: propVariant = dirItem.CreationTime; break; case kpidLastWriteTime: propVariant = dirItem.LastWriteTime; break; } } else { if (propID == kpidPath) { if (updatePair.NewNameIsDefined) { propVariant = updatePair.NewName; propVariant.Detach(value); return S_OK; } } if (updatePair.ExistInArchive && Archive) { UInt32 indexInArchive; if (ArchiveItems == 0) indexInArchive = updatePair.ArchiveItemIndex; else indexInArchive = (*ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer; return Archive->GetProperty(indexInArchive, propID, value); } } propVariant.Detach(value); return S_OK; COM_TRY_END } STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream) { COM_TRY_BEGIN const CUpdatePair2 &updatePair = (*UpdatePairs)[index]; if(!updatePair.NewData) return E_FAIL; RINOK(Callback->CheckBreak()); RINOK(Callback->Finilize()); if(updatePair.IsAnti) { return Callback->GetStream((*ArchiveItems)[updatePair.ArchiveItemIndex].Name, true); } const CDirItem &dirItem = (*DirItems)[updatePair.DirItemIndex]; RINOK(Callback->GetStream(dirItem.Name, false)); if(dirItem.IsDirectory()) return S_OK; if (StdInMode) { CStdInFileStream *inStreamSpec = new CStdInFileStream; CMyComPtr inStreamLoc(inStreamSpec); *inStream = inStreamLoc.Detach(); } else { CInFileStream *inStreamSpec = new CInFileStream; CMyComPtr inStreamLoc(inStreamSpec); UString path = DirPrefix + dirItem.FullPath; if(!inStreamSpec->Open(path)) { return Callback->OpenFileError(path, ::GetLastError()); } *inStream = inStreamLoc.Detach(); } return S_OK; COM_TRY_END } STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 operationResult) { COM_TRY_BEGIN return Callback->SetOperationResult(operationResult); COM_TRY_END } STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size) { if (VolumesSizes.Size() == 0) return S_FALSE; if (index >= (UInt32)VolumesSizes.Size()) index = VolumesSizes.Size() - 1; *size = VolumesSizes[index]; return S_OK; } STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream) { COM_TRY_BEGIN wchar_t temp[32]; ConvertUInt64ToString(index + 1, temp); UString res = temp; while (res.Length() < 2) res = UString(L'0') + res; UString fileName = VolName; fileName += L'.'; fileName += res; fileName += VolExt; COutFileStream *streamSpec = new COutFileStream; CMyComPtr streamLoc(streamSpec); if(!streamSpec->Create(fileName, false)) return ::GetLastError(); *volumeStream = streamLoc.Detach(); return S_OK; COM_TRY_END } STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) { COM_TRY_BEGIN return Callback->CryptoGetTextPassword2(passwordIsDefined, password); COM_TRY_END }