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 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 63struct 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 76STDMETHODIMP 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 110STDMETHODIMP 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