Home | History | Annotate | Download | only in Common
      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