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