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
14using namespace NWindows;
15
16STDMETHODIMP 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
27STDMETHODIMP 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
38STDMETHODIMP 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
63struct 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
76STDMETHODIMP 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
110STDMETHODIMP 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