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