misc/libphysfs/lzma/CPP/7zip/UI/Console/Main.cpp
branchui-scaling
changeset 15283 c4fd2813b127
parent 13390 0135e64c6c66
parent 15279 7ab5cf405686
child 15663 d92eeb468dad
equal deleted inserted replaced
13390:0135e64c6c66 15283:c4fd2813b127
     1 // Main.cpp
       
     2 
       
     3 #include "StdAfx.h"
       
     4 
       
     5 #include "Common/MyInitGuid.h"
       
     6 
       
     7 #include "Common/CommandLineParser.h"
       
     8 #include "Common/MyException.h"
       
     9 #include "Common/IntToString.h"
       
    10 #include "Common/StdOutStream.h"
       
    11 #include "Common/StringConvert.h"
       
    12 #include "Common/StringToInt.h"
       
    13 
       
    14 #include "Windows/FileDir.h"
       
    15 #include "Windows/FileName.h"
       
    16 #include "Windows/Defs.h"
       
    17 #include "Windows/Error.h"
       
    18 #ifdef _WIN32
       
    19 #include "Windows/MemoryLock.h"
       
    20 #endif
       
    21 
       
    22 #include "../../IPassword.h"
       
    23 #include "../../ICoder.h"
       
    24 #include "../Common/UpdateAction.h"
       
    25 #include "../Common/Update.h"
       
    26 #include "../Common/Extract.h"
       
    27 #include "../Common/ArchiveCommandLine.h"
       
    28 #include "../Common/ExitCode.h"
       
    29 #ifdef EXTERNAL_CODECS
       
    30 #include "../Common/LoadCodecs.h"
       
    31 #endif
       
    32 
       
    33 #include "../../Compress/LZMA_Alone/LzmaBenchCon.h"
       
    34 
       
    35 #include "List.h"
       
    36 #include "OpenCallbackConsole.h"
       
    37 #include "ExtractCallbackConsole.h"
       
    38 #include "UpdateCallbackConsole.h"
       
    39 
       
    40 #include "../../MyVersion.h"
       
    41 
       
    42 #if defined( _WIN32) && defined( _7ZIP_LARGE_PAGES)
       
    43 extern "C" 
       
    44 { 
       
    45 #include "../../../../C/Alloc.h"
       
    46 }
       
    47 #endif
       
    48 
       
    49 using namespace NWindows;
       
    50 using namespace NFile;
       
    51 using namespace NCommandLineParser;
       
    52 
       
    53 HINSTANCE g_hInstance = 0;
       
    54 extern CStdOutStream *g_StdStream;
       
    55 
       
    56 static const char *kCopyrightString = "\n7-Zip"
       
    57 #ifndef EXTERNAL_CODECS
       
    58 " (A)"
       
    59 #endif
       
    60 
       
    61 #ifdef _WIN64
       
    62 " [64]"
       
    63 #endif
       
    64 
       
    65 " " MY_VERSION_COPYRIGHT_DATE "\n";
       
    66 
       
    67 static const char *kHelpString = 
       
    68     "\nUsage: 7z"
       
    69 #ifdef _NO_CRYPTO
       
    70     "r"
       
    71 #else
       
    72 #ifndef EXTERNAL_CODECS
       
    73     "a"
       
    74 #endif
       
    75 #endif
       
    76     " <command> [<switches>...] <archive_name> [<file_names>...]\n"
       
    77     "       [<@listfiles...>]\n"
       
    78     "\n"
       
    79     "<Commands>\n"
       
    80     "  a: Add files to archive\n"
       
    81     "  b: Benchmark\n"
       
    82     "  d: Delete files from archive\n"
       
    83     "  e: Extract files from archive (without using directory names)\n"
       
    84     "  l: List contents of archive\n"
       
    85 //    "  l[a|t][f]: List contents of archive\n"
       
    86 //    "    a - with Additional fields\n"
       
    87 //    "    t - with all fields\n"
       
    88 //    "    f - with Full pathnames\n"
       
    89     "  t: Test integrity of archive\n"
       
    90     "  u: Update files to archive\n"
       
    91     "  x: eXtract files with full paths\n"
       
    92     "<Switches>\n"
       
    93     "  -ai[r[-|0]]{@listfile|!wildcard}: Include archives\n"
       
    94     "  -ax[r[-|0]]{@listfile|!wildcard}: eXclude archives\n"
       
    95     "  -bd: Disable percentage indicator\n"
       
    96     "  -i[r[-|0]]{@listfile|!wildcard}: Include filenames\n"
       
    97     "  -m{Parameters}: set compression Method\n"
       
    98     "  -o{Directory}: set Output directory\n"
       
    99     "  -p{Password}: set Password\n"
       
   100     "  -r[-|0]: Recurse subdirectories\n"
       
   101     "  -scs{UTF-8 | WIN | DOS}: set charset for list files\n"
       
   102     "  -sfx[{name}]: Create SFX archive\n"
       
   103     "  -si[{name}]: read data from stdin\n"
       
   104     "  -slt: show technical information for l (List) command\n"
       
   105     "  -so: write data to stdout\n"
       
   106     "  -ssc[-]: set sensitive case mode\n"
       
   107     "  -ssw: compress shared files\n"
       
   108     "  -t{Type}: Set type of archive\n"
       
   109     "  -v{Size}[b|k|m|g]: Create volumes\n"
       
   110     "  -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName]: Update options\n"
       
   111     "  -w[{path}]: assign Work directory. Empty path means a temporary directory\n"
       
   112     "  -x[r[-|0]]]{@listfile|!wildcard}: eXclude filenames\n"
       
   113     "  -y: assume Yes on all queries\n";
       
   114 
       
   115 // ---------------------------
       
   116 // exception messages
       
   117 
       
   118 static const char *kEverythingIsOk = "Everything is Ok";
       
   119 static const char *kUserErrorMessage  = "Incorrect command line"; // NExitCode::kUserError
       
   120 
       
   121 static const wchar_t *kDefaultSfxModule = L"7zCon.sfx";
       
   122 
       
   123 static void ShowMessageAndThrowException(CStdOutStream &s, LPCSTR message, NExitCode::EEnum code)
       
   124 {
       
   125   s << message << endl;
       
   126   throw code;
       
   127 }
       
   128 
       
   129 static void PrintHelpAndExit(CStdOutStream &s) // yyy
       
   130 {
       
   131   s << kHelpString;
       
   132   ShowMessageAndThrowException(s, kUserErrorMessage, NExitCode::kUserError);
       
   133 }
       
   134 
       
   135 #ifndef _WIN32
       
   136 static void GetArguments(int numArguments, const char *arguments[], UStringVector &parts)
       
   137 {
       
   138   parts.Clear();
       
   139   for(int i = 0; i < numArguments; i++)
       
   140   {
       
   141     UString s = MultiByteToUnicodeString(arguments[i]);
       
   142     parts.Add(s);
       
   143   }
       
   144 }
       
   145 #endif
       
   146 
       
   147 static void ShowCopyrightAndHelp(CStdOutStream &s, bool needHelp)
       
   148 {
       
   149   s << kCopyrightString;
       
   150   // s << "# CPUs: " << (UInt64)NWindows::NSystem::GetNumberOfProcessors() << "\n";
       
   151   if (needHelp) 
       
   152     s << kHelpString;
       
   153 }
       
   154 
       
   155 #ifdef EXTERNAL_CODECS
       
   156 static void PrintString(CStdOutStream &stdStream, const AString &s, int size)
       
   157 {
       
   158   int len = s.Length();
       
   159   stdStream << s;
       
   160   for (int i = len; i < size; i++)
       
   161     stdStream << ' ';
       
   162 }
       
   163 #endif
       
   164 
       
   165 static void PrintString(CStdOutStream &stdStream, const UString &s, int size)
       
   166 {
       
   167   int len = s.Length();
       
   168   stdStream << s;
       
   169   for (int i = len; i < size; i++)
       
   170     stdStream << ' ';
       
   171 }
       
   172 
       
   173 static inline char GetHex(Byte value)
       
   174 {
       
   175   return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
       
   176 }
       
   177 
       
   178 int Main2(
       
   179   #ifndef _WIN32  
       
   180   int numArguments, const char *arguments[]
       
   181   #endif
       
   182 )
       
   183 {
       
   184   #ifdef _WIN32  
       
   185   SetFileApisToOEM();
       
   186   #endif
       
   187   
       
   188   UStringVector commandStrings;
       
   189   #ifdef _WIN32  
       
   190   NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
       
   191   #else
       
   192   GetArguments(numArguments, arguments, commandStrings);
       
   193   #endif
       
   194 
       
   195   if(commandStrings.Size() == 1)
       
   196   {
       
   197     ShowCopyrightAndHelp(g_StdOut, true);
       
   198     return 0;
       
   199   }
       
   200   commandStrings.Delete(0);
       
   201 
       
   202   CArchiveCommandLineOptions options;
       
   203 
       
   204   CArchiveCommandLineParser parser;
       
   205 
       
   206   parser.Parse1(commandStrings, options);
       
   207 
       
   208   if(options.HelpMode)
       
   209   {
       
   210     ShowCopyrightAndHelp(g_StdOut, true);
       
   211     return 0;
       
   212   }
       
   213 
       
   214   #if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES)
       
   215   if (options.LargePages)
       
   216   {
       
   217     SetLargePageSize();
       
   218     NSecurity::EnableLockMemoryPrivilege();
       
   219   }
       
   220   #endif
       
   221 
       
   222   CStdOutStream &stdStream = options.StdOutMode ? g_StdErr : g_StdOut;
       
   223   g_StdStream = &stdStream;
       
   224 
       
   225   if (options.EnableHeaders)
       
   226     ShowCopyrightAndHelp(stdStream, false);
       
   227 
       
   228   parser.Parse2(options);
       
   229 
       
   230   CCodecs *codecs = new CCodecs;
       
   231   CMyComPtr<
       
   232     #ifdef EXTERNAL_CODECS
       
   233     ICompressCodecsInfo
       
   234     #else
       
   235     IUnknown
       
   236     #endif
       
   237     > compressCodecsInfo = codecs;
       
   238   HRESULT result = codecs->Load();
       
   239   if (result != S_OK)
       
   240     throw CSystemException(result);
       
   241 
       
   242   bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
       
   243   if (options.Command.CommandType == NCommandType::kInfo)
       
   244   {
       
   245     stdStream << endl << "Formats:" << endl;
       
   246     int i;
       
   247     for (i = 0; i < codecs->Formats.Size(); i++)
       
   248     {
       
   249       const CArcInfoEx &arc = codecs->Formats[i];
       
   250       #ifdef EXTERNAL_CODECS
       
   251       if (arc.LibIndex >= 0)
       
   252       {
       
   253         char s[32];
       
   254         ConvertUInt64ToString(arc.LibIndex, s);
       
   255         PrintString(stdStream, s, 2);
       
   256       }
       
   257       else
       
   258       #endif
       
   259         stdStream << "  ";
       
   260       stdStream << ' ';
       
   261       stdStream << (char)(arc.UpdateEnabled ? 'C' : ' ');
       
   262       stdStream << (char)(arc.KeepName ? 'K' : ' ');
       
   263       stdStream << "  ";
       
   264       PrintString(stdStream, arc.Name, 6);
       
   265       stdStream << "  ";
       
   266       UString s;
       
   267       for (int t = 0; t < arc.Exts.Size(); t++)
       
   268       {
       
   269         const CArcExtInfo &ext = arc.Exts[t];
       
   270         s += ext.Ext;
       
   271         if (!ext.AddExt.IsEmpty())
       
   272         {
       
   273           s += L" (";
       
   274           s += ext.AddExt;
       
   275           s += L')';
       
   276         }
       
   277         s += L' ';
       
   278       }
       
   279       PrintString(stdStream, s, 14);
       
   280       stdStream << "  ";
       
   281       const CByteBuffer &sig = arc.StartSignature;
       
   282       for (size_t j = 0; j < sig.GetCapacity(); j++)
       
   283       {
       
   284         Byte b = sig[j];
       
   285         if (b > 0x20 && b < 0x80)
       
   286         {
       
   287           stdStream << (char)b;
       
   288         }
       
   289         else
       
   290         {
       
   291           stdStream << GetHex((Byte)((b >> 4) & 0xF));
       
   292           stdStream << GetHex((Byte)(b & 0xF));
       
   293         }
       
   294         stdStream << ' ';
       
   295       }
       
   296       stdStream << endl;
       
   297     }
       
   298     stdStream << endl << "Codecs:" << endl;
       
   299 
       
   300     #ifdef EXTERNAL_CODECS
       
   301     UINT32 numMethods;
       
   302     if (codecs->GetNumberOfMethods(&numMethods) == S_OK)
       
   303     for (UInt32 j = 0; j < numMethods; j++)
       
   304     {
       
   305       int libIndex = codecs->GetCodecLibIndex(j);
       
   306       if (libIndex >= 0)
       
   307       {
       
   308         char s[32];
       
   309         ConvertUInt64ToString(libIndex, s);
       
   310         PrintString(stdStream, s, 2);
       
   311       }
       
   312       else
       
   313         stdStream << "  ";
       
   314       stdStream << ' ';
       
   315       stdStream << (char)(codecs->GetCodecEncoderIsAssigned(j) ? 'C' : ' ');
       
   316       UInt64 id;
       
   317       stdStream << "  ";
       
   318       HRESULT res = codecs->GetCodecId(j, id);
       
   319       if (res != S_OK)
       
   320         id = (UInt64)(Int64)-1;
       
   321       char s[32];
       
   322       ConvertUInt64ToString(id, s, 16);
       
   323       PrintString(stdStream, s, 8);
       
   324       stdStream << "  ";
       
   325       PrintString(stdStream, codecs->GetCodecName(j), 11);
       
   326       stdStream << endl;
       
   327       /*
       
   328       if (res != S_OK)
       
   329         throw "incorrect Codec ID";
       
   330       */
       
   331     }
       
   332     #endif
       
   333     return S_OK;
       
   334   }
       
   335   else if (options.Command.CommandType == NCommandType::kBenchmark)
       
   336   {
       
   337     if (options.Method.CompareNoCase(L"CRC") == 0)
       
   338     {
       
   339       HRESULT res = CrcBenchCon((FILE *)stdStream, options.NumIterations, options.NumThreads, options.DictionarySize);
       
   340       if (res != S_OK)
       
   341       {
       
   342         if (res == S_FALSE)
       
   343         {
       
   344           stdStream << "\nCRC Error\n";
       
   345           return NExitCode::kFatalError;
       
   346         }
       
   347         throw CSystemException(res);
       
   348       }
       
   349     }
       
   350     else
       
   351     {
       
   352       HRESULT res = LzmaBenchCon(
       
   353         #ifdef EXTERNAL_LZMA
       
   354         codecs,
       
   355         #endif
       
   356         (FILE *)stdStream, options.NumIterations, options.NumThreads, options.DictionarySize);
       
   357       if (res != S_OK)
       
   358       {
       
   359         if (res == S_FALSE)
       
   360         {
       
   361           stdStream << "\nDecoding Error\n";
       
   362           return NExitCode::kFatalError;
       
   363         }
       
   364         throw CSystemException(res);
       
   365       }
       
   366     }
       
   367   }
       
   368   else if (isExtractGroupCommand || options.Command.CommandType == NCommandType::kList)
       
   369   {
       
   370     if(isExtractGroupCommand)
       
   371     {
       
   372       CExtractCallbackConsole *ecs = new CExtractCallbackConsole;
       
   373       CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
       
   374 
       
   375       ecs->OutStream = &stdStream;
       
   376       ecs->PasswordIsDefined = options.PasswordEnabled;
       
   377       ecs->Password = options.Password;
       
   378       ecs->Init();
       
   379 
       
   380       COpenCallbackConsole openCallback;
       
   381       openCallback.OutStream = &stdStream;
       
   382       openCallback.PasswordIsDefined = options.PasswordEnabled;
       
   383       openCallback.Password = options.Password;
       
   384 
       
   385       CExtractOptions eo;
       
   386       eo.StdOutMode = options.StdOutMode;
       
   387       eo.PathMode = options.Command.GetPathMode();
       
   388       eo.TestMode = options.Command.IsTestMode();
       
   389       eo.OverwriteMode = options.OverwriteMode;
       
   390       eo.OutputDir = options.OutputDir;
       
   391       eo.YesToAll = options.YesToAll;
       
   392       #ifdef COMPRESS_MT
       
   393       eo.Properties = options.ExtractProperties;
       
   394       #endif
       
   395       UString errorMessage;
       
   396       CDecompressStat stat;
       
   397       HRESULT result = DecompressArchives(
       
   398           codecs,
       
   399           options.ArchivePathsSorted, 
       
   400           options.ArchivePathsFullSorted,
       
   401           options.WildcardCensor.Pairs.Front().Head, 
       
   402           eo, &openCallback, ecs, errorMessage, stat);
       
   403       if (!errorMessage.IsEmpty())
       
   404       {
       
   405         stdStream << endl << "Error: " << errorMessage;
       
   406         if (result == S_OK)
       
   407           result = E_FAIL;
       
   408       }
       
   409 
       
   410       stdStream << endl;
       
   411       if (ecs->NumArchives > 1)
       
   412         stdStream << "Archives: " << ecs->NumArchives << endl;
       
   413       if (ecs->NumArchiveErrors != 0 || ecs->NumFileErrors != 0)
       
   414       {
       
   415         if (ecs->NumArchives > 1)
       
   416         {
       
   417           stdStream << endl;
       
   418           if (ecs->NumArchiveErrors != 0)
       
   419             stdStream << "Archive Errors: " << ecs->NumArchiveErrors << endl;
       
   420           if (ecs->NumFileErrors != 0)
       
   421             stdStream << "Sub items Errors: " << ecs->NumFileErrors << endl;
       
   422         }
       
   423         if (result != S_OK)
       
   424           throw CSystemException(result);
       
   425         return NExitCode::kFatalError;
       
   426       }
       
   427       if (result != S_OK)
       
   428         throw CSystemException(result);
       
   429       if (stat.NumFolders != 0)
       
   430         stdStream << "Folders: " << stat.NumFolders << endl;
       
   431       if (stat.NumFiles != 1 || stat.NumFolders != 0)
       
   432           stdStream << "Files: " << stat.NumFiles << endl;
       
   433       stdStream 
       
   434            << "Size:       " << stat.UnpackSize << endl
       
   435            << "Compressed: " << stat.PackSize << endl;
       
   436     }
       
   437     else
       
   438     {
       
   439       UInt64 numErrors = 0;
       
   440       HRESULT result = ListArchives(
       
   441           codecs,
       
   442           options.ArchivePathsSorted, 
       
   443           options.ArchivePathsFullSorted,
       
   444           options.WildcardCensor.Pairs.Front().Head, 
       
   445           options.EnableHeaders, 
       
   446           options.TechMode,
       
   447           options.PasswordEnabled, 
       
   448           options.Password, numErrors);
       
   449       if (numErrors > 0)
       
   450       {
       
   451         g_StdOut << endl << "Errors: " << numErrors;
       
   452         return NExitCode::kFatalError;
       
   453       }
       
   454       if (result != S_OK)
       
   455         throw CSystemException(result);
       
   456     }
       
   457   }
       
   458   else if(options.Command.IsFromUpdateGroup())
       
   459   {
       
   460     UString workingDir;
       
   461 
       
   462     CUpdateOptions &uo = options.UpdateOptions;
       
   463     if (uo.SfxMode && uo.SfxModule.IsEmpty())
       
   464       uo.SfxModule = kDefaultSfxModule;
       
   465 
       
   466     bool passwordIsDefined = 
       
   467         options.PasswordEnabled && !options.Password.IsEmpty();
       
   468 
       
   469     COpenCallbackConsole openCallback;
       
   470     openCallback.OutStream = &stdStream;
       
   471     openCallback.PasswordIsDefined = passwordIsDefined;
       
   472     openCallback.Password = options.Password;
       
   473 
       
   474     CUpdateCallbackConsole callback;
       
   475     callback.EnablePercents = options.EnablePercents;
       
   476     callback.PasswordIsDefined = passwordIsDefined;
       
   477     callback.AskPassword = options.PasswordEnabled && options.Password.IsEmpty();
       
   478     callback.Password = options.Password;
       
   479     callback.StdOutMode = uo.StdOutMode;
       
   480     callback.Init(&stdStream);
       
   481 
       
   482     CUpdateErrorInfo errorInfo;
       
   483 
       
   484     if (!uo.Init(codecs, options.ArchiveName, options.ArcType))
       
   485       throw "Unsupported archive type";
       
   486     HRESULT result = UpdateArchive(codecs, 
       
   487         options.WildcardCensor, uo, 
       
   488         errorInfo, &openCallback, &callback);
       
   489 
       
   490     int exitCode = NExitCode::kSuccess;
       
   491     if (callback.CantFindFiles.Size() > 0)
       
   492     {
       
   493       stdStream << endl;
       
   494       stdStream << "WARNINGS for files:" << endl << endl;
       
   495       int numErrors = callback.CantFindFiles.Size();
       
   496       for (int i = 0; i < numErrors; i++)
       
   497       {
       
   498         stdStream << callback.CantFindFiles[i] << " : ";
       
   499         stdStream << NError::MyFormatMessageW(callback.CantFindCodes[i]) << endl;
       
   500       }
       
   501       stdStream << "----------------" << endl;
       
   502       stdStream << "WARNING: Cannot find " << numErrors << " file";
       
   503       if (numErrors > 1)
       
   504         stdStream << "s";
       
   505       stdStream << endl;
       
   506       exitCode = NExitCode::kWarning;
       
   507     }
       
   508 
       
   509     if (result != S_OK)
       
   510     {
       
   511       UString message;
       
   512       if (!errorInfo.Message.IsEmpty())
       
   513       {
       
   514         message += errorInfo.Message;
       
   515         message += L"\n";
       
   516       }
       
   517       if (!errorInfo.FileName.IsEmpty())
       
   518       {
       
   519         message += errorInfo.FileName;
       
   520         message += L"\n";
       
   521       }
       
   522       if (!errorInfo.FileName2.IsEmpty())
       
   523       {
       
   524         message += errorInfo.FileName2;
       
   525         message += L"\n";
       
   526       }
       
   527       if (errorInfo.SystemError != 0)
       
   528       {
       
   529         message += NError::MyFormatMessageW(errorInfo.SystemError);
       
   530         message += L"\n";
       
   531       }
       
   532       if (!message.IsEmpty())
       
   533         stdStream << L"\nError:\n" << message;
       
   534       throw CSystemException(result);
       
   535     }
       
   536     int numErrors = callback.FailedFiles.Size();
       
   537     if (numErrors == 0)
       
   538     {
       
   539       if (callback.CantFindFiles.Size() == 0)
       
   540         stdStream << kEverythingIsOk << endl;
       
   541     }
       
   542     else
       
   543     {
       
   544       stdStream << endl;
       
   545       stdStream << "WARNINGS for files:" << endl << endl;
       
   546       for (int i = 0; i < numErrors; i++)
       
   547       {
       
   548         stdStream << callback.FailedFiles[i] << " : ";
       
   549         stdStream << NError::MyFormatMessageW(callback.FailedCodes[i]) << endl;
       
   550       }
       
   551       stdStream << "----------------" << endl;
       
   552       stdStream << "WARNING: Cannot open " << numErrors << " file";
       
   553       if (numErrors > 1)
       
   554         stdStream << "s";
       
   555       stdStream << endl;
       
   556       exitCode = NExitCode::kWarning;
       
   557     }
       
   558     return exitCode;
       
   559   }
       
   560   else 
       
   561     PrintHelpAndExit(stdStream);
       
   562   return 0;
       
   563 }