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