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 // case kpidSize: prop = _subArchiveSize; break; // we don't use it now
47 }
48 else
49 switch (propID)
50 {
51 case kpidName: prop = _fileInfo.Name; break;
52 case kpidIsDir: prop = _fileInfo.IsDir(); break;
53 case kpidSize: prop = _fileInfo.Size; break;
54 case kpidAttrib: prop = (UInt32)_fileInfo.Attrib; break;
55 case kpidCTime: prop = _fileInfo.CTime; break;
56 case kpidATime: prop = _fileInfo.ATime; break;
57 case kpidMTime: prop = _fileInfo.MTime; break;
58 }
59 prop.Detach(value);
60 return S_OK;
61 COM_TRY_END
62 }
63
64 struct CInFileStreamVol: public CInFileStream
65 {
66 int FileNameIndex;
67 COpenCallbackImp *OpenCallbackImp;
68 CMyComPtr<IArchiveOpenCallback> OpenCallbackRef;
69
~CInFileStreamVolCInFileStreamVol70 ~CInFileStreamVol()
71 {
72 if (OpenCallbackRef)
73 OpenCallbackImp->FileNames_WasUsed[FileNameIndex] = false;
74 }
75 };
76
77
78 // from ArchiveExtractCallback.cpp
79 bool IsSafePath(const UString &path);
80
GetStream(const wchar_t * name,IInStream ** inStream)81 STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStream)
82 {
83 COM_TRY_BEGIN
84 *inStream = NULL;
85
86 if (_subArchiveMode)
87 return S_FALSE;
88 if (Callback)
89 {
90 RINOK(Callback->Open_CheckBreak());
91 }
92
93 UString name2 = name;
94
95
96 #ifndef _SFX
97
98 #ifdef _WIN32
99 name2.Replace(L'/', WCHAR_PATH_SEPARATOR);
100 #endif
101
102 // if (!allowAbsVolPaths)
103 if (!IsSafePath(name2))
104 return S_FALSE;
105
106 #endif
107
108
109 FString fullPath;
110 if (!NFile::NName::GetFullPath(_folderPrefix, us2fs(name2), fullPath))
111 return S_FALSE;
112 if (!_fileInfo.Find(fullPath))
113 return S_FALSE;
114 if (_fileInfo.IsDir())
115 return S_FALSE;
116 CInFileStreamVol *inFile = new CInFileStreamVol;
117 CMyComPtr<IInStream> inStreamTemp = inFile;
118 if (!inFile->Open(fullPath))
119 {
120 DWORD lastError = ::GetLastError();
121 if (lastError == 0)
122 return E_FAIL;
123 return HRESULT_FROM_WIN32(lastError);
124 }
125
126 FileSizes.Add(_fileInfo.Size);
127 FileNames.Add(name2);
128 inFile->FileNameIndex = FileNames_WasUsed.Add(true);
129 inFile->OpenCallbackImp = this;
130 inFile->OpenCallbackRef = this;
131 // TotalSize += _fileInfo.Size;
132 *inStream = inStreamTemp.Detach();
133 return S_OK;
134 COM_TRY_END
135 }
136
137 #ifndef _NO_CRYPTO
CryptoGetTextPassword(BSTR * password)138 STDMETHODIMP COpenCallbackImp::CryptoGetTextPassword(BSTR *password)
139 {
140 COM_TRY_BEGIN
141 if (ReOpenCallback)
142 {
143 CMyComPtr<ICryptoGetTextPassword> getTextPassword;
144 ReOpenCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
145 if (getTextPassword)
146 return getTextPassword->CryptoGetTextPassword(password);
147 }
148 if (!Callback)
149 return E_NOTIMPL;
150 PasswordWasAsked = true;
151 return Callback->Open_CryptoGetTextPassword(password);
152 COM_TRY_END
153 }
154 #endif
155