1 // Main.cpp
2
3 #include "StdAfx.h"
4
5 #include <Psapi.h>
6
7 #if defined( _WIN32) && defined( _7ZIP_LARGE_PAGES)
8 #include "../../../../C/Alloc.h"
9 #endif
10
11 #include "../../../Common/MyInitGuid.h"
12
13 #include "../../../Common/CommandLineParser.h"
14 #include "../../../Common/IntToString.h"
15 #include "../../../Common/MyException.h"
16 #include "../../../Common/StringConvert.h"
17 #include "../../../Common/StringToInt.h"
18
19 #include "../../../Windows/ErrorMsg.h"
20 #ifdef _WIN32
21 #include "../../../Windows/MemoryLock.h"
22 #endif
23
24 #ifndef _7ZIP_ST
25 #include "../../../Windows/Synchronization.h"
26 #endif
27
28 #include "../../../Windows/TimeUtils.h"
29
30 #include "../Common/ArchiveCommandLine.h"
31 #include "../Common/ExitCode.h"
32 #include "../Common/Extract.h"
33 #ifdef EXTERNAL_CODECS
34 #include "../Common/LoadCodecs.h"
35 #endif
36
37 #include "BenchCon.h"
38 #include "ConsoleClose.h"
39 #include "ExtractCallbackConsole.h"
40 #include "List.h"
41 #include "OpenCallbackConsole.h"
42 #include "UpdateCallbackConsole.h"
43
44 #include "HashCon.h"
45
46 #ifdef PROG_VARIANT_R
47 #include "../../../../C/7zVersion.h"
48 #else
49 #include "../../MyVersion.h"
50 #endif
51
52 using namespace NWindows;
53 using namespace NFile;
54 using namespace NCommandLineParser;
55
56 #ifdef _WIN32
57 HINSTANCE g_hInstance = 0;
58 #endif
59 extern CStdOutStream *g_StdStream;
60
61 static const char *kCopyrightString = "\n7-Zip"
62 #ifndef EXTERNAL_CODECS
63 #ifdef PROG_VARIANT_R
64 " (r)"
65 #else
66 " (a)"
67 #endif
68 #endif
69
70 #ifdef _WIN64
71 " [64]"
72 #endif
73
74 " " MY_VERSION_COPYRIGHT_DATE "\n";
75
76 static const char *kHelpString =
77 "\nUsage: 7z"
78 #ifndef EXTERNAL_CODECS
79 #ifdef PROG_VARIANT_R
80 "r"
81 #else
82 "a"
83 #endif
84 #endif
85 " <command> [<switches>...] <archive_name> [<file_names>...]\n"
86 " [<@listfiles...>]\n"
87 "\n"
88 "<Commands>\n"
89 " a : Add files to archive\n"
90 " b : Benchmark\n"
91 " d : Delete files from archive\n"
92 " e : Extract files from archive (without using directory names)\n"
93 " h : Calculate hash values for files\n"
94 " l : List contents of archive\n"
95 // " l[a|t][f] : List contents of archive\n"
96 // " a - with Additional fields\n"
97 // " t - with all fields\n"
98 // " f - with Full pathnames\n"
99 " rn : Rename files in archive\n"
100 " t : Test integrity of archive\n"
101 " u : Update files to archive\n"
102 " x : eXtract files with full paths\n"
103 "<Switches>\n"
104 " -- : Stop switches parsing\n"
105 " -ai[r[-|0]]{@listfile|!wildcard} : Include archives\n"
106 " -ax[r[-|0]]{@listfile|!wildcard} : eXclude archives\n"
107 " -bd : Disable percentage indicator\n"
108 " -i[r[-|0]]{@listfile|!wildcard} : Include filenames\n"
109 " -m{Parameters} : set compression Method\n"
110 " -o{Directory} : set Output directory\n"
111 #ifndef _NO_CRYPTO
112 " -p{Password} : set Password\n"
113 #endif
114 " -r[-|0] : Recurse subdirectories\n"
115 " -scs{UTF-8|UTF-16LE|UTF-16BE|WIN|DOS|{id}} : set charset for list files\n"
116 " -sfx[{name}] : Create SFX archive\n"
117 " -si[{name}] : read data from stdin\n"
118 " -slt : show technical information for l (List) command\n"
119 " -so : write data to stdout\n"
120 " -ssc[-] : set sensitive case mode\n"
121 " -ssw : compress shared files\n"
122 " -t{Type} : Set type of archive\n"
123 " -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName] : Update options\n"
124 " -v{Size}[b|k|m|g] : Create volumes\n"
125 " -w[{path}] : assign Work directory. Empty path means a temporary directory\n"
126 " -x[r[-|0]]]{@listfile|!wildcard} : eXclude filenames\n"
127 " -y : assume Yes on all queries\n";
128
129 // ---------------------------
130 // exception messages
131
132 static const char *kEverythingIsOk = "Everything is Ok";
133 static const char *kUserErrorMessage = "Incorrect command line";
134 static const char *kNoFormats = "7-Zip cannot find the code that works with archives.";
135 static const char *kUnsupportedArcTypeMessage = "Unsupported archive type";
136 // static const char *kUnsupportedUpdateArcType = "Can't create archive for that type";
137
138 static CFSTR kDefaultSfxModule = FTEXT("7zCon.sfx");
139
ShowMessageAndThrowException(CStdOutStream & s,LPCSTR message,NExitCode::EEnum code)140 static void ShowMessageAndThrowException(CStdOutStream &s, LPCSTR message, NExitCode::EEnum code)
141 {
142 s << endl << "Error: " << message << endl;
143 throw code;
144 }
145
146 #ifndef _WIN32
GetArguments(int numArgs,const char * args[],UStringVector & parts)147 static void GetArguments(int numArgs, const char *args[], UStringVector &parts)
148 {
149 parts.Clear();
150 for (int i = 0; i < numArgs; i++)
151 {
152 UString s = MultiByteToUnicodeString(args[i]);
153 parts.Add(s);
154 }
155 }
156 #endif
157
ShowCopyrightAndHelp(CStdOutStream & s,bool needHelp)158 static void ShowCopyrightAndHelp(CStdOutStream &s, bool needHelp)
159 {
160 s << kCopyrightString;
161 // s << "# CPUs: " << (UInt64)NWindows::NSystem::GetNumberOfProcessors() << "\n";
162 if (needHelp)
163 s << kHelpString;
164 }
165
166 #ifdef EXTERNAL_CODECS
167
PrintString(CStdOutStream & stdStream,const AString & s,int size)168 static void PrintString(CStdOutStream &stdStream, const AString &s, int size)
169 {
170 int len = s.Len();
171 for (int i = len; i < size; i++)
172 stdStream << ' ';
173 stdStream << s;
174 }
175
PrintUInt32(CStdOutStream & stdStream,UInt32 val,int size)176 static void PrintUInt32(CStdOutStream &stdStream, UInt32 val, int size)
177 {
178 char s[16];
179 ConvertUInt32ToString(val, s);
180 PrintString(stdStream, s, size);
181 }
182
PrintLibIndex(CStdOutStream & stdStream,int libIndex)183 static void PrintLibIndex(CStdOutStream &stdStream, int libIndex)
184 {
185 if (libIndex >= 0)
186 PrintUInt32(stdStream, libIndex, 2);
187 else
188 stdStream << " ";
189 stdStream << ' ';
190 }
191
192 #endif
193
PrintString(CStdOutStream & stdStream,const UString & s,int size)194 static void PrintString(CStdOutStream &stdStream, const UString &s, int size)
195 {
196 int len = s.Len();
197 stdStream << s;
198 for (int i = len; i < size; i++)
199 stdStream << ' ';
200 }
201
GetHex(unsigned val)202 static inline char GetHex(unsigned val)
203 {
204 return (char)((val < 10) ? ('0' + val) : ('A' + (val - 10)));
205 }
206
WarningsCheck(HRESULT result,const CCallbackConsoleBase & callback,const CErrorInfo & errorInfo,CStdOutStream & stdStream)207 static int WarningsCheck(HRESULT result, const CCallbackConsoleBase &callback,
208 const CErrorInfo &errorInfo, CStdOutStream &stdStream)
209 {
210 int exitCode = NExitCode::kSuccess;
211
212 if (callback.CantFindFiles.Size() > 0)
213 {
214 stdStream << endl;
215 stdStream << "WARNINGS for files:" << endl << endl;
216 unsigned numErrors = callback.CantFindFiles.Size();
217 for (unsigned i = 0; i < numErrors; i++)
218 {
219 stdStream << callback.CantFindFiles[i] << " : ";
220 stdStream << NError::MyFormatMessage(callback.CantFindCodes[i]) << endl;
221 }
222 stdStream << "----------------" << endl;
223 stdStream << "WARNING: Cannot find " << numErrors << " file";
224 if (numErrors > 1)
225 stdStream << "s";
226 stdStream << endl;
227 exitCode = NExitCode::kWarning;
228 }
229
230 if (result != S_OK)
231 {
232 UString message;
233 if (!errorInfo.Message.IsEmpty())
234 {
235 message += errorInfo.Message;
236 message += L"\n";
237 }
238 if (!errorInfo.FileName.IsEmpty())
239 {
240 message += fs2us(errorInfo.FileName);
241 message += L"\n";
242 }
243 if (!errorInfo.FileName2.IsEmpty())
244 {
245 message += fs2us(errorInfo.FileName2);
246 message += L"\n";
247 }
248 if (errorInfo.SystemError != 0)
249 {
250 message += NError::MyFormatMessage(errorInfo.SystemError);
251 message += L"\n";
252 }
253 if (!message.IsEmpty())
254 stdStream << L"\nError:\n" << message;
255
256 // we will work with (result) later
257 // throw CSystemException(result);
258 return NExitCode::kFatalError;
259 }
260
261 unsigned numErrors = callback.FailedFiles.Size();
262 if (numErrors == 0)
263 {
264 if (callback.CantFindFiles.Size() == 0)
265 stdStream << kEverythingIsOk << endl;
266 }
267 else
268 {
269 stdStream << endl;
270 stdStream << "WARNINGS for files:" << endl << endl;
271 for (unsigned i = 0; i < numErrors; i++)
272 {
273 stdStream << callback.FailedFiles[i] << " : ";
274 stdStream << NError::MyFormatMessage(callback.FailedCodes[i]) << endl;
275 }
276 stdStream << "----------------" << endl;
277 stdStream << "WARNING: Cannot open " << numErrors << " file";
278 if (numErrors > 1)
279 stdStream << "s";
280 stdStream << endl;
281 exitCode = NExitCode::kWarning;
282 }
283 return exitCode;
284 }
285
ThrowException_if_Error(HRESULT res)286 static void ThrowException_if_Error(HRESULT res)
287 {
288 if (res != S_OK)
289 throw CSystemException(res);
290 }
291
292
PrintNum(UInt64 val,unsigned numDigits,char c=' ')293 static void PrintNum(UInt64 val, unsigned numDigits, char c = ' ')
294 {
295 char temp[64];
296 char *p = temp + 32;
297 ConvertUInt64ToString(val, p);
298 unsigned len = MyStringLen(p);
299 for (; len < numDigits; len++)
300 *--p = c;
301 *g_StdStream << p;
302 }
303
PrintTime(const char * s,UInt64 val,UInt64 total)304 static void PrintTime(const char *s, UInt64 val, UInt64 total)
305 {
306 *g_StdStream << endl << s << " Time =";
307 const UInt32 kFreq = 10000000;
308 UInt64 sec = val / kFreq;
309 PrintNum(sec, 6);
310 *g_StdStream << '.';
311 UInt32 ms = (UInt32)(val - (sec * kFreq)) / (kFreq / 1000);
312 PrintNum(ms, 3, '0');
313
314 while (val > ((UInt64)1 << 56))
315 {
316 val >>= 1;
317 total >>= 1;
318 }
319
320 UInt64 percent = 0;
321 if (total != 0)
322 percent = val * 100 / total;
323 *g_StdStream << " =";
324 PrintNum(percent, 5);
325 *g_StdStream << '%';
326 }
327
328 #ifndef UNDER_CE
329
330 #define SHIFT_SIZE_VALUE(x, num) (((x) + (1 << (num)) - 1) >> (num))
331
PrintMemUsage(const char * s,UInt64 val)332 static void PrintMemUsage(const char *s, UInt64 val)
333 {
334 *g_StdStream << " " << s << " Memory =";
335 PrintNum(SHIFT_SIZE_VALUE(val, 20), 7);
336 *g_StdStream << " MB";
337 }
338
339 EXTERN_C_BEGIN
340 typedef BOOL (WINAPI *Func_GetProcessMemoryInfo)(HANDLE Process,
341 PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb);
342 EXTERN_C_END
343
344 #endif
345
GetTime64(const FILETIME & t)346 static inline UInt64 GetTime64(const FILETIME &t) { return ((UInt64)t.dwHighDateTime << 32) | t.dwLowDateTime; }
347
PrintStat()348 static void PrintStat()
349 {
350 FILETIME creationTimeFT, exitTimeFT, kernelTimeFT, userTimeFT;
351 if (!
352 #ifdef UNDER_CE
353 ::GetThreadTimes(::GetCurrentThread()
354 #else
355 // NT 3.5
356 ::GetProcessTimes(::GetCurrentProcess()
357 #endif
358 , &creationTimeFT, &exitTimeFT, &kernelTimeFT, &userTimeFT))
359 return;
360 FILETIME curTimeFT;
361 NTime::GetCurUtcFileTime(curTimeFT);
362
363 #ifndef UNDER_CE
364
365 PROCESS_MEMORY_COUNTERS m;
366 memset(&m, 0, sizeof(m));
367 BOOL memDefined = FALSE;
368 {
369 /* NT 4.0: GetProcessMemoryInfo() in Psapi.dll
370 Win7: new function K32GetProcessMemoryInfo() in kernel32.dll
371 It's faster to call kernel32.dll code than Psapi.dll code
372 GetProcessMemoryInfo() requires Psapi.lib
373 Psapi.lib in SDK7+ can link to K32GetProcessMemoryInfo in kernel32.dll
374 The program with K32GetProcessMemoryInfo will not work on systems before Win7
375 // memDefined = GetProcessMemoryInfo(GetCurrentProcess(), &m, sizeof(m));
376 */
377
378 Func_GetProcessMemoryInfo my_GetProcessMemoryInfo = (Func_GetProcessMemoryInfo)
379 ::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"), "K32GetProcessMemoryInfo");
380 if (!my_GetProcessMemoryInfo)
381 {
382 HMODULE lib = LoadLibraryW(L"Psapi.dll");
383 if (lib)
384 my_GetProcessMemoryInfo = (Func_GetProcessMemoryInfo)::GetProcAddress(lib, "GetProcessMemoryInfo");
385 }
386 if (my_GetProcessMemoryInfo)
387 memDefined = my_GetProcessMemoryInfo(GetCurrentProcess(), &m, sizeof(m));
388 // FreeLibrary(lib);
389 }
390
391 #endif
392
393 UInt64 curTime = GetTime64(curTimeFT);
394 UInt64 creationTime = GetTime64(creationTimeFT);
395 UInt64 kernelTime = GetTime64(kernelTimeFT);
396 UInt64 userTime = GetTime64(userTimeFT);
397
398 UInt64 totalTime = curTime - creationTime;
399
400 PrintTime("Kernel ", kernelTime, totalTime);
401 PrintTime("User ", userTime, totalTime);
402
403 PrintTime("Process", kernelTime + userTime, totalTime);
404 #ifndef UNDER_CE
405 if (memDefined) PrintMemUsage("Virtual ", m.PeakPagefileUsage);
406 #endif
407
408 PrintTime("Global ", totalTime, totalTime);
409 #ifndef UNDER_CE
410 if (memDefined) PrintMemUsage("Physical", m.PeakWorkingSetSize);
411 #endif
412
413 *g_StdStream << endl;
414 }
415
Main2(int numArgs,const char * args[])416 int Main2(
417 #ifndef _WIN32
418 int numArgs, const char *args[]
419 #endif
420 )
421 {
422 #if defined(_WIN32) && !defined(UNDER_CE)
423 SetFileApisToOEM();
424 #endif
425
426 UStringVector commandStrings;
427 #ifdef _WIN32
428 NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
429 #else
430 GetArguments(numArgs, args, commandStrings);
431 #endif
432
433 if (commandStrings.Size() == 1)
434 {
435 ShowCopyrightAndHelp(g_StdOut, true);
436 return 0;
437 }
438
439 commandStrings.Delete(0);
440
441 CArcCmdLineOptions options;
442
443 CArcCmdLineParser parser;
444
445 parser.Parse1(commandStrings, options);
446
447 if (options.HelpMode)
448 {
449 ShowCopyrightAndHelp(g_StdOut, true);
450 return 0;
451 }
452
453 #if defined(_WIN32) && !defined(UNDER_CE)
454 NSecurity::EnablePrivilege_SymLink();
455 #endif
456 #ifdef _7ZIP_LARGE_PAGES
457 if (options.LargePages)
458 {
459 SetLargePageSize();
460 #if defined(_WIN32) && !defined(UNDER_CE)
461 NSecurity::EnablePrivilege_LockMemory();
462 #endif
463 }
464 #endif
465
466 CStdOutStream &stdStream = options.StdOutMode ? g_StdErr : g_StdOut;
467 g_StdStream = &stdStream;
468
469 if (options.EnableHeaders)
470 ShowCopyrightAndHelp(stdStream, false);
471
472 parser.Parse2(options);
473
474 CCodecs *codecs = new CCodecs;
475 #ifdef EXTERNAL_CODECS
476 CExternalCodecs __externalCodecs;
477 __externalCodecs.GetCodecs = codecs;
478 __externalCodecs.GetHashers = codecs;
479 #else
480 CMyComPtr<IUnknown> compressCodecsInfo = codecs;
481 #endif
482 codecs->CaseSensitiveChange = options.CaseSensitiveChange;
483 codecs->CaseSensitive = options.CaseSensitive;
484 ThrowException_if_Error(codecs->Load());
485
486 bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
487
488 if (codecs->Formats.Size() == 0 &&
489 (isExtractGroupCommand
490 || options.Command.CommandType == NCommandType::kList
491 || options.Command.IsFromUpdateGroup()))
492 throw kNoFormats;
493
494 CObjectVector<COpenType> types;
495 if (!ParseOpenTypes(*codecs, options.ArcType, types))
496 throw kUnsupportedArcTypeMessage;
497
498 CIntVector excludedFormats;
499 FOR_VECTOR (k, options.ExcludedArcTypes)
500 {
501 CIntVector tempIndices;
502 if (!codecs->FindFormatForArchiveType(options.ExcludedArcTypes[k], tempIndices)
503 || tempIndices.Size() != 1)
504 throw kUnsupportedArcTypeMessage;
505 excludedFormats.AddToUniqueSorted(tempIndices[0]);
506 // excludedFormats.Sort();
507 }
508
509
510 #ifdef EXTERNAL_CODECS
511 if (isExtractGroupCommand
512 || options.Command.CommandType == NCommandType::kHash
513 || options.Command.CommandType == NCommandType::kBenchmark)
514 ThrowException_if_Error(__externalCodecs.LoadCodecs());
515 #endif
516
517 int retCode = NExitCode::kSuccess;
518 HRESULT hresultMain = S_OK;
519
520 bool showStat = true;
521 if (!options.EnableHeaders ||
522 options.TechMode)
523 showStat = false;
524
525
526 if (options.Command.CommandType == NCommandType::kInfo)
527 {
528 unsigned i;
529
530 #ifdef EXTERNAL_CODECS
531 stdStream << endl << "Libs:" << endl;
532 for (i = 0; i < codecs->Libs.Size(); i++)
533 {
534 PrintLibIndex(stdStream, i);
535 stdStream << ' ' << codecs->Libs[i].Path << endl;
536 }
537 #endif
538
539 stdStream << endl << "Formats:" << endl;
540
541 const char *kArcFlags = "KSNFMGOPBELH";
542 const unsigned kNumArcFlags = (unsigned)strlen(kArcFlags);
543
544 for (i = 0; i < codecs->Formats.Size(); i++)
545 {
546 const CArcInfoEx &arc = codecs->Formats[i];
547 #ifdef EXTERNAL_CODECS
548 PrintLibIndex(stdStream, arc.LibIndex);
549 #else
550 stdStream << " ";
551 #endif
552 stdStream << (char)(arc.UpdateEnabled ? 'C' : ' ');
553 for (unsigned b = 0; b < kNumArcFlags; b++)
554 {
555 stdStream << (char)
556 ((arc.Flags & ((UInt32)1 << b)) != 0 ? kArcFlags[b] : ' ');
557 }
558
559 stdStream << ' ';
560 PrintString(stdStream, arc.Name, 8);
561 stdStream << ' ';
562 UString s;
563 FOR_VECTOR (t, arc.Exts)
564 {
565 if (t != 0)
566 s += L' ';
567 const CArcExtInfo &ext = arc.Exts[t];
568 s += ext.Ext;
569 if (!ext.AddExt.IsEmpty())
570 {
571 s += L" (";
572 s += ext.AddExt;
573 s += L')';
574 }
575 }
576 PrintString(stdStream, s, 13);
577 stdStream << ' ';
578 if (arc.SignatureOffset != 0)
579 stdStream << "offset=" << arc.SignatureOffset << ' ';
580
581 FOR_VECTOR(si, arc.Signatures)
582 {
583 if (si != 0)
584 stdStream << " || ";
585
586 const CByteBuffer &sig = arc.Signatures[si];
587
588 for (size_t j = 0; j < sig.Size(); j++)
589 {
590 if (j != 0)
591 stdStream << ' ';
592 Byte b = sig[j];
593 if (b > 0x20 && b < 0x80)
594 {
595 stdStream << (char)b;
596 }
597 else
598 {
599 stdStream << GetHex((b >> 4) & 0xF);
600 stdStream << GetHex(b & 0xF);
601 }
602 }
603 }
604 stdStream << endl;
605 }
606
607 #ifdef EXTERNAL_CODECS
608
609 stdStream << endl << "Codecs:" << endl << "Lib ID Name" << endl;
610 UInt32 numMethods;
611 if (codecs->GetNumberOfMethods(&numMethods) == S_OK)
612 for (UInt32 j = 0; j < numMethods; j++)
613 {
614 PrintLibIndex(stdStream, codecs->GetCodecLibIndex(j));
615 stdStream << (char)(codecs->GetCodecEncoderIsAssigned(j) ? 'C' : ' ');
616 UInt64 id;
617 stdStream << " ";
618 HRESULT res = codecs->GetCodecId(j, id);
619 if (res != S_OK)
620 id = (UInt64)(Int64)-1;
621 char s[32];
622 ConvertUInt64ToHex(id, s);
623 PrintString(stdStream, s, 8);
624 stdStream << " " << codecs->GetCodecName(j) << endl;
625 }
626
627 stdStream << endl << "Hashers:" << endl << " L Size ID Name" << endl;
628 numMethods = codecs->GetNumHashers();
629 for (UInt32 j = 0; j < numMethods; j++)
630 {
631 PrintLibIndex(stdStream, codecs->GetHasherLibIndex(j));
632 PrintUInt32(stdStream, codecs->GetHasherDigestSize(j), 4);
633 stdStream << ' ';
634 char s[32];
635 ConvertUInt64ToHex(codecs->GetHasherId(j), s);
636 PrintString(stdStream, s, 6);
637 stdStream << " " << codecs->GetHasherName(j) << endl;
638 }
639
640 #endif
641
642 }
643 else if (options.Command.CommandType == NCommandType::kBenchmark)
644 {
645 hresultMain = BenchCon(EXTERNAL_CODECS_VARS
646 options.Properties, options.NumIterations, (FILE *)stdStream);
647 if (hresultMain == S_FALSE)
648 {
649 stdStream << "\nDecoding Error\n";
650 retCode = NExitCode::kFatalError;
651 hresultMain = S_OK;
652 }
653 }
654 else if (isExtractGroupCommand || options.Command.CommandType == NCommandType::kList)
655 {
656 if (isExtractGroupCommand)
657 {
658 CExtractCallbackConsole *ecs = new CExtractCallbackConsole;
659 CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
660
661 ecs->OutStream = &stdStream;
662
663 #ifndef _NO_CRYPTO
664 ecs->PasswordIsDefined = options.PasswordEnabled;
665 ecs->Password = options.Password;
666 #endif
667
668 ecs->Init();
669
670 COpenCallbackConsole openCallback;
671 openCallback.OutStream = &stdStream;
672
673 #ifndef _NO_CRYPTO
674 openCallback.PasswordIsDefined = options.PasswordEnabled;
675 openCallback.Password = options.Password;
676 #endif
677
678 CExtractOptions eo;
679 (CExtractOptionsBase &)eo = options.ExtractOptions;
680 eo.StdInMode = options.StdInMode;
681 eo.StdOutMode = options.StdOutMode;
682 eo.YesToAll = options.YesToAll;
683 eo.TestMode = options.Command.IsTestCommand();
684
685 #ifndef _SFX
686 eo.Properties = options.Properties;
687 #endif
688
689 UString errorMessage;
690 CDecompressStat stat;
691 CHashBundle hb;
692 IHashCalc *hashCalc = NULL;
693
694 if (!options.HashMethods.IsEmpty())
695 {
696 hashCalc = &hb;
697 ThrowException_if_Error(hb.SetMethods(EXTERNAL_CODECS_VARS options.HashMethods));
698 hb.Init();
699 }
700 hresultMain = Extract(
701 codecs,
702 types,
703 excludedFormats,
704 options.ArchivePathsSorted,
705 options.ArchivePathsFullSorted,
706 options.Censor.Pairs.Front().Head,
707 eo, &openCallback, ecs, hashCalc, errorMessage, stat);
708 if (!errorMessage.IsEmpty())
709 {
710 stdStream << endl << "Error: " << errorMessage;
711 if (hresultMain == S_OK)
712 hresultMain = E_FAIL;
713 }
714
715 stdStream << endl;
716
717 if (ecs->NumTryArcs > 1)
718 {
719 stdStream << "Archives: " << ecs->NumTryArcs << endl;
720 stdStream << "OK archives: " << ecs->NumOkArcs << endl;
721 }
722 bool isError = false;
723 if (ecs->NumCantOpenArcs != 0)
724 {
725 isError = true;
726 stdStream << "Can't open as archive: " << ecs->NumCantOpenArcs << endl;
727 }
728 if (ecs->NumArcsWithError != 0)
729 {
730 isError = true;
731 stdStream << "Archives with Errors: " << ecs->NumArcsWithError << endl;
732 }
733 if (ecs->NumArcsWithWarnings != 0)
734 stdStream << "Archives with Warnings: " << ecs->NumArcsWithWarnings << endl;
735
736 if (ecs->NumOpenArcWarnings != 0)
737 {
738 stdStream << endl;
739 if (ecs->NumOpenArcWarnings != 0)
740 stdStream << "Warnings: " << ecs->NumOpenArcWarnings << endl;
741 }
742
743 if (ecs->NumOpenArcErrors != 0)
744 {
745 isError = true;
746 stdStream << endl;
747 if (ecs->NumOpenArcErrors != 0)
748 stdStream << "Open Errors: " << ecs->NumOpenArcErrors << endl;
749 }
750
751 if (isError)
752 retCode = NExitCode::kFatalError;
753
754 if (ecs->NumArcsWithError != 0 || ecs->NumFileErrors != 0)
755 {
756 // if (ecs->NumArchives > 1)
757 {
758 stdStream << endl;
759 if (ecs->NumFileErrors != 0)
760 stdStream << "Sub items Errors: " << ecs->NumFileErrors << endl;
761 }
762 }
763 else if (hresultMain == S_OK)
764 {
765
766 if (stat.NumFolders != 0)
767 stdStream << "Folders: " << stat.NumFolders << endl;
768 if (stat.NumFiles != 1 || stat.NumFolders != 0 || stat.NumAltStreams != 0)
769 stdStream << "Files: " << stat.NumFiles << endl;
770 if (stat.NumAltStreams != 0)
771 {
772 stdStream << "Alternate Streams: " << stat.NumAltStreams << endl;
773 stdStream << "Alternate Streams Size: " << stat.AltStreams_UnpackSize << endl;
774 }
775
776 stdStream
777 << "Size: " << stat.UnpackSize << endl
778 << "Compressed: " << stat.PackSize << endl;
779 if (hashCalc)
780 PrintHashStat(stdStream, hb);
781 }
782 }
783 else
784 {
785 UInt64 numErrors = 0;
786 UInt64 numWarnings = 0;
787
788 // options.ExtractNtOptions.StoreAltStreams = true, if -sns[-] is not definmed
789
790 hresultMain = ListArchives(
791 codecs,
792 types,
793 excludedFormats,
794 options.StdInMode,
795 options.ArchivePathsSorted,
796 options.ArchivePathsFullSorted,
797 options.ExtractOptions.NtOptions.AltStreams.Val,
798 options.AltStreams.Val, // we don't want to show AltStreams by default
799 options.Censor.Pairs.Front().Head,
800 options.EnableHeaders,
801 options.TechMode,
802 #ifndef _NO_CRYPTO
803 options.PasswordEnabled,
804 options.Password,
805 #endif
806 &options.Properties,
807 numErrors, numWarnings);
808
809 if (options.EnableHeaders)
810 if (numWarnings > 0)
811 g_StdOut << endl << "Warnings: " << numWarnings << endl;
812 if (numErrors > 0)
813 {
814 if (options.EnableHeaders)
815 g_StdOut << endl << "Errors: " << numErrors << endl;
816 retCode = NExitCode::kFatalError;
817 }
818 }
819 }
820 else if (options.Command.IsFromUpdateGroup())
821 {
822 CUpdateOptions &uo = options.UpdateOptions;
823 if (uo.SfxMode && uo.SfxModule.IsEmpty())
824 uo.SfxModule = kDefaultSfxModule;
825
826 COpenCallbackConsole openCallback;
827 openCallback.OutStream = &stdStream;
828
829 #ifndef _NO_CRYPTO
830 bool passwordIsDefined =
831 options.PasswordEnabled && !options.Password.IsEmpty();
832 openCallback.PasswordIsDefined = passwordIsDefined;
833 openCallback.Password = options.Password;
834 #endif
835
836 CUpdateCallbackConsole callback;
837 callback.EnablePercents = options.EnablePercents;
838
839 #ifndef _NO_CRYPTO
840 callback.PasswordIsDefined = passwordIsDefined;
841 callback.AskPassword = options.PasswordEnabled && options.Password.IsEmpty();
842 callback.Password = options.Password;
843 #endif
844 callback.StdOutMode = uo.StdOutMode;
845 callback.Init(&stdStream);
846
847 CUpdateErrorInfo errorInfo;
848
849 /*
850 if (!uo.Init(codecs, types, options.ArchiveName))
851 throw kUnsupportedUpdateArcType;
852 */
853 hresultMain = UpdateArchive(codecs,
854 types,
855 options.ArchiveName,
856 options.Censor,
857 uo,
858 errorInfo, &openCallback, &callback, true);
859 retCode = WarningsCheck(hresultMain, callback, errorInfo, stdStream);
860 }
861 else if (options.Command.CommandType == NCommandType::kHash)
862 {
863 const CHashOptions &uo = options.HashOptions;
864
865 CHashCallbackConsole callback;
866 callback.EnablePercents = options.EnablePercents;
867
868 callback.Init(&stdStream);
869
870 UString errorInfoString;
871 hresultMain = HashCalc(EXTERNAL_CODECS_VARS
872 options.Censor, uo,
873 errorInfoString, &callback);
874 CErrorInfo errorInfo;
875 errorInfo.Message = errorInfoString;
876 retCode = WarningsCheck(hresultMain, callback, errorInfo, stdStream);
877 }
878 else
879 ShowMessageAndThrowException(stdStream, kUserErrorMessage, NExitCode::kUserError);
880
881 if (showStat)
882 PrintStat();
883
884 ThrowException_if_Error(hresultMain);
885
886 return retCode;
887 }
888