1 // ArchiveOpenCallback.cpp
2 
3 #include "StdAfx.h"
4 
5 #include "ArchiveOpenCallback.h"
6 
7 #include "Common/StringConvert.h"
8 #include "Windows/PropVariant.h"
9 
10 #include "../../Common/FileStreams.h"
11 
12 using namespace NWindows;
13 
SetTotal(const UInt64 * files,const UInt64 * bytes)14 STDMETHODIMP COpenCallbackImp::SetTotal(const UInt64 *files, const UInt64 *bytes)
15 {
16   return Callback->SetTotal(files, bytes);
17 }
18 
SetCompleted(const UInt64 * files,const UInt64 * bytes)19 STDMETHODIMP COpenCallbackImp::SetCompleted(const UInt64 *files, const UInt64 *bytes)
20 {
21   return Callback->SetTotal(files, bytes);
22 }
23 
GetProperty(PROPID propID,PROPVARIANT * value)24 STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)
25 {
26   NCOM::CPropVariant propVariant;
27   if (_subArchiveMode)
28   {
29     switch(propID)
30     {
31       case kpidName:
32         propVariant = _subArchiveName;
33         break;
34     }
35     propVariant.Detach(value);
36     return S_OK;
37   }
38   switch(propID)
39   {
40     case kpidName:
41       propVariant = _fileInfo.Name;
42       break;
43     case kpidIsFolder:
44       propVariant = _fileInfo.IsDirectory();
45       break;
46     case kpidSize:
47       propVariant = _fileInfo.Size;
48       break;
49     case kpidAttributes:
50       propVariant = (UInt32)_fileInfo.Attributes;
51       break;
52     case kpidLastAccessTime:
53       propVariant = _fileInfo.LastAccessTime;
54       break;
55     case kpidCreationTime:
56       propVariant = _fileInfo.CreationTime;
57       break;
58     case kpidLastWriteTime:
59       propVariant = _fileInfo.LastWriteTime;
60       break;
61     }
62   propVariant.Detach(value);
63   return S_OK;
64 }
65 
FindName(const UString & name)66 int COpenCallbackImp::FindName(const UString &name)
67 {
68   for (int i = 0; i < FileNames.Size(); i++)
69     if (name.CompareNoCase(FileNames[i]) == 0)
70       return i;
71   return -1;
72 }
73 
74 struct CInFileStreamVol: public CInFileStream
75 {
76   UString Name;
77   COpenCallbackImp *OpenCallbackImp;
78   CMyComPtr<IArchiveOpenCallback> OpenCallbackRef;
~CInFileStreamVolCInFileStreamVol79   ~CInFileStreamVol()
80   {
81     int index = OpenCallbackImp->FindName(Name);
82     if (index >= 0)
83       OpenCallbackImp->FileNames.Delete(index);
84   }
85 };
86 
GetStream(const wchar_t * name,IInStream ** inStream)87 STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name,
88     IInStream **inStream)
89 {
90   if (_subArchiveMode)
91     return S_FALSE;
92   RINOK(Callback->CheckBreak());
93   *inStream = NULL;
94   UString fullPath = _folderPrefix + name;
95   if (!NFile::NFind::FindFile(fullPath, _fileInfo))
96     return S_FALSE;
97   if (_fileInfo.IsDirectory())
98     return S_FALSE;
99   CInFileStreamVol *inFile = new CInFileStreamVol;
100   CMyComPtr<IInStream> inStreamTemp = inFile;
101   if (!inFile->Open(fullPath))
102     return ::GetLastError();
103   *inStream = inStreamTemp.Detach();
104   inFile->Name = name;
105   inFile->OpenCallbackImp = this;
106   inFile->OpenCallbackRef = this;
107   FileNames.Add(name);
108   return S_OK;
109 }
110 
111 #ifndef _NO_CRYPTO
CryptoGetTextPassword(BSTR * password)112 STDMETHODIMP COpenCallbackImp::CryptoGetTextPassword(BSTR *password)
113 {
114   return Callback->CryptoGetTextPassword(password);
115 }
116 #endif
117 
118