1370b324cSopenharmony_ci// List.cpp
2370b324cSopenharmony_ci
3370b324cSopenharmony_ci#include "StdAfx.h"
4370b324cSopenharmony_ci
5370b324cSopenharmony_ci#include "../../../Common/IntToString.h"
6370b324cSopenharmony_ci#include "../../../Common/MyCom.h"
7370b324cSopenharmony_ci#include "../../../Common/StdOutStream.h"
8370b324cSopenharmony_ci#include "../../../Common/StringConvert.h"
9370b324cSopenharmony_ci#include "../../../Common/UTFConvert.h"
10370b324cSopenharmony_ci
11370b324cSopenharmony_ci#include "../../../Windows/ErrorMsg.h"
12370b324cSopenharmony_ci#include "../../../Windows/FileDir.h"
13370b324cSopenharmony_ci#include "../../../Windows/PropVariant.h"
14370b324cSopenharmony_ci#include "../../../Windows/PropVariantConv.h"
15370b324cSopenharmony_ci
16370b324cSopenharmony_ci#include "../Common/OpenArchive.h"
17370b324cSopenharmony_ci#include "../Common/PropIDUtils.h"
18370b324cSopenharmony_ci
19370b324cSopenharmony_ci#include "ConsoleClose.h"
20370b324cSopenharmony_ci#include "List.h"
21370b324cSopenharmony_ci#include "OpenCallbackConsole.h"
22370b324cSopenharmony_ci
23370b324cSopenharmony_ciusing namespace NWindows;
24370b324cSopenharmony_ciusing namespace NCOM;
25370b324cSopenharmony_ci
26370b324cSopenharmony_ciextern CStdOutStream *g_StdStream;
27370b324cSopenharmony_ciextern CStdOutStream *g_ErrStream;
28370b324cSopenharmony_ci
29370b324cSopenharmony_cistatic const char * const kPropIdToName[] =
30370b324cSopenharmony_ci{
31370b324cSopenharmony_ci    "0"
32370b324cSopenharmony_ci  , "1"
33370b324cSopenharmony_ci  , "2"
34370b324cSopenharmony_ci  , "Path"
35370b324cSopenharmony_ci  , "Name"
36370b324cSopenharmony_ci  , "Extension"
37370b324cSopenharmony_ci  , "Folder"
38370b324cSopenharmony_ci  , "Size"
39370b324cSopenharmony_ci  , "Packed Size"
40370b324cSopenharmony_ci  , "Attributes"
41370b324cSopenharmony_ci  , "Created"
42370b324cSopenharmony_ci  , "Accessed"
43370b324cSopenharmony_ci  , "Modified"
44370b324cSopenharmony_ci  , "Solid"
45370b324cSopenharmony_ci  , "Commented"
46370b324cSopenharmony_ci  , "Encrypted"
47370b324cSopenharmony_ci  , "Split Before"
48370b324cSopenharmony_ci  , "Split After"
49370b324cSopenharmony_ci  , "Dictionary Size"
50370b324cSopenharmony_ci  , "CRC"
51370b324cSopenharmony_ci  , "Type"
52370b324cSopenharmony_ci  , "Anti"
53370b324cSopenharmony_ci  , "Method"
54370b324cSopenharmony_ci  , "Host OS"
55370b324cSopenharmony_ci  , "File System"
56370b324cSopenharmony_ci  , "User"
57370b324cSopenharmony_ci  , "Group"
58370b324cSopenharmony_ci  , "Block"
59370b324cSopenharmony_ci  , "Comment"
60370b324cSopenharmony_ci  , "Position"
61370b324cSopenharmony_ci  , "Path Prefix"
62370b324cSopenharmony_ci  , "Folders"
63370b324cSopenharmony_ci  , "Files"
64370b324cSopenharmony_ci  , "Version"
65370b324cSopenharmony_ci  , "Volume"
66370b324cSopenharmony_ci  , "Multivolume"
67370b324cSopenharmony_ci  , "Offset"
68370b324cSopenharmony_ci  , "Links"
69370b324cSopenharmony_ci  , "Blocks"
70370b324cSopenharmony_ci  , "Volumes"
71370b324cSopenharmony_ci  , "Time Type"
72370b324cSopenharmony_ci  , "64-bit"
73370b324cSopenharmony_ci  , "Big-endian"
74370b324cSopenharmony_ci  , "CPU"
75370b324cSopenharmony_ci  , "Physical Size"
76370b324cSopenharmony_ci  , "Headers Size"
77370b324cSopenharmony_ci  , "Checksum"
78370b324cSopenharmony_ci  , "Characteristics"
79370b324cSopenharmony_ci  , "Virtual Address"
80370b324cSopenharmony_ci  , "ID"
81370b324cSopenharmony_ci  , "Short Name"
82370b324cSopenharmony_ci  , "Creator Application"
83370b324cSopenharmony_ci  , "Sector Size"
84370b324cSopenharmony_ci  , "Mode"
85370b324cSopenharmony_ci  , "Symbolic Link"
86370b324cSopenharmony_ci  , "Error"
87370b324cSopenharmony_ci  , "Total Size"
88370b324cSopenharmony_ci  , "Free Space"
89370b324cSopenharmony_ci  , "Cluster Size"
90370b324cSopenharmony_ci  , "Label"
91370b324cSopenharmony_ci  , "Local Name"
92370b324cSopenharmony_ci  , "Provider"
93370b324cSopenharmony_ci  , "NT Security"
94370b324cSopenharmony_ci  , "Alternate Stream"
95370b324cSopenharmony_ci  , "Aux"
96370b324cSopenharmony_ci  , "Deleted"
97370b324cSopenharmony_ci  , "Tree"
98370b324cSopenharmony_ci  , "SHA-1"
99370b324cSopenharmony_ci  , "SHA-256"
100370b324cSopenharmony_ci  , "Error Type"
101370b324cSopenharmony_ci  , "Errors"
102370b324cSopenharmony_ci  , "Errors"
103370b324cSopenharmony_ci  , "Warnings"
104370b324cSopenharmony_ci  , "Warning"
105370b324cSopenharmony_ci  , "Streams"
106370b324cSopenharmony_ci  , "Alternate Streams"
107370b324cSopenharmony_ci  , "Alternate Streams Size"
108370b324cSopenharmony_ci  , "Virtual Size"
109370b324cSopenharmony_ci  , "Unpack Size"
110370b324cSopenharmony_ci  , "Total Physical Size"
111370b324cSopenharmony_ci  , "Volume Index"
112370b324cSopenharmony_ci  , "SubType"
113370b324cSopenharmony_ci  , "Short Comment"
114370b324cSopenharmony_ci  , "Code Page"
115370b324cSopenharmony_ci  , "Is not archive type"
116370b324cSopenharmony_ci  , "Physical Size can't be detected"
117370b324cSopenharmony_ci  , "Zeros Tail Is Allowed"
118370b324cSopenharmony_ci  , "Tail Size"
119370b324cSopenharmony_ci  , "Embedded Stub Size"
120370b324cSopenharmony_ci  , "Link"
121370b324cSopenharmony_ci  , "Hard Link"
122370b324cSopenharmony_ci  , "iNode"
123370b324cSopenharmony_ci  , "Stream ID"
124370b324cSopenharmony_ci  , "Read-only"
125370b324cSopenharmony_ci  , "Out Name"
126370b324cSopenharmony_ci  , "Copy Link"
127370b324cSopenharmony_ci  , "ArcFileName"
128370b324cSopenharmony_ci  , "IsHash"
129370b324cSopenharmony_ci  , "Metadata Changed"
130370b324cSopenharmony_ci  , "User ID"
131370b324cSopenharmony_ci  , "Group ID"
132370b324cSopenharmony_ci  , "Device Major"
133370b324cSopenharmony_ci  , "Device Minor"
134370b324cSopenharmony_ci  , "Dev Major"
135370b324cSopenharmony_ci  , "Dev Minor"
136370b324cSopenharmony_ci};
137370b324cSopenharmony_ci
138370b324cSopenharmony_cistatic const char kEmptyAttribChar = '.';
139370b324cSopenharmony_ci
140370b324cSopenharmony_cistatic const char * const kListing = "Listing archive: ";
141370b324cSopenharmony_ci
142370b324cSopenharmony_cistatic const char * const kString_Files = "files";
143370b324cSopenharmony_cistatic const char * const kString_Dirs = "folders";
144370b324cSopenharmony_cistatic const char * const kString_AltStreams = "alternate streams";
145370b324cSopenharmony_cistatic const char * const kString_Streams = "streams";
146370b324cSopenharmony_ci
147370b324cSopenharmony_cistatic const char * const kError = "ERROR: ";
148370b324cSopenharmony_ci
149370b324cSopenharmony_cistatic void GetAttribString(UInt32 wa, bool isDir, bool allAttribs, char *s)
150370b324cSopenharmony_ci{
151370b324cSopenharmony_ci  if (isDir)
152370b324cSopenharmony_ci    wa |= FILE_ATTRIBUTE_DIRECTORY;
153370b324cSopenharmony_ci  if (allAttribs)
154370b324cSopenharmony_ci  {
155370b324cSopenharmony_ci    ConvertWinAttribToString(s, wa);
156370b324cSopenharmony_ci    return;
157370b324cSopenharmony_ci  }
158370b324cSopenharmony_ci  s[0] = ((wa & FILE_ATTRIBUTE_DIRECTORY) != 0) ? 'D': kEmptyAttribChar;
159370b324cSopenharmony_ci  s[1] = ((wa & FILE_ATTRIBUTE_READONLY)  != 0) ? 'R': kEmptyAttribChar;
160370b324cSopenharmony_ci  s[2] = ((wa & FILE_ATTRIBUTE_HIDDEN)    != 0) ? 'H': kEmptyAttribChar;
161370b324cSopenharmony_ci  s[3] = ((wa & FILE_ATTRIBUTE_SYSTEM)    != 0) ? 'S': kEmptyAttribChar;
162370b324cSopenharmony_ci  s[4] = ((wa & FILE_ATTRIBUTE_ARCHIVE)   != 0) ? 'A': kEmptyAttribChar;
163370b324cSopenharmony_ci  s[5] = 0;
164370b324cSopenharmony_ci}
165370b324cSopenharmony_ci
166370b324cSopenharmony_cienum EAdjustment
167370b324cSopenharmony_ci{
168370b324cSopenharmony_ci  kLeft,
169370b324cSopenharmony_ci  kCenter,
170370b324cSopenharmony_ci  kRight
171370b324cSopenharmony_ci};
172370b324cSopenharmony_ci
173370b324cSopenharmony_cistruct CFieldInfo
174370b324cSopenharmony_ci{
175370b324cSopenharmony_ci  PROPID PropID;
176370b324cSopenharmony_ci  bool IsRawProp;
177370b324cSopenharmony_ci  UString NameU;
178370b324cSopenharmony_ci  AString NameA;
179370b324cSopenharmony_ci  EAdjustment TitleAdjustment;
180370b324cSopenharmony_ci  EAdjustment TextAdjustment;
181370b324cSopenharmony_ci  unsigned PrefixSpacesWidth;
182370b324cSopenharmony_ci  unsigned Width;
183370b324cSopenharmony_ci};
184370b324cSopenharmony_ci
185370b324cSopenharmony_cistruct CFieldInfoInit
186370b324cSopenharmony_ci{
187370b324cSopenharmony_ci  PROPID PropID;
188370b324cSopenharmony_ci  const char *Name;
189370b324cSopenharmony_ci  EAdjustment TitleAdjustment;
190370b324cSopenharmony_ci  EAdjustment TextAdjustment;
191370b324cSopenharmony_ci  unsigned PrefixSpacesWidth;
192370b324cSopenharmony_ci  unsigned Width;
193370b324cSopenharmony_ci};
194370b324cSopenharmony_ci
195370b324cSopenharmony_cistatic const CFieldInfoInit kStandardFieldTable[] =
196370b324cSopenharmony_ci{
197370b324cSopenharmony_ci  { kpidMTime, "   Date      Time", kLeft, kLeft, 0, 19 },
198370b324cSopenharmony_ci  { kpidAttrib, "Attr", kRight, kCenter, 1, 5 },
199370b324cSopenharmony_ci  { kpidSize, "Size", kRight, kRight, 1, 12 },
200370b324cSopenharmony_ci  { kpidPackSize, "Compressed", kRight, kRight, 1, 12 },
201370b324cSopenharmony_ci  { kpidPath, "Name", kLeft, kLeft, 2, 24 }
202370b324cSopenharmony_ci};
203370b324cSopenharmony_ci
204370b324cSopenharmony_ciconst unsigned kNumSpacesMax = 32; // it must be larger than max CFieldInfoInit.Width
205370b324cSopenharmony_cistatic const char *g_Spaces =
206370b324cSopenharmony_ci"                                " ;
207370b324cSopenharmony_ci
208370b324cSopenharmony_cistatic void PrintSpaces(unsigned numSpaces)
209370b324cSopenharmony_ci{
210370b324cSopenharmony_ci  if (numSpaces > 0 && numSpaces <= kNumSpacesMax)
211370b324cSopenharmony_ci    g_StdOut << g_Spaces + (kNumSpacesMax - numSpaces);
212370b324cSopenharmony_ci}
213370b324cSopenharmony_ci
214370b324cSopenharmony_cistatic void PrintSpacesToString(char *dest, unsigned numSpaces)
215370b324cSopenharmony_ci{
216370b324cSopenharmony_ci  unsigned i;
217370b324cSopenharmony_ci  for (i = 0; i < numSpaces; i++)
218370b324cSopenharmony_ci    dest[i] = ' ';
219370b324cSopenharmony_ci  dest[i] = 0;
220370b324cSopenharmony_ci}
221370b324cSopenharmony_ci
222370b324cSopenharmony_ci// extern int g_CodePage;
223370b324cSopenharmony_ci
224370b324cSopenharmony_cistatic void PrintUString(EAdjustment adj, unsigned width, const UString &s, AString &temp)
225370b324cSopenharmony_ci{
226370b324cSopenharmony_ci  /*
227370b324cSopenharmony_ci  // we don't need multibyte align.
228370b324cSopenharmony_ci  int codePage = g_CodePage;
229370b324cSopenharmony_ci  if (codePage == -1)
230370b324cSopenharmony_ci    codePage = CP_OEMCP;
231370b324cSopenharmony_ci  if (codePage == CP_UTF8)
232370b324cSopenharmony_ci    ConvertUnicodeToUTF8(s, temp);
233370b324cSopenharmony_ci  else
234370b324cSopenharmony_ci    UnicodeStringToMultiByte2(temp, s, (UINT)codePage);
235370b324cSopenharmony_ci  */
236370b324cSopenharmony_ci
237370b324cSopenharmony_ci  unsigned numSpaces = 0;
238370b324cSopenharmony_ci
239370b324cSopenharmony_ci  if (width > s.Len())
240370b324cSopenharmony_ci  {
241370b324cSopenharmony_ci    numSpaces = width - s.Len();
242370b324cSopenharmony_ci    unsigned numLeftSpaces = 0;
243370b324cSopenharmony_ci    switch (adj)
244370b324cSopenharmony_ci    {
245370b324cSopenharmony_ci      case kLeft:   numLeftSpaces = 0; break;
246370b324cSopenharmony_ci      case kCenter: numLeftSpaces = numSpaces / 2; break;
247370b324cSopenharmony_ci      case kRight:  numLeftSpaces = numSpaces; break;
248370b324cSopenharmony_ci    }
249370b324cSopenharmony_ci    PrintSpaces(numLeftSpaces);
250370b324cSopenharmony_ci    numSpaces -= numLeftSpaces;
251370b324cSopenharmony_ci  }
252370b324cSopenharmony_ci
253370b324cSopenharmony_ci  g_StdOut.PrintUString(s, temp);
254370b324cSopenharmony_ci  PrintSpaces(numSpaces);
255370b324cSopenharmony_ci}
256370b324cSopenharmony_ci
257370b324cSopenharmony_cistatic void PrintString(EAdjustment adj, unsigned width, const char *s)
258370b324cSopenharmony_ci{
259370b324cSopenharmony_ci  unsigned numSpaces = 0;
260370b324cSopenharmony_ci  unsigned len = (unsigned)strlen(s);
261370b324cSopenharmony_ci
262370b324cSopenharmony_ci  if (width > len)
263370b324cSopenharmony_ci  {
264370b324cSopenharmony_ci    numSpaces = width - len;
265370b324cSopenharmony_ci    unsigned numLeftSpaces = 0;
266370b324cSopenharmony_ci    switch (adj)
267370b324cSopenharmony_ci    {
268370b324cSopenharmony_ci      case kLeft:   numLeftSpaces = 0; break;
269370b324cSopenharmony_ci      case kCenter: numLeftSpaces = numSpaces / 2; break;
270370b324cSopenharmony_ci      case kRight:  numLeftSpaces = numSpaces; break;
271370b324cSopenharmony_ci    }
272370b324cSopenharmony_ci    PrintSpaces(numLeftSpaces);
273370b324cSopenharmony_ci    numSpaces -= numLeftSpaces;
274370b324cSopenharmony_ci  }
275370b324cSopenharmony_ci
276370b324cSopenharmony_ci  g_StdOut << s;
277370b324cSopenharmony_ci  PrintSpaces(numSpaces);
278370b324cSopenharmony_ci}
279370b324cSopenharmony_ci
280370b324cSopenharmony_cistatic void PrintStringToString(char *dest, EAdjustment adj, unsigned width, const char *textString)
281370b324cSopenharmony_ci{
282370b324cSopenharmony_ci  unsigned numSpaces = 0;
283370b324cSopenharmony_ci  unsigned len = (unsigned)strlen(textString);
284370b324cSopenharmony_ci
285370b324cSopenharmony_ci  if (width > len)
286370b324cSopenharmony_ci  {
287370b324cSopenharmony_ci    numSpaces = width - len;
288370b324cSopenharmony_ci    unsigned numLeftSpaces = 0;
289370b324cSopenharmony_ci    switch (adj)
290370b324cSopenharmony_ci    {
291370b324cSopenharmony_ci      case kLeft:   numLeftSpaces = 0; break;
292370b324cSopenharmony_ci      case kCenter: numLeftSpaces = numSpaces / 2; break;
293370b324cSopenharmony_ci      case kRight:  numLeftSpaces = numSpaces; break;
294370b324cSopenharmony_ci    }
295370b324cSopenharmony_ci    PrintSpacesToString(dest, numLeftSpaces);
296370b324cSopenharmony_ci    dest += numLeftSpaces;
297370b324cSopenharmony_ci    numSpaces -= numLeftSpaces;
298370b324cSopenharmony_ci  }
299370b324cSopenharmony_ci
300370b324cSopenharmony_ci  memcpy(dest, textString, len);
301370b324cSopenharmony_ci  dest += len;
302370b324cSopenharmony_ci  PrintSpacesToString(dest, numSpaces);
303370b324cSopenharmony_ci}
304370b324cSopenharmony_ci
305370b324cSopenharmony_cistruct CListUInt64Def
306370b324cSopenharmony_ci{
307370b324cSopenharmony_ci  UInt64 Val;
308370b324cSopenharmony_ci  bool Def;
309370b324cSopenharmony_ci
310370b324cSopenharmony_ci  CListUInt64Def(): Val(0), Def(false) {}
311370b324cSopenharmony_ci  void Add(UInt64 v) { Val += v; Def = true; }
312370b324cSopenharmony_ci  void Add(const CListUInt64Def &v) { if (v.Def) Add(v.Val); }
313370b324cSopenharmony_ci};
314370b324cSopenharmony_ci
315370b324cSopenharmony_ci
316370b324cSopenharmony_cistruct CListFileTimeDef: public CArcTime
317370b324cSopenharmony_ci{
318370b324cSopenharmony_ci  void Update(const CListFileTimeDef &t)
319370b324cSopenharmony_ci  {
320370b324cSopenharmony_ci    if (t.Def && (!Def || CompareWith(t) < 0))
321370b324cSopenharmony_ci      (*this) = t;
322370b324cSopenharmony_ci  }
323370b324cSopenharmony_ci};
324370b324cSopenharmony_ci
325370b324cSopenharmony_ci
326370b324cSopenharmony_ci
327370b324cSopenharmony_cistruct CListStat
328370b324cSopenharmony_ci{
329370b324cSopenharmony_ci  CListUInt64Def Size;
330370b324cSopenharmony_ci  CListUInt64Def PackSize;
331370b324cSopenharmony_ci  CListFileTimeDef MTime;
332370b324cSopenharmony_ci  UInt64 NumFiles;
333370b324cSopenharmony_ci
334370b324cSopenharmony_ci  CListStat(): NumFiles(0) {}
335370b324cSopenharmony_ci  void Update(const CListStat &st)
336370b324cSopenharmony_ci  {
337370b324cSopenharmony_ci    Size.Add(st.Size);
338370b324cSopenharmony_ci    PackSize.Add(st.PackSize);
339370b324cSopenharmony_ci    MTime.Update(st.MTime);
340370b324cSopenharmony_ci    NumFiles += st.NumFiles;
341370b324cSopenharmony_ci  }
342370b324cSopenharmony_ci  void SetSizeDefIfNoFiles() { if (NumFiles == 0) Size.Def = true; }
343370b324cSopenharmony_ci};
344370b324cSopenharmony_ci
345370b324cSopenharmony_cistruct CListStat2
346370b324cSopenharmony_ci{
347370b324cSopenharmony_ci  CListStat MainFiles;
348370b324cSopenharmony_ci  CListStat AltStreams;
349370b324cSopenharmony_ci  UInt64 NumDirs;
350370b324cSopenharmony_ci
351370b324cSopenharmony_ci  CListStat2(): NumDirs(0) {}
352370b324cSopenharmony_ci
353370b324cSopenharmony_ci  void Update(const CListStat2 &st)
354370b324cSopenharmony_ci  {
355370b324cSopenharmony_ci    MainFiles.Update(st.MainFiles);
356370b324cSopenharmony_ci    AltStreams.Update(st.AltStreams);
357370b324cSopenharmony_ci    NumDirs += st.NumDirs;
358370b324cSopenharmony_ci  }
359370b324cSopenharmony_ci  UInt64 GetNumStreams() const { return MainFiles.NumFiles + AltStreams.NumFiles; }
360370b324cSopenharmony_ci  CListStat &GetStat(bool altStreamsMode) { return altStreamsMode ? AltStreams : MainFiles; }
361370b324cSopenharmony_ci};
362370b324cSopenharmony_ci
363370b324cSopenharmony_ciclass CFieldPrinter
364370b324cSopenharmony_ci{
365370b324cSopenharmony_ci  CObjectVector<CFieldInfo> _fields;
366370b324cSopenharmony_ci
367370b324cSopenharmony_ci  void AddProp(const wchar_t *name, PROPID propID, bool isRawProp);
368370b324cSopenharmony_cipublic:
369370b324cSopenharmony_ci  const CArc *Arc;
370370b324cSopenharmony_ci  bool TechMode;
371370b324cSopenharmony_ci  UString FilePath;
372370b324cSopenharmony_ci  AString TempAString;
373370b324cSopenharmony_ci  UString TempWString;
374370b324cSopenharmony_ci  bool IsDir;
375370b324cSopenharmony_ci
376370b324cSopenharmony_ci  AString LinesString;
377370b324cSopenharmony_ci
378370b324cSopenharmony_ci  void Clear() { _fields.Clear(); LinesString.Empty(); }
379370b324cSopenharmony_ci  void Init(const CFieldInfoInit *standardFieldTable, unsigned numItems);
380370b324cSopenharmony_ci
381370b324cSopenharmony_ci  HRESULT AddMainProps(IInArchive *archive);
382370b324cSopenharmony_ci  HRESULT AddRawProps(IArchiveGetRawProps *getRawProps);
383370b324cSopenharmony_ci
384370b324cSopenharmony_ci  void PrintTitle();
385370b324cSopenharmony_ci  void PrintTitleLines();
386370b324cSopenharmony_ci  HRESULT PrintItemInfo(UInt32 index, const CListStat &st);
387370b324cSopenharmony_ci  void PrintSum(const CListStat &st, UInt64 numDirs, const char *str);
388370b324cSopenharmony_ci  void PrintSum(const CListStat2 &stat2);
389370b324cSopenharmony_ci};
390370b324cSopenharmony_ci
391370b324cSopenharmony_civoid CFieldPrinter::Init(const CFieldInfoInit *standardFieldTable, unsigned numItems)
392370b324cSopenharmony_ci{
393370b324cSopenharmony_ci  Clear();
394370b324cSopenharmony_ci  for (unsigned i = 0; i < numItems; i++)
395370b324cSopenharmony_ci  {
396370b324cSopenharmony_ci    CFieldInfo &f = _fields.AddNew();
397370b324cSopenharmony_ci    const CFieldInfoInit &fii = standardFieldTable[i];
398370b324cSopenharmony_ci    f.PropID = fii.PropID;
399370b324cSopenharmony_ci    f.IsRawProp = false;
400370b324cSopenharmony_ci    f.NameA = fii.Name;
401370b324cSopenharmony_ci    f.TitleAdjustment = fii.TitleAdjustment;
402370b324cSopenharmony_ci    f.TextAdjustment = fii.TextAdjustment;
403370b324cSopenharmony_ci    f.PrefixSpacesWidth = fii.PrefixSpacesWidth;
404370b324cSopenharmony_ci    f.Width = fii.Width;
405370b324cSopenharmony_ci
406370b324cSopenharmony_ci    unsigned k;
407370b324cSopenharmony_ci    for (k = 0; k < fii.PrefixSpacesWidth; k++)
408370b324cSopenharmony_ci      LinesString.Add_Space();
409370b324cSopenharmony_ci    for (k = 0; k < fii.Width; k++)
410370b324cSopenharmony_ci      LinesString.Add_Minus();
411370b324cSopenharmony_ci  }
412370b324cSopenharmony_ci}
413370b324cSopenharmony_ci
414370b324cSopenharmony_cistatic void GetPropName(PROPID propID, const wchar_t *name, AString &nameA, UString &nameU)
415370b324cSopenharmony_ci{
416370b324cSopenharmony_ci  if (propID < Z7_ARRAY_SIZE(kPropIdToName))
417370b324cSopenharmony_ci  {
418370b324cSopenharmony_ci    nameA = kPropIdToName[propID];
419370b324cSopenharmony_ci    return;
420370b324cSopenharmony_ci  }
421370b324cSopenharmony_ci  if (name)
422370b324cSopenharmony_ci    nameU = name;
423370b324cSopenharmony_ci  else
424370b324cSopenharmony_ci  {
425370b324cSopenharmony_ci    nameA.Empty();
426370b324cSopenharmony_ci    nameA.Add_UInt32(propID);
427370b324cSopenharmony_ci  }
428370b324cSopenharmony_ci}
429370b324cSopenharmony_ci
430370b324cSopenharmony_civoid CFieldPrinter::AddProp(const wchar_t *name, PROPID propID, bool isRawProp)
431370b324cSopenharmony_ci{
432370b324cSopenharmony_ci  CFieldInfo f;
433370b324cSopenharmony_ci  f.PropID = propID;
434370b324cSopenharmony_ci  f.IsRawProp = isRawProp;
435370b324cSopenharmony_ci  GetPropName(propID, name, f.NameA, f.NameU);
436370b324cSopenharmony_ci  f.NameU += " = ";
437370b324cSopenharmony_ci  if (!f.NameA.IsEmpty())
438370b324cSopenharmony_ci    f.NameA += " = ";
439370b324cSopenharmony_ci  else
440370b324cSopenharmony_ci  {
441370b324cSopenharmony_ci    const UString &s = f.NameU;
442370b324cSopenharmony_ci    AString sA;
443370b324cSopenharmony_ci    unsigned i;
444370b324cSopenharmony_ci    for (i = 0; i < s.Len(); i++)
445370b324cSopenharmony_ci    {
446370b324cSopenharmony_ci      wchar_t c = s[i];
447370b324cSopenharmony_ci      if (c >= 0x80)
448370b324cSopenharmony_ci        break;
449370b324cSopenharmony_ci      sA += (char)c;
450370b324cSopenharmony_ci    }
451370b324cSopenharmony_ci    if (i == s.Len())
452370b324cSopenharmony_ci      f.NameA = sA;
453370b324cSopenharmony_ci  }
454370b324cSopenharmony_ci  _fields.Add(f);
455370b324cSopenharmony_ci}
456370b324cSopenharmony_ci
457370b324cSopenharmony_ciHRESULT CFieldPrinter::AddMainProps(IInArchive *archive)
458370b324cSopenharmony_ci{
459370b324cSopenharmony_ci  UInt32 numProps;
460370b324cSopenharmony_ci  RINOK(archive->GetNumberOfProperties(&numProps))
461370b324cSopenharmony_ci  for (UInt32 i = 0; i < numProps; i++)
462370b324cSopenharmony_ci  {
463370b324cSopenharmony_ci    CMyComBSTR name;
464370b324cSopenharmony_ci    PROPID propID;
465370b324cSopenharmony_ci    VARTYPE vt;
466370b324cSopenharmony_ci    RINOK(archive->GetPropertyInfo(i, &name, &propID, &vt))
467370b324cSopenharmony_ci    AddProp(name, propID, false);
468370b324cSopenharmony_ci  }
469370b324cSopenharmony_ci  return S_OK;
470370b324cSopenharmony_ci}
471370b324cSopenharmony_ci
472370b324cSopenharmony_ciHRESULT CFieldPrinter::AddRawProps(IArchiveGetRawProps *getRawProps)
473370b324cSopenharmony_ci{
474370b324cSopenharmony_ci  UInt32 numProps;
475370b324cSopenharmony_ci  RINOK(getRawProps->GetNumRawProps(&numProps))
476370b324cSopenharmony_ci  for (UInt32 i = 0; i < numProps; i++)
477370b324cSopenharmony_ci  {
478370b324cSopenharmony_ci    CMyComBSTR name;
479370b324cSopenharmony_ci    PROPID propID;
480370b324cSopenharmony_ci    RINOK(getRawProps->GetRawPropInfo(i, &name, &propID))
481370b324cSopenharmony_ci    AddProp(name, propID, true);
482370b324cSopenharmony_ci  }
483370b324cSopenharmony_ci  return S_OK;
484370b324cSopenharmony_ci}
485370b324cSopenharmony_ci
486370b324cSopenharmony_civoid CFieldPrinter::PrintTitle()
487370b324cSopenharmony_ci{
488370b324cSopenharmony_ci  FOR_VECTOR (i, _fields)
489370b324cSopenharmony_ci  {
490370b324cSopenharmony_ci    const CFieldInfo &f = _fields[i];
491370b324cSopenharmony_ci    PrintSpaces(f.PrefixSpacesWidth);
492370b324cSopenharmony_ci    PrintString(f.TitleAdjustment, ((f.PropID == kpidPath) ? 0: f.Width), f.NameA);
493370b324cSopenharmony_ci  }
494370b324cSopenharmony_ci}
495370b324cSopenharmony_ci
496370b324cSopenharmony_civoid CFieldPrinter::PrintTitleLines()
497370b324cSopenharmony_ci{
498370b324cSopenharmony_ci  g_StdOut << LinesString;
499370b324cSopenharmony_ci}
500370b324cSopenharmony_ci
501370b324cSopenharmony_cistatic void PrintTime(char *dest, const CListFileTimeDef &t, bool showNS)
502370b324cSopenharmony_ci{
503370b324cSopenharmony_ci  *dest = 0;
504370b324cSopenharmony_ci  if (t.IsZero())
505370b324cSopenharmony_ci    return;
506370b324cSopenharmony_ci  int prec = kTimestampPrintLevel_SEC;
507370b324cSopenharmony_ci  if (showNS)
508370b324cSopenharmony_ci  {
509370b324cSopenharmony_ci    prec = kTimestampPrintLevel_NTFS;
510370b324cSopenharmony_ci    if (t.Prec != 0)
511370b324cSopenharmony_ci    {
512370b324cSopenharmony_ci      prec = t.GetNumDigits();
513370b324cSopenharmony_ci      if (prec < kTimestampPrintLevel_DAY)
514370b324cSopenharmony_ci        prec = kTimestampPrintLevel_NTFS;
515370b324cSopenharmony_ci    }
516370b324cSopenharmony_ci  }
517370b324cSopenharmony_ci
518370b324cSopenharmony_ci  ConvertUtcFileTimeToString2(t.FT, t.Ns100, dest, prec);
519370b324cSopenharmony_ci}
520370b324cSopenharmony_ci
521370b324cSopenharmony_ci#ifndef Z7_SFX
522370b324cSopenharmony_ci
523370b324cSopenharmony_cistatic inline char GetHex(Byte value)
524370b324cSopenharmony_ci{
525370b324cSopenharmony_ci  return (char)((value < 10) ? ('0' + value) : ('a' + (value - 10)));
526370b324cSopenharmony_ci}
527370b324cSopenharmony_ci
528370b324cSopenharmony_cistatic void HexToString(char *dest, const Byte *data, UInt32 size)
529370b324cSopenharmony_ci{
530370b324cSopenharmony_ci  for (UInt32 i = 0; i < size; i++)
531370b324cSopenharmony_ci  {
532370b324cSopenharmony_ci    Byte b = data[i];
533370b324cSopenharmony_ci    dest[0] = GetHex((Byte)((b >> 4) & 0xF));
534370b324cSopenharmony_ci    dest[1] = GetHex((Byte)(b & 0xF));
535370b324cSopenharmony_ci    dest += 2;
536370b324cSopenharmony_ci  }
537370b324cSopenharmony_ci  *dest = 0;
538370b324cSopenharmony_ci}
539370b324cSopenharmony_ci
540370b324cSopenharmony_ci#endif
541370b324cSopenharmony_ci
542370b324cSopenharmony_ci#define MY_ENDL endl
543370b324cSopenharmony_ci
544370b324cSopenharmony_ciHRESULT CFieldPrinter::PrintItemInfo(UInt32 index, const CListStat &st)
545370b324cSopenharmony_ci{
546370b324cSopenharmony_ci  char temp[128];
547370b324cSopenharmony_ci  size_t tempPos = 0;
548370b324cSopenharmony_ci
549370b324cSopenharmony_ci  bool techMode = this->TechMode;
550370b324cSopenharmony_ci  /*
551370b324cSopenharmony_ci  if (techMode)
552370b324cSopenharmony_ci  {
553370b324cSopenharmony_ci    g_StdOut << "Index = ";
554370b324cSopenharmony_ci    g_StdOut << (UInt64)index;
555370b324cSopenharmony_ci    g_StdOut << endl;
556370b324cSopenharmony_ci  }
557370b324cSopenharmony_ci  */
558370b324cSopenharmony_ci  FOR_VECTOR (i, _fields)
559370b324cSopenharmony_ci  {
560370b324cSopenharmony_ci    const CFieldInfo &f = _fields[i];
561370b324cSopenharmony_ci
562370b324cSopenharmony_ci    if (!techMode)
563370b324cSopenharmony_ci    {
564370b324cSopenharmony_ci      PrintSpacesToString(temp + tempPos, f.PrefixSpacesWidth);
565370b324cSopenharmony_ci      tempPos += f.PrefixSpacesWidth;
566370b324cSopenharmony_ci    }
567370b324cSopenharmony_ci
568370b324cSopenharmony_ci    if (techMode)
569370b324cSopenharmony_ci    {
570370b324cSopenharmony_ci      if (!f.NameA.IsEmpty())
571370b324cSopenharmony_ci        g_StdOut << f.NameA;
572370b324cSopenharmony_ci      else
573370b324cSopenharmony_ci        g_StdOut << f.NameU;
574370b324cSopenharmony_ci    }
575370b324cSopenharmony_ci
576370b324cSopenharmony_ci    if (f.PropID == kpidPath)
577370b324cSopenharmony_ci    {
578370b324cSopenharmony_ci      if (!techMode)
579370b324cSopenharmony_ci        g_StdOut << temp;
580370b324cSopenharmony_ci      g_StdOut.NormalizePrint_UString(FilePath, TempWString, TempAString);
581370b324cSopenharmony_ci      if (techMode)
582370b324cSopenharmony_ci        g_StdOut << MY_ENDL;
583370b324cSopenharmony_ci      continue;
584370b324cSopenharmony_ci    }
585370b324cSopenharmony_ci
586370b324cSopenharmony_ci    const unsigned width = f.Width;
587370b324cSopenharmony_ci
588370b324cSopenharmony_ci    if (f.IsRawProp)
589370b324cSopenharmony_ci    {
590370b324cSopenharmony_ci      #ifndef Z7_SFX
591370b324cSopenharmony_ci
592370b324cSopenharmony_ci      const void *data;
593370b324cSopenharmony_ci      UInt32 dataSize;
594370b324cSopenharmony_ci      UInt32 propType;
595370b324cSopenharmony_ci      RINOK(Arc->GetRawProps->GetRawProp(index, f.PropID, &data, &dataSize, &propType))
596370b324cSopenharmony_ci
597370b324cSopenharmony_ci      if (dataSize != 0)
598370b324cSopenharmony_ci      {
599370b324cSopenharmony_ci        bool needPrint = true;
600370b324cSopenharmony_ci
601370b324cSopenharmony_ci        if (f.PropID == kpidNtSecure)
602370b324cSopenharmony_ci        {
603370b324cSopenharmony_ci          if (propType != NPropDataType::kRaw)
604370b324cSopenharmony_ci            return E_FAIL;
605370b324cSopenharmony_ci          #ifndef Z7_SFX
606370b324cSopenharmony_ci          ConvertNtSecureToString((const Byte *)data, dataSize, TempAString);
607370b324cSopenharmony_ci          g_StdOut << TempAString;
608370b324cSopenharmony_ci          needPrint = false;
609370b324cSopenharmony_ci          #endif
610370b324cSopenharmony_ci        }
611370b324cSopenharmony_ci        else if (f.PropID == kpidNtReparse)
612370b324cSopenharmony_ci        {
613370b324cSopenharmony_ci          UString s;
614370b324cSopenharmony_ci          if (ConvertNtReparseToString((const Byte *)data, dataSize, s))
615370b324cSopenharmony_ci          {
616370b324cSopenharmony_ci            needPrint = false;
617370b324cSopenharmony_ci            g_StdOut.PrintUString(s, TempAString);
618370b324cSopenharmony_ci          }
619370b324cSopenharmony_ci        }
620370b324cSopenharmony_ci
621370b324cSopenharmony_ci        if (needPrint)
622370b324cSopenharmony_ci        {
623370b324cSopenharmony_ci          if (propType != NPropDataType::kRaw)
624370b324cSopenharmony_ci            return E_FAIL;
625370b324cSopenharmony_ci
626370b324cSopenharmony_ci          const UInt32 kMaxDataSize = 64;
627370b324cSopenharmony_ci
628370b324cSopenharmony_ci          if (dataSize > kMaxDataSize)
629370b324cSopenharmony_ci          {
630370b324cSopenharmony_ci            g_StdOut << "data:";
631370b324cSopenharmony_ci            g_StdOut << dataSize;
632370b324cSopenharmony_ci          }
633370b324cSopenharmony_ci          else
634370b324cSopenharmony_ci          {
635370b324cSopenharmony_ci            char hexStr[kMaxDataSize * 2 + 4];
636370b324cSopenharmony_ci            HexToString(hexStr, (const Byte *)data, dataSize);
637370b324cSopenharmony_ci            g_StdOut << hexStr;
638370b324cSopenharmony_ci          }
639370b324cSopenharmony_ci        }
640370b324cSopenharmony_ci      }
641370b324cSopenharmony_ci
642370b324cSopenharmony_ci      #endif
643370b324cSopenharmony_ci    }
644370b324cSopenharmony_ci    else
645370b324cSopenharmony_ci    {
646370b324cSopenharmony_ci      CPropVariant prop;
647370b324cSopenharmony_ci      switch (f.PropID)
648370b324cSopenharmony_ci      {
649370b324cSopenharmony_ci        case kpidSize: if (st.Size.Def) prop = st.Size.Val; break;
650370b324cSopenharmony_ci        case kpidPackSize: if (st.PackSize.Def) prop = st.PackSize.Val; break;
651370b324cSopenharmony_ci        case kpidMTime:
652370b324cSopenharmony_ci        {
653370b324cSopenharmony_ci          const CListFileTimeDef &mtime = st.MTime;
654370b324cSopenharmony_ci          if (mtime.Def)
655370b324cSopenharmony_ci            prop.SetAsTimeFrom_FT_Prec_Ns100(mtime.FT, mtime.Prec, mtime.Ns100);
656370b324cSopenharmony_ci          break;
657370b324cSopenharmony_ci        }
658370b324cSopenharmony_ci        default:
659370b324cSopenharmony_ci          RINOK(Arc->Archive->GetProperty(index, f.PropID, &prop))
660370b324cSopenharmony_ci      }
661370b324cSopenharmony_ci      if (f.PropID == kpidAttrib && (prop.vt == VT_EMPTY || prop.vt == VT_UI4))
662370b324cSopenharmony_ci      {
663370b324cSopenharmony_ci        GetAttribString((prop.vt == VT_EMPTY) ? 0 : prop.ulVal, IsDir, techMode, temp + tempPos);
664370b324cSopenharmony_ci        if (techMode)
665370b324cSopenharmony_ci          g_StdOut << temp + tempPos;
666370b324cSopenharmony_ci        else
667370b324cSopenharmony_ci          tempPos += strlen(temp + tempPos);
668370b324cSopenharmony_ci      }
669370b324cSopenharmony_ci      else if (prop.vt == VT_EMPTY)
670370b324cSopenharmony_ci      {
671370b324cSopenharmony_ci        if (!techMode)
672370b324cSopenharmony_ci        {
673370b324cSopenharmony_ci          PrintSpacesToString(temp + tempPos, width);
674370b324cSopenharmony_ci          tempPos += width;
675370b324cSopenharmony_ci        }
676370b324cSopenharmony_ci      }
677370b324cSopenharmony_ci      else if (prop.vt == VT_FILETIME)
678370b324cSopenharmony_ci      {
679370b324cSopenharmony_ci        CListFileTimeDef t;
680370b324cSopenharmony_ci        t.Set_From_Prop(prop);
681370b324cSopenharmony_ci        PrintTime(temp + tempPos, t, techMode);
682370b324cSopenharmony_ci        if (techMode)
683370b324cSopenharmony_ci          g_StdOut << temp + tempPos;
684370b324cSopenharmony_ci        else
685370b324cSopenharmony_ci        {
686370b324cSopenharmony_ci          size_t len = strlen(temp + tempPos);
687370b324cSopenharmony_ci          tempPos += len;
688370b324cSopenharmony_ci          if (len < (unsigned)f.Width)
689370b324cSopenharmony_ci          {
690370b324cSopenharmony_ci            len = f.Width - len;
691370b324cSopenharmony_ci            PrintSpacesToString(temp + tempPos, (unsigned)len);
692370b324cSopenharmony_ci            tempPos += len;
693370b324cSopenharmony_ci          }
694370b324cSopenharmony_ci        }
695370b324cSopenharmony_ci      }
696370b324cSopenharmony_ci      else if (prop.vt == VT_BSTR)
697370b324cSopenharmony_ci      {
698370b324cSopenharmony_ci        TempWString.SetFromBstr(prop.bstrVal);
699370b324cSopenharmony_ci        // do we need multi-line support here ?
700370b324cSopenharmony_ci        g_StdOut.Normalize_UString(TempWString);
701370b324cSopenharmony_ci        if (techMode)
702370b324cSopenharmony_ci        {
703370b324cSopenharmony_ci          g_StdOut.PrintUString(TempWString, TempAString);
704370b324cSopenharmony_ci        }
705370b324cSopenharmony_ci        else
706370b324cSopenharmony_ci          PrintUString(f.TextAdjustment, width, TempWString, TempAString);
707370b324cSopenharmony_ci      }
708370b324cSopenharmony_ci      else
709370b324cSopenharmony_ci      {
710370b324cSopenharmony_ci        char s[64];
711370b324cSopenharmony_ci        ConvertPropertyToShortString2(s, prop, f.PropID);
712370b324cSopenharmony_ci        if (techMode)
713370b324cSopenharmony_ci          g_StdOut << s;
714370b324cSopenharmony_ci        else
715370b324cSopenharmony_ci        {
716370b324cSopenharmony_ci          PrintStringToString(temp + tempPos, f.TextAdjustment, width, s);
717370b324cSopenharmony_ci          tempPos += strlen(temp + tempPos);
718370b324cSopenharmony_ci        }
719370b324cSopenharmony_ci      }
720370b324cSopenharmony_ci    }
721370b324cSopenharmony_ci    if (techMode)
722370b324cSopenharmony_ci      g_StdOut << MY_ENDL;
723370b324cSopenharmony_ci  }
724370b324cSopenharmony_ci  g_StdOut << MY_ENDL;
725370b324cSopenharmony_ci  return S_OK;
726370b324cSopenharmony_ci}
727370b324cSopenharmony_ci
728370b324cSopenharmony_cistatic void PrintNumber(EAdjustment adj, unsigned width, const CListUInt64Def &value)
729370b324cSopenharmony_ci{
730370b324cSopenharmony_ci  char s[32];
731370b324cSopenharmony_ci  s[0] = 0;
732370b324cSopenharmony_ci  if (value.Def)
733370b324cSopenharmony_ci    ConvertUInt64ToString(value.Val, s);
734370b324cSopenharmony_ci  PrintString(adj, width, s);
735370b324cSopenharmony_ci}
736370b324cSopenharmony_ci
737370b324cSopenharmony_civoid Print_UInt64_and_String(AString &s, UInt64 val, const char *name);
738370b324cSopenharmony_ci
739370b324cSopenharmony_civoid CFieldPrinter::PrintSum(const CListStat &st, UInt64 numDirs, const char *str)
740370b324cSopenharmony_ci{
741370b324cSopenharmony_ci  FOR_VECTOR (i, _fields)
742370b324cSopenharmony_ci  {
743370b324cSopenharmony_ci    const CFieldInfo &f = _fields[i];
744370b324cSopenharmony_ci    PrintSpaces(f.PrefixSpacesWidth);
745370b324cSopenharmony_ci    if (f.PropID == kpidSize)
746370b324cSopenharmony_ci      PrintNumber(f.TextAdjustment, f.Width, st.Size);
747370b324cSopenharmony_ci    else if (f.PropID == kpidPackSize)
748370b324cSopenharmony_ci      PrintNumber(f.TextAdjustment, f.Width, st.PackSize);
749370b324cSopenharmony_ci    else if (f.PropID == kpidMTime)
750370b324cSopenharmony_ci    {
751370b324cSopenharmony_ci      char s[64];
752370b324cSopenharmony_ci      s[0] = 0;
753370b324cSopenharmony_ci      if (st.MTime.Def)
754370b324cSopenharmony_ci        PrintTime(s, st.MTime, false); // showNS
755370b324cSopenharmony_ci      PrintString(f.TextAdjustment, f.Width, s);
756370b324cSopenharmony_ci    }
757370b324cSopenharmony_ci    else if (f.PropID == kpidPath)
758370b324cSopenharmony_ci    {
759370b324cSopenharmony_ci      AString s;
760370b324cSopenharmony_ci      Print_UInt64_and_String(s, st.NumFiles, str);
761370b324cSopenharmony_ci      if (numDirs != 0)
762370b324cSopenharmony_ci      {
763370b324cSopenharmony_ci        s += ", ";
764370b324cSopenharmony_ci        Print_UInt64_and_String(s, numDirs, kString_Dirs);
765370b324cSopenharmony_ci      }
766370b324cSopenharmony_ci      PrintString(f.TextAdjustment, 0, s);
767370b324cSopenharmony_ci    }
768370b324cSopenharmony_ci    else
769370b324cSopenharmony_ci      PrintString(f.TextAdjustment, f.Width, "");
770370b324cSopenharmony_ci  }
771370b324cSopenharmony_ci  g_StdOut << endl;
772370b324cSopenharmony_ci}
773370b324cSopenharmony_ci
774370b324cSopenharmony_civoid CFieldPrinter::PrintSum(const CListStat2 &stat2)
775370b324cSopenharmony_ci{
776370b324cSopenharmony_ci  PrintSum(stat2.MainFiles, stat2.NumDirs, kString_Files);
777370b324cSopenharmony_ci  if (stat2.AltStreams.NumFiles != 0)
778370b324cSopenharmony_ci  {
779370b324cSopenharmony_ci    PrintSum(stat2.AltStreams, 0, kString_AltStreams);
780370b324cSopenharmony_ci    CListStat st = stat2.MainFiles;
781370b324cSopenharmony_ci    st.Update(stat2.AltStreams);
782370b324cSopenharmony_ci    PrintSum(st, 0, kString_Streams);
783370b324cSopenharmony_ci  }
784370b324cSopenharmony_ci}
785370b324cSopenharmony_ci
786370b324cSopenharmony_cistatic HRESULT GetUInt64Value(IInArchive *archive, UInt32 index, PROPID propID, CListUInt64Def &value)
787370b324cSopenharmony_ci{
788370b324cSopenharmony_ci  value.Val = 0;
789370b324cSopenharmony_ci  value.Def = false;
790370b324cSopenharmony_ci  CPropVariant prop;
791370b324cSopenharmony_ci  RINOK(archive->GetProperty(index, propID, &prop))
792370b324cSopenharmony_ci  value.Def = ConvertPropVariantToUInt64(prop, value.Val);
793370b324cSopenharmony_ci  return S_OK;
794370b324cSopenharmony_ci}
795370b324cSopenharmony_ci
796370b324cSopenharmony_cistatic HRESULT GetItemMTime(IInArchive *archive, UInt32 index, CListFileTimeDef &t)
797370b324cSopenharmony_ci{
798370b324cSopenharmony_ci  /* maybe we could call CArc::GetItemMTime(UInt32 index, CArcTime &ft, bool &defined) here
799370b324cSopenharmony_ci     that can set default timestamp, if not defined */
800370b324cSopenharmony_ci  t.Clear();
801370b324cSopenharmony_ci  // t.Def = false;
802370b324cSopenharmony_ci  CPropVariant prop;
803370b324cSopenharmony_ci  RINOK(archive->GetProperty(index, kpidMTime, &prop))
804370b324cSopenharmony_ci  if (prop.vt == VT_FILETIME)
805370b324cSopenharmony_ci    t.Set_From_Prop(prop);
806370b324cSopenharmony_ci  else if (prop.vt != VT_EMPTY)
807370b324cSopenharmony_ci    return E_FAIL;
808370b324cSopenharmony_ci  return S_OK;
809370b324cSopenharmony_ci}
810370b324cSopenharmony_ci
811370b324cSopenharmony_cistatic void PrintPropNameAndNumber(CStdOutStream &so, const char *name, UInt64 val)
812370b324cSopenharmony_ci{
813370b324cSopenharmony_ci  so << name << ": " << val << endl;
814370b324cSopenharmony_ci}
815370b324cSopenharmony_ci
816370b324cSopenharmony_cistatic void PrintPropName_and_Eq(CStdOutStream &so, PROPID propID)
817370b324cSopenharmony_ci{
818370b324cSopenharmony_ci  const char *s;
819370b324cSopenharmony_ci  char temp[16];
820370b324cSopenharmony_ci  if (propID < Z7_ARRAY_SIZE(kPropIdToName))
821370b324cSopenharmony_ci    s = kPropIdToName[propID];
822370b324cSopenharmony_ci  else
823370b324cSopenharmony_ci  {
824370b324cSopenharmony_ci    ConvertUInt32ToString(propID, temp);
825370b324cSopenharmony_ci    s = temp;
826370b324cSopenharmony_ci  }
827370b324cSopenharmony_ci  so << s << " = ";
828370b324cSopenharmony_ci}
829370b324cSopenharmony_ci
830370b324cSopenharmony_cistatic void PrintPropNameAndNumber(CStdOutStream &so, PROPID propID, UInt64 val)
831370b324cSopenharmony_ci{
832370b324cSopenharmony_ci  PrintPropName_and_Eq(so, propID);
833370b324cSopenharmony_ci  so << val << endl;
834370b324cSopenharmony_ci}
835370b324cSopenharmony_ci
836370b324cSopenharmony_cistatic void PrintPropNameAndNumber_Signed(CStdOutStream &so, PROPID propID, Int64 val)
837370b324cSopenharmony_ci{
838370b324cSopenharmony_ci  PrintPropName_and_Eq(so, propID);
839370b324cSopenharmony_ci  so << val << endl;
840370b324cSopenharmony_ci}
841370b324cSopenharmony_ci
842370b324cSopenharmony_ci
843370b324cSopenharmony_cistatic void UString_Replace_CRLF_to_LF(UString &s)
844370b324cSopenharmony_ci{
845370b324cSopenharmony_ci  // s.Replace(L"\r\n", L"\n");
846370b324cSopenharmony_ci  wchar_t *src = s.GetBuf();
847370b324cSopenharmony_ci  wchar_t *dest = src;
848370b324cSopenharmony_ci  for (;;)
849370b324cSopenharmony_ci  {
850370b324cSopenharmony_ci    wchar_t c = *src++;
851370b324cSopenharmony_ci    if (c == 0)
852370b324cSopenharmony_ci      break;
853370b324cSopenharmony_ci    if (c == '\r' && *src == '\n')
854370b324cSopenharmony_ci    {
855370b324cSopenharmony_ci      src++;
856370b324cSopenharmony_ci      c = '\n';
857370b324cSopenharmony_ci    }
858370b324cSopenharmony_ci    *dest++ = c;
859370b324cSopenharmony_ci  }
860370b324cSopenharmony_ci  s.ReleaseBuf_SetEnd((unsigned)(dest - s.GetBuf()));
861370b324cSopenharmony_ci}
862370b324cSopenharmony_ci
863370b324cSopenharmony_ci
864370b324cSopenharmony_cistatic void PrintPropVal_MultiLine(CStdOutStream &so, const wchar_t *val)
865370b324cSopenharmony_ci{
866370b324cSopenharmony_ci  UString s (val);
867370b324cSopenharmony_ci  if (s.Find(L'\n') >= 0)
868370b324cSopenharmony_ci  {
869370b324cSopenharmony_ci    so << endl;
870370b324cSopenharmony_ci    so << "{";
871370b324cSopenharmony_ci    so << endl;
872370b324cSopenharmony_ci    UString_Replace_CRLF_to_LF(s);
873370b324cSopenharmony_ci    so.Normalize_UString_LF_Allowed(s);
874370b324cSopenharmony_ci    so << s;
875370b324cSopenharmony_ci    so << endl;
876370b324cSopenharmony_ci    so << "}";
877370b324cSopenharmony_ci  }
878370b324cSopenharmony_ci  else
879370b324cSopenharmony_ci  {
880370b324cSopenharmony_ci    so.Normalize_UString(s);
881370b324cSopenharmony_ci    so << s;
882370b324cSopenharmony_ci  }
883370b324cSopenharmony_ci  so << endl;
884370b324cSopenharmony_ci}
885370b324cSopenharmony_ci
886370b324cSopenharmony_ci
887370b324cSopenharmony_cistatic void PrintPropPair(CStdOutStream &so, const char *name, const wchar_t *val, bool multiLine)
888370b324cSopenharmony_ci{
889370b324cSopenharmony_ci  so << name << " = ";
890370b324cSopenharmony_ci  if (multiLine)
891370b324cSopenharmony_ci  {
892370b324cSopenharmony_ci    PrintPropVal_MultiLine(so, val);
893370b324cSopenharmony_ci    return;
894370b324cSopenharmony_ci  }
895370b324cSopenharmony_ci  UString s (val);
896370b324cSopenharmony_ci  so.Normalize_UString(s);
897370b324cSopenharmony_ci  so << s;
898370b324cSopenharmony_ci  so << endl;
899370b324cSopenharmony_ci}
900370b324cSopenharmony_ci
901370b324cSopenharmony_ci
902370b324cSopenharmony_cistatic void PrintPropertyPair2(CStdOutStream &so, PROPID propID, const wchar_t *name, const CPropVariant &prop)
903370b324cSopenharmony_ci{
904370b324cSopenharmony_ci  UString s;
905370b324cSopenharmony_ci  const int levelTopLimit = 9; // 1ns level
906370b324cSopenharmony_ci  ConvertPropertyToString2(s, prop, propID, levelTopLimit);
907370b324cSopenharmony_ci  if (!s.IsEmpty())
908370b324cSopenharmony_ci  {
909370b324cSopenharmony_ci    AString nameA;
910370b324cSopenharmony_ci    UString nameU;
911370b324cSopenharmony_ci    GetPropName(propID, name, nameA, nameU);
912370b324cSopenharmony_ci    if (!nameA.IsEmpty())
913370b324cSopenharmony_ci      so << nameA;
914370b324cSopenharmony_ci    else
915370b324cSopenharmony_ci      so << nameU;
916370b324cSopenharmony_ci    so << " = ";
917370b324cSopenharmony_ci    PrintPropVal_MultiLine(so, s);
918370b324cSopenharmony_ci  }
919370b324cSopenharmony_ci}
920370b324cSopenharmony_ci
921370b324cSopenharmony_cistatic HRESULT PrintArcProp(CStdOutStream &so, IInArchive *archive, PROPID propID, const wchar_t *name)
922370b324cSopenharmony_ci{
923370b324cSopenharmony_ci  CPropVariant prop;
924370b324cSopenharmony_ci  RINOK(archive->GetArchiveProperty(propID, &prop))
925370b324cSopenharmony_ci  PrintPropertyPair2(so, propID, name, prop);
926370b324cSopenharmony_ci  return S_OK;
927370b324cSopenharmony_ci}
928370b324cSopenharmony_ci
929370b324cSopenharmony_cistatic void PrintArcTypeError(CStdOutStream &so, const UString &type, bool isWarning)
930370b324cSopenharmony_ci{
931370b324cSopenharmony_ci  so << "Open " << (isWarning ? "WARNING" : "ERROR")
932370b324cSopenharmony_ci    << ": Cannot open the file as ["
933370b324cSopenharmony_ci    << type
934370b324cSopenharmony_ci    << "] archive"
935370b324cSopenharmony_ci    << endl;
936370b324cSopenharmony_ci}
937370b324cSopenharmony_ci
938370b324cSopenharmony_ciint Find_FileName_InSortedVector(const UStringVector &fileName, const UString& name);
939370b324cSopenharmony_ci
940370b324cSopenharmony_civoid PrintErrorFlags(CStdOutStream &so, const char *s, UInt32 errorFlags);
941370b324cSopenharmony_ci
942370b324cSopenharmony_cistatic void ErrorInfo_Print(CStdOutStream &so, const CArcErrorInfo &er)
943370b324cSopenharmony_ci{
944370b324cSopenharmony_ci  PrintErrorFlags(so, "ERRORS:", er.GetErrorFlags());
945370b324cSopenharmony_ci  if (!er.ErrorMessage.IsEmpty())
946370b324cSopenharmony_ci    PrintPropPair(so, "ERROR", er.ErrorMessage, true);
947370b324cSopenharmony_ci
948370b324cSopenharmony_ci  PrintErrorFlags(so, "WARNINGS:", er.GetWarningFlags());
949370b324cSopenharmony_ci  if (!er.WarningMessage.IsEmpty())
950370b324cSopenharmony_ci    PrintPropPair(so, "WARNING", er.WarningMessage, true);
951370b324cSopenharmony_ci}
952370b324cSopenharmony_ci
953370b324cSopenharmony_ciHRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink);
954370b324cSopenharmony_ciHRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink)
955370b324cSopenharmony_ci{
956370b324cSopenharmony_ci  FOR_VECTOR (r, arcLink.Arcs)
957370b324cSopenharmony_ci  {
958370b324cSopenharmony_ci    const CArc &arc = arcLink.Arcs[r];
959370b324cSopenharmony_ci    const CArcErrorInfo &er = arc.ErrorInfo;
960370b324cSopenharmony_ci
961370b324cSopenharmony_ci    so << "--\n";
962370b324cSopenharmony_ci    PrintPropPair(so, "Path", arc.Path, false);
963370b324cSopenharmony_ci    if (er.ErrorFormatIndex >= 0)
964370b324cSopenharmony_ci    {
965370b324cSopenharmony_ci      if (er.ErrorFormatIndex == arc.FormatIndex)
966370b324cSopenharmony_ci        so << "Warning: The archive is open with offset" << endl;
967370b324cSopenharmony_ci      else
968370b324cSopenharmony_ci        PrintArcTypeError(so, codecs->GetFormatNamePtr(er.ErrorFormatIndex), true);
969370b324cSopenharmony_ci    }
970370b324cSopenharmony_ci    PrintPropPair(so, "Type", codecs->GetFormatNamePtr(arc.FormatIndex), false);
971370b324cSopenharmony_ci
972370b324cSopenharmony_ci    ErrorInfo_Print(so, er);
973370b324cSopenharmony_ci
974370b324cSopenharmony_ci    Int64 offset = arc.GetGlobalOffset();
975370b324cSopenharmony_ci    if (offset != 0)
976370b324cSopenharmony_ci      PrintPropNameAndNumber_Signed(so, kpidOffset, offset);
977370b324cSopenharmony_ci    IInArchive *archive = arc.Archive;
978370b324cSopenharmony_ci    RINOK(PrintArcProp(so, archive, kpidPhySize, NULL))
979370b324cSopenharmony_ci    if (er.TailSize != 0)
980370b324cSopenharmony_ci      PrintPropNameAndNumber(so, kpidTailSize, er.TailSize);
981370b324cSopenharmony_ci    {
982370b324cSopenharmony_ci      UInt32 numProps;
983370b324cSopenharmony_ci      RINOK(archive->GetNumberOfArchiveProperties(&numProps))
984370b324cSopenharmony_ci
985370b324cSopenharmony_ci      for (UInt32 j = 0; j < numProps; j++)
986370b324cSopenharmony_ci      {
987370b324cSopenharmony_ci        CMyComBSTR name;
988370b324cSopenharmony_ci        PROPID propID;
989370b324cSopenharmony_ci        VARTYPE vt;
990370b324cSopenharmony_ci        RINOK(archive->GetArchivePropertyInfo(j, &name, &propID, &vt))
991370b324cSopenharmony_ci        RINOK(PrintArcProp(so, archive, propID, name))
992370b324cSopenharmony_ci      }
993370b324cSopenharmony_ci    }
994370b324cSopenharmony_ci
995370b324cSopenharmony_ci    if (r != arcLink.Arcs.Size() - 1)
996370b324cSopenharmony_ci    {
997370b324cSopenharmony_ci      UInt32 numProps;
998370b324cSopenharmony_ci      so << "----\n";
999370b324cSopenharmony_ci      if (archive->GetNumberOfProperties(&numProps) == S_OK)
1000370b324cSopenharmony_ci      {
1001370b324cSopenharmony_ci        UInt32 mainIndex = arcLink.Arcs[r + 1].SubfileIndex;
1002370b324cSopenharmony_ci        for (UInt32 j = 0; j < numProps; j++)
1003370b324cSopenharmony_ci        {
1004370b324cSopenharmony_ci          CMyComBSTR name;
1005370b324cSopenharmony_ci          PROPID propID;
1006370b324cSopenharmony_ci          VARTYPE vt;
1007370b324cSopenharmony_ci          RINOK(archive->GetPropertyInfo(j, &name, &propID, &vt))
1008370b324cSopenharmony_ci          CPropVariant prop;
1009370b324cSopenharmony_ci          RINOK(archive->GetProperty(mainIndex, propID, &prop))
1010370b324cSopenharmony_ci          PrintPropertyPair2(so, propID, name, prop);
1011370b324cSopenharmony_ci        }
1012370b324cSopenharmony_ci      }
1013370b324cSopenharmony_ci    }
1014370b324cSopenharmony_ci  }
1015370b324cSopenharmony_ci  return S_OK;
1016370b324cSopenharmony_ci}
1017370b324cSopenharmony_ci
1018370b324cSopenharmony_ciHRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink);
1019370b324cSopenharmony_ciHRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink)
1020370b324cSopenharmony_ci{
1021370b324cSopenharmony_ci  #ifndef Z7_NO_CRYPTO
1022370b324cSopenharmony_ci  if (arcLink.PasswordWasAsked)
1023370b324cSopenharmony_ci    so << "Cannot open encrypted archive. Wrong password?";
1024370b324cSopenharmony_ci  else
1025370b324cSopenharmony_ci  #endif
1026370b324cSopenharmony_ci  {
1027370b324cSopenharmony_ci    if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0)
1028370b324cSopenharmony_ci    {
1029370b324cSopenharmony_ci      so.NormalizePrint_UString(arcLink.NonOpen_ArcPath);
1030370b324cSopenharmony_ci      so << endl;
1031370b324cSopenharmony_ci      PrintArcTypeError(so, codecs->Formats[(unsigned)arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false);
1032370b324cSopenharmony_ci    }
1033370b324cSopenharmony_ci    else
1034370b324cSopenharmony_ci      so << "Cannot open the file as archive";
1035370b324cSopenharmony_ci  }
1036370b324cSopenharmony_ci
1037370b324cSopenharmony_ci  so << endl;
1038370b324cSopenharmony_ci  so << endl;
1039370b324cSopenharmony_ci  ErrorInfo_Print(so, arcLink.NonOpen_ErrorInfo);
1040370b324cSopenharmony_ci
1041370b324cSopenharmony_ci  return S_OK;
1042370b324cSopenharmony_ci}
1043370b324cSopenharmony_ci
1044370b324cSopenharmony_cibool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item);
1045370b324cSopenharmony_ci
1046370b324cSopenharmony_ciHRESULT ListArchives(
1047370b324cSopenharmony_ci    const CListOptions &listOptions,
1048370b324cSopenharmony_ci    CCodecs *codecs,
1049370b324cSopenharmony_ci    const CObjectVector<COpenType> &types,
1050370b324cSopenharmony_ci    const CIntVector &excludedFormats,
1051370b324cSopenharmony_ci    bool stdInMode,
1052370b324cSopenharmony_ci    UStringVector &arcPaths, UStringVector &arcPathsFull,
1053370b324cSopenharmony_ci    bool processAltStreams, bool showAltStreams,
1054370b324cSopenharmony_ci    const NWildcard::CCensorNode &wildcardCensor,
1055370b324cSopenharmony_ci    bool enableHeaders, bool techMode,
1056370b324cSopenharmony_ci    #ifndef Z7_NO_CRYPTO
1057370b324cSopenharmony_ci    bool &passwordEnabled, UString &password,
1058370b324cSopenharmony_ci    #endif
1059370b324cSopenharmony_ci    #ifndef Z7_SFX
1060370b324cSopenharmony_ci    const CObjectVector<CProperty> *props,
1061370b324cSopenharmony_ci    #endif
1062370b324cSopenharmony_ci    UInt64 &numErrors,
1063370b324cSopenharmony_ci    UInt64 &numWarnings)
1064370b324cSopenharmony_ci{
1065370b324cSopenharmony_ci  bool allFilesAreAllowed = wildcardCensor.AreAllAllowed();
1066370b324cSopenharmony_ci
1067370b324cSopenharmony_ci  numErrors = 0;
1068370b324cSopenharmony_ci  numWarnings = 0;
1069370b324cSopenharmony_ci
1070370b324cSopenharmony_ci  CFieldPrinter fp;
1071370b324cSopenharmony_ci  if (!techMode)
1072370b324cSopenharmony_ci    fp.Init(kStandardFieldTable, Z7_ARRAY_SIZE(kStandardFieldTable));
1073370b324cSopenharmony_ci
1074370b324cSopenharmony_ci  CListStat2 stat2total;
1075370b324cSopenharmony_ci
1076370b324cSopenharmony_ci  CBoolArr skipArcs(arcPaths.Size());
1077370b324cSopenharmony_ci  unsigned arcIndex;
1078370b324cSopenharmony_ci  for (arcIndex = 0; arcIndex < arcPaths.Size(); arcIndex++)
1079370b324cSopenharmony_ci    skipArcs[arcIndex] = false;
1080370b324cSopenharmony_ci  UInt64 numVolumes = 0;
1081370b324cSopenharmony_ci  UInt64 numArcs = 0;
1082370b324cSopenharmony_ci  UInt64 totalArcSizes = 0;
1083370b324cSopenharmony_ci
1084370b324cSopenharmony_ci  HRESULT lastError = 0;
1085370b324cSopenharmony_ci
1086370b324cSopenharmony_ci  for (arcIndex = 0; arcIndex < arcPaths.Size(); arcIndex++)
1087370b324cSopenharmony_ci  {
1088370b324cSopenharmony_ci    if (skipArcs[arcIndex])
1089370b324cSopenharmony_ci      continue;
1090370b324cSopenharmony_ci    const UString &arcPath = arcPaths[arcIndex];
1091370b324cSopenharmony_ci    UInt64 arcPackSize = 0;
1092370b324cSopenharmony_ci
1093370b324cSopenharmony_ci    if (!stdInMode)
1094370b324cSopenharmony_ci    {
1095370b324cSopenharmony_ci      NFile::NFind::CFileInfo fi;
1096370b324cSopenharmony_ci      if (!fi.Find_FollowLink(us2fs(arcPath)))
1097370b324cSopenharmony_ci      {
1098370b324cSopenharmony_ci        DWORD errorCode = GetLastError();
1099370b324cSopenharmony_ci        if (errorCode == 0)
1100370b324cSopenharmony_ci          errorCode = ERROR_FILE_NOT_FOUND;
1101370b324cSopenharmony_ci        lastError = HRESULT_FROM_WIN32(errorCode);
1102370b324cSopenharmony_ci        g_StdOut.Flush();
1103370b324cSopenharmony_ci        if (g_ErrStream)
1104370b324cSopenharmony_ci        {
1105370b324cSopenharmony_ci          *g_ErrStream << endl << kError << NError::MyFormatMessage(errorCode) << endl;
1106370b324cSopenharmony_ci          g_ErrStream->NormalizePrint_UString(arcPath);
1107370b324cSopenharmony_ci          *g_ErrStream << endl << endl;
1108370b324cSopenharmony_ci        }
1109370b324cSopenharmony_ci        numErrors++;
1110370b324cSopenharmony_ci        continue;
1111370b324cSopenharmony_ci      }
1112370b324cSopenharmony_ci      if (fi.IsDir())
1113370b324cSopenharmony_ci      {
1114370b324cSopenharmony_ci        g_StdOut.Flush();
1115370b324cSopenharmony_ci        if (g_ErrStream)
1116370b324cSopenharmony_ci        {
1117370b324cSopenharmony_ci          *g_ErrStream << endl << kError;
1118370b324cSopenharmony_ci          g_ErrStream->NormalizePrint_UString(arcPath);
1119370b324cSopenharmony_ci          *g_ErrStream << " is not a file" << endl << endl;
1120370b324cSopenharmony_ci        }
1121370b324cSopenharmony_ci        numErrors++;
1122370b324cSopenharmony_ci        continue;
1123370b324cSopenharmony_ci      }
1124370b324cSopenharmony_ci      arcPackSize = fi.Size;
1125370b324cSopenharmony_ci      totalArcSizes += arcPackSize;
1126370b324cSopenharmony_ci    }
1127370b324cSopenharmony_ci
1128370b324cSopenharmony_ci    CArchiveLink arcLink;
1129370b324cSopenharmony_ci
1130370b324cSopenharmony_ci    COpenCallbackConsole openCallback;
1131370b324cSopenharmony_ci    openCallback.Init(&g_StdOut, g_ErrStream, NULL);
1132370b324cSopenharmony_ci
1133370b324cSopenharmony_ci    #ifndef Z7_NO_CRYPTO
1134370b324cSopenharmony_ci
1135370b324cSopenharmony_ci    openCallback.PasswordIsDefined = passwordEnabled;
1136370b324cSopenharmony_ci    openCallback.Password = password;
1137370b324cSopenharmony_ci
1138370b324cSopenharmony_ci    #endif
1139370b324cSopenharmony_ci
1140370b324cSopenharmony_ci    /*
1141370b324cSopenharmony_ci    CObjectVector<COptionalOpenProperties> optPropsVector;
1142370b324cSopenharmony_ci    COptionalOpenProperties &optProps = optPropsVector.AddNew();
1143370b324cSopenharmony_ci    optProps.Props = *props;
1144370b324cSopenharmony_ci    */
1145370b324cSopenharmony_ci
1146370b324cSopenharmony_ci    COpenOptions options;
1147370b324cSopenharmony_ci    #ifndef Z7_SFX
1148370b324cSopenharmony_ci    options.props = props;
1149370b324cSopenharmony_ci    #endif
1150370b324cSopenharmony_ci    options.codecs = codecs;
1151370b324cSopenharmony_ci    options.types = &types;
1152370b324cSopenharmony_ci    options.excludedFormats = &excludedFormats;
1153370b324cSopenharmony_ci    options.stdInMode = stdInMode;
1154370b324cSopenharmony_ci    options.stream = NULL;
1155370b324cSopenharmony_ci    options.filePath = arcPath;
1156370b324cSopenharmony_ci
1157370b324cSopenharmony_ci    if (enableHeaders)
1158370b324cSopenharmony_ci    {
1159370b324cSopenharmony_ci      g_StdOut << endl << kListing;
1160370b324cSopenharmony_ci      g_StdOut.NormalizePrint_UString(arcPath);
1161370b324cSopenharmony_ci      g_StdOut << endl << endl;
1162370b324cSopenharmony_ci    }
1163370b324cSopenharmony_ci
1164370b324cSopenharmony_ci    HRESULT result = arcLink.Open_Strict(options, &openCallback);
1165370b324cSopenharmony_ci
1166370b324cSopenharmony_ci    if (result != S_OK)
1167370b324cSopenharmony_ci    {
1168370b324cSopenharmony_ci      if (result == E_ABORT)
1169370b324cSopenharmony_ci        return result;
1170370b324cSopenharmony_ci      if (result != S_FALSE)
1171370b324cSopenharmony_ci        lastError = result;
1172370b324cSopenharmony_ci      g_StdOut.Flush();
1173370b324cSopenharmony_ci      if (g_ErrStream)
1174370b324cSopenharmony_ci      {
1175370b324cSopenharmony_ci        *g_ErrStream << endl << kError;
1176370b324cSopenharmony_ci        g_ErrStream->NormalizePrint_UString(arcPath);
1177370b324cSopenharmony_ci        *g_ErrStream << " : ";
1178370b324cSopenharmony_ci        if (result == S_FALSE)
1179370b324cSopenharmony_ci        {
1180370b324cSopenharmony_ci          Print_OpenArchive_Error(*g_ErrStream, codecs, arcLink);
1181370b324cSopenharmony_ci        }
1182370b324cSopenharmony_ci        else
1183370b324cSopenharmony_ci        {
1184370b324cSopenharmony_ci          *g_ErrStream << "opening : ";
1185370b324cSopenharmony_ci          if (result == E_OUTOFMEMORY)
1186370b324cSopenharmony_ci            *g_ErrStream << "Can't allocate required memory";
1187370b324cSopenharmony_ci          else
1188370b324cSopenharmony_ci            *g_ErrStream << NError::MyFormatMessage(result);
1189370b324cSopenharmony_ci        }
1190370b324cSopenharmony_ci        *g_ErrStream << endl;
1191370b324cSopenharmony_ci      }
1192370b324cSopenharmony_ci      numErrors++;
1193370b324cSopenharmony_ci      continue;
1194370b324cSopenharmony_ci    }
1195370b324cSopenharmony_ci
1196370b324cSopenharmony_ci    {
1197370b324cSopenharmony_ci      FOR_VECTOR (r, arcLink.Arcs)
1198370b324cSopenharmony_ci      {
1199370b324cSopenharmony_ci        const CArcErrorInfo &arc = arcLink.Arcs[r].ErrorInfo;
1200370b324cSopenharmony_ci        if (!arc.WarningMessage.IsEmpty())
1201370b324cSopenharmony_ci          numWarnings++;
1202370b324cSopenharmony_ci        if (arc.AreThereWarnings())
1203370b324cSopenharmony_ci          numWarnings++;
1204370b324cSopenharmony_ci        if (arc.ErrorFormatIndex >= 0)
1205370b324cSopenharmony_ci          numWarnings++;
1206370b324cSopenharmony_ci        if (arc.AreThereErrors())
1207370b324cSopenharmony_ci        {
1208370b324cSopenharmony_ci          numErrors++;
1209370b324cSopenharmony_ci          // break;
1210370b324cSopenharmony_ci        }
1211370b324cSopenharmony_ci        if (!arc.ErrorMessage.IsEmpty())
1212370b324cSopenharmony_ci          numErrors++;
1213370b324cSopenharmony_ci      }
1214370b324cSopenharmony_ci    }
1215370b324cSopenharmony_ci
1216370b324cSopenharmony_ci    numArcs++;
1217370b324cSopenharmony_ci    numVolumes++;
1218370b324cSopenharmony_ci
1219370b324cSopenharmony_ci    if (!stdInMode)
1220370b324cSopenharmony_ci    {
1221370b324cSopenharmony_ci      numVolumes += arcLink.VolumePaths.Size();
1222370b324cSopenharmony_ci      totalArcSizes += arcLink.VolumesSize;
1223370b324cSopenharmony_ci      FOR_VECTOR (v, arcLink.VolumePaths)
1224370b324cSopenharmony_ci      {
1225370b324cSopenharmony_ci        int index = Find_FileName_InSortedVector(arcPathsFull, arcLink.VolumePaths[v]);
1226370b324cSopenharmony_ci        if (index >= 0 && (unsigned)index > arcIndex)
1227370b324cSopenharmony_ci          skipArcs[(unsigned)index] = true;
1228370b324cSopenharmony_ci      }
1229370b324cSopenharmony_ci    }
1230370b324cSopenharmony_ci
1231370b324cSopenharmony_ci
1232370b324cSopenharmony_ci    if (enableHeaders)
1233370b324cSopenharmony_ci    {
1234370b324cSopenharmony_ci      RINOK(Print_OpenArchive_Props(g_StdOut, codecs, arcLink))
1235370b324cSopenharmony_ci
1236370b324cSopenharmony_ci      g_StdOut << endl;
1237370b324cSopenharmony_ci      if (techMode)
1238370b324cSopenharmony_ci        g_StdOut << "----------\n";
1239370b324cSopenharmony_ci    }
1240370b324cSopenharmony_ci
1241370b324cSopenharmony_ci    if (enableHeaders && !techMode)
1242370b324cSopenharmony_ci    {
1243370b324cSopenharmony_ci      fp.PrintTitle();
1244370b324cSopenharmony_ci      g_StdOut << endl;
1245370b324cSopenharmony_ci      fp.PrintTitleLines();
1246370b324cSopenharmony_ci      g_StdOut << endl;
1247370b324cSopenharmony_ci    }
1248370b324cSopenharmony_ci
1249370b324cSopenharmony_ci    const CArc &arc = arcLink.Arcs.Back();
1250370b324cSopenharmony_ci    fp.Arc = &arc;
1251370b324cSopenharmony_ci    fp.TechMode = techMode;
1252370b324cSopenharmony_ci    IInArchive *archive = arc.Archive;
1253370b324cSopenharmony_ci    if (techMode)
1254370b324cSopenharmony_ci    {
1255370b324cSopenharmony_ci      fp.Clear();
1256370b324cSopenharmony_ci      RINOK(fp.AddMainProps(archive))
1257370b324cSopenharmony_ci      if (arc.GetRawProps)
1258370b324cSopenharmony_ci      {
1259370b324cSopenharmony_ci        RINOK(fp.AddRawProps(arc.GetRawProps))
1260370b324cSopenharmony_ci      }
1261370b324cSopenharmony_ci    }
1262370b324cSopenharmony_ci
1263370b324cSopenharmony_ci    CListStat2 stat2;
1264370b324cSopenharmony_ci
1265370b324cSopenharmony_ci    UInt32 numItems;
1266370b324cSopenharmony_ci    RINOK(archive->GetNumberOfItems(&numItems))
1267370b324cSopenharmony_ci
1268370b324cSopenharmony_ci    CReadArcItem item;
1269370b324cSopenharmony_ci    UStringVector pathParts;
1270370b324cSopenharmony_ci
1271370b324cSopenharmony_ci    for (UInt32 i = 0; i < numItems; i++)
1272370b324cSopenharmony_ci    {
1273370b324cSopenharmony_ci      if (NConsoleClose::TestBreakSignal())
1274370b324cSopenharmony_ci        return E_ABORT;
1275370b324cSopenharmony_ci
1276370b324cSopenharmony_ci      HRESULT res = arc.GetItem_Path2(i, fp.FilePath);
1277370b324cSopenharmony_ci
1278370b324cSopenharmony_ci      if (stdInMode && res == E_INVALIDARG)
1279370b324cSopenharmony_ci        break;
1280370b324cSopenharmony_ci      RINOK(res)
1281370b324cSopenharmony_ci
1282370b324cSopenharmony_ci      if (arc.Ask_Aux)
1283370b324cSopenharmony_ci      {
1284370b324cSopenharmony_ci        bool isAux;
1285370b324cSopenharmony_ci        RINOK(Archive_IsItem_Aux(archive, i, isAux))
1286370b324cSopenharmony_ci        if (isAux)
1287370b324cSopenharmony_ci          continue;
1288370b324cSopenharmony_ci      }
1289370b324cSopenharmony_ci
1290370b324cSopenharmony_ci      bool isAltStream = false;
1291370b324cSopenharmony_ci      if (arc.Ask_AltStream)
1292370b324cSopenharmony_ci      {
1293370b324cSopenharmony_ci        RINOK(Archive_IsItem_AltStream(archive, i, isAltStream))
1294370b324cSopenharmony_ci        if (isAltStream && !processAltStreams)
1295370b324cSopenharmony_ci          continue;
1296370b324cSopenharmony_ci      }
1297370b324cSopenharmony_ci
1298370b324cSopenharmony_ci      RINOK(Archive_IsItem_Dir(archive, i, fp.IsDir))
1299370b324cSopenharmony_ci
1300370b324cSopenharmony_ci      if (fp.IsDir ? listOptions.ExcludeDirItems : listOptions.ExcludeFileItems)
1301370b324cSopenharmony_ci        continue;
1302370b324cSopenharmony_ci
1303370b324cSopenharmony_ci      if (!allFilesAreAllowed)
1304370b324cSopenharmony_ci      {
1305370b324cSopenharmony_ci        if (isAltStream)
1306370b324cSopenharmony_ci        {
1307370b324cSopenharmony_ci          RINOK(arc.GetItem(i, item))
1308370b324cSopenharmony_ci          if (!CensorNode_CheckPath(wildcardCensor, item))
1309370b324cSopenharmony_ci            continue;
1310370b324cSopenharmony_ci        }
1311370b324cSopenharmony_ci        else
1312370b324cSopenharmony_ci        {
1313370b324cSopenharmony_ci          SplitPathToParts(fp.FilePath, pathParts);
1314370b324cSopenharmony_ci          bool include;
1315370b324cSopenharmony_ci          if (!wildcardCensor.CheckPathVect(pathParts, !fp.IsDir, include))
1316370b324cSopenharmony_ci            continue;
1317370b324cSopenharmony_ci          if (!include)
1318370b324cSopenharmony_ci            continue;
1319370b324cSopenharmony_ci        }
1320370b324cSopenharmony_ci      }
1321370b324cSopenharmony_ci
1322370b324cSopenharmony_ci      CListStat st;
1323370b324cSopenharmony_ci
1324370b324cSopenharmony_ci      RINOK(GetUInt64Value(archive, i, kpidSize, st.Size))
1325370b324cSopenharmony_ci      RINOK(GetUInt64Value(archive, i, kpidPackSize, st.PackSize))
1326370b324cSopenharmony_ci      RINOK(GetItemMTime(archive, i, st.MTime))
1327370b324cSopenharmony_ci
1328370b324cSopenharmony_ci      if (fp.IsDir)
1329370b324cSopenharmony_ci        stat2.NumDirs++;
1330370b324cSopenharmony_ci      else
1331370b324cSopenharmony_ci        st.NumFiles = 1;
1332370b324cSopenharmony_ci      stat2.GetStat(isAltStream).Update(st);
1333370b324cSopenharmony_ci
1334370b324cSopenharmony_ci      if (isAltStream && !showAltStreams)
1335370b324cSopenharmony_ci        continue;
1336370b324cSopenharmony_ci      RINOK(fp.PrintItemInfo(i, st))
1337370b324cSopenharmony_ci    }
1338370b324cSopenharmony_ci
1339370b324cSopenharmony_ci    UInt64 numStreams = stat2.GetNumStreams();
1340370b324cSopenharmony_ci    if (!stdInMode
1341370b324cSopenharmony_ci        && !stat2.MainFiles.PackSize.Def
1342370b324cSopenharmony_ci        && !stat2.AltStreams.PackSize.Def)
1343370b324cSopenharmony_ci    {
1344370b324cSopenharmony_ci      if (arcLink.VolumePaths.Size() != 0)
1345370b324cSopenharmony_ci        arcPackSize += arcLink.VolumesSize;
1346370b324cSopenharmony_ci      stat2.MainFiles.PackSize.Add((numStreams == 0) ? 0 : arcPackSize);
1347370b324cSopenharmony_ci    }
1348370b324cSopenharmony_ci
1349370b324cSopenharmony_ci    stat2.MainFiles.SetSizeDefIfNoFiles();
1350370b324cSopenharmony_ci    stat2.AltStreams.SetSizeDefIfNoFiles();
1351370b324cSopenharmony_ci
1352370b324cSopenharmony_ci    if (enableHeaders && !techMode)
1353370b324cSopenharmony_ci    {
1354370b324cSopenharmony_ci      fp.PrintTitleLines();
1355370b324cSopenharmony_ci      g_StdOut << endl;
1356370b324cSopenharmony_ci      fp.PrintSum(stat2);
1357370b324cSopenharmony_ci    }
1358370b324cSopenharmony_ci
1359370b324cSopenharmony_ci    if (enableHeaders)
1360370b324cSopenharmony_ci    {
1361370b324cSopenharmony_ci      if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0)
1362370b324cSopenharmony_ci      {
1363370b324cSopenharmony_ci        g_StdOut << "----------\n";
1364370b324cSopenharmony_ci        PrintPropPair(g_StdOut, "Path", arcLink.NonOpen_ArcPath, false);
1365370b324cSopenharmony_ci        PrintArcTypeError(g_StdOut, codecs->Formats[(unsigned)arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false);
1366370b324cSopenharmony_ci      }
1367370b324cSopenharmony_ci    }
1368370b324cSopenharmony_ci
1369370b324cSopenharmony_ci    stat2total.Update(stat2);
1370370b324cSopenharmony_ci
1371370b324cSopenharmony_ci    g_StdOut.Flush();
1372370b324cSopenharmony_ci  }
1373370b324cSopenharmony_ci
1374370b324cSopenharmony_ci  if (enableHeaders && !techMode && (arcPaths.Size() > 1 || numVolumes > 1))
1375370b324cSopenharmony_ci  {
1376370b324cSopenharmony_ci    g_StdOut << endl;
1377370b324cSopenharmony_ci    fp.PrintTitleLines();
1378370b324cSopenharmony_ci    g_StdOut << endl;
1379370b324cSopenharmony_ci    fp.PrintSum(stat2total);
1380370b324cSopenharmony_ci    g_StdOut << endl;
1381370b324cSopenharmony_ci    PrintPropNameAndNumber(g_StdOut, "Archives", numArcs);
1382370b324cSopenharmony_ci    PrintPropNameAndNumber(g_StdOut, "Volumes", numVolumes);
1383370b324cSopenharmony_ci    PrintPropNameAndNumber(g_StdOut, "Total archives size", totalArcSizes);
1384370b324cSopenharmony_ci  }
1385370b324cSopenharmony_ci
1386370b324cSopenharmony_ci  if (numErrors == 1 && lastError != 0)
1387370b324cSopenharmony_ci    return lastError;
1388370b324cSopenharmony_ci
1389370b324cSopenharmony_ci  return S_OK;
1390370b324cSopenharmony_ci}
1391