xref: /aosp_15_r20/external/lzma/CPP/7zip/Archive/Tar/TarHandlerOut.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // TarHandlerOut.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 "../../../Common/ComTry.h"
8*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/MyLinux.h"
9*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/StringConvert.h"
10*f6dc9357SAndroid Build Coastguard Worker 
11*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/TimeUtils.h"
12*f6dc9357SAndroid Build Coastguard Worker 
13*f6dc9357SAndroid Build Coastguard Worker #include "../Common/ItemNameUtils.h"
14*f6dc9357SAndroid Build Coastguard Worker 
15*f6dc9357SAndroid Build Coastguard Worker #include "TarHandler.h"
16*f6dc9357SAndroid Build Coastguard Worker #include "TarUpdate.h"
17*f6dc9357SAndroid Build Coastguard Worker 
18*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
19*f6dc9357SAndroid Build Coastguard Worker 
20*f6dc9357SAndroid Build Coastguard Worker namespace NArchive {
21*f6dc9357SAndroid Build Coastguard Worker namespace NTar {
22*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::GetFileTimeType (UInt32 * type))23*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *type))
24*f6dc9357SAndroid Build Coastguard Worker {
25*f6dc9357SAndroid Build Coastguard Worker   UInt32 t = NFileTimeType::kUnix;
26*f6dc9357SAndroid Build Coastguard Worker   const UInt32 prec = _handlerTimeOptions.Prec;
27*f6dc9357SAndroid Build Coastguard Worker   if (prec != (UInt32)(Int32)-1)
28*f6dc9357SAndroid Build Coastguard Worker   {
29*f6dc9357SAndroid Build Coastguard Worker     t = NFileTimeType::kWindows;
30*f6dc9357SAndroid Build Coastguard Worker     if (prec == k_PropVar_TimePrec_0 ||
31*f6dc9357SAndroid Build Coastguard Worker         prec == k_PropVar_TimePrec_100ns)
32*f6dc9357SAndroid Build Coastguard Worker       t = NFileTimeType::kWindows;
33*f6dc9357SAndroid Build Coastguard Worker     else if (prec == k_PropVar_TimePrec_HighPrec)
34*f6dc9357SAndroid Build Coastguard Worker       t = k_PropVar_TimePrec_1ns;
35*f6dc9357SAndroid Build Coastguard Worker     else if (prec >= k_PropVar_TimePrec_Base)
36*f6dc9357SAndroid Build Coastguard Worker       t = prec;
37*f6dc9357SAndroid Build Coastguard Worker   }
38*f6dc9357SAndroid Build Coastguard Worker   // 7-Zip before 22.00 fails, if unknown typeType.
39*f6dc9357SAndroid Build Coastguard Worker   *type = t;
40*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
41*f6dc9357SAndroid Build Coastguard Worker }
42*f6dc9357SAndroid Build Coastguard Worker 
43*f6dc9357SAndroid Build Coastguard Worker 
Get_AString_From_UString(const UString & s,AString & res,UINT codePage,unsigned utfFlags)44*f6dc9357SAndroid Build Coastguard Worker void Get_AString_From_UString(const UString &s, AString &res,
45*f6dc9357SAndroid Build Coastguard Worker     UINT codePage, unsigned utfFlags)
46*f6dc9357SAndroid Build Coastguard Worker {
47*f6dc9357SAndroid Build Coastguard Worker   if (codePage == CP_UTF8)
48*f6dc9357SAndroid Build Coastguard Worker     ConvertUnicodeToUTF8_Flags(s, res, utfFlags);
49*f6dc9357SAndroid Build Coastguard Worker   else
50*f6dc9357SAndroid Build Coastguard Worker     UnicodeStringToMultiByte2(res, s, codePage);
51*f6dc9357SAndroid Build Coastguard Worker }
52*f6dc9357SAndroid Build Coastguard Worker 
53*f6dc9357SAndroid Build Coastguard Worker 
GetPropString(IArchiveUpdateCallback * callback,UInt32 index,PROPID propId,AString & res,UINT codePage,unsigned utfFlags,bool convertSlash)54*f6dc9357SAndroid Build Coastguard Worker HRESULT GetPropString(IArchiveUpdateCallback *callback, UInt32 index, PROPID propId, AString &res,
55*f6dc9357SAndroid Build Coastguard Worker     UINT codePage, unsigned utfFlags, bool convertSlash)
56*f6dc9357SAndroid Build Coastguard Worker {
57*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant prop;
58*f6dc9357SAndroid Build Coastguard Worker   RINOK(callback->GetProperty(index, propId, &prop))
59*f6dc9357SAndroid Build Coastguard Worker 
60*f6dc9357SAndroid Build Coastguard Worker   if (prop.vt == VT_BSTR)
61*f6dc9357SAndroid Build Coastguard Worker   {
62*f6dc9357SAndroid Build Coastguard Worker     UString s = prop.bstrVal;
63*f6dc9357SAndroid Build Coastguard Worker     if (convertSlash)
64*f6dc9357SAndroid Build Coastguard Worker       NItemName::ReplaceSlashes_OsToUnix(s);
65*f6dc9357SAndroid Build Coastguard Worker     Get_AString_From_UString(s, res, codePage, utfFlags);
66*f6dc9357SAndroid Build Coastguard Worker   }
67*f6dc9357SAndroid Build Coastguard Worker   else if (prop.vt != VT_EMPTY)
68*f6dc9357SAndroid Build Coastguard Worker     return E_INVALIDARG;
69*f6dc9357SAndroid Build Coastguard Worker 
70*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
71*f6dc9357SAndroid Build Coastguard Worker }
72*f6dc9357SAndroid Build Coastguard Worker 
73*f6dc9357SAndroid Build Coastguard Worker 
74*f6dc9357SAndroid Build Coastguard Worker // sort old files with original order.
75*f6dc9357SAndroid Build Coastguard Worker 
CompareUpdateItems(void * const * p1,void * const * p2,void *)76*f6dc9357SAndroid Build Coastguard Worker static int CompareUpdateItems(void *const *p1, void *const *p2, void *)
77*f6dc9357SAndroid Build Coastguard Worker {
78*f6dc9357SAndroid Build Coastguard Worker   const CUpdateItem &u1 = *(*((const CUpdateItem *const *)p1));
79*f6dc9357SAndroid Build Coastguard Worker   const CUpdateItem &u2 = *(*((const CUpdateItem *const *)p2));
80*f6dc9357SAndroid Build Coastguard Worker   if (!u1.NewProps)
81*f6dc9357SAndroid Build Coastguard Worker   {
82*f6dc9357SAndroid Build Coastguard Worker     if (u2.NewProps)
83*f6dc9357SAndroid Build Coastguard Worker       return -1;
84*f6dc9357SAndroid Build Coastguard Worker     return MyCompare(u1.IndexInArc, u2.IndexInArc);
85*f6dc9357SAndroid Build Coastguard Worker   }
86*f6dc9357SAndroid Build Coastguard Worker   if (!u2.NewProps)
87*f6dc9357SAndroid Build Coastguard Worker     return 1;
88*f6dc9357SAndroid Build Coastguard Worker   return MyCompare(u1.IndexInClient, u2.IndexInClient);
89*f6dc9357SAndroid Build Coastguard Worker }
90*f6dc9357SAndroid Build Coastguard Worker 
91*f6dc9357SAndroid Build Coastguard Worker 
GetTime(UInt32 i,UInt32 pid,IArchiveUpdateCallback * callback,CPaxTime & pt)92*f6dc9357SAndroid Build Coastguard Worker static HRESULT GetTime(UInt32 i, UInt32 pid, IArchiveUpdateCallback *callback,
93*f6dc9357SAndroid Build Coastguard Worker     CPaxTime &pt)
94*f6dc9357SAndroid Build Coastguard Worker {
95*f6dc9357SAndroid Build Coastguard Worker   pt.Clear();
96*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant prop;
97*f6dc9357SAndroid Build Coastguard Worker   RINOK(callback->GetProperty(i, pid, &prop))
98*f6dc9357SAndroid Build Coastguard Worker   return Prop_To_PaxTime(prop, pt);
99*f6dc9357SAndroid Build Coastguard Worker }
100*f6dc9357SAndroid Build Coastguard Worker 
101*f6dc9357SAndroid Build Coastguard Worker 
102*f6dc9357SAndroid Build Coastguard Worker /*
103*f6dc9357SAndroid Build Coastguard Worker static HRESULT GetDevice(IArchiveUpdateCallback *callback, UInt32 i,
104*f6dc9357SAndroid Build Coastguard Worker     UInt32 &majo, UInt32 &mino, bool &majo_defined, bool &mino_defined)
105*f6dc9357SAndroid Build Coastguard Worker {
106*f6dc9357SAndroid Build Coastguard Worker   NWindows::NCOM::CPropVariant prop;
107*f6dc9357SAndroid Build Coastguard Worker   RINOK(callback->GetProperty(i, kpidDevice, &prop));
108*f6dc9357SAndroid Build Coastguard Worker   if (prop.vt == VT_EMPTY)
109*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
110*f6dc9357SAndroid Build Coastguard Worker   if (prop.vt != VT_UI8)
111*f6dc9357SAndroid Build Coastguard Worker     return E_INVALIDARG;
112*f6dc9357SAndroid Build Coastguard Worker   {
113*f6dc9357SAndroid Build Coastguard Worker     const UInt64 v = prop.uhVal.QuadPart;
114*f6dc9357SAndroid Build Coastguard Worker     majo = MY_dev_major(v);
115*f6dc9357SAndroid Build Coastguard Worker     mino = MY_dev_minor(v);
116*f6dc9357SAndroid Build Coastguard Worker     majo_defined = true;
117*f6dc9357SAndroid Build Coastguard Worker     mino_defined = true;
118*f6dc9357SAndroid Build Coastguard Worker   }
119*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
120*f6dc9357SAndroid Build Coastguard Worker }
121*f6dc9357SAndroid Build Coastguard Worker */
122*f6dc9357SAndroid Build Coastguard Worker 
GetDevice(IArchiveUpdateCallback * callback,UInt32 i,UInt32 pid,UInt32 & id,bool & defined)123*f6dc9357SAndroid Build Coastguard Worker static HRESULT GetDevice(IArchiveUpdateCallback *callback, UInt32 i,
124*f6dc9357SAndroid Build Coastguard Worker     UInt32 pid, UInt32 &id, bool &defined)
125*f6dc9357SAndroid Build Coastguard Worker {
126*f6dc9357SAndroid Build Coastguard Worker   defined = false;
127*f6dc9357SAndroid Build Coastguard Worker   NWindows::NCOM::CPropVariant prop;
128*f6dc9357SAndroid Build Coastguard Worker   RINOK(callback->GetProperty(i, pid, &prop))
129*f6dc9357SAndroid Build Coastguard Worker   if (prop.vt == VT_EMPTY)
130*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
131*f6dc9357SAndroid Build Coastguard Worker   if (prop.vt == VT_UI4)
132*f6dc9357SAndroid Build Coastguard Worker   {
133*f6dc9357SAndroid Build Coastguard Worker     id = prop.ulVal;
134*f6dc9357SAndroid Build Coastguard Worker     defined = true;
135*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
136*f6dc9357SAndroid Build Coastguard Worker   }
137*f6dc9357SAndroid Build Coastguard Worker   return E_INVALIDARG;
138*f6dc9357SAndroid Build Coastguard Worker }
139*f6dc9357SAndroid Build Coastguard Worker 
140*f6dc9357SAndroid Build Coastguard Worker 
GetUser(IArchiveUpdateCallback * callback,UInt32 i,UInt32 pidName,UInt32 pidId,AString & name,UInt32 & id,UINT codePage,unsigned utfFlags)141*f6dc9357SAndroid Build Coastguard Worker static HRESULT GetUser(IArchiveUpdateCallback *callback, UInt32 i,
142*f6dc9357SAndroid Build Coastguard Worker     UInt32 pidName, UInt32 pidId, AString &name, UInt32 &id,
143*f6dc9357SAndroid Build Coastguard Worker     UINT codePage, unsigned utfFlags)
144*f6dc9357SAndroid Build Coastguard Worker {
145*f6dc9357SAndroid Build Coastguard Worker   // printf("\ncallback->GetProperty(i, pidId, &prop))\n");
146*f6dc9357SAndroid Build Coastguard Worker 
147*f6dc9357SAndroid Build Coastguard Worker   bool isSet = false;
148*f6dc9357SAndroid Build Coastguard Worker   {
149*f6dc9357SAndroid Build Coastguard Worker     NWindows::NCOM::CPropVariant prop;
150*f6dc9357SAndroid Build Coastguard Worker     RINOK(callback->GetProperty(i, pidId, &prop))
151*f6dc9357SAndroid Build Coastguard Worker     if (prop.vt == VT_UI4)
152*f6dc9357SAndroid Build Coastguard Worker     {
153*f6dc9357SAndroid Build Coastguard Worker       isSet = true;
154*f6dc9357SAndroid Build Coastguard Worker       id = prop.ulVal;
155*f6dc9357SAndroid Build Coastguard Worker       // printf("\ncallback->GetProperty(i, pidId, &prop)); = %d \n", (unsigned)id);
156*f6dc9357SAndroid Build Coastguard Worker       name.Empty();
157*f6dc9357SAndroid Build Coastguard Worker     }
158*f6dc9357SAndroid Build Coastguard Worker     else if (prop.vt != VT_EMPTY)
159*f6dc9357SAndroid Build Coastguard Worker       return E_INVALIDARG;
160*f6dc9357SAndroid Build Coastguard Worker   }
161*f6dc9357SAndroid Build Coastguard Worker   {
162*f6dc9357SAndroid Build Coastguard Worker     NWindows::NCOM::CPropVariant prop;
163*f6dc9357SAndroid Build Coastguard Worker     RINOK(callback->GetProperty(i, pidName, &prop))
164*f6dc9357SAndroid Build Coastguard Worker     if (prop.vt == VT_BSTR)
165*f6dc9357SAndroid Build Coastguard Worker     {
166*f6dc9357SAndroid Build Coastguard Worker       const UString s = prop.bstrVal;
167*f6dc9357SAndroid Build Coastguard Worker       Get_AString_From_UString(s, name, codePage, utfFlags);
168*f6dc9357SAndroid Build Coastguard Worker       if (!isSet)
169*f6dc9357SAndroid Build Coastguard Worker         id = 0;
170*f6dc9357SAndroid Build Coastguard Worker     }
171*f6dc9357SAndroid Build Coastguard Worker     else if (prop.vt == VT_UI4)
172*f6dc9357SAndroid Build Coastguard Worker     {
173*f6dc9357SAndroid Build Coastguard Worker       id = prop.ulVal;
174*f6dc9357SAndroid Build Coastguard Worker       name.Empty();
175*f6dc9357SAndroid Build Coastguard Worker     }
176*f6dc9357SAndroid Build Coastguard Worker     else if (prop.vt != VT_EMPTY)
177*f6dc9357SAndroid Build Coastguard Worker       return E_INVALIDARG;
178*f6dc9357SAndroid Build Coastguard Worker   }
179*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
180*f6dc9357SAndroid Build Coastguard Worker }
181*f6dc9357SAndroid Build Coastguard Worker 
182*f6dc9357SAndroid Build Coastguard Worker 
183*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CHandler::UpdateItems (ISequentialOutStream * outStream,UInt32 numItems,IArchiveUpdateCallback * callback))184*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
185*f6dc9357SAndroid Build Coastguard Worker     IArchiveUpdateCallback *callback))
186*f6dc9357SAndroid Build Coastguard Worker {
187*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
188*f6dc9357SAndroid Build Coastguard Worker 
189*f6dc9357SAndroid Build Coastguard Worker   if ((_stream && (_arc._error != k_ErrorType_OK || _arc._is_Warning
190*f6dc9357SAndroid Build Coastguard Worker       /* || _isSparse */
191*f6dc9357SAndroid Build Coastguard Worker       )) || _seqStream)
192*f6dc9357SAndroid Build Coastguard Worker     return E_NOTIMPL;
193*f6dc9357SAndroid Build Coastguard Worker   CObjectVector<CUpdateItem> updateItems;
194*f6dc9357SAndroid Build Coastguard Worker   const UINT codePage = (_forceCodePage ? _specifiedCodePage : _openCodePage);
195*f6dc9357SAndroid Build Coastguard Worker   const unsigned utfFlags = g_Unicode_To_UTF8_Flags;
196*f6dc9357SAndroid Build Coastguard Worker   /*
197*f6dc9357SAndroid Build Coastguard Worker   // for debug only:
198*f6dc9357SAndroid Build Coastguard Worker   unsigned utfFlags = 0;
199*f6dc9357SAndroid Build Coastguard Worker   utfFlags |= Z7_UTF_FLAG_TO_UTF8_EXTRACT_BMP_ESCAPE;
200*f6dc9357SAndroid Build Coastguard Worker   utfFlags |= Z7_UTF_FLAG_TO_UTF8_SURROGATE_ERROR;
201*f6dc9357SAndroid Build Coastguard Worker   */
202*f6dc9357SAndroid Build Coastguard Worker 
203*f6dc9357SAndroid Build Coastguard Worker   for (UInt32 i = 0; i < numItems; i++)
204*f6dc9357SAndroid Build Coastguard Worker   {
205*f6dc9357SAndroid Build Coastguard Worker     CUpdateItem ui;
206*f6dc9357SAndroid Build Coastguard Worker     Int32 newData;
207*f6dc9357SAndroid Build Coastguard Worker     Int32 newProps;
208*f6dc9357SAndroid Build Coastguard Worker     UInt32 indexInArc;
209*f6dc9357SAndroid Build Coastguard Worker 
210*f6dc9357SAndroid Build Coastguard Worker     if (!callback)
211*f6dc9357SAndroid Build Coastguard Worker       return E_FAIL;
212*f6dc9357SAndroid Build Coastguard Worker 
213*f6dc9357SAndroid Build Coastguard Worker     RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArc))
214*f6dc9357SAndroid Build Coastguard Worker 
215*f6dc9357SAndroid Build Coastguard Worker     ui.NewProps = IntToBool(newProps);
216*f6dc9357SAndroid Build Coastguard Worker     ui.NewData = IntToBool(newData);
217*f6dc9357SAndroid Build Coastguard Worker     ui.IndexInArc = (int)indexInArc;
218*f6dc9357SAndroid Build Coastguard Worker     ui.IndexInClient = i;
219*f6dc9357SAndroid Build Coastguard Worker 
220*f6dc9357SAndroid Build Coastguard Worker     if (IntToBool(newProps))
221*f6dc9357SAndroid Build Coastguard Worker     {
222*f6dc9357SAndroid Build Coastguard Worker       {
223*f6dc9357SAndroid Build Coastguard Worker         NCOM::CPropVariant prop;
224*f6dc9357SAndroid Build Coastguard Worker         RINOK(callback->GetProperty(i, kpidIsDir, &prop))
225*f6dc9357SAndroid Build Coastguard Worker         if (prop.vt == VT_EMPTY)
226*f6dc9357SAndroid Build Coastguard Worker           ui.IsDir = false;
227*f6dc9357SAndroid Build Coastguard Worker         else if (prop.vt != VT_BOOL)
228*f6dc9357SAndroid Build Coastguard Worker           return E_INVALIDARG;
229*f6dc9357SAndroid Build Coastguard Worker         else
230*f6dc9357SAndroid Build Coastguard Worker           ui.IsDir = (prop.boolVal != VARIANT_FALSE);
231*f6dc9357SAndroid Build Coastguard Worker       }
232*f6dc9357SAndroid Build Coastguard Worker 
233*f6dc9357SAndroid Build Coastguard Worker       {
234*f6dc9357SAndroid Build Coastguard Worker         NCOM::CPropVariant prop;
235*f6dc9357SAndroid Build Coastguard Worker         RINOK(callback->GetProperty(i, kpidPosixAttrib, &prop))
236*f6dc9357SAndroid Build Coastguard Worker         if (prop.vt == VT_EMPTY)
237*f6dc9357SAndroid Build Coastguard Worker           ui.Mode =
238*f6dc9357SAndroid Build Coastguard Worker                 MY_LIN_S_IRWXO
239*f6dc9357SAndroid Build Coastguard Worker               | MY_LIN_S_IRWXG
240*f6dc9357SAndroid Build Coastguard Worker               | MY_LIN_S_IRWXU
241*f6dc9357SAndroid Build Coastguard Worker               | (ui.IsDir ? MY_LIN_S_IFDIR : MY_LIN_S_IFREG);
242*f6dc9357SAndroid Build Coastguard Worker         else if (prop.vt != VT_UI4)
243*f6dc9357SAndroid Build Coastguard Worker           return E_INVALIDARG;
244*f6dc9357SAndroid Build Coastguard Worker         else
245*f6dc9357SAndroid Build Coastguard Worker           ui.Mode = prop.ulVal;
246*f6dc9357SAndroid Build Coastguard Worker         // 21.07 : we clear high file type bits as GNU TAR.
247*f6dc9357SAndroid Build Coastguard Worker         // we will clear it later
248*f6dc9357SAndroid Build Coastguard Worker         // ui.Mode &= ~(UInt32)MY_LIN_S_IFMT;
249*f6dc9357SAndroid Build Coastguard Worker       }
250*f6dc9357SAndroid Build Coastguard Worker 
251*f6dc9357SAndroid Build Coastguard Worker       if (_handlerTimeOptions.Write_MTime.Val)
252*f6dc9357SAndroid Build Coastguard Worker         RINOK(GetTime(i, kpidMTime, callback, ui.PaxTimes.MTime))
253*f6dc9357SAndroid Build Coastguard Worker       if (_handlerTimeOptions.Write_ATime.Val)
254*f6dc9357SAndroid Build Coastguard Worker         RINOK(GetTime(i, kpidATime, callback, ui.PaxTimes.ATime))
255*f6dc9357SAndroid Build Coastguard Worker       if (_handlerTimeOptions.Write_CTime.Val)
256*f6dc9357SAndroid Build Coastguard Worker         RINOK(GetTime(i, kpidCTime, callback, ui.PaxTimes.CTime))
257*f6dc9357SAndroid Build Coastguard Worker 
258*f6dc9357SAndroid Build Coastguard Worker       RINOK(GetPropString(callback, i, kpidPath, ui.Name, codePage, utfFlags, true))
259*f6dc9357SAndroid Build Coastguard Worker       if (ui.IsDir && !ui.Name.IsEmpty() && ui.Name.Back() != '/')
260*f6dc9357SAndroid Build Coastguard Worker         ui.Name.Add_Slash();
261*f6dc9357SAndroid Build Coastguard Worker       // ui.Name.Add_Slash(); // for debug
262*f6dc9357SAndroid Build Coastguard Worker 
263*f6dc9357SAndroid Build Coastguard Worker       if (_posixMode)
264*f6dc9357SAndroid Build Coastguard Worker       {
265*f6dc9357SAndroid Build Coastguard Worker         RINOK(GetDevice(callback, i, kpidDeviceMajor, ui.DeviceMajor, ui.DeviceMajor_Defined))
266*f6dc9357SAndroid Build Coastguard Worker         RINOK(GetDevice(callback, i, kpidDeviceMinor, ui.DeviceMinor, ui.DeviceMinor_Defined))
267*f6dc9357SAndroid Build Coastguard Worker       }
268*f6dc9357SAndroid Build Coastguard Worker 
269*f6dc9357SAndroid Build Coastguard Worker       RINOK(GetUser(callback, i, kpidUser,  kpidUserId,  ui.User,  ui.UID, codePage, utfFlags))
270*f6dc9357SAndroid Build Coastguard Worker       RINOK(GetUser(callback, i, kpidGroup, kpidGroupId, ui.Group, ui.GID, codePage, utfFlags))
271*f6dc9357SAndroid Build Coastguard Worker     }
272*f6dc9357SAndroid Build Coastguard Worker 
273*f6dc9357SAndroid Build Coastguard Worker     if (IntToBool(newData))
274*f6dc9357SAndroid Build Coastguard Worker     {
275*f6dc9357SAndroid Build Coastguard Worker       NCOM::CPropVariant prop;
276*f6dc9357SAndroid Build Coastguard Worker       RINOK(callback->GetProperty(i, kpidSize, &prop))
277*f6dc9357SAndroid Build Coastguard Worker       if (prop.vt != VT_UI8)
278*f6dc9357SAndroid Build Coastguard Worker         return E_INVALIDARG;
279*f6dc9357SAndroid Build Coastguard Worker       ui.Size = prop.uhVal.QuadPart;
280*f6dc9357SAndroid Build Coastguard Worker       /*
281*f6dc9357SAndroid Build Coastguard Worker       // now we support GNU extension for big files
282*f6dc9357SAndroid Build Coastguard Worker       if (ui.Size >= ((UInt64)1 << 33))
283*f6dc9357SAndroid Build Coastguard Worker         return E_INVALIDARG;
284*f6dc9357SAndroid Build Coastguard Worker       */
285*f6dc9357SAndroid Build Coastguard Worker     }
286*f6dc9357SAndroid Build Coastguard Worker 
287*f6dc9357SAndroid Build Coastguard Worker     updateItems.Add(ui);
288*f6dc9357SAndroid Build Coastguard Worker   }
289*f6dc9357SAndroid Build Coastguard Worker 
290*f6dc9357SAndroid Build Coastguard Worker   if (_arc._are_Pax_Items)
291*f6dc9357SAndroid Build Coastguard Worker   {
292*f6dc9357SAndroid Build Coastguard Worker     // we restore original order of files, if there are pax items
293*f6dc9357SAndroid Build Coastguard Worker     updateItems.Sort(CompareUpdateItems, NULL);
294*f6dc9357SAndroid Build Coastguard Worker   }
295*f6dc9357SAndroid Build Coastguard Worker 
296*f6dc9357SAndroid Build Coastguard Worker   CUpdateOptions options;
297*f6dc9357SAndroid Build Coastguard Worker 
298*f6dc9357SAndroid Build Coastguard Worker   options.CodePage = codePage;
299*f6dc9357SAndroid Build Coastguard Worker   options.UtfFlags = utfFlags;
300*f6dc9357SAndroid Build Coastguard Worker   options.PosixMode = _posixMode;
301*f6dc9357SAndroid Build Coastguard Worker 
302*f6dc9357SAndroid Build Coastguard Worker   options.Write_MTime = _handlerTimeOptions.Write_MTime;
303*f6dc9357SAndroid Build Coastguard Worker   options.Write_ATime = _handlerTimeOptions.Write_ATime;
304*f6dc9357SAndroid Build Coastguard Worker   options.Write_CTime = _handlerTimeOptions.Write_CTime;
305*f6dc9357SAndroid Build Coastguard Worker 
306*f6dc9357SAndroid Build Coastguard Worker   // options.TimeOptions = TimeOptions;
307*f6dc9357SAndroid Build Coastguard Worker 
308*f6dc9357SAndroid Build Coastguard Worker   const UInt32 prec = _handlerTimeOptions.Prec;
309*f6dc9357SAndroid Build Coastguard Worker   if (prec != (UInt32)(Int32)-1)
310*f6dc9357SAndroid Build Coastguard Worker   {
311*f6dc9357SAndroid Build Coastguard Worker     unsigned numDigits = 0;
312*f6dc9357SAndroid Build Coastguard Worker     if (prec == 0)
313*f6dc9357SAndroid Build Coastguard Worker       numDigits = 7;
314*f6dc9357SAndroid Build Coastguard Worker     else if (prec == k_PropVar_TimePrec_HighPrec
315*f6dc9357SAndroid Build Coastguard Worker           || prec >= k_PropVar_TimePrec_1ns)
316*f6dc9357SAndroid Build Coastguard Worker       numDigits = 9;
317*f6dc9357SAndroid Build Coastguard Worker     else if (prec >= k_PropVar_TimePrec_Base)
318*f6dc9357SAndroid Build Coastguard Worker       numDigits = prec - k_PropVar_TimePrec_Base;
319*f6dc9357SAndroid Build Coastguard Worker     options.TimeOptions.NumDigitsMax = numDigits;
320*f6dc9357SAndroid Build Coastguard Worker     // options.TimeOptions.RemoveZeroMode =
321*f6dc9357SAndroid Build Coastguard Worker         // k_PaxTimeMode_DontRemoveZero; // pure for debug
322*f6dc9357SAndroid Build Coastguard Worker         // k_PaxTimeMode_RemoveZero_if_PureSecondOnly; // optimized code
323*f6dc9357SAndroid Build Coastguard Worker         // k_PaxTimeMode_RemoveZero_Always; // original pax code
324*f6dc9357SAndroid Build Coastguard Worker   }
325*f6dc9357SAndroid Build Coastguard Worker 
326*f6dc9357SAndroid Build Coastguard Worker   return UpdateArchive(_stream, outStream, _items, updateItems,
327*f6dc9357SAndroid Build Coastguard Worker       options, callback);
328*f6dc9357SAndroid Build Coastguard Worker 
329*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
330*f6dc9357SAndroid Build Coastguard Worker }
331*f6dc9357SAndroid Build Coastguard Worker 
332*f6dc9357SAndroid Build Coastguard Worker }}
333