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
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
FindName(const UString & name)63 int 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
71 struct CInFileStreamVol: public CInFileStream
72 {
73 UString Name;
74 COpenCallbackImp *OpenCallbackImp;
75 CMyComPtr<IArchiveOpenCallback> OpenCallbackRef;
~CInFileStreamVolCInFileStreamVol76 ~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
GetStream(const wchar_t * name,IInStream ** inStream)87 STDMETHODIMP 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
CryptoGetTextPassword(BSTR * password)117 STDMETHODIMP 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