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 14using namespace NWindows; 15 16STDMETHODIMP 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 27STDMETHODIMP 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 38STDMETHODIMP 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 63int 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 71struct 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 87STDMETHODIMP 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 117STDMETHODIMP 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