xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // ArchiveOpenCallback.cpp
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker 
5*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/ComTry.h"
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileName.h"
8*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/PropVariant.h"
9*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/System.h"
10*f6dc9357SAndroid Build Coastguard Worker 
11*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/StreamUtils.h"
12*f6dc9357SAndroid Build Coastguard Worker 
13*f6dc9357SAndroid Build Coastguard Worker #include "ArchiveOpenCallback.h"
14*f6dc9357SAndroid Build Coastguard Worker 
15*f6dc9357SAndroid Build Coastguard Worker // #define DEBUG_VOLUMES
16*f6dc9357SAndroid Build Coastguard Worker 
17*f6dc9357SAndroid Build Coastguard Worker #ifdef DEBUG_VOLUMES
18*f6dc9357SAndroid Build Coastguard Worker #include <stdio.h>
19*f6dc9357SAndroid Build Coastguard Worker #endif
20*f6dc9357SAndroid Build Coastguard Worker 
21*f6dc9357SAndroid Build Coastguard Worker 
22*f6dc9357SAndroid Build Coastguard Worker #ifdef DEBUG_VOLUMES
23*f6dc9357SAndroid Build Coastguard Worker   #define PRF(x) x
24*f6dc9357SAndroid Build Coastguard Worker #else
25*f6dc9357SAndroid Build Coastguard Worker   #define PRF(x)
26*f6dc9357SAndroid Build Coastguard Worker #endif
27*f6dc9357SAndroid Build Coastguard Worker 
28*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
29*f6dc9357SAndroid Build Coastguard Worker 
Init2(const FString & folderPrefix,const FString & fileName)30*f6dc9357SAndroid Build Coastguard Worker HRESULT COpenCallbackImp::Init2(const FString &folderPrefix, const FString &fileName)
31*f6dc9357SAndroid Build Coastguard Worker {
32*f6dc9357SAndroid Build Coastguard Worker   Volumes.Init();
33*f6dc9357SAndroid Build Coastguard Worker   FileNames.Clear();
34*f6dc9357SAndroid Build Coastguard Worker   FileNames_WasUsed.Clear();
35*f6dc9357SAndroid Build Coastguard Worker   FileSizes.Clear();
36*f6dc9357SAndroid Build Coastguard Worker   _subArchiveMode = false;
37*f6dc9357SAndroid Build Coastguard Worker   // TotalSize = 0;
38*f6dc9357SAndroid Build Coastguard Worker   PasswordWasAsked = false;
39*f6dc9357SAndroid Build Coastguard Worker   _folderPrefix = folderPrefix;
40*f6dc9357SAndroid Build Coastguard Worker   if (!_fileInfo.Find_FollowLink(_folderPrefix + fileName))
41*f6dc9357SAndroid Build Coastguard Worker   {
42*f6dc9357SAndroid Build Coastguard Worker     // throw 20121118;
43*f6dc9357SAndroid Build Coastguard Worker     return GetLastError_noZero_HRESULT();
44*f6dc9357SAndroid Build Coastguard Worker   }
45*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
46*f6dc9357SAndroid Build Coastguard Worker }
47*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(COpenCallbackImp::SetSubArchiveName (const wchar_t * name))48*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(COpenCallbackImp::SetSubArchiveName(const wchar_t *name))
49*f6dc9357SAndroid Build Coastguard Worker {
50*f6dc9357SAndroid Build Coastguard Worker   _subArchiveMode = true;
51*f6dc9357SAndroid Build Coastguard Worker   _subArchiveName = name;
52*f6dc9357SAndroid Build Coastguard Worker   // TotalSize = 0;
53*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
54*f6dc9357SAndroid Build Coastguard Worker }
55*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(COpenCallbackImp::SetTotal (const UInt64 * files,const UInt64 * bytes))56*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(COpenCallbackImp::SetTotal(const UInt64 *files, const UInt64 *bytes))
57*f6dc9357SAndroid Build Coastguard Worker {
58*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
59*f6dc9357SAndroid Build Coastguard Worker   if (ReOpenCallback)
60*f6dc9357SAndroid Build Coastguard Worker     return ReOpenCallback->SetTotal(files, bytes);
61*f6dc9357SAndroid Build Coastguard Worker   if (!Callback)
62*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
63*f6dc9357SAndroid Build Coastguard Worker   return Callback->Open_SetTotal(files, bytes);
64*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
65*f6dc9357SAndroid Build Coastguard Worker }
66*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(COpenCallbackImp::SetCompleted (const UInt64 * files,const UInt64 * bytes))67*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(COpenCallbackImp::SetCompleted(const UInt64 *files, const UInt64 *bytes))
68*f6dc9357SAndroid Build Coastguard Worker {
69*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
70*f6dc9357SAndroid Build Coastguard Worker   if (ReOpenCallback)
71*f6dc9357SAndroid Build Coastguard Worker     return ReOpenCallback->SetCompleted(files, bytes);
72*f6dc9357SAndroid Build Coastguard Worker   if (!Callback)
73*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
74*f6dc9357SAndroid Build Coastguard Worker   return Callback->Open_SetCompleted(files, bytes);
75*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
76*f6dc9357SAndroid Build Coastguard Worker }
77*f6dc9357SAndroid Build Coastguard Worker 
78*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(COpenCallbackImp::GetProperty (PROPID propID,PROPVARIANT * value))79*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value))
80*f6dc9357SAndroid Build Coastguard Worker {
81*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
82*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant prop;
83*f6dc9357SAndroid Build Coastguard Worker   if (_subArchiveMode)
84*f6dc9357SAndroid Build Coastguard Worker     switch (propID)
85*f6dc9357SAndroid Build Coastguard Worker     {
86*f6dc9357SAndroid Build Coastguard Worker       case kpidName: prop = _subArchiveName; break;
87*f6dc9357SAndroid Build Coastguard Worker       // case kpidSize:  prop = _subArchiveSize; break; // we don't use it now
88*f6dc9357SAndroid Build Coastguard Worker       default: break;
89*f6dc9357SAndroid Build Coastguard Worker     }
90*f6dc9357SAndroid Build Coastguard Worker   else
91*f6dc9357SAndroid Build Coastguard Worker     switch (propID)
92*f6dc9357SAndroid Build Coastguard Worker     {
93*f6dc9357SAndroid Build Coastguard Worker       case kpidName:  prop = fs2us(_fileInfo.Name); break;
94*f6dc9357SAndroid Build Coastguard Worker       case kpidIsDir:  prop = _fileInfo.IsDir(); break;
95*f6dc9357SAndroid Build Coastguard Worker       case kpidSize:  prop = _fileInfo.Size; break;
96*f6dc9357SAndroid Build Coastguard Worker       case kpidAttrib:  prop = (UInt32)_fileInfo.GetWinAttrib(); break;
97*f6dc9357SAndroid Build Coastguard Worker       case kpidPosixAttrib:  prop = (UInt32)_fileInfo.GetPosixAttrib(); break;
98*f6dc9357SAndroid Build Coastguard Worker       case kpidCTime:  PropVariant_SetFrom_FiTime(prop, _fileInfo.CTime); break;
99*f6dc9357SAndroid Build Coastguard Worker       case kpidATime:  PropVariant_SetFrom_FiTime(prop, _fileInfo.ATime); break;
100*f6dc9357SAndroid Build Coastguard Worker       case kpidMTime:  PropVariant_SetFrom_FiTime(prop, _fileInfo.MTime); break;
101*f6dc9357SAndroid Build Coastguard Worker       default: break;
102*f6dc9357SAndroid Build Coastguard Worker     }
103*f6dc9357SAndroid Build Coastguard Worker   prop.Detach(value);
104*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
105*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
106*f6dc9357SAndroid Build Coastguard Worker }
107*f6dc9357SAndroid Build Coastguard Worker 
108*f6dc9357SAndroid Build Coastguard Worker 
109*f6dc9357SAndroid Build Coastguard Worker // ---------- CInFileStreamVol ----------
110*f6dc9357SAndroid Build Coastguard Worker 
111*f6dc9357SAndroid Build Coastguard Worker Z7_class_final(CInFileStreamVol):
112*f6dc9357SAndroid Build Coastguard Worker     public IInStream
113*f6dc9357SAndroid Build Coastguard Worker   , public IStreamGetSize
114*f6dc9357SAndroid Build Coastguard Worker   , public CMyUnknownImp
115*f6dc9357SAndroid Build Coastguard Worker {
116*f6dc9357SAndroid Build Coastguard Worker   Z7_IFACES_IMP_UNK_3(
117*f6dc9357SAndroid Build Coastguard Worker     IInStream,
118*f6dc9357SAndroid Build Coastguard Worker     ISequentialInStream,
119*f6dc9357SAndroid Build Coastguard Worker     IStreamGetSize)
120*f6dc9357SAndroid Build Coastguard Worker public:
121*f6dc9357SAndroid Build Coastguard Worker   unsigned FileIndex;
122*f6dc9357SAndroid Build Coastguard Worker   COpenCallbackImp *OpenCallbackImp;
123*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IArchiveOpenCallback> OpenCallbackRef;
124*f6dc9357SAndroid Build Coastguard Worker 
125*f6dc9357SAndroid Build Coastguard Worker   HRESULT EnsureOpen()
126*f6dc9357SAndroid Build Coastguard Worker   {
127*f6dc9357SAndroid Build Coastguard Worker     return OpenCallbackImp->Volumes.EnsureOpen(FileIndex);
128*f6dc9357SAndroid Build Coastguard Worker   }
129*f6dc9357SAndroid Build Coastguard Worker 
130*f6dc9357SAndroid Build Coastguard Worker   ~CInFileStreamVol()
131*f6dc9357SAndroid Build Coastguard Worker   {
132*f6dc9357SAndroid Build Coastguard Worker     if (OpenCallbackRef)
133*f6dc9357SAndroid Build Coastguard Worker       OpenCallbackImp->AtCloseFile(FileIndex);
134*f6dc9357SAndroid Build Coastguard Worker   }
135*f6dc9357SAndroid Build Coastguard Worker };
136*f6dc9357SAndroid Build Coastguard Worker 
137*f6dc9357SAndroid Build Coastguard Worker 
138*f6dc9357SAndroid Build Coastguard Worker void CMultiStreams::InsertToList(unsigned index)
139*f6dc9357SAndroid Build Coastguard Worker {
140*f6dc9357SAndroid Build Coastguard Worker   {
141*f6dc9357SAndroid Build Coastguard Worker     CSubStream &s = Streams[index];
142*f6dc9357SAndroid Build Coastguard Worker     s.Next = Head;
143*f6dc9357SAndroid Build Coastguard Worker     s.Prev = -1;
144*f6dc9357SAndroid Build Coastguard Worker   }
145*f6dc9357SAndroid Build Coastguard Worker   if (Head != -1)
146*f6dc9357SAndroid Build Coastguard Worker     Streams[(unsigned)Head].Prev = (int)index;
147*f6dc9357SAndroid Build Coastguard Worker   else
148*f6dc9357SAndroid Build Coastguard Worker   {
149*f6dc9357SAndroid Build Coastguard Worker     // if (Tail != -1) throw 1;
150*f6dc9357SAndroid Build Coastguard Worker     Tail = (int)index;
151*f6dc9357SAndroid Build Coastguard Worker   }
152*f6dc9357SAndroid Build Coastguard Worker   Head = (int)index;
153*f6dc9357SAndroid Build Coastguard Worker   NumListItems++;
154*f6dc9357SAndroid Build Coastguard Worker }
155*f6dc9357SAndroid Build Coastguard Worker 
156*f6dc9357SAndroid Build Coastguard Worker // s must bee in List
157*f6dc9357SAndroid Build Coastguard Worker void CMultiStreams::RemoveFromList(CSubStream &s)
158*f6dc9357SAndroid Build Coastguard Worker {
159*f6dc9357SAndroid Build Coastguard Worker   if (s.Next != -1) Streams[(unsigned)s.Next].Prev = s.Prev; else Tail = s.Prev;
160*f6dc9357SAndroid Build Coastguard Worker   if (s.Prev != -1) Streams[(unsigned)s.Prev].Next = s.Next; else Head = s.Next;
161*f6dc9357SAndroid Build Coastguard Worker   s.Next = -1; // optional
162*f6dc9357SAndroid Build Coastguard Worker   s.Prev = -1; // optional
163*f6dc9357SAndroid Build Coastguard Worker   NumListItems--;
164*f6dc9357SAndroid Build Coastguard Worker }
165*f6dc9357SAndroid Build Coastguard Worker 
166*f6dc9357SAndroid Build Coastguard Worker void CMultiStreams::CloseFile(unsigned index)
167*f6dc9357SAndroid Build Coastguard Worker {
168*f6dc9357SAndroid Build Coastguard Worker   CSubStream &s = Streams[index];
169*f6dc9357SAndroid Build Coastguard Worker   if (s.Stream)
170*f6dc9357SAndroid Build Coastguard Worker   {
171*f6dc9357SAndroid Build Coastguard Worker     s.Stream.Release();
172*f6dc9357SAndroid Build Coastguard Worker     RemoveFromList(s);
173*f6dc9357SAndroid Build Coastguard Worker     // s.InFile->Close();
174*f6dc9357SAndroid Build Coastguard Worker     // s.IsOpen = false;
175*f6dc9357SAndroid Build Coastguard Worker    #ifdef DEBUG_VOLUMES
176*f6dc9357SAndroid Build Coastguard Worker     static int numClosing = 0;
177*f6dc9357SAndroid Build Coastguard Worker     numClosing++;
178*f6dc9357SAndroid Build Coastguard Worker     printf("\nCloseFile %u, total_closes = %u, num_open_files = %u\n", index, numClosing, NumListItems);
179*f6dc9357SAndroid Build Coastguard Worker    #endif
180*f6dc9357SAndroid Build Coastguard Worker   }
181*f6dc9357SAndroid Build Coastguard Worker }
182*f6dc9357SAndroid Build Coastguard Worker 
183*f6dc9357SAndroid Build Coastguard Worker void CMultiStreams::Init()
184*f6dc9357SAndroid Build Coastguard Worker {
185*f6dc9357SAndroid Build Coastguard Worker   Head = -1;
186*f6dc9357SAndroid Build Coastguard Worker   Tail = -1;
187*f6dc9357SAndroid Build Coastguard Worker   NumListItems = 0;
188*f6dc9357SAndroid Build Coastguard Worker   Streams.Clear();
189*f6dc9357SAndroid Build Coastguard Worker }
190*f6dc9357SAndroid Build Coastguard Worker 
191*f6dc9357SAndroid Build Coastguard Worker CMultiStreams::CMultiStreams():
192*f6dc9357SAndroid Build Coastguard Worker     Head(-1),
193*f6dc9357SAndroid Build Coastguard Worker     Tail(-1),
194*f6dc9357SAndroid Build Coastguard Worker     NumListItems(0)
195*f6dc9357SAndroid Build Coastguard Worker {
196*f6dc9357SAndroid Build Coastguard Worker   NumOpenFiles_AllowedMax = NSystem::Get_File_OPEN_MAX_Reduced_for_3_tasks();
197*f6dc9357SAndroid Build Coastguard Worker   PRF(printf("\nNumOpenFiles_Limit = %u\n", NumOpenFiles_AllowedMax));
198*f6dc9357SAndroid Build Coastguard Worker }
199*f6dc9357SAndroid Build Coastguard Worker 
200*f6dc9357SAndroid Build Coastguard Worker 
201*f6dc9357SAndroid Build Coastguard Worker HRESULT CMultiStreams::PrepareToOpenNew()
202*f6dc9357SAndroid Build Coastguard Worker {
203*f6dc9357SAndroid Build Coastguard Worker   if (NumListItems < NumOpenFiles_AllowedMax)
204*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
205*f6dc9357SAndroid Build Coastguard Worker   if (Tail == -1)
206*f6dc9357SAndroid Build Coastguard Worker     return E_FAIL;
207*f6dc9357SAndroid Build Coastguard Worker   CMultiStreams::CSubStream &tailStream = Streams[(unsigned)Tail];
208*f6dc9357SAndroid Build Coastguard Worker   RINOK(InStream_GetPos(tailStream.Stream, tailStream.LocalPos))
209*f6dc9357SAndroid Build Coastguard Worker   CloseFile((unsigned)Tail);
210*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
211*f6dc9357SAndroid Build Coastguard Worker }
212*f6dc9357SAndroid Build Coastguard Worker 
213*f6dc9357SAndroid Build Coastguard Worker 
214*f6dc9357SAndroid Build Coastguard Worker HRESULT CMultiStreams::EnsureOpen(unsigned index)
215*f6dc9357SAndroid Build Coastguard Worker {
216*f6dc9357SAndroid Build Coastguard Worker   CMultiStreams::CSubStream &s = Streams[index];
217*f6dc9357SAndroid Build Coastguard Worker   if (s.Stream)
218*f6dc9357SAndroid Build Coastguard Worker   {
219*f6dc9357SAndroid Build Coastguard Worker     if ((int)index != Head)
220*f6dc9357SAndroid Build Coastguard Worker     {
221*f6dc9357SAndroid Build Coastguard Worker       RemoveFromList(s);
222*f6dc9357SAndroid Build Coastguard Worker       InsertToList(index);
223*f6dc9357SAndroid Build Coastguard Worker     }
224*f6dc9357SAndroid Build Coastguard Worker   }
225*f6dc9357SAndroid Build Coastguard Worker   else
226*f6dc9357SAndroid Build Coastguard Worker   {
227*f6dc9357SAndroid Build Coastguard Worker     RINOK(PrepareToOpenNew())
228*f6dc9357SAndroid Build Coastguard Worker     {
229*f6dc9357SAndroid Build Coastguard Worker       CInFileStream *inFile = new CInFileStream;
230*f6dc9357SAndroid Build Coastguard Worker       CMyComPtr<IInStream> inStreamTemp = inFile;
231*f6dc9357SAndroid Build Coastguard Worker       if (!inFile->Open(s.Path))
232*f6dc9357SAndroid Build Coastguard Worker         return GetLastError_noZero_HRESULT();
233*f6dc9357SAndroid Build Coastguard Worker       s.FileSpec = inFile;
234*f6dc9357SAndroid Build Coastguard Worker       s.Stream = s.FileSpec;
235*f6dc9357SAndroid Build Coastguard Worker       InsertToList(index);
236*f6dc9357SAndroid Build Coastguard Worker     }
237*f6dc9357SAndroid Build Coastguard Worker     // s.IsOpen = true;
238*f6dc9357SAndroid Build Coastguard Worker     if (s.LocalPos != 0)
239*f6dc9357SAndroid Build Coastguard Worker     {
240*f6dc9357SAndroid Build Coastguard Worker       RINOK(s.Stream->Seek((Int64)s.LocalPos, STREAM_SEEK_SET, &s.LocalPos))
241*f6dc9357SAndroid Build Coastguard Worker     }
242*f6dc9357SAndroid Build Coastguard Worker    #ifdef DEBUG_VOLUMES
243*f6dc9357SAndroid Build Coastguard Worker     static int numOpens = 0;
244*f6dc9357SAndroid Build Coastguard Worker     numOpens++;
245*f6dc9357SAndroid Build Coastguard Worker     printf("\n-- %u, ReOpen, total_reopens = %u, num_open_files = %u\n", index, numOpens, NumListItems);
246*f6dc9357SAndroid Build Coastguard Worker    #endif
247*f6dc9357SAndroid Build Coastguard Worker   }
248*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
249*f6dc9357SAndroid Build Coastguard Worker }
250*f6dc9357SAndroid Build Coastguard Worker 
251*f6dc9357SAndroid Build Coastguard Worker 
252*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CInFileStreamVol::Read(void *data, UInt32 size, UInt32 *processedSize))
253*f6dc9357SAndroid Build Coastguard Worker {
254*f6dc9357SAndroid Build Coastguard Worker   if (processedSize)
255*f6dc9357SAndroid Build Coastguard Worker     *processedSize = 0;
256*f6dc9357SAndroid Build Coastguard Worker   if (size == 0)
257*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
258*f6dc9357SAndroid Build Coastguard Worker   RINOK(EnsureOpen())
259*f6dc9357SAndroid Build Coastguard Worker   CMultiStreams::CSubStream &s = OpenCallbackImp->Volumes.Streams[FileIndex];
260*f6dc9357SAndroid Build Coastguard Worker   PRF(printf("\n== %u, Read =%u \n", FileIndex, size));
261*f6dc9357SAndroid Build Coastguard Worker   return s.Stream->Read(data, size, processedSize);
262*f6dc9357SAndroid Build Coastguard Worker }
263*f6dc9357SAndroid Build Coastguard Worker 
264*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CInFileStreamVol::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition))
265*f6dc9357SAndroid Build Coastguard Worker {
266*f6dc9357SAndroid Build Coastguard Worker   // if (seekOrigin >= 3) return STG_E_INVALIDFUNCTION;
267*f6dc9357SAndroid Build Coastguard Worker   RINOK(EnsureOpen())
268*f6dc9357SAndroid Build Coastguard Worker   CMultiStreams::CSubStream &s = OpenCallbackImp->Volumes.Streams[FileIndex];
269*f6dc9357SAndroid Build Coastguard Worker   PRF(printf("\n-- %u, Seek seekOrigin=%u Seek =%u\n", FileIndex, seekOrigin, (unsigned)offset));
270*f6dc9357SAndroid Build Coastguard Worker   return s.Stream->Seek(offset, seekOrigin, newPosition);
271*f6dc9357SAndroid Build Coastguard Worker }
272*f6dc9357SAndroid Build Coastguard Worker 
273*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CInFileStreamVol::GetSize(UInt64 *size))
274*f6dc9357SAndroid Build Coastguard Worker {
275*f6dc9357SAndroid Build Coastguard Worker   RINOK(EnsureOpen())
276*f6dc9357SAndroid Build Coastguard Worker   CMultiStreams::CSubStream &s = OpenCallbackImp->Volumes.Streams[FileIndex];
277*f6dc9357SAndroid Build Coastguard Worker   return s.FileSpec->GetSize(size);
278*f6dc9357SAndroid Build Coastguard Worker }
279*f6dc9357SAndroid Build Coastguard Worker 
280*f6dc9357SAndroid Build Coastguard Worker 
281*f6dc9357SAndroid Build Coastguard Worker // from ArchiveExtractCallback.cpp
282*f6dc9357SAndroid Build Coastguard Worker bool IsSafePath(const UString &path);
283*f6dc9357SAndroid Build Coastguard Worker 
284*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStream))
285*f6dc9357SAndroid Build Coastguard Worker {
286*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
287*f6dc9357SAndroid Build Coastguard Worker   *inStream = NULL;
288*f6dc9357SAndroid Build Coastguard Worker 
289*f6dc9357SAndroid Build Coastguard Worker   if (_subArchiveMode)
290*f6dc9357SAndroid Build Coastguard Worker     return S_FALSE;
291*f6dc9357SAndroid Build Coastguard Worker   if (Callback)
292*f6dc9357SAndroid Build Coastguard Worker   {
293*f6dc9357SAndroid Build Coastguard Worker     RINOK(Callback->Open_CheckBreak())
294*f6dc9357SAndroid Build Coastguard Worker   }
295*f6dc9357SAndroid Build Coastguard Worker 
296*f6dc9357SAndroid Build Coastguard Worker   UString name2 = name;
297*f6dc9357SAndroid Build Coastguard Worker 
298*f6dc9357SAndroid Build Coastguard Worker 
299*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_SFX
300*f6dc9357SAndroid Build Coastguard Worker 
301*f6dc9357SAndroid Build Coastguard Worker   #ifdef _WIN32
302*f6dc9357SAndroid Build Coastguard Worker   name2.Replace(L'/', WCHAR_PATH_SEPARATOR);
303*f6dc9357SAndroid Build Coastguard Worker   #endif
304*f6dc9357SAndroid Build Coastguard Worker 
305*f6dc9357SAndroid Build Coastguard Worker   // if (!allowAbsVolPaths)
306*f6dc9357SAndroid Build Coastguard Worker   if (!IsSafePath(name2))
307*f6dc9357SAndroid Build Coastguard Worker     return S_FALSE;
308*f6dc9357SAndroid Build Coastguard Worker 
309*f6dc9357SAndroid Build Coastguard Worker   #ifdef _WIN32
310*f6dc9357SAndroid Build Coastguard Worker   /* WIN32 allows wildcards in Find() function
311*f6dc9357SAndroid Build Coastguard Worker      and doesn't allow wildcard in File.Open()
312*f6dc9357SAndroid Build Coastguard Worker      so we can work without the following wildcard check here */
313*f6dc9357SAndroid Build Coastguard Worker   if (name2.Find(L'*') >= 0)
314*f6dc9357SAndroid Build Coastguard Worker     return S_FALSE;
315*f6dc9357SAndroid Build Coastguard Worker   {
316*f6dc9357SAndroid Build Coastguard Worker     unsigned startPos = 0;
317*f6dc9357SAndroid Build Coastguard Worker     if (name2.IsPrefixedBy_Ascii_NoCase("\\\\?\\"))
318*f6dc9357SAndroid Build Coastguard Worker       startPos = 3;
319*f6dc9357SAndroid Build Coastguard Worker     if (name2.Find(L'?', startPos) >= 0)
320*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
321*f6dc9357SAndroid Build Coastguard Worker   }
322*f6dc9357SAndroid Build Coastguard Worker   #endif
323*f6dc9357SAndroid Build Coastguard Worker 
324*f6dc9357SAndroid Build Coastguard Worker   #endif
325*f6dc9357SAndroid Build Coastguard Worker 
326*f6dc9357SAndroid Build Coastguard Worker 
327*f6dc9357SAndroid Build Coastguard Worker   FString fullPath;
328*f6dc9357SAndroid Build Coastguard Worker   if (!NFile::NName::GetFullPath(_folderPrefix, us2fs(name2), fullPath))
329*f6dc9357SAndroid Build Coastguard Worker     return S_FALSE;
330*f6dc9357SAndroid Build Coastguard Worker   if (!_fileInfo.Find_FollowLink(fullPath))
331*f6dc9357SAndroid Build Coastguard Worker     return S_FALSE;
332*f6dc9357SAndroid Build Coastguard Worker   if (_fileInfo.IsDir())
333*f6dc9357SAndroid Build Coastguard Worker     return S_FALSE;
334*f6dc9357SAndroid Build Coastguard Worker 
335*f6dc9357SAndroid Build Coastguard Worker   CMultiStreams::CSubStream s;
336*f6dc9357SAndroid Build Coastguard Worker 
337*f6dc9357SAndroid Build Coastguard Worker   {
338*f6dc9357SAndroid Build Coastguard Worker     CInFileStream *inFile = new CInFileStream;
339*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<IInStream> inStreamTemp = inFile;
340*f6dc9357SAndroid Build Coastguard Worker     if (!inFile->Open(fullPath))
341*f6dc9357SAndroid Build Coastguard Worker       return GetLastError_noZero_HRESULT();
342*f6dc9357SAndroid Build Coastguard Worker     RINOK(Volumes.PrepareToOpenNew())
343*f6dc9357SAndroid Build Coastguard Worker     s.FileSpec = inFile;
344*f6dc9357SAndroid Build Coastguard Worker     s.Stream = s.FileSpec;
345*f6dc9357SAndroid Build Coastguard Worker     s.Path = fullPath;
346*f6dc9357SAndroid Build Coastguard Worker     // s.Size = _fileInfo.Size;
347*f6dc9357SAndroid Build Coastguard Worker     // s.IsOpen = true;
348*f6dc9357SAndroid Build Coastguard Worker   }
349*f6dc9357SAndroid Build Coastguard Worker 
350*f6dc9357SAndroid Build Coastguard Worker   const unsigned fileIndex = Volumes.Streams.Add(s);
351*f6dc9357SAndroid Build Coastguard Worker   Volumes.InsertToList(fileIndex);
352*f6dc9357SAndroid Build Coastguard Worker 
353*f6dc9357SAndroid Build Coastguard Worker   FileSizes.Add(_fileInfo.Size);
354*f6dc9357SAndroid Build Coastguard Worker   FileNames.Add(name2);
355*f6dc9357SAndroid Build Coastguard Worker   FileNames_WasUsed.Add(true);
356*f6dc9357SAndroid Build Coastguard Worker 
357*f6dc9357SAndroid Build Coastguard Worker   CInFileStreamVol *inFile = new CInFileStreamVol;
358*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<IInStream> inStreamTemp = inFile;
359*f6dc9357SAndroid Build Coastguard Worker   inFile->FileIndex = fileIndex;
360*f6dc9357SAndroid Build Coastguard Worker   inFile->OpenCallbackImp = this;
361*f6dc9357SAndroid Build Coastguard Worker   inFile->OpenCallbackRef = this;
362*f6dc9357SAndroid Build Coastguard Worker   // TotalSize += _fileInfo.Size;
363*f6dc9357SAndroid Build Coastguard Worker   *inStream = inStreamTemp.Detach();
364*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
365*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
366*f6dc9357SAndroid Build Coastguard Worker }
367*f6dc9357SAndroid Build Coastguard Worker 
368*f6dc9357SAndroid Build Coastguard Worker 
369*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_NO_CRYPTO
370*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(COpenCallbackImp::CryptoGetTextPassword(BSTR *password))
371*f6dc9357SAndroid Build Coastguard Worker {
372*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
373*f6dc9357SAndroid Build Coastguard Worker   if (ReOpenCallback)
374*f6dc9357SAndroid Build Coastguard Worker   {
375*f6dc9357SAndroid Build Coastguard Worker     Z7_DECL_CMyComPtr_QI_FROM(
376*f6dc9357SAndroid Build Coastguard Worker         ICryptoGetTextPassword,
377*f6dc9357SAndroid Build Coastguard Worker         getTextPassword, ReOpenCallback)
378*f6dc9357SAndroid Build Coastguard Worker     if (getTextPassword)
379*f6dc9357SAndroid Build Coastguard Worker       return getTextPassword->CryptoGetTextPassword(password);
380*f6dc9357SAndroid Build Coastguard Worker   }
381*f6dc9357SAndroid Build Coastguard Worker   if (!Callback)
382*f6dc9357SAndroid Build Coastguard Worker     return E_NOTIMPL;
383*f6dc9357SAndroid Build Coastguard Worker   PasswordWasAsked = true;
384*f6dc9357SAndroid Build Coastguard Worker   return Callback->Open_CryptoGetTextPassword(password);
385*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
386*f6dc9357SAndroid Build Coastguard Worker }
387*f6dc9357SAndroid Build Coastguard Worker #endif
388*f6dc9357SAndroid Build Coastguard Worker 
389*f6dc9357SAndroid Build Coastguard Worker // IProgress
390*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(COpenCallbackImp::SetTotal(const UInt64 /* total */))
391*f6dc9357SAndroid Build Coastguard Worker {
392*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
393*f6dc9357SAndroid Build Coastguard Worker }
394*f6dc9357SAndroid Build Coastguard Worker 
395*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(COpenCallbackImp::SetCompleted(const UInt64 * /* completed */))
396*f6dc9357SAndroid Build Coastguard Worker {
397*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
398*f6dc9357SAndroid Build Coastguard Worker }
399