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
SetTotal(const UInt64 * files,const UInt64 * bytes)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
SetCompleted(const UInt64 * files,const UInt64 * bytes)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
GetProperty(PROPID propID,PROPVARIANT * value)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
~CInFileStreamVolCInFileStreamVol69 ~CInFileStreamVol()
70 {
71 if (OpenCallbackRef)
72 OpenCallbackImp->FileNames_WasUsed[FileNameIndex] = false;
73 }
74 };
75
GetStream(const wchar_t * name,IInStream ** inStream)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
CryptoGetTextPassword(BSTR * password)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