Main.cpp (31948B)
1 // Main.cpp 2 3 #include "StdAfx.h" 4 5 #include "../../../Common/MyWindows.h" 6 7 #ifdef _WIN32 8 #include <Psapi.h> 9 #endif 10 11 #include "../../../../C/CpuArch.h" 12 13 #include "../../../Common/MyInitGuid.h" 14 15 #include "../../../Common/CommandLineParser.h" 16 #include "../../../Common/IntToString.h" 17 #include "../../../Common/MyException.h" 18 #include "../../../Common/StringConvert.h" 19 #include "../../../Common/StringToInt.h" 20 #include "../../../Common/UTFConvert.h" 21 22 #include "../../../Windows/ErrorMsg.h" 23 24 #include "../../../Windows/TimeUtils.h" 25 26 #include "../Common/ArchiveCommandLine.h" 27 #include "../Common/ExitCode.h" 28 #include "../Common/Extract.h" 29 30 #ifdef EXTERNAL_CODECS 31 #include "../Common/LoadCodecs.h" 32 #endif 33 34 #include "../../Common/RegisterCodec.h" 35 36 #include "BenchCon.h" 37 #include "ConsoleClose.h" 38 #include "ExtractCallbackConsole.h" 39 #include "List.h" 40 #include "OpenCallbackConsole.h" 41 #include "UpdateCallbackConsole.h" 42 43 #include "HashCon.h" 44 45 #ifdef PROG_VARIANT_R 46 #include "../../../../C/7zVersion.h" 47 #else 48 #include "../../MyVersion.h" 49 #endif 50 51 using namespace NWindows; 52 using namespace NFile; 53 using namespace NCommandLineParser; 54 55 #ifdef _WIN32 56 HINSTANCE g_hInstance = 0; 57 #endif 58 59 extern bool g_LargePagesMode; 60 61 extern CStdOutStream *g_StdStream; 62 extern CStdOutStream *g_ErrStream; 63 64 extern unsigned g_NumCodecs; 65 extern const CCodecInfo *g_Codecs[]; 66 67 extern unsigned g_NumHashers; 68 extern const CHasherInfo *g_Hashers[]; 69 70 static const char * const kCopyrightString = "\n7-Zip" 71 #ifndef EXTERNAL_CODECS 72 #ifdef PROG_VARIANT_R 73 " (r)" 74 #else 75 " (a)" 76 #endif 77 #endif 78 79 " " MY_VERSION_CPU 80 " : " MY_COPYRIGHT_DATE "\n\n"; 81 82 static const char * const kHelpString = 83 "Usage: 7z" 84 #ifndef EXTERNAL_CODECS 85 #ifdef PROG_VARIANT_R 86 "r" 87 #else 88 "a" 89 #endif 90 #endif 91 " <command> [<switches>...] <archive_name> [<file_names>...]\n" 92 "\n" 93 "<Commands>\n" 94 " a : Add files to archive\n" 95 " b : Benchmark\n" 96 " d : Delete files from archive\n" 97 " e : Extract files from archive (without using directory names)\n" 98 " h : Calculate hash values for files\n" 99 " i : Show information about supported formats\n" 100 " l : List contents of archive\n" 101 " rn : Rename files in archive\n" 102 " t : Test integrity of archive\n" 103 " u : Update files to archive\n" 104 " x : eXtract files with full paths\n" 105 "\n" 106 "<Switches>\n" 107 " -- : Stop switches parsing\n" 108 " @listfile : set path to listfile that contains file names\n" 109 " -ai[r[-|0]]{@listfile|!wildcard} : Include archives\n" 110 " -ax[r[-|0]]{@listfile|!wildcard} : eXclude archives\n" 111 " -ao{a|s|t|u} : set Overwrite mode\n" 112 " -an : disable archive_name field\n" 113 " -bb[0-3] : set output log level\n" 114 " -bd : disable progress indicator\n" 115 " -bs{o|e|p}{0|1|2} : set output stream for output/error/progress line\n" 116 " -bt : show execution time statistics\n" 117 " -i[r[-|0]]{@listfile|!wildcard} : Include filenames\n" 118 " -m{Parameters} : set compression Method\n" 119 " -mmt[N] : set number of CPU threads\n" 120 " -mx[N] : set compression level: -mx1 (fastest) ... -mx9 (ultra)\n" 121 " -o{Directory} : set Output directory\n" 122 #ifndef _NO_CRYPTO 123 " -p{Password} : set Password\n" 124 #endif 125 " -r[-|0] : Recurse subdirectories\n" 126 " -sa{a|e|s} : set Archive name mode\n" 127 " -scc{UTF-8|WIN|DOS} : set charset for for console input/output\n" 128 " -scs{UTF-8|UTF-16LE|UTF-16BE|WIN|DOS|{id}} : set charset for list files\n" 129 " -scrc[CRC32|CRC64|SHA1|SHA256|*] : set hash function for x, e, h commands\n" 130 " -sdel : delete files after compression\n" 131 " -seml[.] : send archive by email\n" 132 " -sfx[{name}] : Create SFX archive\n" 133 " -si[{name}] : read data from stdin\n" 134 " -slp : set Large Pages mode\n" 135 " -slt : show technical information for l (List) command\n" 136 " -snh : store hard links as links\n" 137 " -snl : store symbolic links as links\n" 138 " -sni : store NT security information\n" 139 " -sns[-] : store NTFS alternate streams\n" 140 " -so : write data to stdout\n" 141 " -spd : disable wildcard matching for file names\n" 142 " -spe : eliminate duplication of root folder for extract command\n" 143 " -spf : use fully qualified file paths\n" 144 " -ssc[-] : set sensitive case mode\n" 145 " -sse : stop archive creating, if it can't open some input file\n" 146 " -ssw : compress shared files\n" 147 " -stl : set archive timestamp from the most recently modified file\n" 148 " -stm{HexMask} : set CPU thread affinity mask (hexadecimal number)\n" 149 " -stx{Type} : exclude archive type\n" 150 " -t{Type} : Set type of archive\n" 151 " -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName] : Update options\n" 152 " -v{Size}[b|k|m|g] : Create volumes\n" 153 " -w[{path}] : assign Work directory. Empty path means a temporary directory\n" 154 " -x[r[-|0]]{@listfile|!wildcard} : eXclude filenames\n" 155 " -y : assume Yes on all queries\n"; 156 157 // --------------------------- 158 // exception messages 159 160 static const char * const kEverythingIsOk = "Everything is Ok"; 161 static const char * const kUserErrorMessage = "Incorrect command line"; 162 static const char * const kNoFormats = "7-Zip cannot find the code that works with archives."; 163 static const char * const kUnsupportedArcTypeMessage = "Unsupported archive type"; 164 // static const char * const kUnsupportedUpdateArcType = "Can't create archive for that type"; 165 166 #define kDefaultSfxModule "7zCon.sfx" 167 168 static void ShowMessageAndThrowException(LPCSTR message, NExitCode::EEnum code) 169 { 170 if (g_ErrStream) 171 *g_ErrStream << endl << "ERROR: " << message << endl; 172 throw code; 173 } 174 175 #ifndef _WIN32 176 static void GetArguments(int numArgs, const char *args[], UStringVector &parts) 177 { 178 parts.Clear(); 179 for (int i = 0; i < numArgs; i++) 180 { 181 UString s = MultiByteToUnicodeString(args[i]); 182 parts.Add(s); 183 } 184 } 185 #endif 186 187 static void ShowCopyrightAndHelp(CStdOutStream *so, bool needHelp) 188 { 189 if (!so) 190 return; 191 *so << kCopyrightString; 192 // *so << "# CPUs: " << (UInt64)NWindows::NSystem::GetNumberOfProcessors() << endl; 193 if (needHelp) 194 *so << kHelpString; 195 } 196 197 198 static void PrintStringRight(CStdOutStream &so, const char *s, unsigned size) 199 { 200 unsigned len = MyStringLen(s); 201 for (unsigned i = len; i < size; i++) 202 so << ' '; 203 so << s; 204 } 205 206 static void PrintUInt32(CStdOutStream &so, UInt32 val, unsigned size) 207 { 208 char s[16]; 209 ConvertUInt32ToString(val, s); 210 PrintStringRight(so, s, size); 211 } 212 213 static void PrintLibIndex(CStdOutStream &so, int libIndex) 214 { 215 if (libIndex >= 0) 216 PrintUInt32(so, libIndex, 2); 217 else 218 so << " "; 219 so << ' '; 220 } 221 222 static void PrintString(CStdOutStream &so, const UString &s, unsigned size) 223 { 224 unsigned len = s.Len(); 225 so << s; 226 for (unsigned i = len; i < size; i++) 227 so << ' '; 228 } 229 230 static inline char GetHex(unsigned val) 231 { 232 return (char)((val < 10) ? ('0' + val) : ('A' + (val - 10))); 233 } 234 235 static void PrintWarningsPaths(const CErrorPathCodes &pc, CStdOutStream &so) 236 { 237 FOR_VECTOR(i, pc.Paths) 238 { 239 so.NormalizePrint_UString(pc.Paths[i]); 240 so << " : "; 241 so << NError::MyFormatMessage(pc.Codes[i]) << endl; 242 } 243 so << "----------------" << endl; 244 } 245 246 static int WarningsCheck(HRESULT result, const CCallbackConsoleBase &callback, 247 const CUpdateErrorInfo &errorInfo, 248 CStdOutStream *so, 249 CStdOutStream *se, 250 bool showHeaders) 251 { 252 int exitCode = NExitCode::kSuccess; 253 254 if (callback.ScanErrors.Paths.Size() != 0) 255 { 256 if (se) 257 { 258 *se << endl; 259 *se << "Scan WARNINGS for files and folders:" << endl << endl; 260 PrintWarningsPaths(callback.ScanErrors, *se); 261 *se << "Scan WARNINGS: " << callback.ScanErrors.Paths.Size(); 262 *se << endl; 263 } 264 exitCode = NExitCode::kWarning; 265 } 266 267 if (result != S_OK || errorInfo.ThereIsError()) 268 { 269 if (se) 270 { 271 UString message; 272 if (!errorInfo.Message.IsEmpty()) 273 { 274 message += errorInfo.Message.Ptr(); 275 message.Add_LF(); 276 } 277 { 278 FOR_VECTOR(i, errorInfo.FileNames) 279 { 280 message += fs2us(errorInfo.FileNames[i]); 281 message.Add_LF(); 282 } 283 } 284 if (errorInfo.SystemError != 0) 285 { 286 message += NError::MyFormatMessage(errorInfo.SystemError); 287 message.Add_LF(); 288 } 289 if (!message.IsEmpty()) 290 *se << L"\nError:\n" << message; 291 } 292 293 // we will work with (result) later 294 // throw CSystemException(result); 295 return NExitCode::kFatalError; 296 } 297 298 unsigned numErrors = callback.FailedFiles.Paths.Size(); 299 if (numErrors == 0) 300 { 301 if (showHeaders) 302 if (callback.ScanErrors.Paths.Size() == 0) 303 if (so) 304 { 305 if (se) 306 se->Flush(); 307 *so << kEverythingIsOk << endl; 308 } 309 } 310 else 311 { 312 if (se) 313 { 314 *se << endl; 315 *se << "WARNINGS for files:" << endl << endl; 316 PrintWarningsPaths(callback.FailedFiles, *se); 317 *se << "WARNING: Cannot open " << numErrors << " file"; 318 if (numErrors > 1) 319 *se << 's'; 320 *se << endl; 321 } 322 exitCode = NExitCode::kWarning; 323 } 324 325 return exitCode; 326 } 327 328 static void ThrowException_if_Error(HRESULT res) 329 { 330 if (res != S_OK) 331 throw CSystemException(res); 332 } 333 334 335 static void PrintNum(UInt64 val, unsigned numDigits, char c = ' ') 336 { 337 char temp[64]; 338 char *p = temp + 32; 339 ConvertUInt64ToString(val, p); 340 unsigned len = MyStringLen(p); 341 for (; len < numDigits; len++) 342 *--p = c; 343 *g_StdStream << p; 344 } 345 346 static void PrintTime(const char *s, UInt64 val, UInt64 total) 347 { 348 *g_StdStream << endl << s << " Time ="; 349 const UInt32 kFreq = 10000000; 350 UInt64 sec = val / kFreq; 351 PrintNum(sec, 6); 352 *g_StdStream << '.'; 353 UInt32 ms = (UInt32)(val - (sec * kFreq)) / (kFreq / 1000); 354 PrintNum(ms, 3, '0'); 355 356 while (val > ((UInt64)1 << 56)) 357 { 358 val >>= 1; 359 total >>= 1; 360 } 361 362 UInt64 percent = 0; 363 if (total != 0) 364 percent = val * 100 / total; 365 *g_StdStream << " ="; 366 PrintNum(percent, 5); 367 *g_StdStream << '%'; 368 } 369 370 #ifndef UNDER_CE 371 372 #define SHIFT_SIZE_VALUE(x, num) (((x) + (1 << (num)) - 1) >> (num)) 373 374 static void PrintMemUsage(const char *s, UInt64 val) 375 { 376 *g_StdStream << " " << s << " Memory ="; 377 PrintNum(SHIFT_SIZE_VALUE(val, 20), 7); 378 *g_StdStream << " MB"; 379 if (g_LargePagesMode) 380 *g_StdStream << " (LP)"; 381 } 382 383 EXTERN_C_BEGIN 384 typedef BOOL (WINAPI *Func_GetProcessMemoryInfo)(HANDLE Process, 385 PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb); 386 typedef BOOL (WINAPI *Func_QueryProcessCycleTime)(HANDLE Process, PULONG64 CycleTime); 387 EXTERN_C_END 388 389 #endif 390 391 static inline UInt64 GetTime64(const FILETIME &t) { return ((UInt64)t.dwHighDateTime << 32) | t.dwLowDateTime; } 392 393 static void PrintStat() 394 { 395 FILETIME creationTimeFT, exitTimeFT, kernelTimeFT, userTimeFT; 396 if (! 397 #ifdef UNDER_CE 398 ::GetThreadTimes(::GetCurrentThread() 399 #else 400 // NT 3.5 401 ::GetProcessTimes(::GetCurrentProcess() 402 #endif 403 , &creationTimeFT, &exitTimeFT, &kernelTimeFT, &userTimeFT)) 404 return; 405 FILETIME curTimeFT; 406 NTime::GetCurUtcFileTime(curTimeFT); 407 408 #ifndef UNDER_CE 409 410 PROCESS_MEMORY_COUNTERS m; 411 memset(&m, 0, sizeof(m)); 412 BOOL memDefined = FALSE; 413 BOOL cycleDefined = FALSE; 414 ULONG64 cycleTime = 0; 415 { 416 /* NT 4.0: GetProcessMemoryInfo() in Psapi.dll 417 Win7: new function K32GetProcessMemoryInfo() in kernel32.dll 418 It's faster to call kernel32.dll code than Psapi.dll code 419 GetProcessMemoryInfo() requires Psapi.lib 420 Psapi.lib in SDK7+ can link to K32GetProcessMemoryInfo in kernel32.dll 421 The program with K32GetProcessMemoryInfo will not work on systems before Win7 422 // memDefined = GetProcessMemoryInfo(GetCurrentProcess(), &m, sizeof(m)); 423 */ 424 425 HMODULE kern = ::GetModuleHandleW(L"kernel32.dll"); 426 Func_GetProcessMemoryInfo my_GetProcessMemoryInfo = (Func_GetProcessMemoryInfo) 427 ::GetProcAddress(kern, "K32GetProcessMemoryInfo"); 428 if (!my_GetProcessMemoryInfo) 429 { 430 HMODULE lib = LoadLibraryW(L"Psapi.dll"); 431 if (lib) 432 my_GetProcessMemoryInfo = (Func_GetProcessMemoryInfo)::GetProcAddress(lib, "GetProcessMemoryInfo"); 433 } 434 if (my_GetProcessMemoryInfo) 435 memDefined = my_GetProcessMemoryInfo(GetCurrentProcess(), &m, sizeof(m)); 436 // FreeLibrary(lib); 437 438 Func_QueryProcessCycleTime my_QueryProcessCycleTime = (Func_QueryProcessCycleTime) 439 ::GetProcAddress(kern, "QueryProcessCycleTime"); 440 if (my_QueryProcessCycleTime) 441 cycleDefined = my_QueryProcessCycleTime(GetCurrentProcess(), &cycleTime); 442 } 443 444 #endif 445 446 UInt64 curTime = GetTime64(curTimeFT); 447 UInt64 creationTime = GetTime64(creationTimeFT); 448 UInt64 kernelTime = GetTime64(kernelTimeFT); 449 UInt64 userTime = GetTime64(userTimeFT); 450 451 UInt64 totalTime = curTime - creationTime; 452 453 PrintTime("Kernel ", kernelTime, totalTime); 454 455 #ifndef UNDER_CE 456 if (cycleDefined) 457 { 458 *g_StdStream << " "; 459 PrintNum(cycleTime / 1000000, 22); 460 *g_StdStream << " MCycles"; 461 } 462 #endif 463 464 PrintTime("User ", userTime, totalTime); 465 466 PrintTime("Process", kernelTime + userTime, totalTime); 467 #ifndef UNDER_CE 468 if (memDefined) PrintMemUsage("Virtual ", m.PeakPagefileUsage); 469 #endif 470 471 PrintTime("Global ", totalTime, totalTime); 472 #ifndef UNDER_CE 473 if (memDefined) PrintMemUsage("Physical", m.PeakWorkingSetSize); 474 #endif 475 476 *g_StdStream << endl; 477 } 478 479 static void PrintHexId(CStdOutStream &so, UInt64 id) 480 { 481 char s[32]; 482 ConvertUInt64ToHex(id, s); 483 PrintStringRight(so, s, 8); 484 } 485 486 487 int Main2( 488 #ifndef _WIN32 489 int numArgs, char *args[] 490 #endif 491 ) 492 { 493 #if defined(_WIN32) && !defined(UNDER_CE) 494 SetFileApisToOEM(); 495 #endif 496 497 UStringVector commandStrings; 498 499 #ifdef _WIN32 500 NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings); 501 #else 502 GetArguments(numArgs, args, commandStrings); 503 #endif 504 505 #ifndef UNDER_CE 506 if (commandStrings.Size() > 0) 507 commandStrings.Delete(0); 508 #endif 509 510 if (commandStrings.Size() == 0) 511 { 512 ShowCopyrightAndHelp(g_StdStream, true); 513 return 0; 514 } 515 516 CArcCmdLineOptions options; 517 518 CArcCmdLineParser parser; 519 520 parser.Parse1(commandStrings, options); 521 522 g_StdOut.IsTerminalMode = options.IsStdOutTerminal; 523 g_StdErr.IsTerminalMode = options.IsStdErrTerminal; 524 525 if (options.Number_for_Out != k_OutStream_stdout) 526 g_StdStream = (options.Number_for_Out == k_OutStream_stderr ? &g_StdErr : NULL); 527 528 if (options.Number_for_Errors != k_OutStream_stderr) 529 g_ErrStream = (options.Number_for_Errors == k_OutStream_stdout ? &g_StdOut : NULL); 530 531 CStdOutStream *percentsStream = NULL; 532 if (options.Number_for_Percents != k_OutStream_disabled) 533 percentsStream = (options.Number_for_Percents == k_OutStream_stderr) ? &g_StdErr : &g_StdOut;; 534 535 if (options.HelpMode) 536 { 537 ShowCopyrightAndHelp(g_StdStream, true); 538 return 0; 539 } 540 541 if (options.EnableHeaders) 542 ShowCopyrightAndHelp(g_StdStream, false); 543 544 parser.Parse2(options); 545 546 unsigned percentsNameLevel = 1; 547 if (options.LogLevel == 0 || options.Number_for_Percents != options.Number_for_Out) 548 percentsNameLevel = 2; 549 550 unsigned consoleWidth = 80; 551 552 if (percentsStream) 553 { 554 #ifdef _WIN32 555 556 #if !defined(UNDER_CE) 557 CONSOLE_SCREEN_BUFFER_INFO consoleInfo; 558 if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo)) 559 consoleWidth = consoleInfo.dwSize.X; 560 #endif 561 562 #else 563 564 struct winsize w; 565 if (ioctl(0, TIOCGWINSZ, &w) == ) 566 consoleWidth = w.ws_col; 567 568 #endif 569 } 570 571 CREATE_CODECS_OBJECT 572 573 codecs->CaseSensitiveChange = options.CaseSensitiveChange; 574 codecs->CaseSensitive = options.CaseSensitive; 575 ThrowException_if_Error(codecs->Load()); 576 577 bool isExtractGroupCommand = options.Command.IsFromExtractGroup(); 578 579 if (codecs->Formats.Size() == 0 && 580 (isExtractGroupCommand 581 || options.Command.CommandType == NCommandType::kList 582 || options.Command.IsFromUpdateGroup())) 583 { 584 #ifdef EXTERNAL_CODECS 585 if (!codecs->MainDll_ErrorPath.IsEmpty()) 586 { 587 UString s ("Can't load module: "); 588 s += fs2us(codecs->MainDll_ErrorPath); 589 throw s; 590 } 591 #endif 592 593 throw kNoFormats; 594 } 595 596 CObjectVector<COpenType> types; 597 if (!ParseOpenTypes(*codecs, options.ArcType, types)) 598 throw kUnsupportedArcTypeMessage; 599 600 CIntVector excludedFormats; 601 FOR_VECTOR (k, options.ExcludedArcTypes) 602 { 603 CIntVector tempIndices; 604 if (!codecs->FindFormatForArchiveType(options.ExcludedArcTypes[k], tempIndices) 605 || tempIndices.Size() != 1) 606 throw kUnsupportedArcTypeMessage; 607 excludedFormats.AddToUniqueSorted(tempIndices[0]); 608 // excludedFormats.Sort(); 609 } 610 611 612 #ifdef EXTERNAL_CODECS 613 if (isExtractGroupCommand 614 || options.Command.CommandType == NCommandType::kHash 615 || options.Command.CommandType == NCommandType::kBenchmark) 616 ThrowException_if_Error(__externalCodecs.Load()); 617 #endif 618 619 int retCode = NExitCode::kSuccess; 620 HRESULT hresultMain = S_OK; 621 622 // bool showStat = options.ShowTime; 623 624 /* 625 if (!options.EnableHeaders || 626 options.TechMode) 627 showStat = false; 628 */ 629 630 631 if (options.Command.CommandType == NCommandType::kInfo) 632 { 633 CStdOutStream &so = (g_StdStream ? *g_StdStream : g_StdOut); 634 unsigned i; 635 636 #ifdef EXTERNAL_CODECS 637 so << endl << "Libs:" << endl; 638 for (i = 0; i < codecs->Libs.Size(); i++) 639 { 640 PrintLibIndex(so, i); 641 so << ' ' << codecs->Libs[i].Path << endl; 642 } 643 #endif 644 645 so << endl << "Formats:" << endl; 646 647 const char * const kArcFlags = "KSNFMGOPBELH"; 648 const unsigned kNumArcFlags = (unsigned)strlen(kArcFlags); 649 650 for (i = 0; i < codecs->Formats.Size(); i++) 651 { 652 const CArcInfoEx &arc = codecs->Formats[i]; 653 654 #ifdef EXTERNAL_CODECS 655 PrintLibIndex(so, arc.LibIndex); 656 #else 657 so << " "; 658 #endif 659 660 so << (char)(arc.UpdateEnabled ? 'C' : ' '); 661 662 for (unsigned b = 0; b < kNumArcFlags; b++) 663 { 664 so << (char) 665 ((arc.Flags & ((UInt32)1 << b)) != 0 ? kArcFlags[b] : ' '); 666 } 667 668 so << ' '; 669 PrintString(so, arc.Name, 8); 670 so << ' '; 671 UString s; 672 673 FOR_VECTOR (t, arc.Exts) 674 { 675 if (t != 0) 676 s.Add_Space(); 677 const CArcExtInfo &ext = arc.Exts[t]; 678 s += ext.Ext; 679 if (!ext.AddExt.IsEmpty()) 680 { 681 s += " ("; 682 s += ext.AddExt; 683 s += ')'; 684 } 685 } 686 687 PrintString(so, s, 13); 688 so << ' '; 689 690 if (arc.SignatureOffset != 0) 691 so << "offset=" << arc.SignatureOffset << ' '; 692 693 FOR_VECTOR(si, arc.Signatures) 694 { 695 if (si != 0) 696 so << " || "; 697 698 const CByteBuffer &sig = arc.Signatures[si]; 699 700 for (size_t j = 0; j < sig.Size(); j++) 701 { 702 if (j != 0) 703 so << ' '; 704 Byte b = sig[j]; 705 if (b > 0x20 && b < 0x80) 706 { 707 so << (char)b; 708 } 709 else 710 { 711 so << GetHex((b >> 4) & 0xF); 712 so << GetHex(b & 0xF); 713 } 714 } 715 } 716 so << endl; 717 } 718 719 so << endl << "Codecs:" << endl; // << "Lib ID Name" << endl; 720 721 for (i = 0; i < g_NumCodecs; i++) 722 { 723 const CCodecInfo &cod = *g_Codecs[i]; 724 725 PrintLibIndex(so, -1); 726 727 if (cod.NumStreams == 1) 728 so << ' '; 729 else 730 so << cod.NumStreams; 731 732 so << (char)(cod.CreateEncoder ? 'E' : ' '); 733 so << (char)(cod.CreateDecoder ? 'D' : ' '); 734 735 so << ' '; 736 PrintHexId(so, cod.Id); 737 so << ' ' << cod.Name << endl; 738 } 739 740 741 #ifdef EXTERNAL_CODECS 742 743 UInt32 numMethods; 744 if (codecs->GetNumMethods(&numMethods) == S_OK) 745 for (UInt32 j = 0; j < numMethods; j++) 746 { 747 PrintLibIndex(so, codecs->GetCodec_LibIndex(j)); 748 749 UInt32 numStreams = codecs->GetCodec_NumStreams(j); 750 if (numStreams == 1) 751 so << ' '; 752 else 753 so << numStreams; 754 755 so << (char)(codecs->GetCodec_EncoderIsAssigned(j) ? 'E' : ' '); 756 so << (char)(codecs->GetCodec_DecoderIsAssigned(j) ? 'D' : ' '); 757 758 so << ' '; 759 UInt64 id; 760 HRESULT res = codecs->GetCodec_Id(j, id); 761 if (res != S_OK) 762 id = (UInt64)(Int64)-1; 763 PrintHexId(so, id); 764 so << ' ' << codecs->GetCodec_Name(j) << endl; 765 } 766 767 #endif 768 769 770 so << endl << "Hashers:" << endl; // << " L Size ID Name" << endl; 771 772 for (i = 0; i < g_NumHashers; i++) 773 { 774 const CHasherInfo &codec = *g_Hashers[i]; 775 PrintLibIndex(so, -1); 776 PrintUInt32(so, codec.DigestSize, 4); 777 so << ' '; 778 PrintHexId(so, codec.Id); 779 so << ' ' << codec.Name << endl; 780 } 781 782 #ifdef EXTERNAL_CODECS 783 784 numMethods = codecs->GetNumHashers(); 785 for (UInt32 j = 0; j < numMethods; j++) 786 { 787 PrintLibIndex(so, codecs->GetHasherLibIndex(j)); 788 PrintUInt32(so, codecs->GetHasherDigestSize(j), 4); 789 so << ' '; 790 PrintHexId(so, codecs->GetHasherId(j)); 791 so << ' ' << codecs->GetHasherName(j) << endl; 792 } 793 794 #endif 795 796 } 797 else if (options.Command.CommandType == NCommandType::kBenchmark) 798 { 799 CStdOutStream &so = (g_StdStream ? *g_StdStream : g_StdOut); 800 hresultMain = BenchCon(EXTERNAL_CODECS_VARS_L 801 options.Properties, options.NumIterations, (FILE *)so); 802 if (hresultMain == S_FALSE) 803 { 804 if (g_ErrStream) 805 *g_ErrStream << "\nDecoding ERROR\n"; 806 retCode = NExitCode::kFatalError; 807 hresultMain = S_OK; 808 } 809 } 810 else if (isExtractGroupCommand || options.Command.CommandType == NCommandType::kList) 811 { 812 UStringVector ArchivePathsSorted; 813 UStringVector ArchivePathsFullSorted; 814 815 if (options.StdInMode) 816 { 817 ArchivePathsSorted.Add(options.ArcName_for_StdInMode); 818 ArchivePathsFullSorted.Add(options.ArcName_for_StdInMode); 819 } 820 else 821 { 822 CExtractScanConsole scan; 823 824 scan.Init(options.EnableHeaders ? g_StdStream : NULL, g_ErrStream, percentsStream); 825 scan.SetWindowWidth(consoleWidth); 826 827 if (g_StdStream && options.EnableHeaders) 828 *g_StdStream << "Scanning the drive for archives:" << endl; 829 830 CDirItemsStat st; 831 832 scan.StartScanning(); 833 834 hresultMain = EnumerateDirItemsAndSort( 835 options.arcCensor, 836 NWildcard::k_RelatPath, 837 UString(), // addPathPrefix 838 ArchivePathsSorted, 839 ArchivePathsFullSorted, 840 st, 841 &scan); 842 843 scan.CloseScanning(); 844 845 if (hresultMain == S_OK) 846 { 847 if (options.EnableHeaders) 848 scan.PrintStat(st); 849 } 850 else 851 { 852 /* 853 if (res != E_ABORT) 854 { 855 throw CSystemException(res); 856 // errorInfo.Message = "Scanning error"; 857 } 858 return res; 859 */ 860 } 861 } 862 863 if (hresultMain == S_OK) 864 if (isExtractGroupCommand) 865 { 866 CExtractCallbackConsole *ecs = new CExtractCallbackConsole; 867 CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs; 868 869 #ifndef _NO_CRYPTO 870 ecs->PasswordIsDefined = options.PasswordEnabled; 871 ecs->Password = options.Password; 872 #endif 873 874 ecs->Init(g_StdStream, g_ErrStream, percentsStream); 875 ecs->MultiArcMode = (ArchivePathsSorted.Size() > 1); 876 877 ecs->LogLevel = options.LogLevel; 878 ecs->PercentsNameLevel = percentsNameLevel; 879 880 if (percentsStream) 881 ecs->SetWindowWidth(consoleWidth); 882 883 /* 884 COpenCallbackConsole openCallback; 885 openCallback.Init(g_StdStream, g_ErrStream); 886 887 #ifndef _NO_CRYPTO 888 openCallback.PasswordIsDefined = options.PasswordEnabled; 889 openCallback.Password = options.Password; 890 #endif 891 */ 892 893 CExtractOptions eo; 894 (CExtractOptionsBase &)eo = options.ExtractOptions; 895 896 eo.StdInMode = options.StdInMode; 897 eo.StdOutMode = options.StdOutMode; 898 eo.YesToAll = options.YesToAll; 899 eo.TestMode = options.Command.IsTestCommand(); 900 901 #ifndef _SFX 902 eo.Properties = options.Properties; 903 #endif 904 905 UString errorMessage; 906 CDecompressStat stat; 907 CHashBundle hb; 908 IHashCalc *hashCalc = NULL; 909 910 if (!options.HashMethods.IsEmpty()) 911 { 912 hashCalc = &hb; 913 ThrowException_if_Error(hb.SetMethods(EXTERNAL_CODECS_VARS_L options.HashMethods)); 914 hb.Init(); 915 } 916 917 hresultMain = Extract( 918 codecs, 919 types, 920 excludedFormats, 921 ArchivePathsSorted, 922 ArchivePathsFullSorted, 923 options.Censor.Pairs.Front().Head, 924 eo, ecs, ecs, hashCalc, errorMessage, stat); 925 926 ecs->ClosePercents(); 927 928 if (!errorMessage.IsEmpty()) 929 { 930 if (g_ErrStream) 931 *g_ErrStream << endl << "ERROR:" << endl << errorMessage << endl; 932 if (hresultMain == S_OK) 933 hresultMain = E_FAIL; 934 } 935 936 CStdOutStream *so = g_StdStream; 937 938 bool isError = false; 939 940 if (so) 941 { 942 *so << endl; 943 944 if (ecs->NumTryArcs > 1) 945 { 946 *so << "Archives: " << ecs->NumTryArcs << endl; 947 *so << "OK archives: " << ecs->NumOkArcs << endl; 948 } 949 } 950 951 if (ecs->NumCantOpenArcs != 0) 952 { 953 isError = true; 954 if (so) 955 *so << "Can't open as archive: " << ecs->NumCantOpenArcs << endl; 956 } 957 958 if (ecs->NumArcsWithError != 0) 959 { 960 isError = true; 961 if (so) 962 *so << "Archives with Errors: " << ecs->NumArcsWithError << endl; 963 } 964 965 if (so) 966 { 967 if (ecs->NumArcsWithWarnings != 0) 968 *so << "Archives with Warnings: " << ecs->NumArcsWithWarnings << endl; 969 970 if (ecs->NumOpenArcWarnings != 0) 971 { 972 *so << endl; 973 if (ecs->NumOpenArcWarnings != 0) 974 *so << "Warnings: " << ecs->NumOpenArcWarnings << endl; 975 } 976 } 977 978 if (ecs->NumOpenArcErrors != 0) 979 { 980 isError = true; 981 if (so) 982 { 983 *so << endl; 984 if (ecs->NumOpenArcErrors != 0) 985 *so << "Open Errors: " << ecs->NumOpenArcErrors << endl; 986 } 987 } 988 989 if (isError) 990 retCode = NExitCode::kFatalError; 991 992 if (so) 993 if (ecs->NumArcsWithError != 0 || ecs->NumFileErrors != 0) 994 { 995 // if (ecs->NumArchives > 1) 996 { 997 *so << endl; 998 if (ecs->NumFileErrors != 0) 999 *so << "Sub items Errors: " << ecs->NumFileErrors << endl; 1000 } 1001 } 1002 else if (hresultMain == S_OK) 1003 { 1004 if (stat.NumFolders != 0) 1005 *so << "Folders: " << stat.NumFolders << endl; 1006 if (stat.NumFiles != 1 || stat.NumFolders != 0 || stat.NumAltStreams != 0) 1007 *so << "Files: " << stat.NumFiles << endl; 1008 if (stat.NumAltStreams != 0) 1009 { 1010 *so << "Alternate Streams: " << stat.NumAltStreams << endl; 1011 *so << "Alternate Streams Size: " << stat.AltStreams_UnpackSize << endl; 1012 } 1013 1014 *so 1015 << "Size: " << stat.UnpackSize << endl 1016 << "Compressed: " << stat.PackSize << endl; 1017 if (hashCalc) 1018 { 1019 *so << endl; 1020 PrintHashStat(*so, hb); 1021 } 1022 } 1023 } 1024 else 1025 { 1026 UInt64 numErrors = 0; 1027 UInt64 numWarnings = 0; 1028 1029 // options.ExtractNtOptions.StoreAltStreams = true, if -sns[-] is not definmed 1030 1031 hresultMain = ListArchives( 1032 codecs, 1033 types, 1034 excludedFormats, 1035 options.StdInMode, 1036 ArchivePathsSorted, 1037 ArchivePathsFullSorted, 1038 options.ExtractOptions.NtOptions.AltStreams.Val, 1039 options.AltStreams.Val, // we don't want to show AltStreams by default 1040 options.Censor.Pairs.Front().Head, 1041 options.EnableHeaders, 1042 options.TechMode, 1043 #ifndef _NO_CRYPTO 1044 options.PasswordEnabled, 1045 options.Password, 1046 #endif 1047 &options.Properties, 1048 numErrors, numWarnings); 1049 1050 if (options.EnableHeaders) 1051 if (numWarnings > 0) 1052 g_StdOut << endl << "Warnings: " << numWarnings << endl; 1053 1054 if (numErrors > 0) 1055 { 1056 if (options.EnableHeaders) 1057 g_StdOut << endl << "Errors: " << numErrors << endl; 1058 retCode = NExitCode::kFatalError; 1059 } 1060 } 1061 } 1062 else if (options.Command.IsFromUpdateGroup()) 1063 { 1064 CUpdateOptions &uo = options.UpdateOptions; 1065 if (uo.SfxMode && uo.SfxModule.IsEmpty()) 1066 uo.SfxModule = kDefaultSfxModule; 1067 1068 COpenCallbackConsole openCallback; 1069 openCallback.Init(g_StdStream, g_ErrStream, percentsStream); 1070 1071 #ifndef _NO_CRYPTO 1072 bool passwordIsDefined = 1073 (options.PasswordEnabled && !options.Password.IsEmpty()); 1074 openCallback.PasswordIsDefined = passwordIsDefined; 1075 openCallback.Password = options.Password; 1076 #endif 1077 1078 CUpdateCallbackConsole callback; 1079 callback.LogLevel = options.LogLevel; 1080 callback.PercentsNameLevel = percentsNameLevel; 1081 1082 if (percentsStream) 1083 callback.SetWindowWidth(consoleWidth); 1084 1085 #ifndef _NO_CRYPTO 1086 callback.PasswordIsDefined = passwordIsDefined; 1087 callback.AskPassword = (options.PasswordEnabled && options.Password.IsEmpty()); 1088 callback.Password = options.Password; 1089 #endif 1090 1091 callback.StdOutMode = uo.StdOutMode; 1092 callback.Init( 1093 // NULL, 1094 g_StdStream, g_ErrStream, percentsStream); 1095 1096 CUpdateErrorInfo errorInfo; 1097 1098 /* 1099 if (!uo.Init(codecs, types, options.ArchiveName)) 1100 throw kUnsupportedUpdateArcType; 1101 */ 1102 hresultMain = UpdateArchive(codecs, 1103 types, 1104 options.ArchiveName, 1105 options.Censor, 1106 uo, 1107 errorInfo, &openCallback, &callback, true); 1108 1109 callback.ClosePercents2(); 1110 1111 CStdOutStream *se = g_StdStream; 1112 if (!se) 1113 se = g_ErrStream; 1114 1115 retCode = WarningsCheck(hresultMain, callback, errorInfo, 1116 g_StdStream, se, 1117 true // options.EnableHeaders 1118 ); 1119 } 1120 else if (options.Command.CommandType == NCommandType::kHash) 1121 { 1122 const CHashOptions &uo = options.HashOptions; 1123 1124 CHashCallbackConsole callback; 1125 if (percentsStream) 1126 callback.SetWindowWidth(consoleWidth); 1127 1128 callback.Init(g_StdStream, g_ErrStream, percentsStream); 1129 callback.PrintHeaders = options.EnableHeaders; 1130 1131 AString errorInfoString; 1132 hresultMain = HashCalc(EXTERNAL_CODECS_VARS_L 1133 options.Censor, uo, 1134 errorInfoString, &callback); 1135 CUpdateErrorInfo errorInfo; 1136 errorInfo.Message = errorInfoString; 1137 CStdOutStream *se = g_StdStream; 1138 if (!se) 1139 se = g_ErrStream; 1140 retCode = WarningsCheck(hresultMain, callback, errorInfo, g_StdStream, se, options.EnableHeaders); 1141 } 1142 else 1143 ShowMessageAndThrowException(kUserErrorMessage, NExitCode::kUserError); 1144 1145 if (options.ShowTime && g_StdStream) 1146 PrintStat(); 1147 1148 ThrowException_if_Error(hresultMain); 1149 1150 return retCode; 1151 }