Home | History | Annotate | Download | only in Common
      1 // ArchiveOpenCallback.cpp
      2 
      3 #include "StdAfx.h"
      4 
      5 #include "Common/StringConvert.h"
      6 #include "Common/ComTry.h"
      7 
      8 #include "Windows/PropVariant.h"
      9 
     10 #include "../../Common/FileStreams.h"
     11 
     12 #include "ArchiveOpenCallback.h"
     13 
     14 using namespace NWindows;
     15 
     16 STDMETHODIMP COpenCallbackImp::SetTotal(const UInt64 *files, const UInt64 *bytes)
     17 {
     18   COM_TRY_BEGIN
     19   if (ReOpenCallback)
     20     return ReOpenCallback->SetTotal(files, bytes);
     21   if (!Callback)
     22     return S_OK;
     23   return Callback->Open_SetTotal(files, bytes);
     24   COM_TRY_END
     25 }
     26 
     27 STDMETHODIMP COpenCallbackImp::SetCompleted(const UInt64 *files, const UInt64 *bytes)
     28 {
     29   COM_TRY_BEGIN
     30   if (ReOpenCallback)
     31     return ReOpenCallback->SetCompleted(files, bytes);
     32   if (!Callback)
     33     return S_OK;
     34   return Callback->Open_SetCompleted(files, bytes);
     35   COM_TRY_END
     36 }
     37 
     38 STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)
     39 {
     40   COM_TRY_BEGIN
     41   NCOM::CPropVariant prop;
     42   if (_subArchiveMode)
     43     switch(propID)
     44     {
     45       case kpidName: prop = _subArchiveName; break;
     46     }
     47   else
     48     switch(propID)
     49     {
     50       case kpidName:  prop = _fileInfo.Name; break;
     51       case kpidIsDir:  prop = _fileInfo.IsDir(); break;
     52       case kpidSize:  prop = _fileInfo.Size; break;
     53       case kpidAttrib:  prop = (UInt32)_fileInfo.Attrib; break;
     54       case kpidCTime:  prop = _fileInfo.CTime; break;
     55       case kpidATime:  prop = _fileInfo.ATime; break;
     56       case kpidMTime:  prop = _fileInfo.MTime; break;
     57     }
     58   prop.Detach(value);
     59   return S_OK;
     60   COM_TRY_END
     61 }
     62 
     63 int COpenCallbackImp::FindName(const UString &name)
     64 {
     65   for (int i = 0; i < FileNames.Size(); i++)
     66     if (name.CompareNoCase(FileNames[i]) == 0)
     67       return i;
     68   return -1;
     69 }
     70 
     71 struct CInFileStreamVol: public CInFileStream
     72 {
     73   UString Name;
     74   COpenCallbackImp *OpenCallbackImp;
     75   CMyComPtr<IArchiveOpenCallback> OpenCallbackRef;
     76   ~CInFileStreamVol()
     77   {
     78     if (OpenCallbackRef)
     79     {
     80       int index = OpenCallbackImp->FindName(Name);
     81       if (index >= 0)
     82         OpenCallbackImp->FileNames.Delete(index);
     83     }
     84   }
     85 };
     86 
     87 STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStream)
     88 {
     89   COM_TRY_BEGIN
     90   if (_subArchiveMode)
     91     return S_FALSE;
     92   if (Callback)
     93   {
     94     RINOK(Callback->Open_CheckBreak());
     95   }
     96   *inStream = NULL;
     97   UString fullPath = _folderPrefix + name;
     98   if (!_fileInfo.Find(fullPath))
     99     return S_FALSE;
    100   if (_fileInfo.IsDir())
    101     return S_FALSE;
    102   CInFileStreamVol *inFile = new CInFileStreamVol;
    103   CMyComPtr<IInStream> inStreamTemp = inFile;
    104   if (!inFile->Open(fullPath))
    105     return ::GetLastError();
    106   *inStream = inStreamTemp.Detach();
    107   inFile->Name = name;
    108   inFile->OpenCallbackImp = this;
    109   inFile->OpenCallbackRef = this;
    110   FileNames.Add(name);
    111   TotalSize += _fileInfo.Size;
    112   return S_OK;
    113   COM_TRY_END
    114 }
    115 
    116 #ifndef _NO_CRYPTO
    117 STDMETHODIMP COpenCallbackImp::CryptoGetTextPassword(BSTR *password)
    118 {
    119   COM_TRY_BEGIN
    120   if (ReOpenCallback)
    121   {
    122     CMyComPtr<ICryptoGetTextPassword> getTextPassword;
    123     ReOpenCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
    124     if (getTextPassword)
    125       return getTextPassword->CryptoGetTextPassword(password);
    126   }
    127   if (!Callback)
    128     return E_NOTIMPL;
    129   return Callback->Open_CryptoGetTextPassword(password);
    130   COM_TRY_END
    131 }
    132 #endif
    133 
    134