Home | History | Annotate | Download | only in Common
      1 // ArchiveOpenCallback.cpp
      2 
      3 #include "StdAfx.h"
      4 
      5 #include "../../../Common/ComTry.h"
      6 
      7 #include "../../../Windows/FileName.h"
      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 struct CInFileStreamVol: public CInFileStream
     64 {
     65   int FileNameIndex;
     66   COpenCallbackImp *OpenCallbackImp;
     67   CMyComPtr<IArchiveOpenCallback> OpenCallbackRef;
     68 
     69   ~CInFileStreamVol()
     70   {
     71     if (OpenCallbackRef)
     72       OpenCallbackImp->FileNames_WasUsed[FileNameIndex] = false;
     73   }
     74 };
     75 
     76 STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStream)
     77 {
     78   COM_TRY_BEGIN
     79   *inStream = NULL;
     80   if (_subArchiveMode)
     81     return S_FALSE;
     82   if (Callback)
     83   {
     84     RINOK(Callback->Open_CheckBreak());
     85   }
     86   FString fullPath;
     87   if (!NFile::NName::GetFullPath(_folderPrefix, us2fs(name), fullPath))
     88     return S_FALSE;
     89   if (!_fileInfo.Find(fullPath))
     90     return S_FALSE;
     91   if (_fileInfo.IsDir())
     92     return S_FALSE;
     93   CInFileStreamVol *inFile = new CInFileStreamVol;
     94   CMyComPtr<IInStream> inStreamTemp = inFile;
     95   if (!inFile->Open(fullPath))
     96     return ::GetLastError();
     97 
     98   FileSizes.Add(_fileInfo.Size);
     99   FileNames.Add(name);
    100   inFile->FileNameIndex = FileNames_WasUsed.Add(true);
    101   inFile->OpenCallbackImp = this;
    102   inFile->OpenCallbackRef = this;
    103   // TotalSize += _fileInfo.Size;
    104   *inStream = inStreamTemp.Detach();
    105   return S_OK;
    106   COM_TRY_END
    107 }
    108 
    109 #ifndef _NO_CRYPTO
    110 STDMETHODIMP COpenCallbackImp::CryptoGetTextPassword(BSTR *password)
    111 {
    112   COM_TRY_BEGIN
    113   if (ReOpenCallback)
    114   {
    115     CMyComPtr<ICryptoGetTextPassword> getTextPassword;
    116     ReOpenCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
    117     if (getTextPassword)
    118       return getTextPassword->CryptoGetTextPassword(password);
    119   }
    120   if (!Callback)
    121     return E_NOTIMPL;
    122   return Callback->Open_CryptoGetTextPassword(password);
    123   COM_TRY_END
    124 }
    125 #endif
    126