xref: /aosp_15_r20/external/lzma/CPP/7zip/Archive/HandlerCont.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // HandlerCont.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 "../Common/LimitedStreams.h"
8*f6dc9357SAndroid Build Coastguard Worker #include "../Common/ProgressUtils.h"
9*f6dc9357SAndroid Build Coastguard Worker #include "../Common/StreamUtils.h"
10*f6dc9357SAndroid Build Coastguard Worker 
11*f6dc9357SAndroid Build Coastguard Worker #include "../Compress/CopyCoder.h"
12*f6dc9357SAndroid Build Coastguard Worker 
13*f6dc9357SAndroid Build Coastguard Worker #include "HandlerCont.h"
14*f6dc9357SAndroid Build Coastguard Worker 
15*f6dc9357SAndroid Build Coastguard Worker namespace NArchive {
16*f6dc9357SAndroid Build Coastguard Worker 
17*f6dc9357SAndroid Build Coastguard Worker namespace NExt {
18*f6dc9357SAndroid Build Coastguard Worker API_FUNC_IsArc IsArc_Ext(const Byte *p, size_t size);
19*f6dc9357SAndroid Build Coastguard Worker }
20*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandlerCont::Extract (const UInt32 * indices,UInt32 numItems,Int32 testMode,IArchiveExtractCallback * extractCallback))21*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandlerCont::Extract(const UInt32 *indices, UInt32 numItems,
22*f6dc9357SAndroid Build Coastguard Worker     Int32 testMode, IArchiveExtractCallback *extractCallback))
23*f6dc9357SAndroid Build Coastguard Worker {
24*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
25*f6dc9357SAndroid Build Coastguard Worker   const bool allFilesMode = (numItems == (UInt32)(Int32)-1);
26*f6dc9357SAndroid Build Coastguard Worker   if (allFilesMode)
27*f6dc9357SAndroid Build Coastguard Worker   {
28*f6dc9357SAndroid Build Coastguard Worker     RINOK(GetNumberOfItems(&numItems))
29*f6dc9357SAndroid Build Coastguard Worker   }
30*f6dc9357SAndroid Build Coastguard Worker   if (numItems == 0)
31*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
32*f6dc9357SAndroid Build Coastguard Worker   UInt64 totalSize = 0;
33*f6dc9357SAndroid Build Coastguard Worker   UInt32 i;
34*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < numItems; i++)
35*f6dc9357SAndroid Build Coastguard Worker   {
36*f6dc9357SAndroid Build Coastguard Worker     UInt64 pos, size;
37*f6dc9357SAndroid Build Coastguard Worker     GetItem_ExtractInfo(allFilesMode ? i : indices[i], pos, size);
38*f6dc9357SAndroid Build Coastguard Worker     totalSize += size;
39*f6dc9357SAndroid Build Coastguard Worker   }
40*f6dc9357SAndroid Build Coastguard Worker   RINOK(extractCallback->SetTotal(totalSize))
41*f6dc9357SAndroid Build Coastguard Worker 
42*f6dc9357SAndroid Build Coastguard Worker   totalSize = 0;
43*f6dc9357SAndroid Build Coastguard Worker 
44*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr2_Create<ICompressProgressInfo, CLocalProgress> lps;
45*f6dc9357SAndroid Build Coastguard Worker   lps->Init(extractCallback, false);
46*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr2_Create<ISequentialInStream, CLimitedSequentialInStream> streamSpec;
47*f6dc9357SAndroid Build Coastguard Worker   streamSpec->SetStream(_stream);
48*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr2_Create<ICompressCoder, NCompress::CCopyCoder> copyCoder;
49*f6dc9357SAndroid Build Coastguard Worker 
50*f6dc9357SAndroid Build Coastguard Worker   for (i = 0;; i++)
51*f6dc9357SAndroid Build Coastguard Worker   {
52*f6dc9357SAndroid Build Coastguard Worker     lps->InSize = totalSize;
53*f6dc9357SAndroid Build Coastguard Worker     lps->OutSize = totalSize;
54*f6dc9357SAndroid Build Coastguard Worker     RINOK(lps->SetCur())
55*f6dc9357SAndroid Build Coastguard Worker     if (i >= numItems)
56*f6dc9357SAndroid Build Coastguard Worker       break;
57*f6dc9357SAndroid Build Coastguard Worker 
58*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<ISequentialOutStream> outStream;
59*f6dc9357SAndroid Build Coastguard Worker     const Int32 askMode = testMode ?
60*f6dc9357SAndroid Build Coastguard Worker         NExtract::NAskMode::kTest :
61*f6dc9357SAndroid Build Coastguard Worker         NExtract::NAskMode::kExtract;
62*f6dc9357SAndroid Build Coastguard Worker     const UInt32 index = allFilesMode ? i : indices[i];
63*f6dc9357SAndroid Build Coastguard Worker 
64*f6dc9357SAndroid Build Coastguard Worker     RINOK(extractCallback->GetStream(index, &outStream, askMode))
65*f6dc9357SAndroid Build Coastguard Worker 
66*f6dc9357SAndroid Build Coastguard Worker     UInt64 pos, size;
67*f6dc9357SAndroid Build Coastguard Worker     int opRes = GetItem_ExtractInfo(index, pos, size);
68*f6dc9357SAndroid Build Coastguard Worker     totalSize += size;
69*f6dc9357SAndroid Build Coastguard Worker     if (!testMode && !outStream)
70*f6dc9357SAndroid Build Coastguard Worker       continue;
71*f6dc9357SAndroid Build Coastguard Worker 
72*f6dc9357SAndroid Build Coastguard Worker     RINOK(extractCallback->PrepareOperation(askMode))
73*f6dc9357SAndroid Build Coastguard Worker 
74*f6dc9357SAndroid Build Coastguard Worker     if (opRes == NExtract::NOperationResult::kOK)
75*f6dc9357SAndroid Build Coastguard Worker     {
76*f6dc9357SAndroid Build Coastguard Worker       RINOK(InStream_SeekSet(_stream, pos))
77*f6dc9357SAndroid Build Coastguard Worker       streamSpec->Init(size);
78*f6dc9357SAndroid Build Coastguard Worker 
79*f6dc9357SAndroid Build Coastguard Worker       RINOK(copyCoder.Interface()->Code(streamSpec, outStream, NULL, NULL, lps))
80*f6dc9357SAndroid Build Coastguard Worker 
81*f6dc9357SAndroid Build Coastguard Worker       opRes = NExtract::NOperationResult::kDataError;
82*f6dc9357SAndroid Build Coastguard Worker       if (copyCoder->TotalSize == size)
83*f6dc9357SAndroid Build Coastguard Worker         opRes = NExtract::NOperationResult::kOK;
84*f6dc9357SAndroid Build Coastguard Worker       else if (copyCoder->TotalSize < size)
85*f6dc9357SAndroid Build Coastguard Worker         opRes = NExtract::NOperationResult::kUnexpectedEnd;
86*f6dc9357SAndroid Build Coastguard Worker     }
87*f6dc9357SAndroid Build Coastguard Worker 
88*f6dc9357SAndroid Build Coastguard Worker     outStream.Release();
89*f6dc9357SAndroid Build Coastguard Worker     RINOK(extractCallback->SetOperationResult(opRes))
90*f6dc9357SAndroid Build Coastguard Worker   }
91*f6dc9357SAndroid Build Coastguard Worker 
92*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
93*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
94*f6dc9357SAndroid Build Coastguard Worker }
95*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandlerCont::GetStream (UInt32 index,ISequentialInStream ** stream))96*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandlerCont::GetStream(UInt32 index, ISequentialInStream **stream))
97*f6dc9357SAndroid Build Coastguard Worker {
98*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
99*f6dc9357SAndroid Build Coastguard Worker   *stream = NULL;
100*f6dc9357SAndroid Build Coastguard Worker   UInt64 pos, size;
101*f6dc9357SAndroid Build Coastguard Worker   if (GetItem_ExtractInfo(index, pos, size) != NExtract::NOperationResult::kOK)
102*f6dc9357SAndroid Build Coastguard Worker     return S_FALSE;
103*f6dc9357SAndroid Build Coastguard Worker   return CreateLimitedInStream(_stream, pos, size, stream);
104*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
105*f6dc9357SAndroid Build Coastguard Worker }
106*f6dc9357SAndroid Build Coastguard Worker 
107*f6dc9357SAndroid Build Coastguard Worker 
108*f6dc9357SAndroid Build Coastguard Worker 
CHandlerImg()109*f6dc9357SAndroid Build Coastguard Worker CHandlerImg::CHandlerImg()
110*f6dc9357SAndroid Build Coastguard Worker {
111*f6dc9357SAndroid Build Coastguard Worker   Clear_HandlerImg_Vars();
112*f6dc9357SAndroid Build Coastguard Worker }
113*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandlerImg::Seek (Int64 offset,UInt32 seekOrigin,UInt64 * newPosition))114*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandlerImg::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition))
115*f6dc9357SAndroid Build Coastguard Worker {
116*f6dc9357SAndroid Build Coastguard Worker   switch (seekOrigin)
117*f6dc9357SAndroid Build Coastguard Worker   {
118*f6dc9357SAndroid Build Coastguard Worker     case STREAM_SEEK_SET: break;
119*f6dc9357SAndroid Build Coastguard Worker     case STREAM_SEEK_CUR: offset += _virtPos; break;
120*f6dc9357SAndroid Build Coastguard Worker     case STREAM_SEEK_END: offset += _size; break;
121*f6dc9357SAndroid Build Coastguard Worker     default: return STG_E_INVALIDFUNCTION;
122*f6dc9357SAndroid Build Coastguard Worker   }
123*f6dc9357SAndroid Build Coastguard Worker   if (offset < 0)
124*f6dc9357SAndroid Build Coastguard Worker   {
125*f6dc9357SAndroid Build Coastguard Worker     if (newPosition)
126*f6dc9357SAndroid Build Coastguard Worker       *newPosition = _virtPos;
127*f6dc9357SAndroid Build Coastguard Worker     return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
128*f6dc9357SAndroid Build Coastguard Worker   }
129*f6dc9357SAndroid Build Coastguard Worker   _virtPos = (UInt64)offset;
130*f6dc9357SAndroid Build Coastguard Worker   if (newPosition)
131*f6dc9357SAndroid Build Coastguard Worker     *newPosition = (UInt64)offset;
132*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
133*f6dc9357SAndroid Build Coastguard Worker }
134*f6dc9357SAndroid Build Coastguard Worker 
135*f6dc9357SAndroid Build Coastguard Worker static const Byte k_GDP_Signature[] =
136*f6dc9357SAndroid Build Coastguard Worker     { 'E', 'F', 'I', ' ', 'P', 'A', 'R', 'T', 0, 0, 1, 0 };
137*f6dc9357SAndroid Build Coastguard Worker // static const Byte k_Ext_Signature[] = { 0x53, 0xEF };
138*f6dc9357SAndroid Build Coastguard Worker // static const unsigned k_Ext_Signature_offset = 0x438;
139*f6dc9357SAndroid Build Coastguard Worker 
GetImgExt(ISequentialInStream * stream)140*f6dc9357SAndroid Build Coastguard Worker static const char *GetImgExt(ISequentialInStream *stream)
141*f6dc9357SAndroid Build Coastguard Worker {
142*f6dc9357SAndroid Build Coastguard Worker   // const size_t kHeaderSize_for_Ext = (1 << 11); // for ext
143*f6dc9357SAndroid Build Coastguard Worker   const size_t kHeaderSize = 2 << 12; // for 4 KB sector GPT
144*f6dc9357SAndroid Build Coastguard Worker   Byte buf[kHeaderSize];
145*f6dc9357SAndroid Build Coastguard Worker   size_t processed = kHeaderSize;
146*f6dc9357SAndroid Build Coastguard Worker   if (ReadStream(stream, buf, &processed) == S_OK)
147*f6dc9357SAndroid Build Coastguard Worker   {
148*f6dc9357SAndroid Build Coastguard Worker     if (processed >= kHeaderSize)
149*f6dc9357SAndroid Build Coastguard Worker     if (buf[0x1FE] == 0x55 && buf[0x1FF] == 0xAA)
150*f6dc9357SAndroid Build Coastguard Worker     {
151*f6dc9357SAndroid Build Coastguard Worker       for (unsigned k = (1 << 9); k <= (1u << 12); k <<= 3)
152*f6dc9357SAndroid Build Coastguard Worker         if (memcmp(buf + k, k_GDP_Signature, sizeof(k_GDP_Signature)) == 0)
153*f6dc9357SAndroid Build Coastguard Worker           return "gpt";
154*f6dc9357SAndroid Build Coastguard Worker       return "mbr";
155*f6dc9357SAndroid Build Coastguard Worker     }
156*f6dc9357SAndroid Build Coastguard Worker     if (NExt::IsArc_Ext(buf, processed) == k_IsArc_Res_YES)
157*f6dc9357SAndroid Build Coastguard Worker       return "ext";
158*f6dc9357SAndroid Build Coastguard Worker   }
159*f6dc9357SAndroid Build Coastguard Worker   return NULL;
160*f6dc9357SAndroid Build Coastguard Worker }
161*f6dc9357SAndroid Build Coastguard Worker 
CloseAtError()162*f6dc9357SAndroid Build Coastguard Worker void CHandlerImg::CloseAtError()
163*f6dc9357SAndroid Build Coastguard Worker {
164*f6dc9357SAndroid Build Coastguard Worker   Stream.Release();
165*f6dc9357SAndroid Build Coastguard Worker }
166*f6dc9357SAndroid Build Coastguard Worker 
Clear_HandlerImg_Vars()167*f6dc9357SAndroid Build Coastguard Worker void CHandlerImg::Clear_HandlerImg_Vars()
168*f6dc9357SAndroid Build Coastguard Worker {
169*f6dc9357SAndroid Build Coastguard Worker   _imgExt = NULL;
170*f6dc9357SAndroid Build Coastguard Worker   _size = 0;
171*f6dc9357SAndroid Build Coastguard Worker   ClearStreamVars();
172*f6dc9357SAndroid Build Coastguard Worker   Reset_VirtPos();
173*f6dc9357SAndroid Build Coastguard Worker   Reset_PosInArc();
174*f6dc9357SAndroid Build Coastguard Worker }
175*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandlerImg::Open (IInStream * stream,const UInt64 *,IArchiveOpenCallback * openCallback))176*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandlerImg::Open(IInStream *stream,
177*f6dc9357SAndroid Build Coastguard Worker     const UInt64 * /* maxCheckStartPosition */,
178*f6dc9357SAndroid Build Coastguard Worker     IArchiveOpenCallback * openCallback))
179*f6dc9357SAndroid Build Coastguard Worker {
180*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
181*f6dc9357SAndroid Build Coastguard Worker   {
182*f6dc9357SAndroid Build Coastguard Worker     Close();
183*f6dc9357SAndroid Build Coastguard Worker     HRESULT res;
184*f6dc9357SAndroid Build Coastguard Worker     try
185*f6dc9357SAndroid Build Coastguard Worker     {
186*f6dc9357SAndroid Build Coastguard Worker       res = Open2(stream, openCallback);
187*f6dc9357SAndroid Build Coastguard Worker       if (res == S_OK)
188*f6dc9357SAndroid Build Coastguard Worker       {
189*f6dc9357SAndroid Build Coastguard Worker         CMyComPtr<ISequentialInStream> inStream;
190*f6dc9357SAndroid Build Coastguard Worker         const HRESULT res2 = GetStream(0, &inStream);
191*f6dc9357SAndroid Build Coastguard Worker         if (res2 == S_OK && inStream)
192*f6dc9357SAndroid Build Coastguard Worker           _imgExt = GetImgExt(inStream);
193*f6dc9357SAndroid Build Coastguard Worker         // _imgExt = GetImgExt(this); // for debug
194*f6dc9357SAndroid Build Coastguard Worker         /*  we reset (_virtPos) to support cases, if some code will
195*f6dc9357SAndroid Build Coastguard Worker             call Read() from Handler object instead of GetStream() object. */
196*f6dc9357SAndroid Build Coastguard Worker         Reset_VirtPos();
197*f6dc9357SAndroid Build Coastguard Worker         // optional: we reset (_posInArc). if real seek position of stream will be changed in external code
198*f6dc9357SAndroid Build Coastguard Worker         Reset_PosInArc();
199*f6dc9357SAndroid Build Coastguard Worker         // optional: here we could also reset seek positions in parent streams..
200*f6dc9357SAndroid Build Coastguard Worker         return S_OK;
201*f6dc9357SAndroid Build Coastguard Worker       }
202*f6dc9357SAndroid Build Coastguard Worker     }
203*f6dc9357SAndroid Build Coastguard Worker     catch(...)
204*f6dc9357SAndroid Build Coastguard Worker     {
205*f6dc9357SAndroid Build Coastguard Worker       CloseAtError();
206*f6dc9357SAndroid Build Coastguard Worker       throw;
207*f6dc9357SAndroid Build Coastguard Worker     }
208*f6dc9357SAndroid Build Coastguard Worker     CloseAtError();
209*f6dc9357SAndroid Build Coastguard Worker     return res;
210*f6dc9357SAndroid Build Coastguard Worker   }
211*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
212*f6dc9357SAndroid Build Coastguard Worker }
213*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandlerImg::GetNumberOfItems (UInt32 * numItems))214*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandlerImg::GetNumberOfItems(UInt32 *numItems))
215*f6dc9357SAndroid Build Coastguard Worker {
216*f6dc9357SAndroid Build Coastguard Worker   *numItems = 1;
217*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
218*f6dc9357SAndroid Build Coastguard Worker }
219*f6dc9357SAndroid Build Coastguard Worker 
220*f6dc9357SAndroid Build Coastguard Worker 
221*f6dc9357SAndroid Build Coastguard Worker Z7_CLASS_IMP_NOQIB_1(
222*f6dc9357SAndroid Build Coastguard Worker   CHandlerImgProgress
223*f6dc9357SAndroid Build Coastguard Worker   , ICompressProgressInfo
224*f6dc9357SAndroid Build Coastguard Worker )
225*f6dc9357SAndroid Build Coastguard Worker public:
226*f6dc9357SAndroid Build Coastguard Worker   CHandlerImg &Handler;
227*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ICompressProgressInfo> _ratioProgress;
228*f6dc9357SAndroid Build Coastguard Worker 
229*f6dc9357SAndroid Build Coastguard Worker   CHandlerImgProgress(CHandlerImg &handler) : Handler(handler) {}
230*f6dc9357SAndroid Build Coastguard Worker };
231*f6dc9357SAndroid Build Coastguard Worker 
232*f6dc9357SAndroid Build Coastguard Worker 
233*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandlerImgProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize))
234*f6dc9357SAndroid Build Coastguard Worker {
235*f6dc9357SAndroid Build Coastguard Worker   UInt64 inSize2;
236*f6dc9357SAndroid Build Coastguard Worker   if (Handler.Get_PackSizeProcessed(inSize2))
237*f6dc9357SAndroid Build Coastguard Worker     inSize = &inSize2;
238*f6dc9357SAndroid Build Coastguard Worker   return _ratioProgress->SetRatioInfo(inSize, outSize);
239*f6dc9357SAndroid Build Coastguard Worker }
240*f6dc9357SAndroid Build Coastguard Worker 
241*f6dc9357SAndroid Build Coastguard Worker 
242*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandlerImg::Extract(const UInt32 *indices, UInt32 numItems,
243*f6dc9357SAndroid Build Coastguard Worker     Int32 testMode, IArchiveExtractCallback *extractCallback))
244*f6dc9357SAndroid Build Coastguard Worker {
245*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
246*f6dc9357SAndroid Build Coastguard Worker   if (numItems == 0)
247*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
248*f6dc9357SAndroid Build Coastguard Worker   if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0))
249*f6dc9357SAndroid Build Coastguard Worker     return E_INVALIDARG;
250*f6dc9357SAndroid Build Coastguard Worker 
251*f6dc9357SAndroid Build Coastguard Worker   RINOK(extractCallback->SetTotal(_size))
252*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ISequentialOutStream> outStream;
253*f6dc9357SAndroid Build Coastguard Worker   const Int32 askMode = testMode ?
254*f6dc9357SAndroid Build Coastguard Worker       NExtract::NAskMode::kTest :
255*f6dc9357SAndroid Build Coastguard Worker       NExtract::NAskMode::kExtract;
256*f6dc9357SAndroid Build Coastguard Worker   RINOK(extractCallback->GetStream(0, &outStream, askMode))
257*f6dc9357SAndroid Build Coastguard Worker   if (!testMode && !outStream)
258*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
259*f6dc9357SAndroid Build Coastguard Worker   RINOK(extractCallback->PrepareOperation(askMode))
260*f6dc9357SAndroid Build Coastguard Worker 
261*f6dc9357SAndroid Build Coastguard Worker   int opRes = NExtract::NOperationResult::kDataError;
262*f6dc9357SAndroid Build Coastguard Worker 
263*f6dc9357SAndroid Build Coastguard Worker   ClearStreamVars();
264*f6dc9357SAndroid Build Coastguard Worker 
265*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ISequentialInStream> inStream;
266*f6dc9357SAndroid Build Coastguard Worker   HRESULT hres = GetStream(0, &inStream);
267*f6dc9357SAndroid Build Coastguard Worker   if (hres == S_FALSE)
268*f6dc9357SAndroid Build Coastguard Worker     hres = E_NOTIMPL;
269*f6dc9357SAndroid Build Coastguard Worker 
270*f6dc9357SAndroid Build Coastguard Worker   if (hres == S_OK && inStream)
271*f6dc9357SAndroid Build Coastguard Worker   {
272*f6dc9357SAndroid Build Coastguard Worker     CLocalProgress *lps = new CLocalProgress;
273*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<ICompressProgressInfo> progress = lps;
274*f6dc9357SAndroid Build Coastguard Worker     lps->Init(extractCallback, false);
275*f6dc9357SAndroid Build Coastguard Worker 
276*f6dc9357SAndroid Build Coastguard Worker     if (Init_PackSizeProcessed())
277*f6dc9357SAndroid Build Coastguard Worker     {
278*f6dc9357SAndroid Build Coastguard Worker       CHandlerImgProgress *imgProgressSpec = new CHandlerImgProgress(*this);
279*f6dc9357SAndroid Build Coastguard Worker       CMyComPtr<ICompressProgressInfo> imgProgress = imgProgressSpec;
280*f6dc9357SAndroid Build Coastguard Worker       imgProgressSpec->_ratioProgress = progress;
281*f6dc9357SAndroid Build Coastguard Worker       progress.Release();
282*f6dc9357SAndroid Build Coastguard Worker       progress = imgProgress;
283*f6dc9357SAndroid Build Coastguard Worker     }
284*f6dc9357SAndroid Build Coastguard Worker 
285*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr2_Create<ICompressCoder, NCompress::CCopyCoder> copyCoder;
286*f6dc9357SAndroid Build Coastguard Worker 
287*f6dc9357SAndroid Build Coastguard Worker     hres = copyCoder.Interface()->Code(inStream, outStream, NULL, &_size, progress);
288*f6dc9357SAndroid Build Coastguard Worker     if (hres == S_OK)
289*f6dc9357SAndroid Build Coastguard Worker     {
290*f6dc9357SAndroid Build Coastguard Worker       if (copyCoder->TotalSize == _size)
291*f6dc9357SAndroid Build Coastguard Worker         opRes = NExtract::NOperationResult::kOK;
292*f6dc9357SAndroid Build Coastguard Worker 
293*f6dc9357SAndroid Build Coastguard Worker       if (_stream_unavailData)
294*f6dc9357SAndroid Build Coastguard Worker         opRes = NExtract::NOperationResult::kUnavailable;
295*f6dc9357SAndroid Build Coastguard Worker       else if (_stream_unsupportedMethod)
296*f6dc9357SAndroid Build Coastguard Worker         opRes = NExtract::NOperationResult::kUnsupportedMethod;
297*f6dc9357SAndroid Build Coastguard Worker       else if (_stream_dataError)
298*f6dc9357SAndroid Build Coastguard Worker         opRes = NExtract::NOperationResult::kDataError;
299*f6dc9357SAndroid Build Coastguard Worker       else if (copyCoder->TotalSize < _size)
300*f6dc9357SAndroid Build Coastguard Worker         opRes = NExtract::NOperationResult::kUnexpectedEnd;
301*f6dc9357SAndroid Build Coastguard Worker     }
302*f6dc9357SAndroid Build Coastguard Worker   }
303*f6dc9357SAndroid Build Coastguard Worker 
304*f6dc9357SAndroid Build Coastguard Worker   inStream.Release();
305*f6dc9357SAndroid Build Coastguard Worker   outStream.Release();
306*f6dc9357SAndroid Build Coastguard Worker 
307*f6dc9357SAndroid Build Coastguard Worker   if (hres != S_OK)
308*f6dc9357SAndroid Build Coastguard Worker   {
309*f6dc9357SAndroid Build Coastguard Worker     if (hres == S_FALSE)
310*f6dc9357SAndroid Build Coastguard Worker       opRes = NExtract::NOperationResult::kDataError;
311*f6dc9357SAndroid Build Coastguard Worker     else if (hres == E_NOTIMPL)
312*f6dc9357SAndroid Build Coastguard Worker       opRes = NExtract::NOperationResult::kUnsupportedMethod;
313*f6dc9357SAndroid Build Coastguard Worker     else
314*f6dc9357SAndroid Build Coastguard Worker       return hres;
315*f6dc9357SAndroid Build Coastguard Worker   }
316*f6dc9357SAndroid Build Coastguard Worker 
317*f6dc9357SAndroid Build Coastguard Worker   return extractCallback->SetOperationResult(opRes);
318*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
319*f6dc9357SAndroid Build Coastguard Worker }
320*f6dc9357SAndroid Build Coastguard Worker 
321*f6dc9357SAndroid Build Coastguard Worker }
322