1370b324cSopenharmony_ci// Main.cpp
2370b324cSopenharmony_ci
3370b324cSopenharmony_ci#include "StdAfx.h"
4370b324cSopenharmony_ci
5370b324cSopenharmony_ci#include "../../../Common/MyWindows.h"
6370b324cSopenharmony_ci
7370b324cSopenharmony_ci#ifdef _WIN32
8370b324cSopenharmony_ci
9370b324cSopenharmony_ci#ifndef Z7_OLD_WIN_SDK
10370b324cSopenharmony_ci
11370b324cSopenharmony_ci#if defined(__MINGW32__) || defined(__MINGW64__)
12370b324cSopenharmony_ci#include <psapi.h>
13370b324cSopenharmony_ci#else
14370b324cSopenharmony_ci#include <Psapi.h>
15370b324cSopenharmony_ci#endif
16370b324cSopenharmony_ci
17370b324cSopenharmony_ci#else // Z7_OLD_WIN_SDK
18370b324cSopenharmony_ci
19370b324cSopenharmony_citypedef struct _PROCESS_MEMORY_COUNTERS {
20370b324cSopenharmony_ci    DWORD cb;
21370b324cSopenharmony_ci    DWORD PageFaultCount;
22370b324cSopenharmony_ci    SIZE_T PeakWorkingSetSize;
23370b324cSopenharmony_ci    SIZE_T WorkingSetSize;
24370b324cSopenharmony_ci    SIZE_T QuotaPeakPagedPoolUsage;
25370b324cSopenharmony_ci    SIZE_T QuotaPagedPoolUsage;
26370b324cSopenharmony_ci    SIZE_T QuotaPeakNonPagedPoolUsage;
27370b324cSopenharmony_ci    SIZE_T QuotaNonPagedPoolUsage;
28370b324cSopenharmony_ci    SIZE_T PagefileUsage;
29370b324cSopenharmony_ci    SIZE_T PeakPagefileUsage;
30370b324cSopenharmony_ci} PROCESS_MEMORY_COUNTERS;
31370b324cSopenharmony_citypedef PROCESS_MEMORY_COUNTERS *PPROCESS_MEMORY_COUNTERS;
32370b324cSopenharmony_ci
33370b324cSopenharmony_ci#endif // Z7_OLD_WIN_SDK
34370b324cSopenharmony_ci
35370b324cSopenharmony_ci#else // _WIN32
36370b324cSopenharmony_ci#include <unistd.h>
37370b324cSopenharmony_ci#include <sys/ioctl.h>
38370b324cSopenharmony_ci#include <sys/time.h>
39370b324cSopenharmony_ci#include <sys/times.h>
40370b324cSopenharmony_ci#endif // _WIN32
41370b324cSopenharmony_ci
42370b324cSopenharmony_ci#include "../../../../C/CpuArch.h"
43370b324cSopenharmony_ci
44370b324cSopenharmony_ci#include "../../../Common/MyInitGuid.h"
45370b324cSopenharmony_ci
46370b324cSopenharmony_ci#include "../../../Common/CommandLineParser.h"
47370b324cSopenharmony_ci#include "../../../Common/IntToString.h"
48370b324cSopenharmony_ci#include "../../../Common/MyException.h"
49370b324cSopenharmony_ci#include "../../../Common/StdInStream.h"
50370b324cSopenharmony_ci#include "../../../Common/StdOutStream.h"
51370b324cSopenharmony_ci#include "../../../Common/StringConvert.h"
52370b324cSopenharmony_ci#include "../../../Common/StringToInt.h"
53370b324cSopenharmony_ci#include "../../../Common/UTFConvert.h"
54370b324cSopenharmony_ci
55370b324cSopenharmony_ci#include "../../../Windows/ErrorMsg.h"
56370b324cSopenharmony_ci#include "../../../Windows/TimeUtils.h"
57370b324cSopenharmony_ci#include "../../../Windows/FileDir.h"
58370b324cSopenharmony_ci
59370b324cSopenharmony_ci#include "../Common/ArchiveCommandLine.h"
60370b324cSopenharmony_ci#include "../Common/Bench.h"
61370b324cSopenharmony_ci#include "../Common/ExitCode.h"
62370b324cSopenharmony_ci#include "../Common/Extract.h"
63370b324cSopenharmony_ci
64370b324cSopenharmony_ci#ifdef Z7_EXTERNAL_CODECS
65370b324cSopenharmony_ci#include "../Common/LoadCodecs.h"
66370b324cSopenharmony_ci#endif
67370b324cSopenharmony_ci
68370b324cSopenharmony_ci#include "../../Common/RegisterCodec.h"
69370b324cSopenharmony_ci
70370b324cSopenharmony_ci#include "BenchCon.h"
71370b324cSopenharmony_ci#include "ConsoleClose.h"
72370b324cSopenharmony_ci#include "ExtractCallbackConsole.h"
73370b324cSopenharmony_ci#include "HashCon.h"
74370b324cSopenharmony_ci#include "List.h"
75370b324cSopenharmony_ci#include "OpenCallbackConsole.h"
76370b324cSopenharmony_ci#include "UpdateCallbackConsole.h"
77370b324cSopenharmony_ci
78370b324cSopenharmony_ci#ifdef Z7_PROG_VARIANT_R
79370b324cSopenharmony_ci#include "../../../../C/7zVersion.h"
80370b324cSopenharmony_ci#else
81370b324cSopenharmony_ci#include "../../MyVersion.h"
82370b324cSopenharmony_ci#endif
83370b324cSopenharmony_ci
84370b324cSopenharmony_ciusing namespace NWindows;
85370b324cSopenharmony_ciusing namespace NFile;
86370b324cSopenharmony_ciusing namespace NCommandLineParser;
87370b324cSopenharmony_ci
88370b324cSopenharmony_ci#ifdef _WIN32
89370b324cSopenharmony_ciextern
90370b324cSopenharmony_ciHINSTANCE g_hInstance;
91370b324cSopenharmony_ciHINSTANCE g_hInstance = NULL;
92370b324cSopenharmony_ci#endif
93370b324cSopenharmony_ci
94370b324cSopenharmony_ciextern CStdOutStream *g_StdStream;
95370b324cSopenharmony_ciextern CStdOutStream *g_ErrStream;
96370b324cSopenharmony_ci
97370b324cSopenharmony_ciextern unsigned g_NumCodecs;
98370b324cSopenharmony_ciextern const CCodecInfo *g_Codecs[];
99370b324cSopenharmony_ci
100370b324cSopenharmony_ciextern unsigned g_NumHashers;
101370b324cSopenharmony_ciextern const CHasherInfo *g_Hashers[];
102370b324cSopenharmony_ci
103370b324cSopenharmony_ci#ifdef Z7_EXTERNAL_CODECS
104370b324cSopenharmony_ciextern
105370b324cSopenharmony_ciconst CExternalCodecs *g_ExternalCodecs_Ptr;
106370b324cSopenharmony_ciconst CExternalCodecs *g_ExternalCodecs_Ptr;
107370b324cSopenharmony_ci#endif
108370b324cSopenharmony_ci
109370b324cSopenharmony_ciDECLARE_AND_SET_CLIENT_VERSION_VAR
110370b324cSopenharmony_ci
111370b324cSopenharmony_ci#if defined(Z7_PROG_VARIANT_Z)
112370b324cSopenharmony_ci  #define PROG_POSTFIX      "z"
113370b324cSopenharmony_ci  #define PROG_POSTFIX_2  " (z)"
114370b324cSopenharmony_ci#elif defined(Z7_PROG_VARIANT_R)
115370b324cSopenharmony_ci  #define PROG_POSTFIX      "r"
116370b324cSopenharmony_ci  #define PROG_POSTFIX_2  " (r)"
117370b324cSopenharmony_ci#elif !defined(Z7_EXTERNAL_CODECS)
118370b324cSopenharmony_ci  #define PROG_POSTFIX      "a"
119370b324cSopenharmony_ci  #define PROG_POSTFIX_2  " (a)"
120370b324cSopenharmony_ci#else
121370b324cSopenharmony_ci  #define PROG_POSTFIX    ""
122370b324cSopenharmony_ci  #define PROG_POSTFIX_2  ""
123370b324cSopenharmony_ci#endif
124370b324cSopenharmony_ci
125370b324cSopenharmony_ci
126370b324cSopenharmony_cistatic const char * const kCopyrightString = "\n7-Zip"
127370b324cSopenharmony_ci  PROG_POSTFIX_2
128370b324cSopenharmony_ci  " " MY_VERSION_CPU
129370b324cSopenharmony_ci  " : " MY_COPYRIGHT_DATE "\n";
130370b324cSopenharmony_ci
131370b324cSopenharmony_cistatic const char * const kHelpString =
132370b324cSopenharmony_ci    "Usage: 7z"
133370b324cSopenharmony_ci    PROG_POSTFIX
134370b324cSopenharmony_ci    " <command> [<switches>...] <archive_name> [<file_names>...] [@listfile]\n"
135370b324cSopenharmony_ci    "\n"
136370b324cSopenharmony_ci    "<Commands>\n"
137370b324cSopenharmony_ci    "  a : Add files to archive\n"
138370b324cSopenharmony_ci    "  b : Benchmark\n"
139370b324cSopenharmony_ci    "  d : Delete files from archive\n"
140370b324cSopenharmony_ci    "  e : Extract files from archive (without using directory names)\n"
141370b324cSopenharmony_ci    "  h : Calculate hash values for files\n"
142370b324cSopenharmony_ci    "  i : Show information about supported formats\n"
143370b324cSopenharmony_ci    "  l : List contents of archive\n"
144370b324cSopenharmony_ci    "  rn : Rename files in archive\n"
145370b324cSopenharmony_ci    "  t : Test integrity of archive\n"
146370b324cSopenharmony_ci    "  u : Update files to archive\n"
147370b324cSopenharmony_ci    "  x : eXtract files with full paths\n"
148370b324cSopenharmony_ci    "\n"
149370b324cSopenharmony_ci    "<Switches>\n"
150370b324cSopenharmony_ci    "  -- : Stop switches and @listfile parsing\n"
151370b324cSopenharmony_ci    "  -ai[r[-|0]]{@listfile|!wildcard} : Include archives\n"
152370b324cSopenharmony_ci    "  -ax[r[-|0]]{@listfile|!wildcard} : eXclude archives\n"
153370b324cSopenharmony_ci    "  -ao{a|s|t|u} : set Overwrite mode\n"
154370b324cSopenharmony_ci    "  -an : disable archive_name field\n"
155370b324cSopenharmony_ci    "  -bb[0-3] : set output log level\n"
156370b324cSopenharmony_ci    "  -bd : disable progress indicator\n"
157370b324cSopenharmony_ci    "  -bs{o|e|p}{0|1|2} : set output stream for output/error/progress line\n"
158370b324cSopenharmony_ci    "  -bt : show execution time statistics\n"
159370b324cSopenharmony_ci    "  -i[r[-|0]]{@listfile|!wildcard} : Include filenames\n"
160370b324cSopenharmony_ci    "  -m{Parameters} : set compression Method\n"
161370b324cSopenharmony_ci    "    -mmt[N] : set number of CPU threads\n"
162370b324cSopenharmony_ci    "    -mx[N] : set compression level: -mx1 (fastest) ... -mx9 (ultra)\n"
163370b324cSopenharmony_ci    "  -o{Directory} : set Output directory\n"
164370b324cSopenharmony_ci    #ifndef Z7_NO_CRYPTO
165370b324cSopenharmony_ci    "  -p{Password} : set Password\n"
166370b324cSopenharmony_ci    #endif
167370b324cSopenharmony_ci    "  -r[-|0] : Recurse subdirectories for name search\n"
168370b324cSopenharmony_ci    "  -sa{a|e|s} : set Archive name mode\n"
169370b324cSopenharmony_ci    "  -scc{UTF-8|WIN|DOS} : set charset for console input/output\n"
170370b324cSopenharmony_ci    "  -scs{UTF-8|UTF-16LE|UTF-16BE|WIN|DOS|{id}} : set charset for list files\n"
171370b324cSopenharmony_ci    "  -scrc[CRC32|CRC64|SHA1|SHA256|*] : set hash function for x, e, h commands\n"
172370b324cSopenharmony_ci    "  -sdel : delete files after compression\n"
173370b324cSopenharmony_ci    "  -seml[.] : send archive by email\n"
174370b324cSopenharmony_ci    "  -sfx[{name}] : Create SFX archive\n"
175370b324cSopenharmony_ci    "  -si[{name}] : read data from stdin\n"
176370b324cSopenharmony_ci    "  -slp : set Large Pages mode\n"
177370b324cSopenharmony_ci    "  -slt : show technical information for l (List) command\n"
178370b324cSopenharmony_ci    "  -snh : store hard links as links\n"
179370b324cSopenharmony_ci    "  -snl : store symbolic links as links\n"
180370b324cSopenharmony_ci    "  -sni : store NT security information\n"
181370b324cSopenharmony_ci    "  -sns[-] : store NTFS alternate streams\n"
182370b324cSopenharmony_ci    "  -so : write data to stdout\n"
183370b324cSopenharmony_ci    "  -spd : disable wildcard matching for file names\n"
184370b324cSopenharmony_ci    "  -spe : eliminate duplication of root folder for extract command\n"
185370b324cSopenharmony_ci    "  -spf[2] : use fully qualified file paths\n"
186370b324cSopenharmony_ci    "  -ssc[-] : set sensitive case mode\n"
187370b324cSopenharmony_ci    "  -sse : stop archive creating, if it can't open some input file\n"
188370b324cSopenharmony_ci    "  -ssp : do not change Last Access Time of source files while archiving\n"
189370b324cSopenharmony_ci    "  -ssw : compress shared files\n"
190370b324cSopenharmony_ci    "  -stl : set archive timestamp from the most recently modified file\n"
191370b324cSopenharmony_ci    "  -stm{HexMask} : set CPU thread affinity mask (hexadecimal number)\n"
192370b324cSopenharmony_ci    "  -stx{Type} : exclude archive type\n"
193370b324cSopenharmony_ci    "  -t{Type} : Set type of archive\n"
194370b324cSopenharmony_ci    "  -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName] : Update options\n"
195370b324cSopenharmony_ci    "  -v{Size}[b|k|m|g] : Create volumes\n"
196370b324cSopenharmony_ci    "  -w[{path}] : assign Work directory. Empty path means a temporary directory\n"
197370b324cSopenharmony_ci    "  -x[r[-|0]]{@listfile|!wildcard} : eXclude filenames\n"
198370b324cSopenharmony_ci    "  -y : assume Yes on all queries\n";
199370b324cSopenharmony_ci
200370b324cSopenharmony_ci// ---------------------------
201370b324cSopenharmony_ci// exception messages
202370b324cSopenharmony_ci
203370b324cSopenharmony_cistatic const char * const kEverythingIsOk = "Everything is Ok";
204370b324cSopenharmony_cistatic const char * const kUserErrorMessage = "Incorrect command line";
205370b324cSopenharmony_cistatic const char * const kNoFormats = "7-Zip cannot find the code that works with archives.";
206370b324cSopenharmony_cistatic const char * const kUnsupportedArcTypeMessage = "Unsupported archive type";
207370b324cSopenharmony_ci// static const char * const kUnsupportedUpdateArcType = "Can't create archive for that type";
208370b324cSopenharmony_ci
209370b324cSopenharmony_ci#define kDefaultSfxModule "7zCon.sfx"
210370b324cSopenharmony_ci
211370b324cSopenharmony_ciZ7_ATTR_NORETURN
212370b324cSopenharmony_cistatic void ShowMessageAndThrowException(LPCSTR message, NExitCode::EEnum code)
213370b324cSopenharmony_ci{
214370b324cSopenharmony_ci  if (g_ErrStream)
215370b324cSopenharmony_ci    *g_ErrStream << endl << "ERROR: " << message << endl;
216370b324cSopenharmony_ci  throw code;
217370b324cSopenharmony_ci}
218370b324cSopenharmony_ci
219370b324cSopenharmony_ci
220370b324cSopenharmony_ci#ifdef _WIN32
221370b324cSopenharmony_ci#define ShowProgInfo(so)
222370b324cSopenharmony_ci#else
223370b324cSopenharmony_cistatic void ShowProgInfo(CStdOutStream *so)
224370b324cSopenharmony_ci{
225370b324cSopenharmony_ci  if (!so)
226370b324cSopenharmony_ci    return;
227370b324cSopenharmony_ci
228370b324cSopenharmony_ci  *so
229370b324cSopenharmony_ci
230370b324cSopenharmony_ci  /*
231370b324cSopenharmony_ci  #ifdef __DATE__
232370b324cSopenharmony_ci      << " " << __DATE__
233370b324cSopenharmony_ci  #endif
234370b324cSopenharmony_ci  #ifdef __TIME__
235370b324cSopenharmony_ci      << " " << __TIME__
236370b324cSopenharmony_ci  #endif
237370b324cSopenharmony_ci  */
238370b324cSopenharmony_ci
239370b324cSopenharmony_ci  << " " << (unsigned)(sizeof(void *)) * 8 << "-bit"
240370b324cSopenharmony_ci
241370b324cSopenharmony_ci  #ifdef __ILP32__
242370b324cSopenharmony_ci    << " ILP32"
243370b324cSopenharmony_ci  #endif
244370b324cSopenharmony_ci
245370b324cSopenharmony_ci  #ifdef __ARM_ARCH
246370b324cSopenharmony_ci  << " arm_v:" << __ARM_ARCH
247370b324cSopenharmony_ci  #ifdef __ARM_ARCH_ISA_THUMB
248370b324cSopenharmony_ci  << " thumb:" << __ARM_ARCH_ISA_THUMB
249370b324cSopenharmony_ci  #endif
250370b324cSopenharmony_ci  #endif
251370b324cSopenharmony_ci  ;
252370b324cSopenharmony_ci
253370b324cSopenharmony_ci
254370b324cSopenharmony_ci
255370b324cSopenharmony_ci  #ifdef ENV_HAVE_LOCALE
256370b324cSopenharmony_ci    *so << " locale=" << GetLocale();
257370b324cSopenharmony_ci  #endif
258370b324cSopenharmony_ci  #ifndef _WIN32
259370b324cSopenharmony_ci  {
260370b324cSopenharmony_ci    const bool is_IsNativeUTF8 = IsNativeUTF8();
261370b324cSopenharmony_ci    if (!is_IsNativeUTF8)
262370b324cSopenharmony_ci      *so << " UTF8=" << (is_IsNativeUTF8 ? "+" : "-");
263370b324cSopenharmony_ci  }
264370b324cSopenharmony_ci  if (!g_ForceToUTF8)
265370b324cSopenharmony_ci    *so << " use-UTF8=" << (g_ForceToUTF8 ? "+" : "-");
266370b324cSopenharmony_ci  {
267370b324cSopenharmony_ci    const unsigned wchar_t_size = (unsigned)sizeof(wchar_t);
268370b324cSopenharmony_ci    if (wchar_t_size != 4)
269370b324cSopenharmony_ci      *so << " wchar_t=" << wchar_t_size * 8 << "-bit";
270370b324cSopenharmony_ci  }
271370b324cSopenharmony_ci  {
272370b324cSopenharmony_ci    const unsigned off_t_size = (unsigned)sizeof(off_t);
273370b324cSopenharmony_ci    if (off_t_size != 8)
274370b324cSopenharmony_ci      *so << " Files=" << off_t_size * 8 << "-bit";
275370b324cSopenharmony_ci  }
276370b324cSopenharmony_ci  #endif
277370b324cSopenharmony_ci
278370b324cSopenharmony_ci  {
279370b324cSopenharmony_ci    const UInt32 numCpus = NWindows::NSystem::GetNumberOfProcessors();
280370b324cSopenharmony_ci    *so << " Threads:" << numCpus;
281370b324cSopenharmony_ci    const UInt64 openMAX= NWindows::NSystem::Get_File_OPEN_MAX();
282370b324cSopenharmony_ci    *so << " OPEN_MAX:" << openMAX;
283370b324cSopenharmony_ci    {
284370b324cSopenharmony_ci      FString temp;
285370b324cSopenharmony_ci      NDir::MyGetTempPath(temp);
286370b324cSopenharmony_ci      if (!temp.IsEqualTo(STRING_PATH_SEPARATOR "tmp" STRING_PATH_SEPARATOR))
287370b324cSopenharmony_ci        *so << " temp_path:" << temp;
288370b324cSopenharmony_ci    }
289370b324cSopenharmony_ci  }
290370b324cSopenharmony_ci
291370b324cSopenharmony_ci  #ifdef Z7_7ZIP_ASM
292370b324cSopenharmony_ci  *so << ", ASM";
293370b324cSopenharmony_ci  #endif
294370b324cSopenharmony_ci
295370b324cSopenharmony_ci  /*
296370b324cSopenharmony_ci  {
297370b324cSopenharmony_ci    AString s;
298370b324cSopenharmony_ci    GetCpuName(s);
299370b324cSopenharmony_ci    s.Trim();
300370b324cSopenharmony_ci    *so << ", " << s;
301370b324cSopenharmony_ci  }
302370b324cSopenharmony_ci
303370b324cSopenharmony_ci  #ifdef __ARM_FEATURE_CRC32
304370b324cSopenharmony_ci     << " CRC32"
305370b324cSopenharmony_ci  #endif
306370b324cSopenharmony_ci
307370b324cSopenharmony_ci
308370b324cSopenharmony_ci  #if (defined MY_CPU_X86_OR_AMD64 || defined(MY_CPU_ARM_OR_ARM64))
309370b324cSopenharmony_ci  if (CPU_IsSupported_AES()) *so << ",AES";
310370b324cSopenharmony_ci  #endif
311370b324cSopenharmony_ci
312370b324cSopenharmony_ci  #ifdef MY_CPU_ARM_OR_ARM64
313370b324cSopenharmony_ci  if (CPU_IsSupported_CRC32()) *so << ",CRC32";
314370b324cSopenharmony_ci  #if defined(_WIN32)
315370b324cSopenharmony_ci  if (CPU_IsSupported_CRYPTO()) *so << ",CRYPTO";
316370b324cSopenharmony_ci  #else
317370b324cSopenharmony_ci  if (CPU_IsSupported_SHA1()) *so << ",SHA1";
318370b324cSopenharmony_ci  if (CPU_IsSupported_SHA2()) *so << ",SHA2";
319370b324cSopenharmony_ci  #endif
320370b324cSopenharmony_ci  #endif
321370b324cSopenharmony_ci  */
322370b324cSopenharmony_ci
323370b324cSopenharmony_ci  *so << endl;
324370b324cSopenharmony_ci}
325370b324cSopenharmony_ci#endif
326370b324cSopenharmony_ci
327370b324cSopenharmony_cistatic void ShowCopyrightAndHelp(CStdOutStream *so, bool needHelp)
328370b324cSopenharmony_ci{
329370b324cSopenharmony_ci  if (!so)
330370b324cSopenharmony_ci    return;
331370b324cSopenharmony_ci  *so << kCopyrightString;
332370b324cSopenharmony_ci  // *so << "# CPUs: " << (UInt64)NWindows::NSystem::GetNumberOfProcessors() << endl;
333370b324cSopenharmony_ci  ShowProgInfo(so);
334370b324cSopenharmony_ci  *so << endl;
335370b324cSopenharmony_ci  if (needHelp)
336370b324cSopenharmony_ci    *so << kHelpString;
337370b324cSopenharmony_ci}
338370b324cSopenharmony_ci
339370b324cSopenharmony_ci
340370b324cSopenharmony_cistatic void PrintStringRight(CStdOutStream &so, const char *s, unsigned size)
341370b324cSopenharmony_ci{
342370b324cSopenharmony_ci  unsigned len = MyStringLen(s);
343370b324cSopenharmony_ci  for (unsigned i = len; i < size; i++)
344370b324cSopenharmony_ci    so << ' ';
345370b324cSopenharmony_ci  so << s;
346370b324cSopenharmony_ci}
347370b324cSopenharmony_ci
348370b324cSopenharmony_cistatic void PrintUInt32(CStdOutStream &so, UInt32 val, unsigned size)
349370b324cSopenharmony_ci{
350370b324cSopenharmony_ci  char s[16];
351370b324cSopenharmony_ci  ConvertUInt32ToString(val, s);
352370b324cSopenharmony_ci  PrintStringRight(so, s, size);
353370b324cSopenharmony_ci}
354370b324cSopenharmony_ci
355370b324cSopenharmony_ci#ifdef Z7_EXTERNAL_CODECS
356370b324cSopenharmony_cistatic void PrintNumber(CStdOutStream &so, UInt32 val, unsigned numDigits)
357370b324cSopenharmony_ci{
358370b324cSopenharmony_ci  AString s;
359370b324cSopenharmony_ci  s.Add_UInt32(val);
360370b324cSopenharmony_ci  while (s.Len() < numDigits)
361370b324cSopenharmony_ci    s.InsertAtFront('0');
362370b324cSopenharmony_ci  so << s;
363370b324cSopenharmony_ci}
364370b324cSopenharmony_ci#endif
365370b324cSopenharmony_ci
366370b324cSopenharmony_cistatic void PrintLibIndex(CStdOutStream &so, int libIndex)
367370b324cSopenharmony_ci{
368370b324cSopenharmony_ci  if (libIndex >= 0)
369370b324cSopenharmony_ci    PrintUInt32(so, (UInt32)libIndex, 2);
370370b324cSopenharmony_ci  else
371370b324cSopenharmony_ci    so << "  ";
372370b324cSopenharmony_ci  so << ' ';
373370b324cSopenharmony_ci}
374370b324cSopenharmony_ci
375370b324cSopenharmony_cistatic void PrintString(CStdOutStream &so, const UString &s, unsigned size)
376370b324cSopenharmony_ci{
377370b324cSopenharmony_ci  unsigned len = s.Len();
378370b324cSopenharmony_ci  so << s;
379370b324cSopenharmony_ci  for (unsigned i = len; i < size; i++)
380370b324cSopenharmony_ci    so << ' ';
381370b324cSopenharmony_ci}
382370b324cSopenharmony_ci
383370b324cSopenharmony_cistatic inline char GetHex(unsigned val)
384370b324cSopenharmony_ci{
385370b324cSopenharmony_ci  return (char)((val < 10) ? ('0' + val) : ('A' + (val - 10)));
386370b324cSopenharmony_ci}
387370b324cSopenharmony_ci
388370b324cSopenharmony_cistatic void PrintWarningsPaths(const CErrorPathCodes &pc, CStdOutStream &so)
389370b324cSopenharmony_ci{
390370b324cSopenharmony_ci  FOR_VECTOR(i, pc.Paths)
391370b324cSopenharmony_ci  {
392370b324cSopenharmony_ci    so.NormalizePrint_UString(fs2us(pc.Paths[i]));
393370b324cSopenharmony_ci    so << " : ";
394370b324cSopenharmony_ci    so << NError::MyFormatMessage(pc.Codes[i]) << endl;
395370b324cSopenharmony_ci  }
396370b324cSopenharmony_ci  so << "----------------" << endl;
397370b324cSopenharmony_ci}
398370b324cSopenharmony_ci
399370b324cSopenharmony_cistatic int WarningsCheck(HRESULT result, const CCallbackConsoleBase &callback,
400370b324cSopenharmony_ci    const CUpdateErrorInfo &errorInfo,
401370b324cSopenharmony_ci    CStdOutStream *so,
402370b324cSopenharmony_ci    CStdOutStream *se,
403370b324cSopenharmony_ci    bool showHeaders)
404370b324cSopenharmony_ci{
405370b324cSopenharmony_ci  int exitCode = NExitCode::kSuccess;
406370b324cSopenharmony_ci
407370b324cSopenharmony_ci  if (callback.ScanErrors.Paths.Size() != 0)
408370b324cSopenharmony_ci  {
409370b324cSopenharmony_ci    if (se)
410370b324cSopenharmony_ci    {
411370b324cSopenharmony_ci      *se << endl;
412370b324cSopenharmony_ci      *se << "Scan WARNINGS for files and folders:" << endl << endl;
413370b324cSopenharmony_ci      PrintWarningsPaths(callback.ScanErrors, *se);
414370b324cSopenharmony_ci      *se << "Scan WARNINGS: " << callback.ScanErrors.Paths.Size();
415370b324cSopenharmony_ci      *se << endl;
416370b324cSopenharmony_ci    }
417370b324cSopenharmony_ci    exitCode = NExitCode::kWarning;
418370b324cSopenharmony_ci  }
419370b324cSopenharmony_ci
420370b324cSopenharmony_ci  if (result != S_OK || errorInfo.ThereIsError())
421370b324cSopenharmony_ci  {
422370b324cSopenharmony_ci    if (se)
423370b324cSopenharmony_ci    {
424370b324cSopenharmony_ci      UString message;
425370b324cSopenharmony_ci      if (!errorInfo.Message.IsEmpty())
426370b324cSopenharmony_ci      {
427370b324cSopenharmony_ci        message += errorInfo.Message.Ptr();
428370b324cSopenharmony_ci        message.Add_LF();
429370b324cSopenharmony_ci      }
430370b324cSopenharmony_ci      {
431370b324cSopenharmony_ci        FOR_VECTOR(i, errorInfo.FileNames)
432370b324cSopenharmony_ci        {
433370b324cSopenharmony_ci          message += fs2us(errorInfo.FileNames[i]);
434370b324cSopenharmony_ci          message.Add_LF();
435370b324cSopenharmony_ci        }
436370b324cSopenharmony_ci      }
437370b324cSopenharmony_ci      if (errorInfo.SystemError != 0)
438370b324cSopenharmony_ci      {
439370b324cSopenharmony_ci        message += NError::MyFormatMessage(errorInfo.SystemError);
440370b324cSopenharmony_ci        message.Add_LF();
441370b324cSopenharmony_ci      }
442370b324cSopenharmony_ci      if (!message.IsEmpty())
443370b324cSopenharmony_ci        *se << L"\nError:\n" << message;
444370b324cSopenharmony_ci    }
445370b324cSopenharmony_ci
446370b324cSopenharmony_ci    // we will work with (result) later
447370b324cSopenharmony_ci    // throw CSystemException(result);
448370b324cSopenharmony_ci    return NExitCode::kFatalError;
449370b324cSopenharmony_ci  }
450370b324cSopenharmony_ci
451370b324cSopenharmony_ci  unsigned numErrors = callback.FailedFiles.Paths.Size();
452370b324cSopenharmony_ci  if (numErrors == 0)
453370b324cSopenharmony_ci  {
454370b324cSopenharmony_ci    if (showHeaders)
455370b324cSopenharmony_ci      if (callback.ScanErrors.Paths.Size() == 0)
456370b324cSopenharmony_ci        if (so)
457370b324cSopenharmony_ci        {
458370b324cSopenharmony_ci          if (se)
459370b324cSopenharmony_ci            se->Flush();
460370b324cSopenharmony_ci          *so << kEverythingIsOk << endl;
461370b324cSopenharmony_ci        }
462370b324cSopenharmony_ci  }
463370b324cSopenharmony_ci  else
464370b324cSopenharmony_ci  {
465370b324cSopenharmony_ci    if (se)
466370b324cSopenharmony_ci    {
467370b324cSopenharmony_ci      *se << endl;
468370b324cSopenharmony_ci      *se << "WARNINGS for files:" << endl << endl;
469370b324cSopenharmony_ci      PrintWarningsPaths(callback.FailedFiles, *se);
470370b324cSopenharmony_ci      *se << "WARNING: Cannot open " << numErrors << " file";
471370b324cSopenharmony_ci      if (numErrors > 1)
472370b324cSopenharmony_ci        *se << 's';
473370b324cSopenharmony_ci      *se << endl;
474370b324cSopenharmony_ci    }
475370b324cSopenharmony_ci    exitCode = NExitCode::kWarning;
476370b324cSopenharmony_ci  }
477370b324cSopenharmony_ci
478370b324cSopenharmony_ci  return exitCode;
479370b324cSopenharmony_ci}
480370b324cSopenharmony_ci
481370b324cSopenharmony_cistatic void ThrowException_if_Error(HRESULT res)
482370b324cSopenharmony_ci{
483370b324cSopenharmony_ci  if (res != S_OK)
484370b324cSopenharmony_ci    throw CSystemException(res);
485370b324cSopenharmony_ci}
486370b324cSopenharmony_ci
487370b324cSopenharmony_cistatic void PrintNum(UInt64 val, unsigned numDigits, char c = ' ')
488370b324cSopenharmony_ci{
489370b324cSopenharmony_ci  char temp[64];
490370b324cSopenharmony_ci  char *p = temp + 32;
491370b324cSopenharmony_ci  ConvertUInt64ToString(val, p);
492370b324cSopenharmony_ci  unsigned len = MyStringLen(p);
493370b324cSopenharmony_ci  for (; len < numDigits; len++)
494370b324cSopenharmony_ci    *--p = c;
495370b324cSopenharmony_ci  *g_StdStream << p;
496370b324cSopenharmony_ci}
497370b324cSopenharmony_ci
498370b324cSopenharmony_ci#ifdef _WIN32
499370b324cSopenharmony_ci
500370b324cSopenharmony_cistatic void PrintTime(const char *s, UInt64 val, UInt64 total)
501370b324cSopenharmony_ci{
502370b324cSopenharmony_ci  *g_StdStream << endl << s << " Time =";
503370b324cSopenharmony_ci  const UInt32 kFreq = 10000000;
504370b324cSopenharmony_ci  UInt64 sec = val / kFreq;
505370b324cSopenharmony_ci  PrintNum(sec, 6);
506370b324cSopenharmony_ci  *g_StdStream << '.';
507370b324cSopenharmony_ci  UInt32 ms = (UInt32)(val - (sec * kFreq)) / (kFreq / 1000);
508370b324cSopenharmony_ci  PrintNum(ms, 3, '0');
509370b324cSopenharmony_ci
510370b324cSopenharmony_ci  while (val > ((UInt64)1 << 56))
511370b324cSopenharmony_ci  {
512370b324cSopenharmony_ci    val >>= 1;
513370b324cSopenharmony_ci    total >>= 1;
514370b324cSopenharmony_ci  }
515370b324cSopenharmony_ci
516370b324cSopenharmony_ci  UInt64 percent = 0;
517370b324cSopenharmony_ci  if (total != 0)
518370b324cSopenharmony_ci    percent = val * 100 / total;
519370b324cSopenharmony_ci  *g_StdStream << " =";
520370b324cSopenharmony_ci  PrintNum(percent, 5);
521370b324cSopenharmony_ci  *g_StdStream << '%';
522370b324cSopenharmony_ci}
523370b324cSopenharmony_ci
524370b324cSopenharmony_ci#ifndef UNDER_CE
525370b324cSopenharmony_ci
526370b324cSopenharmony_ci#define SHIFT_SIZE_VALUE(x, num) (((x) + (1 << (num)) - 1) >> (num))
527370b324cSopenharmony_ci
528370b324cSopenharmony_cistatic void PrintMemUsage(const char *s, UInt64 val)
529370b324cSopenharmony_ci{
530370b324cSopenharmony_ci  *g_StdStream << "    " << s << " Memory =";
531370b324cSopenharmony_ci  PrintNum(SHIFT_SIZE_VALUE(val, 20), 7);
532370b324cSopenharmony_ci  *g_StdStream << " MB";
533370b324cSopenharmony_ci  /*
534370b324cSopenharmony_ci  *g_StdStream << " =";
535370b324cSopenharmony_ci  PrintNum(SHIFT_SIZE_VALUE(val, 10), 9);
536370b324cSopenharmony_ci  *g_StdStream << " KB";
537370b324cSopenharmony_ci  */
538370b324cSopenharmony_ci  #ifdef Z7_LARGE_PAGES
539370b324cSopenharmony_ci  AString lp;
540370b324cSopenharmony_ci  Add_LargePages_String(lp);
541370b324cSopenharmony_ci  if (!lp.IsEmpty())
542370b324cSopenharmony_ci    *g_StdStream << lp;
543370b324cSopenharmony_ci  #endif
544370b324cSopenharmony_ci}
545370b324cSopenharmony_ci
546370b324cSopenharmony_ciEXTERN_C_BEGIN
547370b324cSopenharmony_citypedef BOOL (WINAPI *Func_GetProcessMemoryInfo)(HANDLE Process,
548370b324cSopenharmony_ci    PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb);
549370b324cSopenharmony_citypedef BOOL (WINAPI *Func_QueryProcessCycleTime)(HANDLE Process, PULONG64 CycleTime);
550370b324cSopenharmony_ciEXTERN_C_END
551370b324cSopenharmony_ci
552370b324cSopenharmony_ci#endif
553370b324cSopenharmony_ci
554370b324cSopenharmony_cistatic inline UInt64 GetTime64(const FILETIME &t) { return ((UInt64)t.dwHighDateTime << 32) | t.dwLowDateTime; }
555370b324cSopenharmony_ci
556370b324cSopenharmony_cistatic void PrintStat()
557370b324cSopenharmony_ci{
558370b324cSopenharmony_ci  FILETIME creationTimeFT, exitTimeFT, kernelTimeFT, userTimeFT;
559370b324cSopenharmony_ci  if (!
560370b324cSopenharmony_ci      #ifdef UNDER_CE
561370b324cSopenharmony_ci        ::GetThreadTimes(::GetCurrentThread()
562370b324cSopenharmony_ci      #else
563370b324cSopenharmony_ci        // NT 3.5
564370b324cSopenharmony_ci        ::GetProcessTimes(::GetCurrentProcess()
565370b324cSopenharmony_ci      #endif
566370b324cSopenharmony_ci      , &creationTimeFT, &exitTimeFT, &kernelTimeFT, &userTimeFT))
567370b324cSopenharmony_ci    return;
568370b324cSopenharmony_ci  FILETIME curTimeFT;
569370b324cSopenharmony_ci  NTime::GetCurUtc_FiTime(curTimeFT);
570370b324cSopenharmony_ci
571370b324cSopenharmony_ci  #ifndef UNDER_CE
572370b324cSopenharmony_ci
573370b324cSopenharmony_ci  PROCESS_MEMORY_COUNTERS m;
574370b324cSopenharmony_ci  memset(&m, 0, sizeof(m));
575370b324cSopenharmony_ci  BOOL memDefined = FALSE;
576370b324cSopenharmony_ci  BOOL cycleDefined = FALSE;
577370b324cSopenharmony_ci  ULONG64 cycleTime = 0;
578370b324cSopenharmony_ci  {
579370b324cSopenharmony_ci    /* NT 4.0: GetProcessMemoryInfo() in Psapi.dll
580370b324cSopenharmony_ci       Win7: new function K32GetProcessMemoryInfo() in kernel32.dll
581370b324cSopenharmony_ci       It's faster to call kernel32.dll code than Psapi.dll code
582370b324cSopenharmony_ci       GetProcessMemoryInfo() requires Psapi.lib
583370b324cSopenharmony_ci       Psapi.lib in SDK7+ can link to K32GetProcessMemoryInfo in kernel32.dll
584370b324cSopenharmony_ci       The program with K32GetProcessMemoryInfo will not work on systems before Win7
585370b324cSopenharmony_ci       // memDefined = GetProcessMemoryInfo(GetCurrentProcess(), &m, sizeof(m));
586370b324cSopenharmony_ci    */
587370b324cSopenharmony_ci    const HMODULE kern = ::GetModuleHandleW(L"kernel32.dll");
588370b324cSopenharmony_ci    Func_GetProcessMemoryInfo
589370b324cSopenharmony_ci      my_GetProcessMemoryInfo = Z7_GET_PROC_ADDRESS(
590370b324cSopenharmony_ci    Func_GetProcessMemoryInfo, kern,
591370b324cSopenharmony_ci     "K32GetProcessMemoryInfo");
592370b324cSopenharmony_ci    if (!my_GetProcessMemoryInfo)
593370b324cSopenharmony_ci    {
594370b324cSopenharmony_ci      const HMODULE lib = LoadLibraryW(L"Psapi.dll");
595370b324cSopenharmony_ci      if (lib)
596370b324cSopenharmony_ci          my_GetProcessMemoryInfo = Z7_GET_PROC_ADDRESS(
597370b324cSopenharmony_ci        Func_GetProcessMemoryInfo, lib,
598370b324cSopenharmony_ci            "GetProcessMemoryInfo");
599370b324cSopenharmony_ci    }
600370b324cSopenharmony_ci    if (my_GetProcessMemoryInfo)
601370b324cSopenharmony_ci      memDefined = my_GetProcessMemoryInfo(GetCurrentProcess(), &m, sizeof(m));
602370b324cSopenharmony_ci    // FreeLibrary(lib);
603370b324cSopenharmony_ci    const
604370b324cSopenharmony_ci    Func_QueryProcessCycleTime
605370b324cSopenharmony_ci      my_QueryProcessCycleTime = Z7_GET_PROC_ADDRESS(
606370b324cSopenharmony_ci    Func_QueryProcessCycleTime, kern,
607370b324cSopenharmony_ci        "QueryProcessCycleTime");
608370b324cSopenharmony_ci    if (my_QueryProcessCycleTime)
609370b324cSopenharmony_ci      cycleDefined = my_QueryProcessCycleTime(GetCurrentProcess(), &cycleTime);
610370b324cSopenharmony_ci  }
611370b324cSopenharmony_ci
612370b324cSopenharmony_ci  #endif
613370b324cSopenharmony_ci
614370b324cSopenharmony_ci  UInt64 curTime = GetTime64(curTimeFT);
615370b324cSopenharmony_ci  UInt64 creationTime = GetTime64(creationTimeFT);
616370b324cSopenharmony_ci  UInt64 kernelTime = GetTime64(kernelTimeFT);
617370b324cSopenharmony_ci  UInt64 userTime = GetTime64(userTimeFT);
618370b324cSopenharmony_ci
619370b324cSopenharmony_ci  UInt64 totalTime = curTime - creationTime;
620370b324cSopenharmony_ci
621370b324cSopenharmony_ci  PrintTime("Kernel ", kernelTime, totalTime);
622370b324cSopenharmony_ci
623370b324cSopenharmony_ci  const UInt64 processTime = kernelTime + userTime;
624370b324cSopenharmony_ci
625370b324cSopenharmony_ci  #ifndef UNDER_CE
626370b324cSopenharmony_ci  if (cycleDefined)
627370b324cSopenharmony_ci  {
628370b324cSopenharmony_ci    *g_StdStream << "    Cnt:";
629370b324cSopenharmony_ci    PrintNum(cycleTime / 1000000, 15);
630370b324cSopenharmony_ci    *g_StdStream << " MCycles";
631370b324cSopenharmony_ci  }
632370b324cSopenharmony_ci  #endif
633370b324cSopenharmony_ci
634370b324cSopenharmony_ci  PrintTime("User   ", userTime, totalTime);
635370b324cSopenharmony_ci
636370b324cSopenharmony_ci  #ifndef UNDER_CE
637370b324cSopenharmony_ci  if (cycleDefined)
638370b324cSopenharmony_ci  {
639370b324cSopenharmony_ci    *g_StdStream << "    Freq (cnt/ptime):";
640370b324cSopenharmony_ci    UInt64 us = processTime / 10;
641370b324cSopenharmony_ci    if (us == 0)
642370b324cSopenharmony_ci      us = 1;
643370b324cSopenharmony_ci    PrintNum(cycleTime / us, 6);
644370b324cSopenharmony_ci    *g_StdStream << " MHz";
645370b324cSopenharmony_ci  }
646370b324cSopenharmony_ci  #endif
647370b324cSopenharmony_ci
648370b324cSopenharmony_ci  PrintTime("Process", processTime, totalTime);
649370b324cSopenharmony_ci  #ifndef UNDER_CE
650370b324cSopenharmony_ci  if (memDefined) PrintMemUsage("Virtual ", m.PeakPagefileUsage);
651370b324cSopenharmony_ci  #endif
652370b324cSopenharmony_ci
653370b324cSopenharmony_ci  PrintTime("Global ", totalTime, totalTime);
654370b324cSopenharmony_ci  #ifndef UNDER_CE
655370b324cSopenharmony_ci  if (memDefined) PrintMemUsage("Physical", m.PeakWorkingSetSize);
656370b324cSopenharmony_ci  #endif
657370b324cSopenharmony_ci  *g_StdStream << endl;
658370b324cSopenharmony_ci}
659370b324cSopenharmony_ci
660370b324cSopenharmony_ci
661370b324cSopenharmony_ci#else  // ! _WIN32
662370b324cSopenharmony_ci
663370b324cSopenharmony_cistatic UInt64 Get_timeofday_us()
664370b324cSopenharmony_ci{
665370b324cSopenharmony_ci  struct timeval now;
666370b324cSopenharmony_ci  if (gettimeofday(&now, NULL) == 0)
667370b324cSopenharmony_ci    return (UInt64)now.tv_sec * 1000000 + (UInt64)now.tv_usec;
668370b324cSopenharmony_ci  return 0;
669370b324cSopenharmony_ci}
670370b324cSopenharmony_ci
671370b324cSopenharmony_cistatic void PrintTime(const char *s, UInt64 val, UInt64 total_us, UInt64 kFreq)
672370b324cSopenharmony_ci{
673370b324cSopenharmony_ci  *g_StdStream << endl << s << " Time =";
674370b324cSopenharmony_ci
675370b324cSopenharmony_ci  {
676370b324cSopenharmony_ci    UInt64 sec, ms;
677370b324cSopenharmony_ci
678370b324cSopenharmony_ci    if (kFreq == 0)
679370b324cSopenharmony_ci    {
680370b324cSopenharmony_ci      sec = val / 1000000;
681370b324cSopenharmony_ci      ms  = val % 1000000 / 1000;
682370b324cSopenharmony_ci    }
683370b324cSopenharmony_ci    else
684370b324cSopenharmony_ci    {
685370b324cSopenharmony_ci      sec = val / kFreq;
686370b324cSopenharmony_ci      ms = (UInt32)((val - (sec * kFreq)) * 1000 / kFreq);
687370b324cSopenharmony_ci    }
688370b324cSopenharmony_ci
689370b324cSopenharmony_ci    PrintNum(sec, 6);
690370b324cSopenharmony_ci    *g_StdStream << '.';
691370b324cSopenharmony_ci    PrintNum(ms, 3, '0');
692370b324cSopenharmony_ci  }
693370b324cSopenharmony_ci
694370b324cSopenharmony_ci  if (total_us == 0)
695370b324cSopenharmony_ci    return;
696370b324cSopenharmony_ci
697370b324cSopenharmony_ci  UInt64 percent = 0;
698370b324cSopenharmony_ci  if (kFreq == 0)
699370b324cSopenharmony_ci    percent = val * 100 / total_us;
700370b324cSopenharmony_ci  else
701370b324cSopenharmony_ci  {
702370b324cSopenharmony_ci    const UInt64 kMaxVal = (UInt64)(Int64)-1;
703370b324cSopenharmony_ci    UInt32 m = 100000000;
704370b324cSopenharmony_ci    for (;;)
705370b324cSopenharmony_ci    {
706370b324cSopenharmony_ci      if (m == 0 || kFreq == 0)
707370b324cSopenharmony_ci        break;
708370b324cSopenharmony_ci      if (kMaxVal / m > val &&
709370b324cSopenharmony_ci        kMaxVal / kFreq > total_us)
710370b324cSopenharmony_ci        break;
711370b324cSopenharmony_ci      if (val > m)
712370b324cSopenharmony_ci        val >>= 1;
713370b324cSopenharmony_ci      else
714370b324cSopenharmony_ci        m >>= 1;
715370b324cSopenharmony_ci      if (kFreq > total_us)
716370b324cSopenharmony_ci        kFreq >>= 1;
717370b324cSopenharmony_ci      else
718370b324cSopenharmony_ci        total_us >>= 1;
719370b324cSopenharmony_ci    }
720370b324cSopenharmony_ci    const UInt64 total = kFreq * total_us;
721370b324cSopenharmony_ci    if (total != 0)
722370b324cSopenharmony_ci      percent = val * m / total;
723370b324cSopenharmony_ci  }
724370b324cSopenharmony_ci  *g_StdStream << " =";
725370b324cSopenharmony_ci  PrintNum(percent, 5);
726370b324cSopenharmony_ci  *g_StdStream << '%';
727370b324cSopenharmony_ci}
728370b324cSopenharmony_ci
729370b324cSopenharmony_cistatic void PrintStat(const UInt64 startTime)
730370b324cSopenharmony_ci{
731370b324cSopenharmony_ci  tms t;
732370b324cSopenharmony_ci  /* clock_t res = */ times(&t);
733370b324cSopenharmony_ci  const UInt64 totalTime = Get_timeofday_us() - startTime;
734370b324cSopenharmony_ci  const UInt64 kFreq = (UInt64)sysconf(_SC_CLK_TCK);
735370b324cSopenharmony_ci  PrintTime("Kernel ", (UInt64)t.tms_stime, totalTime, kFreq);
736370b324cSopenharmony_ci  PrintTime("User   ", (UInt64)t.tms_utime, totalTime, kFreq);
737370b324cSopenharmony_ci  PrintTime("Process", (UInt64)t.tms_utime + (UInt64)t.tms_stime, totalTime, kFreq);
738370b324cSopenharmony_ci  PrintTime("Global ", totalTime, totalTime, 0);
739370b324cSopenharmony_ci  *g_StdStream << endl;
740370b324cSopenharmony_ci}
741370b324cSopenharmony_ci
742370b324cSopenharmony_ci#endif // ! _WIN32
743370b324cSopenharmony_ci
744370b324cSopenharmony_ci
745370b324cSopenharmony_ci
746370b324cSopenharmony_ci
747370b324cSopenharmony_ci
748370b324cSopenharmony_cistatic void PrintHexId(CStdOutStream &so, UInt64 id)
749370b324cSopenharmony_ci{
750370b324cSopenharmony_ci  char s[32];
751370b324cSopenharmony_ci  ConvertUInt64ToHex(id, s);
752370b324cSopenharmony_ci  PrintStringRight(so, s, 8);
753370b324cSopenharmony_ci}
754370b324cSopenharmony_ci
755370b324cSopenharmony_ci#ifndef _WIN32
756370b324cSopenharmony_civoid Set_ModuleDirPrefix_From_ProgArg0(const char *s);
757370b324cSopenharmony_ci#endif
758370b324cSopenharmony_ci
759370b324cSopenharmony_ciint Main2(
760370b324cSopenharmony_ci  #ifndef _WIN32
761370b324cSopenharmony_ci  int numArgs, char *args[]
762370b324cSopenharmony_ci  #endif
763370b324cSopenharmony_ci);
764370b324cSopenharmony_ciint Main2(
765370b324cSopenharmony_ci  #ifndef _WIN32
766370b324cSopenharmony_ci  int numArgs, char *args[]
767370b324cSopenharmony_ci  #endif
768370b324cSopenharmony_ci)
769370b324cSopenharmony_ci{
770370b324cSopenharmony_ci  #if defined(MY_CPU_SIZEOF_POINTER)
771370b324cSopenharmony_ci    { unsigned k = sizeof(void *); if (k != MY_CPU_SIZEOF_POINTER) throw "incorrect MY_CPU_PTR_SIZE"; }
772370b324cSopenharmony_ci  #endif
773370b324cSopenharmony_ci
774370b324cSopenharmony_ci  #if defined(_WIN32) && !defined(UNDER_CE)
775370b324cSopenharmony_ci  SetFileApisToOEM();
776370b324cSopenharmony_ci  #endif
777370b324cSopenharmony_ci
778370b324cSopenharmony_ci  #ifdef ENV_HAVE_LOCALE
779370b324cSopenharmony_ci  // printf("\nBefore SetLocale() : %s\n", IsNativeUtf8() ? "NATIVE UTF-8" : "IS NOT NATIVE UTF-8");
780370b324cSopenharmony_ci  MY_SetLocale();
781370b324cSopenharmony_ci  // printf("\nAfter  SetLocale() : %s\n", IsNativeUtf8() ? "NATIVE UTF-8" : "IS NOT NATIVE UTF-8");
782370b324cSopenharmony_ci  #endif
783370b324cSopenharmony_ci
784370b324cSopenharmony_ci  #ifndef _WIN32
785370b324cSopenharmony_ci  const UInt64 startTime = Get_timeofday_us();
786370b324cSopenharmony_ci  #endif
787370b324cSopenharmony_ci
788370b324cSopenharmony_ci  /*
789370b324cSopenharmony_ci  {
790370b324cSopenharmony_ci    g_StdOut << "DWORD:" << (unsigned)sizeof(DWORD);
791370b324cSopenharmony_ci    g_StdOut << " LONG:" << (unsigned)sizeof(LONG);
792370b324cSopenharmony_ci    g_StdOut << " long:" << (unsigned)sizeof(long);
793370b324cSopenharmony_ci    #ifdef _WIN64
794370b324cSopenharmony_ci    // g_StdOut << " long long:" << (unsigned)sizeof(long long);
795370b324cSopenharmony_ci    #endif
796370b324cSopenharmony_ci    g_StdOut << " int:" << (unsigned)sizeof(int);
797370b324cSopenharmony_ci    g_StdOut << " void*:"  << (unsigned)sizeof(void *);
798370b324cSopenharmony_ci    g_StdOut << endl;
799370b324cSopenharmony_ci  }
800370b324cSopenharmony_ci  */
801370b324cSopenharmony_ci
802370b324cSopenharmony_ci  UStringVector commandStrings;
803370b324cSopenharmony_ci
804370b324cSopenharmony_ci  #ifdef _WIN32
805370b324cSopenharmony_ci  NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
806370b324cSopenharmony_ci  #else
807370b324cSopenharmony_ci  {
808370b324cSopenharmony_ci    if (numArgs > 0)
809370b324cSopenharmony_ci      Set_ModuleDirPrefix_From_ProgArg0(args[0]);
810370b324cSopenharmony_ci
811370b324cSopenharmony_ci    for (int i = 0; i < numArgs; i++)
812370b324cSopenharmony_ci    {
813370b324cSopenharmony_ci      AString a (args[i]);
814370b324cSopenharmony_ci      /*
815370b324cSopenharmony_ci      printf("\n%d %s :", i, a.Ptr());
816370b324cSopenharmony_ci      for (unsigned k = 0; k < a.Len(); k++)
817370b324cSopenharmony_ci        printf(" %2x", (unsigned)(Byte)a[k]);
818370b324cSopenharmony_ci      */
819370b324cSopenharmony_ci      const UString s = MultiByteToUnicodeString(a);
820370b324cSopenharmony_ci      commandStrings.Add(s);
821370b324cSopenharmony_ci    }
822370b324cSopenharmony_ci    // printf("\n");
823370b324cSopenharmony_ci  }
824370b324cSopenharmony_ci
825370b324cSopenharmony_ci  #endif
826370b324cSopenharmony_ci
827370b324cSopenharmony_ci  #ifndef UNDER_CE
828370b324cSopenharmony_ci  if (commandStrings.Size() > 0)
829370b324cSopenharmony_ci    commandStrings.Delete(0);
830370b324cSopenharmony_ci  #endif
831370b324cSopenharmony_ci
832370b324cSopenharmony_ci  if (commandStrings.Size() == 0)
833370b324cSopenharmony_ci  {
834370b324cSopenharmony_ci    ShowCopyrightAndHelp(g_StdStream, true);
835370b324cSopenharmony_ci    return 0;
836370b324cSopenharmony_ci  }
837370b324cSopenharmony_ci
838370b324cSopenharmony_ci  CArcCmdLineOptions options;
839370b324cSopenharmony_ci
840370b324cSopenharmony_ci  CArcCmdLineParser parser;
841370b324cSopenharmony_ci
842370b324cSopenharmony_ci  parser.Parse1(commandStrings, options);
843370b324cSopenharmony_ci
844370b324cSopenharmony_ci  g_StdOut.IsTerminalMode = options.IsStdOutTerminal;
845370b324cSopenharmony_ci  g_StdErr.IsTerminalMode = options.IsStdErrTerminal;
846370b324cSopenharmony_ci
847370b324cSopenharmony_ci  if (options.Number_for_Out != k_OutStream_stdout)
848370b324cSopenharmony_ci    g_StdStream = (options.Number_for_Out == k_OutStream_stderr ? &g_StdErr : NULL);
849370b324cSopenharmony_ci
850370b324cSopenharmony_ci  if (options.Number_for_Errors != k_OutStream_stderr)
851370b324cSopenharmony_ci    g_ErrStream = (options.Number_for_Errors == k_OutStream_stdout ? &g_StdOut : NULL);
852370b324cSopenharmony_ci
853370b324cSopenharmony_ci  CStdOutStream *percentsStream = NULL;
854370b324cSopenharmony_ci  if (options.Number_for_Percents != k_OutStream_disabled)
855370b324cSopenharmony_ci    percentsStream = (options.Number_for_Percents == k_OutStream_stderr) ? &g_StdErr : &g_StdOut;
856370b324cSopenharmony_ci
857370b324cSopenharmony_ci  if (options.HelpMode)
858370b324cSopenharmony_ci  {
859370b324cSopenharmony_ci    ShowCopyrightAndHelp(g_StdStream, true);
860370b324cSopenharmony_ci    return 0;
861370b324cSopenharmony_ci  }
862370b324cSopenharmony_ci
863370b324cSopenharmony_ci  if (options.EnableHeaders)
864370b324cSopenharmony_ci  {
865370b324cSopenharmony_ci    ShowCopyrightAndHelp(g_StdStream, false);
866370b324cSopenharmony_ci    if (!parser.Parse1Log.IsEmpty())
867370b324cSopenharmony_ci      *g_StdStream << parser.Parse1Log;
868370b324cSopenharmony_ci  }
869370b324cSopenharmony_ci
870370b324cSopenharmony_ci  parser.Parse2(options);
871370b324cSopenharmony_ci
872370b324cSopenharmony_ci  {
873370b324cSopenharmony_ci    int cp = options.ConsoleCodePage;
874370b324cSopenharmony_ci
875370b324cSopenharmony_ci    int stdout_cp = cp;
876370b324cSopenharmony_ci    int stderr_cp = cp;
877370b324cSopenharmony_ci    int stdin_cp = cp;
878370b324cSopenharmony_ci
879370b324cSopenharmony_ci    /*
880370b324cSopenharmony_ci    // these cases are complicated.
881370b324cSopenharmony_ci    // maybe we must use CRT functions instead of console WIN32.
882370b324cSopenharmony_ci    // different Windows/CRT versions also can work different ways.
883370b324cSopenharmony_ci    // so the following code was not enabled:
884370b324cSopenharmony_ci    if (cp == -1)
885370b324cSopenharmony_ci    {
886370b324cSopenharmony_ci      // we set CodePage only if stream is attached to terminal
887370b324cSopenharmony_ci      // maybe we should set CodePage even if is not terminal?
888370b324cSopenharmony_ci      #ifdef _WIN32
889370b324cSopenharmony_ci      {
890370b324cSopenharmony_ci        UINT ccp = GetConsoleOutputCP();
891370b324cSopenharmony_ci        if (ccp != 0)
892370b324cSopenharmony_ci        {
893370b324cSopenharmony_ci          if (options.IsStdOutTerminal) stdout_cp = ccp;
894370b324cSopenharmony_ci          if (options.IsStdErrTerminal) stderr_cp = ccp;
895370b324cSopenharmony_ci        }
896370b324cSopenharmony_ci      }
897370b324cSopenharmony_ci      if (options.IsInTerminal)
898370b324cSopenharmony_ci      {
899370b324cSopenharmony_ci        UINT ccp = GetConsoleCP();
900370b324cSopenharmony_ci        if (ccp != 0) stdin_cp = ccp;
901370b324cSopenharmony_ci      }
902370b324cSopenharmony_ci      #endif
903370b324cSopenharmony_ci    }
904370b324cSopenharmony_ci    */
905370b324cSopenharmony_ci
906370b324cSopenharmony_ci    if (stdout_cp != -1) g_StdOut.CodePage = stdout_cp;
907370b324cSopenharmony_ci    if (stderr_cp != -1) g_StdErr.CodePage = stderr_cp;
908370b324cSopenharmony_ci    if (stdin_cp != -1) g_StdIn.CodePage = stdin_cp;
909370b324cSopenharmony_ci  }
910370b324cSopenharmony_ci
911370b324cSopenharmony_ci  unsigned percentsNameLevel = 1;
912370b324cSopenharmony_ci  if (options.LogLevel == 0 || options.Number_for_Percents != options.Number_for_Out)
913370b324cSopenharmony_ci    percentsNameLevel = 2;
914370b324cSopenharmony_ci
915370b324cSopenharmony_ci  unsigned consoleWidth = 80;
916370b324cSopenharmony_ci
917370b324cSopenharmony_ci  if (percentsStream)
918370b324cSopenharmony_ci  {
919370b324cSopenharmony_ci    #ifdef _WIN32
920370b324cSopenharmony_ci
921370b324cSopenharmony_ci    #if !defined(UNDER_CE)
922370b324cSopenharmony_ci    CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
923370b324cSopenharmony_ci    if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo))
924370b324cSopenharmony_ci      consoleWidth = (unsigned)(unsigned short)consoleInfo.dwSize.X;
925370b324cSopenharmony_ci    #endif
926370b324cSopenharmony_ci
927370b324cSopenharmony_ci    #else
928370b324cSopenharmony_ci
929370b324cSopenharmony_ci    struct winsize w;
930370b324cSopenharmony_ci    if (ioctl(0, TIOCGWINSZ, &w) == 0)
931370b324cSopenharmony_ci      consoleWidth = w.ws_col;
932370b324cSopenharmony_ci
933370b324cSopenharmony_ci    #endif
934370b324cSopenharmony_ci  }
935370b324cSopenharmony_ci
936370b324cSopenharmony_ci  CREATE_CODECS_OBJECT
937370b324cSopenharmony_ci
938370b324cSopenharmony_ci  codecs->CaseSensitive_Change = options.CaseSensitive_Change;
939370b324cSopenharmony_ci  codecs->CaseSensitive = options.CaseSensitive;
940370b324cSopenharmony_ci  ThrowException_if_Error(codecs->Load());
941370b324cSopenharmony_ci  Codecs_AddHashArcHandler(codecs);
942370b324cSopenharmony_ci
943370b324cSopenharmony_ci  #ifdef Z7_EXTERNAL_CODECS
944370b324cSopenharmony_ci  {
945370b324cSopenharmony_ci    g_ExternalCodecs_Ptr = &_externalCodecs;
946370b324cSopenharmony_ci    UString s;
947370b324cSopenharmony_ci    codecs->GetCodecsErrorMessage(s);
948370b324cSopenharmony_ci    if (!s.IsEmpty())
949370b324cSopenharmony_ci    {
950370b324cSopenharmony_ci      CStdOutStream &so = (g_StdStream ? *g_StdStream : g_StdOut);
951370b324cSopenharmony_ci      so << endl << s << endl;
952370b324cSopenharmony_ci    }
953370b324cSopenharmony_ci  }
954370b324cSopenharmony_ci  #endif
955370b324cSopenharmony_ci
956370b324cSopenharmony_ci  const bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
957370b324cSopenharmony_ci
958370b324cSopenharmony_ci  if (codecs->Formats.Size() == 0 &&
959370b324cSopenharmony_ci        (isExtractGroupCommand
960370b324cSopenharmony_ci        || options.Command.CommandType == NCommandType::kList
961370b324cSopenharmony_ci        || options.Command.IsFromUpdateGroup()))
962370b324cSopenharmony_ci  {
963370b324cSopenharmony_ci    #ifdef Z7_EXTERNAL_CODECS
964370b324cSopenharmony_ci    if (!codecs->MainDll_ErrorPath.IsEmpty())
965370b324cSopenharmony_ci    {
966370b324cSopenharmony_ci      UString s ("Can't load module: ");
967370b324cSopenharmony_ci      s += fs2us(codecs->MainDll_ErrorPath);
968370b324cSopenharmony_ci      throw s;
969370b324cSopenharmony_ci    }
970370b324cSopenharmony_ci    #endif
971370b324cSopenharmony_ci    throw kNoFormats;
972370b324cSopenharmony_ci  }
973370b324cSopenharmony_ci
974370b324cSopenharmony_ci  CObjectVector<COpenType> types;
975370b324cSopenharmony_ci  if (!ParseOpenTypes(*codecs, options.ArcType, types))
976370b324cSopenharmony_ci  {
977370b324cSopenharmony_ci    throw kUnsupportedArcTypeMessage;
978370b324cSopenharmony_ci  }
979370b324cSopenharmony_ci
980370b324cSopenharmony_ci
981370b324cSopenharmony_ci  CIntVector excludedFormats;
982370b324cSopenharmony_ci  FOR_VECTOR (k, options.ExcludedArcTypes)
983370b324cSopenharmony_ci  {
984370b324cSopenharmony_ci    CIntVector tempIndices;
985370b324cSopenharmony_ci    if (!codecs->FindFormatForArchiveType(options.ExcludedArcTypes[k], tempIndices)
986370b324cSopenharmony_ci        || tempIndices.Size() != 1)
987370b324cSopenharmony_ci      throw kUnsupportedArcTypeMessage;
988370b324cSopenharmony_ci
989370b324cSopenharmony_ci
990370b324cSopenharmony_ci
991370b324cSopenharmony_ci    excludedFormats.AddToUniqueSorted(tempIndices[0]);
992370b324cSopenharmony_ci    // excludedFormats.Sort();
993370b324cSopenharmony_ci  }
994370b324cSopenharmony_ci
995370b324cSopenharmony_ci  #ifdef Z7_EXTERNAL_CODECS
996370b324cSopenharmony_ci  if (isExtractGroupCommand
997370b324cSopenharmony_ci      || options.Command.IsFromUpdateGroup()
998370b324cSopenharmony_ci      || options.Command.CommandType == NCommandType::kHash
999370b324cSopenharmony_ci      || options.Command.CommandType == NCommandType::kBenchmark)
1000370b324cSopenharmony_ci    ThrowException_if_Error(_externalCodecs.Load());
1001370b324cSopenharmony_ci  #endif
1002370b324cSopenharmony_ci
1003370b324cSopenharmony_ci  int retCode = NExitCode::kSuccess;
1004370b324cSopenharmony_ci  HRESULT hresultMain = S_OK;
1005370b324cSopenharmony_ci
1006370b324cSopenharmony_ci  // bool showStat = options.ShowTime;
1007370b324cSopenharmony_ci
1008370b324cSopenharmony_ci  /*
1009370b324cSopenharmony_ci  if (!options.EnableHeaders ||
1010370b324cSopenharmony_ci      options.TechMode)
1011370b324cSopenharmony_ci    showStat = false;
1012370b324cSopenharmony_ci  */
1013370b324cSopenharmony_ci
1014370b324cSopenharmony_ci
1015370b324cSopenharmony_ci  if (options.Command.CommandType == NCommandType::kInfo)
1016370b324cSopenharmony_ci  {
1017370b324cSopenharmony_ci    CStdOutStream &so = (g_StdStream ? *g_StdStream : g_StdOut);
1018370b324cSopenharmony_ci    unsigned i;
1019370b324cSopenharmony_ci
1020370b324cSopenharmony_ci    #ifdef Z7_EXTERNAL_CODECS
1021370b324cSopenharmony_ci    so << endl << "Libs:" << endl;
1022370b324cSopenharmony_ci    for (i = 0; i < codecs->Libs.Size(); i++)
1023370b324cSopenharmony_ci    {
1024370b324cSopenharmony_ci      PrintLibIndex(so, (int)i);
1025370b324cSopenharmony_ci      const CCodecLib &lib = codecs->Libs[i];
1026370b324cSopenharmony_ci      // if (lib.Version != 0)
1027370b324cSopenharmony_ci      so << ": " << (lib.Version >> 16) << ".";
1028370b324cSopenharmony_ci      PrintNumber(so, lib.Version & 0xffff, 2);
1029370b324cSopenharmony_ci      so << " : " << lib.Path << endl;
1030370b324cSopenharmony_ci    }
1031370b324cSopenharmony_ci    #endif
1032370b324cSopenharmony_ci
1033370b324cSopenharmony_ci    so << endl << "Formats:" << endl;
1034370b324cSopenharmony_ci
1035370b324cSopenharmony_ci    const char * const kArcFlags = "KSNFMGOPBELHXCc+a+m+r+";
1036370b324cSopenharmony_ci    const char * const kArcTimeFlags = "wudn";
1037370b324cSopenharmony_ci    const unsigned kNumArcFlags = (unsigned)strlen(kArcFlags);
1038370b324cSopenharmony_ci    const unsigned kNumArcTimeFlags = (unsigned)strlen(kArcTimeFlags);
1039370b324cSopenharmony_ci
1040370b324cSopenharmony_ci    for (i = 0; i < codecs->Formats.Size(); i++)
1041370b324cSopenharmony_ci    {
1042370b324cSopenharmony_ci      const CArcInfoEx &arc = codecs->Formats[i];
1043370b324cSopenharmony_ci
1044370b324cSopenharmony_ci      #ifdef Z7_EXTERNAL_CODECS
1045370b324cSopenharmony_ci      PrintLibIndex(so, arc.LibIndex);
1046370b324cSopenharmony_ci      #else
1047370b324cSopenharmony_ci      so << "   ";
1048370b324cSopenharmony_ci      #endif
1049370b324cSopenharmony_ci
1050370b324cSopenharmony_ci      so << (char)(arc.UpdateEnabled ? 'C' : ' ');
1051370b324cSopenharmony_ci
1052370b324cSopenharmony_ci      {
1053370b324cSopenharmony_ci        unsigned b;
1054370b324cSopenharmony_ci        for (b = 0; b < kNumArcFlags; b++)
1055370b324cSopenharmony_ci          so << (char)((arc.Flags & ((UInt32)1 << b)) != 0 ? kArcFlags[b] : '.');
1056370b324cSopenharmony_ci        so << ' ';
1057370b324cSopenharmony_ci      }
1058370b324cSopenharmony_ci
1059370b324cSopenharmony_ci      if (arc.TimeFlags != 0)
1060370b324cSopenharmony_ci      {
1061370b324cSopenharmony_ci        unsigned b;
1062370b324cSopenharmony_ci        for (b = 0; b < kNumArcTimeFlags; b++)
1063370b324cSopenharmony_ci          so << (char)((arc.TimeFlags & ((UInt32)1 << b)) != 0 ? kArcTimeFlags[b] : '.');
1064370b324cSopenharmony_ci        so << arc.Get_DefaultTimePrec();
1065370b324cSopenharmony_ci        so << ' ';
1066370b324cSopenharmony_ci      }
1067370b324cSopenharmony_ci
1068370b324cSopenharmony_ci      so << ' ';
1069370b324cSopenharmony_ci      PrintString(so, arc.Name, 8);
1070370b324cSopenharmony_ci      so << ' ';
1071370b324cSopenharmony_ci      UString s;
1072370b324cSopenharmony_ci
1073370b324cSopenharmony_ci      FOR_VECTOR (t, arc.Exts)
1074370b324cSopenharmony_ci      {
1075370b324cSopenharmony_ci        if (t != 0)
1076370b324cSopenharmony_ci          s.Add_Space();
1077370b324cSopenharmony_ci        const CArcExtInfo &ext = arc.Exts[t];
1078370b324cSopenharmony_ci        s += ext.Ext;
1079370b324cSopenharmony_ci        if (!ext.AddExt.IsEmpty())
1080370b324cSopenharmony_ci        {
1081370b324cSopenharmony_ci          s += " (";
1082370b324cSopenharmony_ci          s += ext.AddExt;
1083370b324cSopenharmony_ci          s += ')';
1084370b324cSopenharmony_ci        }
1085370b324cSopenharmony_ci      }
1086370b324cSopenharmony_ci
1087370b324cSopenharmony_ci      PrintString(so, s, 13);
1088370b324cSopenharmony_ci      so << ' ';
1089370b324cSopenharmony_ci
1090370b324cSopenharmony_ci      if (arc.SignatureOffset != 0)
1091370b324cSopenharmony_ci        so << "offset=" << arc.SignatureOffset << ' ';
1092370b324cSopenharmony_ci
1093370b324cSopenharmony_ci      // so << "numSignatures = " << arc.Signatures.Size() << " ";
1094370b324cSopenharmony_ci
1095370b324cSopenharmony_ci      FOR_VECTOR(si, arc.Signatures)
1096370b324cSopenharmony_ci      {
1097370b324cSopenharmony_ci        if (si != 0)
1098370b324cSopenharmony_ci          so << "  ||  ";
1099370b324cSopenharmony_ci
1100370b324cSopenharmony_ci        const CByteBuffer &sig = arc.Signatures[si];
1101370b324cSopenharmony_ci
1102370b324cSopenharmony_ci        for (size_t j = 0; j < sig.Size(); j++)
1103370b324cSopenharmony_ci        {
1104370b324cSopenharmony_ci          if (j != 0)
1105370b324cSopenharmony_ci            so << ' ';
1106370b324cSopenharmony_ci          Byte b = sig[j];
1107370b324cSopenharmony_ci          if (b > 0x20 && b < 0x80)
1108370b324cSopenharmony_ci          {
1109370b324cSopenharmony_ci            so << (char)b;
1110370b324cSopenharmony_ci          }
1111370b324cSopenharmony_ci          else
1112370b324cSopenharmony_ci          {
1113370b324cSopenharmony_ci            so << GetHex((b >> 4) & 0xF);
1114370b324cSopenharmony_ci            so << GetHex(b & 0xF);
1115370b324cSopenharmony_ci          }
1116370b324cSopenharmony_ci        }
1117370b324cSopenharmony_ci      }
1118370b324cSopenharmony_ci      so << endl;
1119370b324cSopenharmony_ci    }
1120370b324cSopenharmony_ci
1121370b324cSopenharmony_ci    so << endl << "Codecs:" << endl; //  << "Lib          ID Name" << endl;
1122370b324cSopenharmony_ci
1123370b324cSopenharmony_ci    for (i = 0; i < g_NumCodecs; i++)
1124370b324cSopenharmony_ci    {
1125370b324cSopenharmony_ci      const CCodecInfo &cod = *g_Codecs[i];
1126370b324cSopenharmony_ci
1127370b324cSopenharmony_ci      PrintLibIndex(so, -1);
1128370b324cSopenharmony_ci
1129370b324cSopenharmony_ci      if (cod.NumStreams == 1)
1130370b324cSopenharmony_ci        so << ' ';
1131370b324cSopenharmony_ci      else
1132370b324cSopenharmony_ci        so << cod.NumStreams;
1133370b324cSopenharmony_ci
1134370b324cSopenharmony_ci      so << (char)(cod.CreateEncoder ? 'E' : ' ');
1135370b324cSopenharmony_ci      so << (char)(cod.CreateDecoder ? 'D' : ' ');
1136370b324cSopenharmony_ci      so << (char)(cod.IsFilter      ? 'F' : ' ');
1137370b324cSopenharmony_ci
1138370b324cSopenharmony_ci      so << ' ';
1139370b324cSopenharmony_ci      PrintHexId(so, cod.Id);
1140370b324cSopenharmony_ci      so << ' ' << cod.Name << endl;
1141370b324cSopenharmony_ci    }
1142370b324cSopenharmony_ci
1143370b324cSopenharmony_ci
1144370b324cSopenharmony_ci    #ifdef Z7_EXTERNAL_CODECS
1145370b324cSopenharmony_ci
1146370b324cSopenharmony_ci    UInt32 numMethods;
1147370b324cSopenharmony_ci    if (_externalCodecs.GetCodecs->GetNumMethods(&numMethods) == S_OK)
1148370b324cSopenharmony_ci    for (UInt32 j = 0; j < numMethods; j++)
1149370b324cSopenharmony_ci    {
1150370b324cSopenharmony_ci      PrintLibIndex(so, codecs->GetCodec_LibIndex(j));
1151370b324cSopenharmony_ci
1152370b324cSopenharmony_ci      UInt32 numStreams = codecs->GetCodec_NumStreams(j);
1153370b324cSopenharmony_ci      if (numStreams == 1)
1154370b324cSopenharmony_ci        so << ' ';
1155370b324cSopenharmony_ci      else
1156370b324cSopenharmony_ci        so << numStreams;
1157370b324cSopenharmony_ci
1158370b324cSopenharmony_ci      so << (char)(codecs->GetCodec_EncoderIsAssigned(j) ? 'E' : ' ');
1159370b324cSopenharmony_ci      so << (char)(codecs->GetCodec_DecoderIsAssigned(j) ? 'D' : ' ');
1160370b324cSopenharmony_ci      {
1161370b324cSopenharmony_ci        bool isFilter_Assigned;
1162370b324cSopenharmony_ci        const bool isFilter = codecs->GetCodec_IsFilter(j, isFilter_Assigned);
1163370b324cSopenharmony_ci        so << (char)(isFilter ? 'F' : isFilter_Assigned ? ' ' : '*');
1164370b324cSopenharmony_ci      }
1165370b324cSopenharmony_ci
1166370b324cSopenharmony_ci
1167370b324cSopenharmony_ci      so << ' ';
1168370b324cSopenharmony_ci      UInt64 id;
1169370b324cSopenharmony_ci      HRESULT res = codecs->GetCodec_Id(j, id);
1170370b324cSopenharmony_ci      if (res != S_OK)
1171370b324cSopenharmony_ci        id = (UInt64)(Int64)-1;
1172370b324cSopenharmony_ci      PrintHexId(so, id);
1173370b324cSopenharmony_ci      so << ' ' << codecs->GetCodec_Name(j) << endl;
1174370b324cSopenharmony_ci    }
1175370b324cSopenharmony_ci
1176370b324cSopenharmony_ci    #endif
1177370b324cSopenharmony_ci
1178370b324cSopenharmony_ci
1179370b324cSopenharmony_ci    so << endl << "Hashers:" << endl; //  << " L Size       ID Name" << endl;
1180370b324cSopenharmony_ci
1181370b324cSopenharmony_ci    for (i = 0; i < g_NumHashers; i++)
1182370b324cSopenharmony_ci    {
1183370b324cSopenharmony_ci      const CHasherInfo &codec = *g_Hashers[i];
1184370b324cSopenharmony_ci      PrintLibIndex(so, -1);
1185370b324cSopenharmony_ci      PrintUInt32(so, codec.DigestSize, 4);
1186370b324cSopenharmony_ci      so << ' ';
1187370b324cSopenharmony_ci      PrintHexId(so, codec.Id);
1188370b324cSopenharmony_ci      so << ' ' << codec.Name << endl;
1189370b324cSopenharmony_ci    }
1190370b324cSopenharmony_ci
1191370b324cSopenharmony_ci    #ifdef Z7_EXTERNAL_CODECS
1192370b324cSopenharmony_ci
1193370b324cSopenharmony_ci    numMethods = _externalCodecs.GetHashers->GetNumHashers();
1194370b324cSopenharmony_ci    for (UInt32 j = 0; j < numMethods; j++)
1195370b324cSopenharmony_ci    {
1196370b324cSopenharmony_ci      PrintLibIndex(so, codecs->GetHasherLibIndex(j));
1197370b324cSopenharmony_ci      PrintUInt32(so, codecs->GetHasherDigestSize(j), 4);
1198370b324cSopenharmony_ci      so << ' ';
1199370b324cSopenharmony_ci      PrintHexId(so, codecs->GetHasherId(j));
1200370b324cSopenharmony_ci      so << ' ' << codecs->GetHasherName(j) << endl;
1201370b324cSopenharmony_ci    }
1202370b324cSopenharmony_ci
1203370b324cSopenharmony_ci    #endif
1204370b324cSopenharmony_ci
1205370b324cSopenharmony_ci  }
1206370b324cSopenharmony_ci  else if (options.Command.CommandType == NCommandType::kBenchmark)
1207370b324cSopenharmony_ci  {
1208370b324cSopenharmony_ci    CStdOutStream &so = (g_StdStream ? *g_StdStream : g_StdOut);
1209370b324cSopenharmony_ci    hresultMain = BenchCon(EXTERNAL_CODECS_VARS_L
1210370b324cSopenharmony_ci        options.Properties, options.NumIterations, (FILE *)so);
1211370b324cSopenharmony_ci    if (hresultMain == S_FALSE)
1212370b324cSopenharmony_ci    {
1213370b324cSopenharmony_ci      so << endl;
1214370b324cSopenharmony_ci      if (g_ErrStream)
1215370b324cSopenharmony_ci        *g_ErrStream << "\nDecoding ERROR\n";
1216370b324cSopenharmony_ci      retCode = NExitCode::kFatalError;
1217370b324cSopenharmony_ci      hresultMain = S_OK;
1218370b324cSopenharmony_ci    }
1219370b324cSopenharmony_ci  }
1220370b324cSopenharmony_ci  else if (isExtractGroupCommand || options.Command.CommandType == NCommandType::kList)
1221370b324cSopenharmony_ci  {
1222370b324cSopenharmony_ci    UStringVector ArchivePathsSorted;
1223370b324cSopenharmony_ci    UStringVector ArchivePathsFullSorted;
1224370b324cSopenharmony_ci
1225370b324cSopenharmony_ci    if (options.StdInMode)
1226370b324cSopenharmony_ci    {
1227370b324cSopenharmony_ci      ArchivePathsSorted.Add(options.ArcName_for_StdInMode);
1228370b324cSopenharmony_ci      ArchivePathsFullSorted.Add(options.ArcName_for_StdInMode);
1229370b324cSopenharmony_ci    }
1230370b324cSopenharmony_ci    else
1231370b324cSopenharmony_ci    {
1232370b324cSopenharmony_ci      CExtractScanConsole scan;
1233370b324cSopenharmony_ci
1234370b324cSopenharmony_ci      scan.Init(options.EnableHeaders ? g_StdStream : NULL, g_ErrStream, percentsStream);
1235370b324cSopenharmony_ci      scan.SetWindowWidth(consoleWidth);
1236370b324cSopenharmony_ci
1237370b324cSopenharmony_ci      if (g_StdStream && options.EnableHeaders)
1238370b324cSopenharmony_ci        *g_StdStream << "Scanning the drive for archives:" << endl;
1239370b324cSopenharmony_ci
1240370b324cSopenharmony_ci      CDirItemsStat st;
1241370b324cSopenharmony_ci
1242370b324cSopenharmony_ci      scan.StartScanning();
1243370b324cSopenharmony_ci
1244370b324cSopenharmony_ci      hresultMain = EnumerateDirItemsAndSort(
1245370b324cSopenharmony_ci          options.arcCensor,
1246370b324cSopenharmony_ci          NWildcard::k_RelatPath,
1247370b324cSopenharmony_ci          UString(), // addPathPrefix
1248370b324cSopenharmony_ci          ArchivePathsSorted,
1249370b324cSopenharmony_ci          ArchivePathsFullSorted,
1250370b324cSopenharmony_ci          st,
1251370b324cSopenharmony_ci          &scan);
1252370b324cSopenharmony_ci
1253370b324cSopenharmony_ci      scan.CloseScanning();
1254370b324cSopenharmony_ci
1255370b324cSopenharmony_ci      if (hresultMain == S_OK)
1256370b324cSopenharmony_ci      {
1257370b324cSopenharmony_ci        if (options.EnableHeaders)
1258370b324cSopenharmony_ci          scan.PrintStat(st);
1259370b324cSopenharmony_ci      }
1260370b324cSopenharmony_ci      else
1261370b324cSopenharmony_ci      {
1262370b324cSopenharmony_ci        /*
1263370b324cSopenharmony_ci        if (res != E_ABORT)
1264370b324cSopenharmony_ci        {
1265370b324cSopenharmony_ci          throw CSystemException(res);
1266370b324cSopenharmony_ci          // errorInfo.Message = "Scanning error";
1267370b324cSopenharmony_ci        }
1268370b324cSopenharmony_ci        return res;
1269370b324cSopenharmony_ci        */
1270370b324cSopenharmony_ci      }
1271370b324cSopenharmony_ci    }
1272370b324cSopenharmony_ci
1273370b324cSopenharmony_ci    if (hresultMain == S_OK) {
1274370b324cSopenharmony_ci    if (isExtractGroupCommand)
1275370b324cSopenharmony_ci    {
1276370b324cSopenharmony_ci      CExtractCallbackConsole *ecs = new CExtractCallbackConsole;
1277370b324cSopenharmony_ci      CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
1278370b324cSopenharmony_ci
1279370b324cSopenharmony_ci      #ifndef Z7_NO_CRYPTO
1280370b324cSopenharmony_ci      ecs->PasswordIsDefined = options.PasswordEnabled;
1281370b324cSopenharmony_ci      ecs->Password = options.Password;
1282370b324cSopenharmony_ci      #endif
1283370b324cSopenharmony_ci
1284370b324cSopenharmony_ci      ecs->Init(g_StdStream, g_ErrStream, percentsStream);
1285370b324cSopenharmony_ci      ecs->MultiArcMode = (ArchivePathsSorted.Size() > 1);
1286370b324cSopenharmony_ci
1287370b324cSopenharmony_ci      ecs->LogLevel = options.LogLevel;
1288370b324cSopenharmony_ci      ecs->PercentsNameLevel = percentsNameLevel;
1289370b324cSopenharmony_ci
1290370b324cSopenharmony_ci      if (percentsStream)
1291370b324cSopenharmony_ci        ecs->SetWindowWidth(consoleWidth);
1292370b324cSopenharmony_ci
1293370b324cSopenharmony_ci      /*
1294370b324cSopenharmony_ci      COpenCallbackConsole openCallback;
1295370b324cSopenharmony_ci      openCallback.Init(g_StdStream, g_ErrStream);
1296370b324cSopenharmony_ci
1297370b324cSopenharmony_ci      #ifndef Z7_NO_CRYPTO
1298370b324cSopenharmony_ci      openCallback.PasswordIsDefined = options.PasswordEnabled;
1299370b324cSopenharmony_ci      openCallback.Password = options.Password;
1300370b324cSopenharmony_ci      #endif
1301370b324cSopenharmony_ci      */
1302370b324cSopenharmony_ci
1303370b324cSopenharmony_ci      CExtractOptions eo;
1304370b324cSopenharmony_ci      (CExtractOptionsBase &)eo = options.ExtractOptions;
1305370b324cSopenharmony_ci
1306370b324cSopenharmony_ci      eo.StdInMode = options.StdInMode;
1307370b324cSopenharmony_ci      eo.StdOutMode = options.StdOutMode;
1308370b324cSopenharmony_ci      eo.YesToAll = options.YesToAll;
1309370b324cSopenharmony_ci      eo.TestMode = options.Command.IsTestCommand();
1310370b324cSopenharmony_ci
1311370b324cSopenharmony_ci      #ifndef Z7_SFX
1312370b324cSopenharmony_ci      eo.Properties = options.Properties;
1313370b324cSopenharmony_ci      #endif
1314370b324cSopenharmony_ci
1315370b324cSopenharmony_ci      UString errorMessage;
1316370b324cSopenharmony_ci      CDecompressStat stat;
1317370b324cSopenharmony_ci      CHashBundle hb;
1318370b324cSopenharmony_ci      IHashCalc *hashCalc = NULL;
1319370b324cSopenharmony_ci
1320370b324cSopenharmony_ci      if (!options.HashMethods.IsEmpty())
1321370b324cSopenharmony_ci      {
1322370b324cSopenharmony_ci        hashCalc = &hb;
1323370b324cSopenharmony_ci        ThrowException_if_Error(hb.SetMethods(EXTERNAL_CODECS_VARS_L options.HashMethods));
1324370b324cSopenharmony_ci        // hb.Init();
1325370b324cSopenharmony_ci      }
1326370b324cSopenharmony_ci
1327370b324cSopenharmony_ci      hresultMain = Extract(
1328370b324cSopenharmony_ci          // EXTERNAL_CODECS_VARS_L
1329370b324cSopenharmony_ci          codecs,
1330370b324cSopenharmony_ci          types,
1331370b324cSopenharmony_ci          excludedFormats,
1332370b324cSopenharmony_ci          ArchivePathsSorted,
1333370b324cSopenharmony_ci          ArchivePathsFullSorted,
1334370b324cSopenharmony_ci          options.Censor.Pairs.Front().Head,
1335370b324cSopenharmony_ci          eo,
1336370b324cSopenharmony_ci          ecs, ecs, ecs,
1337370b324cSopenharmony_ci          hashCalc, errorMessage, stat);
1338370b324cSopenharmony_ci
1339370b324cSopenharmony_ci      ecs->ClosePercents();
1340370b324cSopenharmony_ci
1341370b324cSopenharmony_ci      if (!errorMessage.IsEmpty())
1342370b324cSopenharmony_ci      {
1343370b324cSopenharmony_ci        if (g_ErrStream)
1344370b324cSopenharmony_ci          *g_ErrStream << endl << "ERROR:" << endl << errorMessage << endl;
1345370b324cSopenharmony_ci        if (hresultMain == S_OK)
1346370b324cSopenharmony_ci          hresultMain = E_FAIL;
1347370b324cSopenharmony_ci      }
1348370b324cSopenharmony_ci
1349370b324cSopenharmony_ci      CStdOutStream *so = g_StdStream;
1350370b324cSopenharmony_ci
1351370b324cSopenharmony_ci      bool isError = false;
1352370b324cSopenharmony_ci
1353370b324cSopenharmony_ci      if (so)
1354370b324cSopenharmony_ci      {
1355370b324cSopenharmony_ci        *so << endl;
1356370b324cSopenharmony_ci
1357370b324cSopenharmony_ci        if (ecs->NumTryArcs > 1)
1358370b324cSopenharmony_ci        {
1359370b324cSopenharmony_ci          *so << "Archives: " << ecs->NumTryArcs << endl;
1360370b324cSopenharmony_ci          *so << "OK archives: " << ecs->NumOkArcs << endl;
1361370b324cSopenharmony_ci        }
1362370b324cSopenharmony_ci      }
1363370b324cSopenharmony_ci
1364370b324cSopenharmony_ci      if (ecs->NumCantOpenArcs != 0)
1365370b324cSopenharmony_ci      {
1366370b324cSopenharmony_ci        isError = true;
1367370b324cSopenharmony_ci        if (so)
1368370b324cSopenharmony_ci          *so << "Can't open as archive: " << ecs->NumCantOpenArcs << endl;
1369370b324cSopenharmony_ci      }
1370370b324cSopenharmony_ci
1371370b324cSopenharmony_ci      if (ecs->NumArcsWithError != 0)
1372370b324cSopenharmony_ci      {
1373370b324cSopenharmony_ci        isError = true;
1374370b324cSopenharmony_ci        if (so)
1375370b324cSopenharmony_ci          *so << "Archives with Errors: " << ecs->NumArcsWithError << endl;
1376370b324cSopenharmony_ci      }
1377370b324cSopenharmony_ci
1378370b324cSopenharmony_ci      if (so)
1379370b324cSopenharmony_ci      {
1380370b324cSopenharmony_ci        if (ecs->NumArcsWithWarnings != 0)
1381370b324cSopenharmony_ci          *so << "Archives with Warnings: " << ecs->NumArcsWithWarnings << endl;
1382370b324cSopenharmony_ci
1383370b324cSopenharmony_ci        if (ecs->NumOpenArcWarnings != 0)
1384370b324cSopenharmony_ci        {
1385370b324cSopenharmony_ci          *so << endl;
1386370b324cSopenharmony_ci          if (ecs->NumOpenArcWarnings != 0)
1387370b324cSopenharmony_ci            *so << "Warnings: " << ecs->NumOpenArcWarnings << endl;
1388370b324cSopenharmony_ci        }
1389370b324cSopenharmony_ci      }
1390370b324cSopenharmony_ci
1391370b324cSopenharmony_ci      if (ecs->NumOpenArcErrors != 0)
1392370b324cSopenharmony_ci      {
1393370b324cSopenharmony_ci        isError = true;
1394370b324cSopenharmony_ci        if (so)
1395370b324cSopenharmony_ci        {
1396370b324cSopenharmony_ci          *so << endl;
1397370b324cSopenharmony_ci          if (ecs->NumOpenArcErrors != 0)
1398370b324cSopenharmony_ci            *so << "Open Errors: " << ecs->NumOpenArcErrors << endl;
1399370b324cSopenharmony_ci        }
1400370b324cSopenharmony_ci      }
1401370b324cSopenharmony_ci
1402370b324cSopenharmony_ci      if (isError)
1403370b324cSopenharmony_ci        retCode = NExitCode::kFatalError;
1404370b324cSopenharmony_ci
1405370b324cSopenharmony_ci      if (so) {
1406370b324cSopenharmony_ci      if (ecs->NumArcsWithError != 0 || ecs->NumFileErrors != 0)
1407370b324cSopenharmony_ci      {
1408370b324cSopenharmony_ci        // if (ecs->NumArchives > 1)
1409370b324cSopenharmony_ci        {
1410370b324cSopenharmony_ci          *so << endl;
1411370b324cSopenharmony_ci          if (ecs->NumFileErrors != 0)
1412370b324cSopenharmony_ci            *so << "Sub items Errors: " << ecs->NumFileErrors << endl;
1413370b324cSopenharmony_ci        }
1414370b324cSopenharmony_ci      }
1415370b324cSopenharmony_ci      else if (hresultMain == S_OK)
1416370b324cSopenharmony_ci      {
1417370b324cSopenharmony_ci        if (stat.NumFolders != 0)
1418370b324cSopenharmony_ci          *so << "Folders: " << stat.NumFolders << endl;
1419370b324cSopenharmony_ci        if (stat.NumFiles != 1 || stat.NumFolders != 0 || stat.NumAltStreams != 0)
1420370b324cSopenharmony_ci          *so << "Files: " << stat.NumFiles << endl;
1421370b324cSopenharmony_ci        if (stat.NumAltStreams != 0)
1422370b324cSopenharmony_ci        {
1423370b324cSopenharmony_ci          *so << "Alternate Streams: " << stat.NumAltStreams << endl;
1424370b324cSopenharmony_ci          *so << "Alternate Streams Size: " << stat.AltStreams_UnpackSize << endl;
1425370b324cSopenharmony_ci        }
1426370b324cSopenharmony_ci
1427370b324cSopenharmony_ci        *so
1428370b324cSopenharmony_ci          << "Size:       " << stat.UnpackSize << endl
1429370b324cSopenharmony_ci          << "Compressed: " << stat.PackSize << endl;
1430370b324cSopenharmony_ci        if (hashCalc)
1431370b324cSopenharmony_ci        {
1432370b324cSopenharmony_ci          *so << endl;
1433370b324cSopenharmony_ci          PrintHashStat(*so, hb);
1434370b324cSopenharmony_ci        }
1435370b324cSopenharmony_ci      }
1436370b324cSopenharmony_ci      } // if (so)
1437370b324cSopenharmony_ci    }
1438370b324cSopenharmony_ci    else // if_(!isExtractGroupCommand)
1439370b324cSopenharmony_ci    {
1440370b324cSopenharmony_ci      UInt64 numErrors = 0;
1441370b324cSopenharmony_ci      UInt64 numWarnings = 0;
1442370b324cSopenharmony_ci
1443370b324cSopenharmony_ci      // options.ExtractNtOptions.StoreAltStreams = true, if -sns[-] is not definmed
1444370b324cSopenharmony_ci
1445370b324cSopenharmony_ci      CListOptions lo;
1446370b324cSopenharmony_ci      lo.ExcludeDirItems = options.Censor.ExcludeDirItems;
1447370b324cSopenharmony_ci      lo.ExcludeFileItems = options.Censor.ExcludeFileItems;
1448370b324cSopenharmony_ci
1449370b324cSopenharmony_ci      hresultMain = ListArchives(
1450370b324cSopenharmony_ci          lo,
1451370b324cSopenharmony_ci          codecs,
1452370b324cSopenharmony_ci          types,
1453370b324cSopenharmony_ci          excludedFormats,
1454370b324cSopenharmony_ci          options.StdInMode,
1455370b324cSopenharmony_ci          ArchivePathsSorted,
1456370b324cSopenharmony_ci          ArchivePathsFullSorted,
1457370b324cSopenharmony_ci          options.ExtractOptions.NtOptions.AltStreams.Val,
1458370b324cSopenharmony_ci          options.AltStreams.Val, // we don't want to show AltStreams by default
1459370b324cSopenharmony_ci          options.Censor.Pairs.Front().Head,
1460370b324cSopenharmony_ci          options.EnableHeaders,
1461370b324cSopenharmony_ci          options.TechMode,
1462370b324cSopenharmony_ci          #ifndef Z7_NO_CRYPTO
1463370b324cSopenharmony_ci          options.PasswordEnabled,
1464370b324cSopenharmony_ci          options.Password,
1465370b324cSopenharmony_ci          #endif
1466370b324cSopenharmony_ci          &options.Properties,
1467370b324cSopenharmony_ci          numErrors, numWarnings);
1468370b324cSopenharmony_ci
1469370b324cSopenharmony_ci      if (options.EnableHeaders)
1470370b324cSopenharmony_ci        if (numWarnings > 0)
1471370b324cSopenharmony_ci          g_StdOut << endl << "Warnings: " << numWarnings << endl;
1472370b324cSopenharmony_ci
1473370b324cSopenharmony_ci      if (numErrors > 0)
1474370b324cSopenharmony_ci      {
1475370b324cSopenharmony_ci        if (options.EnableHeaders)
1476370b324cSopenharmony_ci          g_StdOut << endl << "Errors: " << numErrors << endl;
1477370b324cSopenharmony_ci        retCode = NExitCode::kFatalError;
1478370b324cSopenharmony_ci      }
1479370b324cSopenharmony_ci    } // if_(isExtractGroupCommand)
1480370b324cSopenharmony_ci    } // if_(hresultMain == S_OK)
1481370b324cSopenharmony_ci  }
1482370b324cSopenharmony_ci  else if (options.Command.IsFromUpdateGroup())
1483370b324cSopenharmony_ci  {
1484370b324cSopenharmony_ci    CUpdateOptions &uo = options.UpdateOptions;
1485370b324cSopenharmony_ci    if (uo.SfxMode && uo.SfxModule.IsEmpty())
1486370b324cSopenharmony_ci      uo.SfxModule = kDefaultSfxModule;
1487370b324cSopenharmony_ci
1488370b324cSopenharmony_ci    COpenCallbackConsole openCallback;
1489370b324cSopenharmony_ci    openCallback.Init(g_StdStream, g_ErrStream, percentsStream);
1490370b324cSopenharmony_ci
1491370b324cSopenharmony_ci    #ifndef Z7_NO_CRYPTO
1492370b324cSopenharmony_ci    bool passwordIsDefined =
1493370b324cSopenharmony_ci        (options.PasswordEnabled && !options.Password.IsEmpty());
1494370b324cSopenharmony_ci    openCallback.PasswordIsDefined = passwordIsDefined;
1495370b324cSopenharmony_ci    openCallback.Password = options.Password;
1496370b324cSopenharmony_ci    #endif
1497370b324cSopenharmony_ci
1498370b324cSopenharmony_ci    CUpdateCallbackConsole callback;
1499370b324cSopenharmony_ci    callback.LogLevel = options.LogLevel;
1500370b324cSopenharmony_ci    callback.PercentsNameLevel = percentsNameLevel;
1501370b324cSopenharmony_ci
1502370b324cSopenharmony_ci    if (percentsStream)
1503370b324cSopenharmony_ci      callback.SetWindowWidth(consoleWidth);
1504370b324cSopenharmony_ci
1505370b324cSopenharmony_ci    #ifndef Z7_NO_CRYPTO
1506370b324cSopenharmony_ci    callback.PasswordIsDefined = passwordIsDefined;
1507370b324cSopenharmony_ci    callback.AskPassword = (options.PasswordEnabled && options.Password.IsEmpty());
1508370b324cSopenharmony_ci    callback.Password = options.Password;
1509370b324cSopenharmony_ci    #endif
1510370b324cSopenharmony_ci
1511370b324cSopenharmony_ci    callback.StdOutMode = uo.StdOutMode;
1512370b324cSopenharmony_ci    callback.Init(
1513370b324cSopenharmony_ci      // NULL,
1514370b324cSopenharmony_ci      g_StdStream, g_ErrStream, percentsStream);
1515370b324cSopenharmony_ci
1516370b324cSopenharmony_ci    CUpdateErrorInfo errorInfo;
1517370b324cSopenharmony_ci
1518370b324cSopenharmony_ci    /*
1519370b324cSopenharmony_ci    if (!uo.Init(codecs, types, options.ArchiveName))
1520370b324cSopenharmony_ci      throw kUnsupportedUpdateArcType;
1521370b324cSopenharmony_ci    */
1522370b324cSopenharmony_ci    hresultMain = UpdateArchive(codecs,
1523370b324cSopenharmony_ci        types,
1524370b324cSopenharmony_ci        options.ArchiveName,
1525370b324cSopenharmony_ci        options.Censor,
1526370b324cSopenharmony_ci        uo,
1527370b324cSopenharmony_ci        errorInfo, &openCallback, &callback, true);
1528370b324cSopenharmony_ci
1529370b324cSopenharmony_ci    callback.ClosePercents2();
1530370b324cSopenharmony_ci
1531370b324cSopenharmony_ci    CStdOutStream *se = g_StdStream;
1532370b324cSopenharmony_ci    if (!se)
1533370b324cSopenharmony_ci      se = g_ErrStream;
1534370b324cSopenharmony_ci
1535370b324cSopenharmony_ci    retCode = WarningsCheck(hresultMain, callback, errorInfo,
1536370b324cSopenharmony_ci        g_StdStream, se,
1537370b324cSopenharmony_ci        true // options.EnableHeaders
1538370b324cSopenharmony_ci        );
1539370b324cSopenharmony_ci  }
1540370b324cSopenharmony_ci  else if (options.Command.CommandType == NCommandType::kHash)
1541370b324cSopenharmony_ci  {
1542370b324cSopenharmony_ci    const CHashOptions &uo = options.HashOptions;
1543370b324cSopenharmony_ci
1544370b324cSopenharmony_ci    CHashCallbackConsole callback;
1545370b324cSopenharmony_ci    if (percentsStream)
1546370b324cSopenharmony_ci      callback.SetWindowWidth(consoleWidth);
1547370b324cSopenharmony_ci
1548370b324cSopenharmony_ci    callback.Init(g_StdStream, g_ErrStream, percentsStream);
1549370b324cSopenharmony_ci    callback.PrintHeaders = options.EnableHeaders;
1550370b324cSopenharmony_ci    callback.PrintFields = options.ListFields;
1551370b324cSopenharmony_ci
1552370b324cSopenharmony_ci    AString errorInfoString;
1553370b324cSopenharmony_ci    hresultMain = HashCalc(EXTERNAL_CODECS_VARS_L
1554370b324cSopenharmony_ci        options.Censor, uo,
1555370b324cSopenharmony_ci        errorInfoString, &callback);
1556370b324cSopenharmony_ci    CUpdateErrorInfo errorInfo;
1557370b324cSopenharmony_ci    errorInfo.Message = errorInfoString;
1558370b324cSopenharmony_ci    CStdOutStream *se = g_StdStream;
1559370b324cSopenharmony_ci    if (!se)
1560370b324cSopenharmony_ci      se = g_ErrStream;
1561370b324cSopenharmony_ci    retCode = WarningsCheck(hresultMain, callback, errorInfo, g_StdStream, se, options.EnableHeaders);
1562370b324cSopenharmony_ci  }
1563370b324cSopenharmony_ci  else
1564370b324cSopenharmony_ci    ShowMessageAndThrowException(kUserErrorMessage, NExitCode::kUserError);
1565370b324cSopenharmony_ci
1566370b324cSopenharmony_ci  if (options.ShowTime && g_StdStream)
1567370b324cSopenharmony_ci    PrintStat(
1568370b324cSopenharmony_ci      #ifndef _WIN32
1569370b324cSopenharmony_ci        startTime
1570370b324cSopenharmony_ci      #endif
1571370b324cSopenharmony_ci    );
1572370b324cSopenharmony_ci
1573370b324cSopenharmony_ci  ThrowException_if_Error(hresultMain);
1574370b324cSopenharmony_ci
1575370b324cSopenharmony_ci  return retCode;
1576370b324cSopenharmony_ci}
1577