blob: 55c937402377eb109ea248866a27c121ef75ff48 [file] [log] [blame]
// UpdateCallback.cpp
#include "StdAfx.h"
#include "Common/ComTry.h"
#include "Common/Defs.h"
#include "Common/IntToString.h"
#include "Common/StringConvert.h"
#include "Windows/PropVariant.h"
#include "../../Common/FileStreams.h"
#include "UpdateCallback.h"
using namespace NWindows;
CArchiveUpdateCallback::CArchiveUpdateCallback():
Callback(0),
ShareForWrite(false),
StdInMode(false),
DirItems(0),
ArcItems(0),
UpdatePairs(0),
NewNames(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
}
STDMETHODIMP CArchiveUpdateCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
{
COM_TRY_BEGIN
return Callback->SetRatioInfo(inSize, outSize);
COM_TRY_END
}
/*
STATPROPSTG kProperties[] =
{
{ NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsDir, VT_BOOL},
{ NULL, kpidSize, VT_UI8},
{ NULL, kpidCTime, VT_FILETIME},
{ NULL, kpidATime, VT_FILETIME},
{ NULL, kpidMTime, VT_FILETIME},
{ NULL, kpidAttrib, VT_UI4},
{ NULL, kpidIsAnti, VT_BOOL}
};
STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **)
{
return CStatPropEnumerator::CreateEnumerator(kProperties, sizeof(kProperties) / sizeof(kProperties[0]), enumerator);
}
*/
STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index,
Int32 *newData, Int32 *newProps, UInt32 *indexInArchive)
{
COM_TRY_BEGIN
RINOK(Callback->CheckBreak());
const CUpdatePair2 &up = (*UpdatePairs)[index];
if (newData != NULL) *newData = BoolToInt(up.NewData);
if (newProps != NULL) *newProps = BoolToInt(up.NewProps);
if (indexInArchive != NULL)
{
*indexInArchive = (UInt32)-1;
if (up.ExistInArchive())
*indexInArchive = (ArcItems == 0) ? up.ArcIndex : (*ArcItems)[up.ArcIndex].IndexInServer;
}
return S_OK;
COM_TRY_END
}
STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
const CUpdatePair2 &up = (*UpdatePairs)[index];
NWindows::NCOM::CPropVariant prop;
if (propID == kpidIsAnti)
{
prop = up.IsAnti;
prop.Detach(value);
return S_OK;
}
if (up.IsAnti)
{
switch(propID)
{
case kpidIsDir:
case kpidPath:
break;
case kpidSize:
prop = (UInt64)0;
prop.Detach(value);
return S_OK;
default:
prop.Detach(value);
return S_OK;
}
}
if (up.ExistOnDisk())
{
const CDirItem &di = DirItems->Items[up.DirIndex];
switch(propID)
{
case kpidPath: prop = DirItems->GetLogPath(up.DirIndex); break;
case kpidIsDir: prop = di.IsDir(); break;
case kpidSize: prop = di.Size; break;
case kpidAttrib: prop = di.Attrib; break;
case kpidCTime: prop = di.CTime; break;
case kpidATime: prop = di.ATime; break;
case kpidMTime: prop = di.MTime; break;
}
}
else
{
if (propID == kpidPath)
{
if (up.NewNameIndex >= 0)
{
prop = (*NewNames)[up.NewNameIndex];
prop.Detach(value);
return S_OK;
}
}
if (up.ExistInArchive() && Archive)
{
UInt32 indexInArchive;
if (ArcItems == 0)
indexInArchive = up.ArcIndex;
else
indexInArchive = (*ArcItems)[up.ArcIndex].IndexInServer;
return Archive->GetProperty(indexInArchive, propID, value);
}
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)
{
COM_TRY_BEGIN
const CUpdatePair2 &up = (*UpdatePairs)[index];
if (!up.NewData)
return E_FAIL;
RINOK(Callback->CheckBreak());
RINOK(Callback->Finilize());
if (up.IsAnti)
{
return Callback->GetStream((*ArcItems)[up.ArcIndex].Name, true);
}
const CDirItem &di = DirItems->Items[up.DirIndex];
RINOK(Callback->GetStream(DirItems->GetLogPath(up.DirIndex), false));
if (di.IsDir())
return S_OK;
if (StdInMode)
{
CStdInFileStream *inStreamSpec = new CStdInFileStream;
CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
*inStream = inStreamLoc.Detach();
}
else
{
CInFileStream *inStreamSpec = new CInFileStream;
CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
const UString path = DirItems->GetPhyPath(up.DirIndex);
if (!inStreamSpec->OpenShared(path, ShareForWrite))
{
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[16];
ConvertUInt32ToString(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<ISequentialOutStream> 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
}
STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword(BSTR *password)
{
COM_TRY_BEGIN
return Callback->CryptoGetTextPassword(password);
COM_TRY_END
}