xref: /aosp_15_r20/external/lzma/CPP/7zip/Archive/Tar/TarUpdate.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // TarUpdate.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 <stdio.h>
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/TimeUtils.h"
8*f6dc9357SAndroid Build Coastguard Worker 
9*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/LimitedStreams.h"
10*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/ProgressUtils.h"
11*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/StreamUtils.h"
12*f6dc9357SAndroid Build Coastguard Worker 
13*f6dc9357SAndroid Build Coastguard Worker #include "../../Compress/CopyCoder.h"
14*f6dc9357SAndroid Build Coastguard Worker 
15*f6dc9357SAndroid Build Coastguard Worker #include "TarOut.h"
16*f6dc9357SAndroid Build Coastguard Worker #include "TarUpdate.h"
17*f6dc9357SAndroid Build Coastguard Worker 
18*f6dc9357SAndroid Build Coastguard Worker namespace NArchive {
19*f6dc9357SAndroid Build Coastguard Worker namespace NTar {
20*f6dc9357SAndroid Build Coastguard Worker 
FILETIME_To_PaxTime(const FILETIME & ft,CPaxTime & pt)21*f6dc9357SAndroid Build Coastguard Worker static void FILETIME_To_PaxTime(const FILETIME &ft, CPaxTime &pt)
22*f6dc9357SAndroid Build Coastguard Worker {
23*f6dc9357SAndroid Build Coastguard Worker   UInt32 ns;
24*f6dc9357SAndroid Build Coastguard Worker   pt.Sec = NWindows::NTime::FileTime_To_UnixTime64_and_Quantums(ft, ns);
25*f6dc9357SAndroid Build Coastguard Worker   pt.Ns = ns * 100;
26*f6dc9357SAndroid Build Coastguard Worker   pt.NumDigits = 7;
27*f6dc9357SAndroid Build Coastguard Worker }
28*f6dc9357SAndroid Build Coastguard Worker 
29*f6dc9357SAndroid Build Coastguard Worker 
Prop_To_PaxTime(const NWindows::NCOM::CPropVariant & prop,CPaxTime & pt)30*f6dc9357SAndroid Build Coastguard Worker HRESULT Prop_To_PaxTime(const NWindows::NCOM::CPropVariant &prop, CPaxTime &pt)
31*f6dc9357SAndroid Build Coastguard Worker {
32*f6dc9357SAndroid Build Coastguard Worker   pt.Clear();
33*f6dc9357SAndroid Build Coastguard Worker   if (prop.vt == VT_EMPTY)
34*f6dc9357SAndroid Build Coastguard Worker   {
35*f6dc9357SAndroid Build Coastguard Worker     // pt.Sec = 0;
36*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
37*f6dc9357SAndroid Build Coastguard Worker   }
38*f6dc9357SAndroid Build Coastguard Worker   if (prop.vt != VT_FILETIME)
39*f6dc9357SAndroid Build Coastguard Worker     return E_INVALIDARG;
40*f6dc9357SAndroid Build Coastguard Worker   {
41*f6dc9357SAndroid Build Coastguard Worker     UInt32 ns;
42*f6dc9357SAndroid Build Coastguard Worker     pt.Sec = NWindows::NTime::FileTime_To_UnixTime64_and_Quantums(prop.filetime, ns);
43*f6dc9357SAndroid Build Coastguard Worker     ns *= 100;
44*f6dc9357SAndroid Build Coastguard Worker     pt.NumDigits = 7;
45*f6dc9357SAndroid Build Coastguard Worker     const unsigned prec = prop.wReserved1;
46*f6dc9357SAndroid Build Coastguard Worker     if (prec >= k_PropVar_TimePrec_Base)
47*f6dc9357SAndroid Build Coastguard Worker     {
48*f6dc9357SAndroid Build Coastguard Worker       pt.NumDigits = (int)(prec - k_PropVar_TimePrec_Base);
49*f6dc9357SAndroid Build Coastguard Worker       if (prop.wReserved2 < 100)
50*f6dc9357SAndroid Build Coastguard Worker         ns += prop.wReserved2;
51*f6dc9357SAndroid Build Coastguard Worker     }
52*f6dc9357SAndroid Build Coastguard Worker     pt.Ns = ns;
53*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
54*f6dc9357SAndroid Build Coastguard Worker   }
55*f6dc9357SAndroid Build Coastguard Worker }
56*f6dc9357SAndroid Build Coastguard Worker 
57*f6dc9357SAndroid Build Coastguard Worker 
GetTime(IStreamGetProp * getProp,UInt32 pid,CPaxTime & pt)58*f6dc9357SAndroid Build Coastguard Worker static HRESULT GetTime(IStreamGetProp *getProp, UInt32 pid, CPaxTime &pt)
59*f6dc9357SAndroid Build Coastguard Worker {
60*f6dc9357SAndroid Build Coastguard Worker   pt.Clear();
61*f6dc9357SAndroid Build Coastguard Worker   NWindows::NCOM::CPropVariant prop;
62*f6dc9357SAndroid Build Coastguard Worker   RINOK(getProp->GetProperty(pid, &prop))
63*f6dc9357SAndroid Build Coastguard Worker   return Prop_To_PaxTime(prop, pt);
64*f6dc9357SAndroid Build Coastguard Worker }
65*f6dc9357SAndroid Build Coastguard Worker 
66*f6dc9357SAndroid Build Coastguard Worker 
GetUser(IStreamGetProp * getProp,UInt32 pidName,UInt32 pidId,AString & name,UInt32 & id,UINT codePage,unsigned utfFlags)67*f6dc9357SAndroid Build Coastguard Worker static HRESULT GetUser(IStreamGetProp *getProp,
68*f6dc9357SAndroid Build Coastguard Worker     UInt32 pidName, UInt32 pidId, AString &name, UInt32 &id,
69*f6dc9357SAndroid Build Coastguard Worker     UINT codePage, unsigned utfFlags)
70*f6dc9357SAndroid Build Coastguard Worker {
71*f6dc9357SAndroid Build Coastguard Worker   // printf("\nGetUser\n");
72*f6dc9357SAndroid Build Coastguard Worker   // we keep  old values, if both   GetProperty() return VT_EMPTY
73*f6dc9357SAndroid Build Coastguard Worker   // we clear old values, if any of GetProperty() returns non-VT_EMPTY;
74*f6dc9357SAndroid Build Coastguard Worker   bool isSet = false;
75*f6dc9357SAndroid Build Coastguard Worker   {
76*f6dc9357SAndroid Build Coastguard Worker     NWindows::NCOM::CPropVariant prop;
77*f6dc9357SAndroid Build Coastguard Worker     RINOK(getProp->GetProperty(pidId, &prop))
78*f6dc9357SAndroid Build Coastguard Worker     if (prop.vt == VT_UI4)
79*f6dc9357SAndroid Build Coastguard Worker     {
80*f6dc9357SAndroid Build Coastguard Worker       isSet = true;
81*f6dc9357SAndroid Build Coastguard Worker       id = prop.ulVal;
82*f6dc9357SAndroid Build Coastguard Worker       name.Empty();
83*f6dc9357SAndroid Build Coastguard Worker     }
84*f6dc9357SAndroid Build Coastguard Worker     else if (prop.vt != VT_EMPTY)
85*f6dc9357SAndroid Build Coastguard Worker       return E_INVALIDARG;
86*f6dc9357SAndroid Build Coastguard Worker   }
87*f6dc9357SAndroid Build Coastguard Worker   {
88*f6dc9357SAndroid Build Coastguard Worker     NWindows::NCOM::CPropVariant prop;
89*f6dc9357SAndroid Build Coastguard Worker     RINOK(getProp->GetProperty(pidName, &prop))
90*f6dc9357SAndroid Build Coastguard Worker     if (prop.vt == VT_BSTR)
91*f6dc9357SAndroid Build Coastguard Worker     {
92*f6dc9357SAndroid Build Coastguard Worker       const UString s = prop.bstrVal;
93*f6dc9357SAndroid Build Coastguard Worker       Get_AString_From_UString(s, name, codePage, utfFlags);
94*f6dc9357SAndroid Build Coastguard Worker       // printf("\ngetProp->GetProperty(pidName, &prop) : %s" , name.Ptr());
95*f6dc9357SAndroid Build Coastguard Worker       if (!isSet)
96*f6dc9357SAndroid Build Coastguard Worker         id = 0;
97*f6dc9357SAndroid Build Coastguard Worker     }
98*f6dc9357SAndroid Build Coastguard Worker     else if (prop.vt == VT_UI4)
99*f6dc9357SAndroid Build Coastguard Worker     {
100*f6dc9357SAndroid Build Coastguard Worker       id = prop.ulVal;
101*f6dc9357SAndroid Build Coastguard Worker       name.Empty();
102*f6dc9357SAndroid Build Coastguard Worker     }
103*f6dc9357SAndroid Build Coastguard Worker     else if (prop.vt != VT_EMPTY)
104*f6dc9357SAndroid Build Coastguard Worker       return E_INVALIDARG;
105*f6dc9357SAndroid Build Coastguard Worker   }
106*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
107*f6dc9357SAndroid Build Coastguard Worker }
108*f6dc9357SAndroid Build Coastguard Worker 
109*f6dc9357SAndroid Build Coastguard Worker 
110*f6dc9357SAndroid Build Coastguard Worker /*
111*f6dc9357SAndroid Build Coastguard Worker static HRESULT GetDevice(IStreamGetProp *getProp,
112*f6dc9357SAndroid Build Coastguard Worker     UInt32 &majo, UInt32 &mino, bool &majo_defined, bool &mino_defined)
113*f6dc9357SAndroid Build Coastguard Worker {
114*f6dc9357SAndroid Build Coastguard Worker   NWindows::NCOM::CPropVariant prop;
115*f6dc9357SAndroid Build Coastguard Worker   RINOK(getProp->GetProperty(kpidDevice, &prop));
116*f6dc9357SAndroid Build Coastguard Worker   if (prop.vt == VT_EMPTY)
117*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
118*f6dc9357SAndroid Build Coastguard Worker   if (prop.vt != VT_UI8)
119*f6dc9357SAndroid Build Coastguard Worker     return E_INVALIDARG;
120*f6dc9357SAndroid Build Coastguard Worker   {
121*f6dc9357SAndroid Build Coastguard Worker     printf("\nTarUpdate.cpp :: GetDevice()\n");
122*f6dc9357SAndroid Build Coastguard Worker     const UInt64 v = prop.uhVal.QuadPart;
123*f6dc9357SAndroid Build Coastguard Worker     majo = MY_dev_major(v);
124*f6dc9357SAndroid Build Coastguard Worker     mino = MY_dev_minor(v);
125*f6dc9357SAndroid Build Coastguard Worker     majo_defined = true;
126*f6dc9357SAndroid Build Coastguard Worker     mino_defined = true;
127*f6dc9357SAndroid Build Coastguard Worker   }
128*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
129*f6dc9357SAndroid Build Coastguard Worker }
130*f6dc9357SAndroid Build Coastguard Worker */
131*f6dc9357SAndroid Build Coastguard Worker 
GetDevice(IStreamGetProp * getProp,UInt32 pid,UInt32 & id,bool & defined)132*f6dc9357SAndroid Build Coastguard Worker static HRESULT GetDevice(IStreamGetProp *getProp,
133*f6dc9357SAndroid Build Coastguard Worker     UInt32 pid, UInt32 &id, bool &defined)
134*f6dc9357SAndroid Build Coastguard Worker {
135*f6dc9357SAndroid Build Coastguard Worker   defined = false;
136*f6dc9357SAndroid Build Coastguard Worker   NWindows::NCOM::CPropVariant prop;
137*f6dc9357SAndroid Build Coastguard Worker   RINOK(getProp->GetProperty(pid, &prop))
138*f6dc9357SAndroid Build Coastguard Worker   if (prop.vt == VT_EMPTY)
139*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
140*f6dc9357SAndroid Build Coastguard Worker   if (prop.vt == VT_UI4)
141*f6dc9357SAndroid Build Coastguard Worker   {
142*f6dc9357SAndroid Build Coastguard Worker     id = prop.ulVal;
143*f6dc9357SAndroid Build Coastguard Worker     defined = true;
144*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
145*f6dc9357SAndroid Build Coastguard Worker   }
146*f6dc9357SAndroid Build Coastguard Worker   return E_INVALIDARG;
147*f6dc9357SAndroid Build Coastguard Worker }
148*f6dc9357SAndroid Build Coastguard Worker 
149*f6dc9357SAndroid Build Coastguard Worker 
UpdateArchive(IInStream * inStream,ISequentialOutStream * outStream,const CObjectVector<NArchive::NTar::CItemEx> & inputItems,const CObjectVector<CUpdateItem> & updateItems,const CUpdateOptions & options,IArchiveUpdateCallback * updateCallback)150*f6dc9357SAndroid Build Coastguard Worker HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
151*f6dc9357SAndroid Build Coastguard Worker     const CObjectVector<NArchive::NTar::CItemEx> &inputItems,
152*f6dc9357SAndroid Build Coastguard Worker     const CObjectVector<CUpdateItem> &updateItems,
153*f6dc9357SAndroid Build Coastguard Worker     const CUpdateOptions &options,
154*f6dc9357SAndroid Build Coastguard Worker     IArchiveUpdateCallback *updateCallback)
155*f6dc9357SAndroid Build Coastguard Worker {
156*f6dc9357SAndroid Build Coastguard Worker   COutArchive outArchive;
157*f6dc9357SAndroid Build Coastguard Worker   outArchive.Create(outStream);
158*f6dc9357SAndroid Build Coastguard Worker   outArchive.Pos = 0;
159*f6dc9357SAndroid Build Coastguard Worker   outArchive.IsPosixMode = options.PosixMode;
160*f6dc9357SAndroid Build Coastguard Worker   outArchive.TimeOptions = options.TimeOptions;
161*f6dc9357SAndroid Build Coastguard Worker 
162*f6dc9357SAndroid Build Coastguard Worker   Z7_DECL_CMyComPtr_QI_FROM(IOutStream, outSeekStream, outStream)
163*f6dc9357SAndroid Build Coastguard Worker   Z7_DECL_CMyComPtr_QI_FROM(IStreamSetRestriction, setRestriction, outStream)
164*f6dc9357SAndroid Build Coastguard Worker   Z7_DECL_CMyComPtr_QI_FROM(IArchiveUpdateCallbackFile, opCallback, outStream)
165*f6dc9357SAndroid Build Coastguard Worker 
166*f6dc9357SAndroid Build Coastguard Worker   if (outSeekStream)
167*f6dc9357SAndroid Build Coastguard Worker   {
168*f6dc9357SAndroid Build Coastguard Worker     /*
169*f6dc9357SAndroid Build Coastguard Worker     // for debug
170*f6dc9357SAndroid Build Coastguard Worker     Byte buf[1 << 14];
171*f6dc9357SAndroid Build Coastguard Worker     memset (buf, 0, sizeof(buf));
172*f6dc9357SAndroid Build Coastguard Worker     RINOK(outStream->Write(buf, sizeof(buf), NULL));
173*f6dc9357SAndroid Build Coastguard Worker     */
174*f6dc9357SAndroid Build Coastguard Worker     // we need real outArchive.Pos, if outSeekStream->SetSize() will be used.
175*f6dc9357SAndroid Build Coastguard Worker     RINOK(outSeekStream->Seek(0, STREAM_SEEK_CUR, &outArchive.Pos))
176*f6dc9357SAndroid Build Coastguard Worker   }
177*f6dc9357SAndroid Build Coastguard Worker   if (setRestriction)
178*f6dc9357SAndroid Build Coastguard Worker     RINOK(setRestriction->SetRestriction(0, 0))
179*f6dc9357SAndroid Build Coastguard Worker 
180*f6dc9357SAndroid Build Coastguard Worker   UInt64 complexity = 0;
181*f6dc9357SAndroid Build Coastguard Worker 
182*f6dc9357SAndroid Build Coastguard Worker   unsigned i;
183*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < updateItems.Size(); i++)
184*f6dc9357SAndroid Build Coastguard Worker   {
185*f6dc9357SAndroid Build Coastguard Worker     const CUpdateItem &ui = updateItems[i];
186*f6dc9357SAndroid Build Coastguard Worker     if (ui.NewData)
187*f6dc9357SAndroid Build Coastguard Worker     {
188*f6dc9357SAndroid Build Coastguard Worker       if (ui.Size == (UInt64)(Int64)-1)
189*f6dc9357SAndroid Build Coastguard Worker         break;
190*f6dc9357SAndroid Build Coastguard Worker       complexity += ui.Size;
191*f6dc9357SAndroid Build Coastguard Worker     }
192*f6dc9357SAndroid Build Coastguard Worker     else
193*f6dc9357SAndroid Build Coastguard Worker       complexity += inputItems[(unsigned)ui.IndexInArc].Get_FullSize_Aligned();
194*f6dc9357SAndroid Build Coastguard Worker   }
195*f6dc9357SAndroid Build Coastguard Worker 
196*f6dc9357SAndroid Build Coastguard Worker   if (i == updateItems.Size())
197*f6dc9357SAndroid Build Coastguard Worker     RINOK(updateCallback->SetTotal(complexity))
198*f6dc9357SAndroid Build Coastguard Worker 
199*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr2_Create<ICompressProgressInfo, CLocalProgress> lps;
200*f6dc9357SAndroid Build Coastguard Worker   lps->Init(updateCallback, true);
201*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr2_Create<ICompressCoder, NCompress::CCopyCoder> copyCoder;
202*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr2_Create<ISequentialInStream, CLimitedSequentialInStream> inStreamLimited;
203*f6dc9357SAndroid Build Coastguard Worker   inStreamLimited->SetStream(inStream);
204*f6dc9357SAndroid Build Coastguard Worker 
205*f6dc9357SAndroid Build Coastguard Worker   complexity = 0;
206*f6dc9357SAndroid Build Coastguard Worker 
207*f6dc9357SAndroid Build Coastguard Worker   // const int kNumReduceDigits = -1; // for debug
208*f6dc9357SAndroid Build Coastguard Worker 
209*f6dc9357SAndroid Build Coastguard Worker   for (i = 0;; i++)
210*f6dc9357SAndroid Build Coastguard Worker   {
211*f6dc9357SAndroid Build Coastguard Worker     lps->InSize = lps->OutSize = complexity;
212*f6dc9357SAndroid Build Coastguard Worker     RINOK(lps->SetCur())
213*f6dc9357SAndroid Build Coastguard Worker 
214*f6dc9357SAndroid Build Coastguard Worker     if (i == updateItems.Size())
215*f6dc9357SAndroid Build Coastguard Worker     {
216*f6dc9357SAndroid Build Coastguard Worker       if (outSeekStream && setRestriction)
217*f6dc9357SAndroid Build Coastguard Worker         RINOK(setRestriction->SetRestriction(0, 0))
218*f6dc9357SAndroid Build Coastguard Worker       return outArchive.WriteFinishHeader();
219*f6dc9357SAndroid Build Coastguard Worker     }
220*f6dc9357SAndroid Build Coastguard Worker 
221*f6dc9357SAndroid Build Coastguard Worker     const CUpdateItem &ui = updateItems[i];
222*f6dc9357SAndroid Build Coastguard Worker     CItem item;
223*f6dc9357SAndroid Build Coastguard Worker 
224*f6dc9357SAndroid Build Coastguard Worker     if (ui.NewProps)
225*f6dc9357SAndroid Build Coastguard Worker     {
226*f6dc9357SAndroid Build Coastguard Worker       item.SetMagic_Posix(options.PosixMode);
227*f6dc9357SAndroid Build Coastguard Worker       item.Name = ui.Name;
228*f6dc9357SAndroid Build Coastguard Worker       item.User = ui.User;
229*f6dc9357SAndroid Build Coastguard Worker       item.Group = ui.Group;
230*f6dc9357SAndroid Build Coastguard Worker       item.UID = ui.UID;
231*f6dc9357SAndroid Build Coastguard Worker       item.GID = ui.GID;
232*f6dc9357SAndroid Build Coastguard Worker       item.DeviceMajor = ui.DeviceMajor;
233*f6dc9357SAndroid Build Coastguard Worker       item.DeviceMinor = ui.DeviceMinor;
234*f6dc9357SAndroid Build Coastguard Worker       item.DeviceMajor_Defined = ui.DeviceMajor_Defined;
235*f6dc9357SAndroid Build Coastguard Worker       item.DeviceMinor_Defined = ui.DeviceMinor_Defined;
236*f6dc9357SAndroid Build Coastguard Worker 
237*f6dc9357SAndroid Build Coastguard Worker       if (ui.IsDir)
238*f6dc9357SAndroid Build Coastguard Worker       {
239*f6dc9357SAndroid Build Coastguard Worker         item.LinkFlag = NFileHeader::NLinkFlag::kDirectory;
240*f6dc9357SAndroid Build Coastguard Worker         item.PackSize = 0;
241*f6dc9357SAndroid Build Coastguard Worker       }
242*f6dc9357SAndroid Build Coastguard Worker       else
243*f6dc9357SAndroid Build Coastguard Worker       {
244*f6dc9357SAndroid Build Coastguard Worker         item.PackSize = ui.Size;
245*f6dc9357SAndroid Build Coastguard Worker         item.Set_LinkFlag_for_File(ui.Mode);
246*f6dc9357SAndroid Build Coastguard Worker       }
247*f6dc9357SAndroid Build Coastguard Worker 
248*f6dc9357SAndroid Build Coastguard Worker       // 22.00
249*f6dc9357SAndroid Build Coastguard Worker       item.Mode = ui.Mode & ~(UInt32)MY_LIN_S_IFMT;
250*f6dc9357SAndroid Build Coastguard Worker       item.PaxTimes = ui.PaxTimes;
251*f6dc9357SAndroid Build Coastguard Worker       // item.PaxTimes.ReducePrecison(kNumReduceDigits); // for debug
252*f6dc9357SAndroid Build Coastguard Worker       item.MTime = ui.PaxTimes.MTime.GetSec();
253*f6dc9357SAndroid Build Coastguard Worker     }
254*f6dc9357SAndroid Build Coastguard Worker     else
255*f6dc9357SAndroid Build Coastguard Worker       item = inputItems[(unsigned)ui.IndexInArc];
256*f6dc9357SAndroid Build Coastguard Worker 
257*f6dc9357SAndroid Build Coastguard Worker     AString symLink;
258*f6dc9357SAndroid Build Coastguard Worker     if (ui.NewData || ui.NewProps)
259*f6dc9357SAndroid Build Coastguard Worker     {
260*f6dc9357SAndroid Build Coastguard Worker       RINOK(GetPropString(updateCallback, ui.IndexInClient, kpidSymLink, symLink,
261*f6dc9357SAndroid Build Coastguard Worker           options.CodePage, options.UtfFlags, true))
262*f6dc9357SAndroid Build Coastguard Worker       if (!symLink.IsEmpty())
263*f6dc9357SAndroid Build Coastguard Worker       {
264*f6dc9357SAndroid Build Coastguard Worker         item.LinkFlag = NFileHeader::NLinkFlag::kSymLink;
265*f6dc9357SAndroid Build Coastguard Worker         item.LinkName = symLink;
266*f6dc9357SAndroid Build Coastguard Worker       }
267*f6dc9357SAndroid Build Coastguard Worker     }
268*f6dc9357SAndroid Build Coastguard Worker 
269*f6dc9357SAndroid Build Coastguard Worker     if (ui.NewData)
270*f6dc9357SAndroid Build Coastguard Worker     {
271*f6dc9357SAndroid Build Coastguard Worker       item.SparseBlocks.Clear();
272*f6dc9357SAndroid Build Coastguard Worker       item.PackSize = ui.Size;
273*f6dc9357SAndroid Build Coastguard Worker       item.Size = ui.Size;
274*f6dc9357SAndroid Build Coastguard Worker #if 0
275*f6dc9357SAndroid Build Coastguard Worker       if (ui.Size == (UInt64)(Int64)-1)
276*f6dc9357SAndroid Build Coastguard Worker         return E_INVALIDARG;
277*f6dc9357SAndroid Build Coastguard Worker #endif
278*f6dc9357SAndroid Build Coastguard Worker       CMyComPtr<ISequentialInStream> fileInStream;
279*f6dc9357SAndroid Build Coastguard Worker 
280*f6dc9357SAndroid Build Coastguard Worker       bool needWrite = true;
281*f6dc9357SAndroid Build Coastguard Worker 
282*f6dc9357SAndroid Build Coastguard Worker       if (!symLink.IsEmpty())
283*f6dc9357SAndroid Build Coastguard Worker       {
284*f6dc9357SAndroid Build Coastguard Worker         item.PackSize = 0;
285*f6dc9357SAndroid Build Coastguard Worker         item.Size = 0;
286*f6dc9357SAndroid Build Coastguard Worker       }
287*f6dc9357SAndroid Build Coastguard Worker       else
288*f6dc9357SAndroid Build Coastguard Worker       {
289*f6dc9357SAndroid Build Coastguard Worker         const HRESULT res = updateCallback->GetStream(ui.IndexInClient, &fileInStream);
290*f6dc9357SAndroid Build Coastguard Worker 
291*f6dc9357SAndroid Build Coastguard Worker         if (res == S_FALSE)
292*f6dc9357SAndroid Build Coastguard Worker           needWrite = false;
293*f6dc9357SAndroid Build Coastguard Worker         else
294*f6dc9357SAndroid Build Coastguard Worker         {
295*f6dc9357SAndroid Build Coastguard Worker           RINOK(res)
296*f6dc9357SAndroid Build Coastguard Worker 
297*f6dc9357SAndroid Build Coastguard Worker           if (!fileInStream)
298*f6dc9357SAndroid Build Coastguard Worker           {
299*f6dc9357SAndroid Build Coastguard Worker             item.PackSize = 0;
300*f6dc9357SAndroid Build Coastguard Worker             item.Size = 0;
301*f6dc9357SAndroid Build Coastguard Worker           }
302*f6dc9357SAndroid Build Coastguard Worker           else
303*f6dc9357SAndroid Build Coastguard Worker           {
304*f6dc9357SAndroid Build Coastguard Worker             Z7_DECL_CMyComPtr_QI_FROM(IStreamGetProp, getProp, fileInStream)
305*f6dc9357SAndroid Build Coastguard Worker             if (getProp)
306*f6dc9357SAndroid Build Coastguard Worker             {
307*f6dc9357SAndroid Build Coastguard Worker               if (options.Write_MTime.Val) RINOK(GetTime(getProp, kpidMTime, item.PaxTimes.MTime))
308*f6dc9357SAndroid Build Coastguard Worker               if (options.Write_ATime.Val) RINOK(GetTime(getProp, kpidATime, item.PaxTimes.ATime))
309*f6dc9357SAndroid Build Coastguard Worker               if (options.Write_CTime.Val) RINOK(GetTime(getProp, kpidCTime, item.PaxTimes.CTime))
310*f6dc9357SAndroid Build Coastguard Worker 
311*f6dc9357SAndroid Build Coastguard Worker               if (options.PosixMode)
312*f6dc9357SAndroid Build Coastguard Worker               {
313*f6dc9357SAndroid Build Coastguard Worker                 /*
314*f6dc9357SAndroid Build Coastguard Worker                 RINOK(GetDevice(getProp, item.DeviceMajor, item.DeviceMinor,
315*f6dc9357SAndroid Build Coastguard Worker                     item.DeviceMajor_Defined, item.DeviceMinor_Defined));
316*f6dc9357SAndroid Build Coastguard Worker                 */
317*f6dc9357SAndroid Build Coastguard Worker                 bool defined = false;
318*f6dc9357SAndroid Build Coastguard Worker                 UInt32 val = 0;
319*f6dc9357SAndroid Build Coastguard Worker                 RINOK(GetDevice(getProp, kpidDeviceMajor, val, defined))
320*f6dc9357SAndroid Build Coastguard Worker                 if (defined)
321*f6dc9357SAndroid Build Coastguard Worker                 {
322*f6dc9357SAndroid Build Coastguard Worker                   item.DeviceMajor = val;
323*f6dc9357SAndroid Build Coastguard Worker                   item.DeviceMajor_Defined = true;
324*f6dc9357SAndroid Build Coastguard Worker                   item.DeviceMinor = 0;
325*f6dc9357SAndroid Build Coastguard Worker                   item.DeviceMinor_Defined = false;
326*f6dc9357SAndroid Build Coastguard Worker                   RINOK(GetDevice(getProp, kpidDeviceMinor, item.DeviceMinor, item.DeviceMinor_Defined))
327*f6dc9357SAndroid Build Coastguard Worker                 }
328*f6dc9357SAndroid Build Coastguard Worker               }
329*f6dc9357SAndroid Build Coastguard Worker 
330*f6dc9357SAndroid Build Coastguard Worker               RINOK(GetUser(getProp, kpidUser,  kpidUserId,  item.User,  item.UID, options.CodePage, options.UtfFlags))
331*f6dc9357SAndroid Build Coastguard Worker               RINOK(GetUser(getProp, kpidGroup, kpidGroupId, item.Group, item.GID, options.CodePage, options.UtfFlags))
332*f6dc9357SAndroid Build Coastguard Worker 
333*f6dc9357SAndroid Build Coastguard Worker               {
334*f6dc9357SAndroid Build Coastguard Worker                 NWindows::NCOM::CPropVariant prop;
335*f6dc9357SAndroid Build Coastguard Worker                 RINOK(getProp->GetProperty(kpidPosixAttrib, &prop))
336*f6dc9357SAndroid Build Coastguard Worker                 if (prop.vt == VT_EMPTY)
337*f6dc9357SAndroid Build Coastguard Worker                   item.Mode =
338*f6dc9357SAndroid Build Coastguard Worker                     MY_LIN_S_IRWXO
339*f6dc9357SAndroid Build Coastguard Worker                   | MY_LIN_S_IRWXG
340*f6dc9357SAndroid Build Coastguard Worker                   | MY_LIN_S_IRWXU
341*f6dc9357SAndroid Build Coastguard Worker                   | (ui.IsDir ? MY_LIN_S_IFDIR : MY_LIN_S_IFREG);
342*f6dc9357SAndroid Build Coastguard Worker                 else if (prop.vt != VT_UI4)
343*f6dc9357SAndroid Build Coastguard Worker                   return E_INVALIDARG;
344*f6dc9357SAndroid Build Coastguard Worker                 else
345*f6dc9357SAndroid Build Coastguard Worker                   item.Mode = prop.ulVal;
346*f6dc9357SAndroid Build Coastguard Worker                 // 21.07 : we clear high file type bits as GNU TAR.
347*f6dc9357SAndroid Build Coastguard Worker                 item.Set_LinkFlag_for_File(item.Mode);
348*f6dc9357SAndroid Build Coastguard Worker                 item.Mode &= ~(UInt32)MY_LIN_S_IFMT;
349*f6dc9357SAndroid Build Coastguard Worker               }
350*f6dc9357SAndroid Build Coastguard Worker 
351*f6dc9357SAndroid Build Coastguard Worker               {
352*f6dc9357SAndroid Build Coastguard Worker                 NWindows::NCOM::CPropVariant prop;
353*f6dc9357SAndroid Build Coastguard Worker                 RINOK(getProp->GetProperty(kpidSize, &prop))
354*f6dc9357SAndroid Build Coastguard Worker                 if (prop.vt != VT_UI8)
355*f6dc9357SAndroid Build Coastguard Worker                   return E_INVALIDARG;
356*f6dc9357SAndroid Build Coastguard Worker                 const UInt64 size = prop.uhVal.QuadPart;
357*f6dc9357SAndroid Build Coastguard Worker                 // printf("\nTAR after GetProperty(kpidSize size = %8d\n", (unsigned)size);
358*f6dc9357SAndroid Build Coastguard Worker                 item.PackSize = size;
359*f6dc9357SAndroid Build Coastguard Worker                 item.Size = size;
360*f6dc9357SAndroid Build Coastguard Worker               }
361*f6dc9357SAndroid Build Coastguard Worker               /*
362*f6dc9357SAndroid Build Coastguard Worker               printf("\nNum digits = %d %d\n",
363*f6dc9357SAndroid Build Coastguard Worker                   (int)item.PaxTimes.MTime.NumDigits,
364*f6dc9357SAndroid Build Coastguard Worker                   (int)item.PaxTimes.MTime.Ns);
365*f6dc9357SAndroid Build Coastguard Worker               */
366*f6dc9357SAndroid Build Coastguard Worker             }
367*f6dc9357SAndroid Build Coastguard Worker             else
368*f6dc9357SAndroid Build Coastguard Worker             {
369*f6dc9357SAndroid Build Coastguard Worker               Z7_DECL_CMyComPtr_QI_FROM(IStreamGetProps, getProps, fileInStream)
370*f6dc9357SAndroid Build Coastguard Worker               if (getProps)
371*f6dc9357SAndroid Build Coastguard Worker               {
372*f6dc9357SAndroid Build Coastguard Worker                 FILETIME mTime, aTime, cTime;
373*f6dc9357SAndroid Build Coastguard Worker                 UInt64 size2;
374*f6dc9357SAndroid Build Coastguard Worker                 if (getProps->GetProps(&size2,
375*f6dc9357SAndroid Build Coastguard Worker                     options.Write_CTime.Val ? &cTime : NULL,
376*f6dc9357SAndroid Build Coastguard Worker                     options.Write_ATime.Val ? &aTime : NULL,
377*f6dc9357SAndroid Build Coastguard Worker                     options.Write_MTime.Val ? &mTime : NULL,
378*f6dc9357SAndroid Build Coastguard Worker                     NULL) == S_OK)
379*f6dc9357SAndroid Build Coastguard Worker                 {
380*f6dc9357SAndroid Build Coastguard Worker                   item.PackSize = size2;
381*f6dc9357SAndroid Build Coastguard Worker                   item.Size = size2;
382*f6dc9357SAndroid Build Coastguard Worker                   if (options.Write_MTime.Val) FILETIME_To_PaxTime(mTime, item.PaxTimes.MTime);
383*f6dc9357SAndroid Build Coastguard Worker                   if (options.Write_ATime.Val) FILETIME_To_PaxTime(aTime, item.PaxTimes.ATime);
384*f6dc9357SAndroid Build Coastguard Worker                   if (options.Write_CTime.Val) FILETIME_To_PaxTime(cTime, item.PaxTimes.CTime);
385*f6dc9357SAndroid Build Coastguard Worker                 }
386*f6dc9357SAndroid Build Coastguard Worker               }
387*f6dc9357SAndroid Build Coastguard Worker             }
388*f6dc9357SAndroid Build Coastguard Worker           }
389*f6dc9357SAndroid Build Coastguard Worker 
390*f6dc9357SAndroid Build Coastguard Worker           {
391*f6dc9357SAndroid Build Coastguard Worker             // we must request kpidHardLink after updateCallback->GetStream()
392*f6dc9357SAndroid Build Coastguard Worker             AString hardLink;
393*f6dc9357SAndroid Build Coastguard Worker             RINOK(GetPropString(updateCallback, ui.IndexInClient, kpidHardLink, hardLink,
394*f6dc9357SAndroid Build Coastguard Worker                 options.CodePage, options.UtfFlags, true))
395*f6dc9357SAndroid Build Coastguard Worker             if (!hardLink.IsEmpty())
396*f6dc9357SAndroid Build Coastguard Worker             {
397*f6dc9357SAndroid Build Coastguard Worker               item.LinkFlag = NFileHeader::NLinkFlag::kHardLink;
398*f6dc9357SAndroid Build Coastguard Worker               item.LinkName = hardLink;
399*f6dc9357SAndroid Build Coastguard Worker               item.PackSize = 0;
400*f6dc9357SAndroid Build Coastguard Worker               item.Size = 0;
401*f6dc9357SAndroid Build Coastguard Worker               fileInStream.Release();
402*f6dc9357SAndroid Build Coastguard Worker             }
403*f6dc9357SAndroid Build Coastguard Worker           }
404*f6dc9357SAndroid Build Coastguard Worker         }
405*f6dc9357SAndroid Build Coastguard Worker       }
406*f6dc9357SAndroid Build Coastguard Worker 
407*f6dc9357SAndroid Build Coastguard Worker       // item.PaxTimes.ReducePrecison(kNumReduceDigits); // for debug
408*f6dc9357SAndroid Build Coastguard Worker 
409*f6dc9357SAndroid Build Coastguard Worker       if (ui.NewProps)
410*f6dc9357SAndroid Build Coastguard Worker         item.MTime = item.PaxTimes.MTime.GetSec();
411*f6dc9357SAndroid Build Coastguard Worker 
412*f6dc9357SAndroid Build Coastguard Worker       if (needWrite)
413*f6dc9357SAndroid Build Coastguard Worker       {
414*f6dc9357SAndroid Build Coastguard Worker         if (fileInStream)
415*f6dc9357SAndroid Build Coastguard Worker         // if (item.PackSize == (UInt64)(Int64)-1)
416*f6dc9357SAndroid Build Coastguard Worker         if (item.Size == (UInt64)(Int64)-1)
417*f6dc9357SAndroid Build Coastguard Worker           return E_INVALIDARG;
418*f6dc9357SAndroid Build Coastguard Worker 
419*f6dc9357SAndroid Build Coastguard Worker         const UInt64 headerPos = outArchive.Pos;
420*f6dc9357SAndroid Build Coastguard Worker         // item.PackSize = ((UInt64)1 << 33); // for debug
421*f6dc9357SAndroid Build Coastguard Worker 
422*f6dc9357SAndroid Build Coastguard Worker         if (outSeekStream && setRestriction)
423*f6dc9357SAndroid Build Coastguard Worker           RINOK(setRestriction->SetRestriction(outArchive.Pos, (UInt64)(Int64)-1))
424*f6dc9357SAndroid Build Coastguard Worker 
425*f6dc9357SAndroid Build Coastguard Worker         RINOK(outArchive.WriteHeader(item))
426*f6dc9357SAndroid Build Coastguard Worker         if (fileInStream)
427*f6dc9357SAndroid Build Coastguard Worker         {
428*f6dc9357SAndroid Build Coastguard Worker           for (unsigned numPasses = 0;; numPasses++)
429*f6dc9357SAndroid Build Coastguard Worker           {
430*f6dc9357SAndroid Build Coastguard Worker             // printf("\nTAR numPasses = %d" " old size = %8d\n", numPasses, (unsigned)item.PackSize);
431*f6dc9357SAndroid Build Coastguard Worker             /* we support 2 attempts to write header:
432*f6dc9357SAndroid Build Coastguard Worker                 pass-0: main pass:
433*f6dc9357SAndroid Build Coastguard Worker                 pass-1: additional pass, if size_of_file and size_of_header are changed */
434*f6dc9357SAndroid Build Coastguard Worker             if (numPasses >= 2)
435*f6dc9357SAndroid Build Coastguard Worker             {
436*f6dc9357SAndroid Build Coastguard Worker               // opRes = NArchive::NUpdate::NOperationResult::kError_FileChanged;
437*f6dc9357SAndroid Build Coastguard Worker               // break;
438*f6dc9357SAndroid Build Coastguard Worker               return E_FAIL;
439*f6dc9357SAndroid Build Coastguard Worker             }
440*f6dc9357SAndroid Build Coastguard Worker 
441*f6dc9357SAndroid Build Coastguard Worker             const UInt64 dataPos = outArchive.Pos;
442*f6dc9357SAndroid Build Coastguard Worker             RINOK(copyCoder.Interface()->Code(fileInStream, outStream, NULL, NULL, lps))
443*f6dc9357SAndroid Build Coastguard Worker             outArchive.Pos += copyCoder->TotalSize;
444*f6dc9357SAndroid Build Coastguard Worker             RINOK(outArchive.Write_AfterDataResidual(copyCoder->TotalSize))
445*f6dc9357SAndroid Build Coastguard Worker             // printf("\nTAR after Code old size = %8d copyCoder->TotalSize = %8d \n", (unsigned)item.PackSize, (unsigned)copyCoder->TotalSize);
446*f6dc9357SAndroid Build Coastguard Worker             // if (numPasses >= 10) // for debug
447*f6dc9357SAndroid Build Coastguard Worker             if (copyCoder->TotalSize == item.PackSize)
448*f6dc9357SAndroid Build Coastguard Worker               break;
449*f6dc9357SAndroid Build Coastguard Worker 
450*f6dc9357SAndroid Build Coastguard Worker             if (opCallback)
451*f6dc9357SAndroid Build Coastguard Worker             {
452*f6dc9357SAndroid Build Coastguard Worker               RINOK(opCallback->ReportOperation(
453*f6dc9357SAndroid Build Coastguard Worker                   NEventIndexType::kOutArcIndex, (UInt32)ui.IndexInClient,
454*f6dc9357SAndroid Build Coastguard Worker                   NUpdateNotifyOp::kInFileChanged))
455*f6dc9357SAndroid Build Coastguard Worker             }
456*f6dc9357SAndroid Build Coastguard Worker 
457*f6dc9357SAndroid Build Coastguard Worker             if (!outSeekStream)
458*f6dc9357SAndroid Build Coastguard Worker               return E_FAIL;
459*f6dc9357SAndroid Build Coastguard Worker             const UInt64 nextPos = outArchive.Pos;
460*f6dc9357SAndroid Build Coastguard Worker             RINOK(outSeekStream->Seek(-(Int64)(nextPos - headerPos), STREAM_SEEK_CUR, NULL))
461*f6dc9357SAndroid Build Coastguard Worker             outArchive.Pos = headerPos;
462*f6dc9357SAndroid Build Coastguard Worker             item.PackSize = copyCoder->TotalSize;
463*f6dc9357SAndroid Build Coastguard Worker 
464*f6dc9357SAndroid Build Coastguard Worker             RINOK(outArchive.WriteHeader(item))
465*f6dc9357SAndroid Build Coastguard Worker 
466*f6dc9357SAndroid Build Coastguard Worker             // if (numPasses >= 10) // for debug
467*f6dc9357SAndroid Build Coastguard Worker             if (outArchive.Pos == dataPos)
468*f6dc9357SAndroid Build Coastguard Worker             {
469*f6dc9357SAndroid Build Coastguard Worker               const UInt64 alignedSize = nextPos - dataPos;
470*f6dc9357SAndroid Build Coastguard Worker               if (alignedSize != 0)
471*f6dc9357SAndroid Build Coastguard Worker               {
472*f6dc9357SAndroid Build Coastguard Worker                 RINOK(outSeekStream->Seek((Int64)alignedSize, STREAM_SEEK_CUR, NULL))
473*f6dc9357SAndroid Build Coastguard Worker                 outArchive.Pos += alignedSize;
474*f6dc9357SAndroid Build Coastguard Worker               }
475*f6dc9357SAndroid Build Coastguard Worker               break;
476*f6dc9357SAndroid Build Coastguard Worker             }
477*f6dc9357SAndroid Build Coastguard Worker 
478*f6dc9357SAndroid Build Coastguard Worker             // size of header was changed.
479*f6dc9357SAndroid Build Coastguard Worker             // we remove data after header and try new attempt, if required
480*f6dc9357SAndroid Build Coastguard Worker             Z7_DECL_CMyComPtr_QI_FROM(IInStream, fileSeekStream, fileInStream)
481*f6dc9357SAndroid Build Coastguard Worker             if (!fileSeekStream)
482*f6dc9357SAndroid Build Coastguard Worker               return E_FAIL;
483*f6dc9357SAndroid Build Coastguard Worker             RINOK(InStream_SeekToBegin(fileSeekStream))
484*f6dc9357SAndroid Build Coastguard Worker             RINOK(outSeekStream->SetSize(outArchive.Pos))
485*f6dc9357SAndroid Build Coastguard Worker             if (item.PackSize == 0)
486*f6dc9357SAndroid Build Coastguard Worker               break;
487*f6dc9357SAndroid Build Coastguard Worker           }
488*f6dc9357SAndroid Build Coastguard Worker         }
489*f6dc9357SAndroid Build Coastguard Worker       }
490*f6dc9357SAndroid Build Coastguard Worker 
491*f6dc9357SAndroid Build Coastguard Worker       complexity += item.PackSize;
492*f6dc9357SAndroid Build Coastguard Worker       fileInStream.Release();
493*f6dc9357SAndroid Build Coastguard Worker       RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK))
494*f6dc9357SAndroid Build Coastguard Worker     }
495*f6dc9357SAndroid Build Coastguard Worker     else
496*f6dc9357SAndroid Build Coastguard Worker     {
497*f6dc9357SAndroid Build Coastguard Worker       // (ui.NewData == false)
498*f6dc9357SAndroid Build Coastguard Worker 
499*f6dc9357SAndroid Build Coastguard Worker       if (opCallback)
500*f6dc9357SAndroid Build Coastguard Worker       {
501*f6dc9357SAndroid Build Coastguard Worker         RINOK(opCallback->ReportOperation(
502*f6dc9357SAndroid Build Coastguard Worker             NEventIndexType::kInArcIndex, (UInt32)ui.IndexInArc,
503*f6dc9357SAndroid Build Coastguard Worker             NUpdateNotifyOp::kReplicate))
504*f6dc9357SAndroid Build Coastguard Worker       }
505*f6dc9357SAndroid Build Coastguard Worker 
506*f6dc9357SAndroid Build Coastguard Worker       const CItemEx &existItem = inputItems[(unsigned)ui.IndexInArc];
507*f6dc9357SAndroid Build Coastguard Worker       UInt64 size, pos;
508*f6dc9357SAndroid Build Coastguard Worker 
509*f6dc9357SAndroid Build Coastguard Worker       if (ui.NewProps)
510*f6dc9357SAndroid Build Coastguard Worker       {
511*f6dc9357SAndroid Build Coastguard Worker         // memcpy(item.Magic, NFileHeader::NMagic::kEmpty, 8);
512*f6dc9357SAndroid Build Coastguard Worker 
513*f6dc9357SAndroid Build Coastguard Worker         if (!symLink.IsEmpty())
514*f6dc9357SAndroid Build Coastguard Worker         {
515*f6dc9357SAndroid Build Coastguard Worker           item.PackSize = 0;
516*f6dc9357SAndroid Build Coastguard Worker           item.Size = 0;
517*f6dc9357SAndroid Build Coastguard Worker         }
518*f6dc9357SAndroid Build Coastguard Worker         else
519*f6dc9357SAndroid Build Coastguard Worker         {
520*f6dc9357SAndroid Build Coastguard Worker           if (ui.IsDir == existItem.IsDir())
521*f6dc9357SAndroid Build Coastguard Worker             item.LinkFlag = existItem.LinkFlag;
522*f6dc9357SAndroid Build Coastguard Worker 
523*f6dc9357SAndroid Build Coastguard Worker           item.SparseBlocks = existItem.SparseBlocks;
524*f6dc9357SAndroid Build Coastguard Worker           item.Size = existItem.Size;
525*f6dc9357SAndroid Build Coastguard Worker           item.PackSize = existItem.PackSize;
526*f6dc9357SAndroid Build Coastguard Worker         }
527*f6dc9357SAndroid Build Coastguard Worker 
528*f6dc9357SAndroid Build Coastguard Worker         item.DeviceMajor_Defined = existItem.DeviceMajor_Defined;
529*f6dc9357SAndroid Build Coastguard Worker         item.DeviceMinor_Defined = existItem.DeviceMinor_Defined;
530*f6dc9357SAndroid Build Coastguard Worker         item.DeviceMajor = existItem.DeviceMajor;
531*f6dc9357SAndroid Build Coastguard Worker         item.DeviceMinor = existItem.DeviceMinor;
532*f6dc9357SAndroid Build Coastguard Worker         item.UID = existItem.UID;
533*f6dc9357SAndroid Build Coastguard Worker         item.GID = existItem.GID;
534*f6dc9357SAndroid Build Coastguard Worker 
535*f6dc9357SAndroid Build Coastguard Worker         RINOK(outArchive.WriteHeader(item))
536*f6dc9357SAndroid Build Coastguard Worker         size = existItem.Get_PackSize_Aligned();
537*f6dc9357SAndroid Build Coastguard Worker         pos = existItem.Get_DataPos();
538*f6dc9357SAndroid Build Coastguard Worker       }
539*f6dc9357SAndroid Build Coastguard Worker       else
540*f6dc9357SAndroid Build Coastguard Worker       {
541*f6dc9357SAndroid Build Coastguard Worker         size = existItem.Get_FullSize_Aligned();
542*f6dc9357SAndroid Build Coastguard Worker         pos = existItem.HeaderPos;
543*f6dc9357SAndroid Build Coastguard Worker       }
544*f6dc9357SAndroid Build Coastguard Worker 
545*f6dc9357SAndroid Build Coastguard Worker       if (size != 0)
546*f6dc9357SAndroid Build Coastguard Worker       {
547*f6dc9357SAndroid Build Coastguard Worker         RINOK(InStream_SeekSet(inStream, pos))
548*f6dc9357SAndroid Build Coastguard Worker         inStreamLimited->Init(size);
549*f6dc9357SAndroid Build Coastguard Worker         if (outSeekStream && setRestriction)
550*f6dc9357SAndroid Build Coastguard Worker           RINOK(setRestriction->SetRestriction(0, 0))
551*f6dc9357SAndroid Build Coastguard Worker         // 22.00 : we copy Residual data from old archive to new archive instead of zeroing
552*f6dc9357SAndroid Build Coastguard Worker         RINOK(copyCoder.Interface()->Code(inStreamLimited, outStream, NULL, NULL, lps))
553*f6dc9357SAndroid Build Coastguard Worker         if (copyCoder->TotalSize != size)
554*f6dc9357SAndroid Build Coastguard Worker           return E_FAIL;
555*f6dc9357SAndroid Build Coastguard Worker         outArchive.Pos += size;
556*f6dc9357SAndroid Build Coastguard Worker         // RINOK(outArchive.Write_AfterDataResidual(existItem.PackSize));
557*f6dc9357SAndroid Build Coastguard Worker         complexity += size;
558*f6dc9357SAndroid Build Coastguard Worker       }
559*f6dc9357SAndroid Build Coastguard Worker     }
560*f6dc9357SAndroid Build Coastguard Worker   }
561*f6dc9357SAndroid Build Coastguard Worker }
562*f6dc9357SAndroid Build Coastguard Worker 
563*f6dc9357SAndroid Build Coastguard Worker }}
564