• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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