misc/libphysfs/lzma/CPP/7zip/UI/Common/UpdateCallback.cpp
changeset 13886 99b265e0d1d0
parent 13885 5f819b90d479
child 13887 b172a5d40eee
equal deleted inserted replaced
13885:5f819b90d479 13886:99b265e0d1d0
     1 // UpdateCallback.cpp
       
     2 
       
     3 #include "StdAfx.h"
       
     4 
       
     5 #include "UpdateCallback.h"
       
     6 
       
     7 #include "Common/StringConvert.h"
       
     8 #include "Common/IntToString.h"
       
     9 #include "Common/Defs.h"
       
    10 #include "Common/ComTry.h"
       
    11 
       
    12 #include "Windows/PropVariant.h"
       
    13 
       
    14 #include "../../Common/FileStreams.h"
       
    15 
       
    16 using namespace NWindows;
       
    17 
       
    18 CArchiveUpdateCallback::CArchiveUpdateCallback():
       
    19   Callback(0),
       
    20   ShareForWrite(false),
       
    21   StdInMode(false),
       
    22   DirItems(0),
       
    23   ArchiveItems(0),
       
    24   UpdatePairs(0)
       
    25   {}
       
    26 
       
    27 
       
    28 STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size)
       
    29 {
       
    30   COM_TRY_BEGIN
       
    31   return Callback->SetTotal(size);
       
    32   COM_TRY_END
       
    33 }
       
    34 
       
    35 STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue)
       
    36 {
       
    37   COM_TRY_BEGIN
       
    38   return Callback->SetCompleted(completeValue);
       
    39   COM_TRY_END
       
    40 }
       
    41 
       
    42 STDMETHODIMP CArchiveUpdateCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
       
    43 {
       
    44   COM_TRY_BEGIN
       
    45   return Callback->SetRatioInfo(inSize, outSize);
       
    46   COM_TRY_END
       
    47 }
       
    48 
       
    49 
       
    50 /*
       
    51 STATPROPSTG kProperties[] = 
       
    52 {
       
    53   { NULL, kpidPath, VT_BSTR},
       
    54   { NULL, kpidIsFolder, VT_BOOL},
       
    55   { NULL, kpidSize, VT_UI8},
       
    56   { NULL, kpidLastAccessTime, VT_FILETIME},
       
    57   { NULL, kpidCreationTime, VT_FILETIME},
       
    58   { NULL, kpidLastWriteTime, VT_FILETIME},
       
    59   { NULL, kpidAttributes, VT_UI4},
       
    60   { NULL, kpidIsAnti, VT_BOOL}
       
    61 };
       
    62 */
       
    63 
       
    64 STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **)
       
    65 {
       
    66   return E_NOTIMPL;
       
    67   /*
       
    68   return CStatPropEnumerator::CreateEnumerator(kProperties, 
       
    69       sizeof(kProperties) / sizeof(kProperties[0]), enumerator);
       
    70   */
       
    71 }
       
    72 
       
    73 STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index, 
       
    74       Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive)
       
    75 {
       
    76   COM_TRY_BEGIN
       
    77   RINOK(Callback->CheckBreak());
       
    78   const CUpdatePair2 &updatePair = (*UpdatePairs)[index];
       
    79   if(newData != NULL)
       
    80     *newData = BoolToInt(updatePair.NewData);
       
    81   if(newProperties != NULL)
       
    82     *newProperties = BoolToInt(updatePair.NewProperties);
       
    83   if(indexInArchive != NULL)
       
    84   {
       
    85     if (updatePair.ExistInArchive)
       
    86     {
       
    87       if (ArchiveItems == 0)
       
    88         *indexInArchive = updatePair.ArchiveItemIndex;
       
    89       else
       
    90         *indexInArchive = (*ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer;
       
    91     }
       
    92     else
       
    93       *indexInArchive = UInt32(-1);
       
    94   }
       
    95   return S_OK;
       
    96   COM_TRY_END
       
    97 }
       
    98 
       
    99 STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
       
   100 {
       
   101   COM_TRY_BEGIN
       
   102   const CUpdatePair2 &updatePair = (*UpdatePairs)[index];
       
   103   NWindows::NCOM::CPropVariant propVariant;
       
   104   
       
   105   if (propID == kpidIsAnti)
       
   106   {
       
   107     propVariant = updatePair.IsAnti;
       
   108     propVariant.Detach(value);
       
   109     return S_OK;
       
   110   }
       
   111 
       
   112   if (updatePair.IsAnti)
       
   113   {
       
   114     switch(propID)
       
   115     {
       
   116       case kpidIsFolder:
       
   117       case kpidPath:
       
   118         break;
       
   119       case kpidSize:
       
   120         propVariant = (UInt64)0;
       
   121         propVariant.Detach(value);
       
   122         return S_OK;
       
   123       default:
       
   124         propVariant.Detach(value);
       
   125         return S_OK;
       
   126     }
       
   127   }
       
   128   
       
   129   if(updatePair.ExistOnDisk)
       
   130   {
       
   131     const CDirItem &dirItem = (*DirItems)[updatePair.DirItemIndex];
       
   132     switch(propID)
       
   133     {
       
   134       case kpidPath:
       
   135         propVariant = dirItem.Name;
       
   136         break;
       
   137       case kpidIsFolder:
       
   138         propVariant = dirItem.IsDirectory();
       
   139         break;
       
   140       case kpidSize:
       
   141         propVariant = dirItem.Size;
       
   142         break;
       
   143       case kpidAttributes:
       
   144         propVariant = dirItem.Attributes;
       
   145         break;
       
   146       case kpidLastAccessTime:
       
   147         propVariant = dirItem.LastAccessTime;
       
   148         break;
       
   149       case kpidCreationTime:
       
   150         propVariant = dirItem.CreationTime;
       
   151         break;
       
   152       case kpidLastWriteTime:
       
   153         propVariant = dirItem.LastWriteTime;
       
   154         break;
       
   155     }
       
   156   }
       
   157   else
       
   158   {
       
   159     if (propID == kpidPath)
       
   160     {
       
   161       if (updatePair.NewNameIsDefined)
       
   162       {
       
   163         propVariant = updatePair.NewName;
       
   164         propVariant.Detach(value);
       
   165         return S_OK;
       
   166       }
       
   167     }
       
   168     if (updatePair.ExistInArchive && Archive)
       
   169     {
       
   170       UInt32 indexInArchive;
       
   171       if (ArchiveItems == 0)
       
   172         indexInArchive = updatePair.ArchiveItemIndex;
       
   173       else
       
   174         indexInArchive = (*ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer;
       
   175       return Archive->GetProperty(indexInArchive, propID, value);
       
   176     }
       
   177   }
       
   178   propVariant.Detach(value);
       
   179   return S_OK;
       
   180   COM_TRY_END
       
   181 }
       
   182 
       
   183 STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)
       
   184 {
       
   185   COM_TRY_BEGIN
       
   186   const CUpdatePair2 &updatePair = (*UpdatePairs)[index];
       
   187   if(!updatePair.NewData)
       
   188     return E_FAIL;
       
   189   
       
   190   RINOK(Callback->CheckBreak());
       
   191   RINOK(Callback->Finilize());
       
   192 
       
   193   if(updatePair.IsAnti)
       
   194   {
       
   195     return Callback->GetStream((*ArchiveItems)[updatePair.ArchiveItemIndex].Name, true);
       
   196   }
       
   197   const CDirItem &dirItem = (*DirItems)[updatePair.DirItemIndex];
       
   198   RINOK(Callback->GetStream(dirItem.Name, false));
       
   199  
       
   200   if(dirItem.IsDirectory())
       
   201     return S_OK;
       
   202 
       
   203   if (StdInMode)
       
   204   {
       
   205     CStdInFileStream *inStreamSpec = new CStdInFileStream;
       
   206     CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
       
   207     *inStream = inStreamLoc.Detach();
       
   208   }
       
   209   else
       
   210   {
       
   211     CInFileStream *inStreamSpec = new CInFileStream;
       
   212     CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
       
   213     UString path = DirPrefix + dirItem.FullPath;
       
   214     if(!inStreamSpec->OpenShared(path, ShareForWrite))
       
   215     {
       
   216       return Callback->OpenFileError(path, ::GetLastError());
       
   217     }
       
   218     *inStream = inStreamLoc.Detach();
       
   219   }
       
   220   return S_OK;
       
   221   COM_TRY_END
       
   222 }
       
   223 
       
   224 STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 operationResult)
       
   225 {
       
   226   COM_TRY_BEGIN
       
   227   return Callback->SetOperationResult(operationResult);
       
   228   COM_TRY_END
       
   229 }
       
   230 
       
   231 STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)
       
   232 {
       
   233   if (VolumesSizes.Size() == 0)
       
   234     return S_FALSE;
       
   235   if (index >= (UInt32)VolumesSizes.Size())
       
   236     index = VolumesSizes.Size() - 1;
       
   237   *size = VolumesSizes[index];
       
   238   return S_OK;
       
   239 }
       
   240 
       
   241 STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)
       
   242 {
       
   243   COM_TRY_BEGIN
       
   244   wchar_t temp[32];
       
   245   ConvertUInt64ToString(index + 1, temp);
       
   246   UString res = temp;
       
   247   while (res.Length() < 2)
       
   248     res = UString(L'0') + res;
       
   249   UString fileName = VolName;
       
   250   fileName += L'.';
       
   251   fileName += res;
       
   252   fileName += VolExt;
       
   253   COutFileStream *streamSpec = new COutFileStream;
       
   254   CMyComPtr<ISequentialOutStream> streamLoc(streamSpec);
       
   255   if(!streamSpec->Create(fileName, false))
       
   256     return ::GetLastError();
       
   257   *volumeStream = streamLoc.Detach();
       
   258   return S_OK;
       
   259   COM_TRY_END
       
   260 }
       
   261 
       
   262 STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
       
   263 {
       
   264   COM_TRY_BEGIN
       
   265   return Callback->CryptoGetTextPassword2(passwordIsDefined, password);
       
   266   COM_TRY_END
       
   267 }