Home | History | Annotate | Download | only in Console
      1 // ExtractCallbackConsole.h
      2 
      3 #include "StdAfx.h"
      4 
      5 #include "ExtractCallbackConsole.h"
      6 #include "UserInputUtils.h"
      7 #include "ConsoleClose.h"
      8 
      9 #include "Common/Wildcard.h"
     10 
     11 #include "Windows/FileDir.h"
     12 #include "Windows/FileFind.h"
     13 #include "Windows/Time.h"
     14 #include "Windows/Defs.h"
     15 #include "Windows/PropVariant.h"
     16 #include "Windows/Error.h"
     17 #include "Windows/PropVariantConversions.h"
     18 
     19 #include "../../Common/FilePathAutoRename.h"
     20 
     21 #include "../Common/ExtractingFilePath.h"
     22 
     23 using namespace NWindows;
     24 using namespace NFile;
     25 using namespace NDirectory;
     26 
     27 static const char *kTestString    =  "Testing     ";
     28 static const char *kExtractString =  "Extracting  ";
     29 static const char *kSkipString   =  "Skipping    ";
     30 
     31 // static const char *kCantAutoRename = "can not create file with auto name\n";
     32 // static const char *kCantRenameFile = "can not rename existing file\n";
     33 // static const char *kCantDeleteOutputFile = "can not delete output file ";
     34 static const char *kError = "ERROR: ";
     35 static const char *kMemoryExceptionMessage = "Can't allocate required memory!";
     36 
     37 static const char *kProcessing = "Processing archive: ";
     38 static const char *kEverythingIsOk = "Everything is Ok";
     39 static const char *kNoFiles = "No files to process";
     40 
     41 static const char *kUnsupportedMethod = "Unsupported Method";
     42 static const char *kCrcFailed = "CRC Failed";
     43 static const char *kCrcFailedEncrypted = "CRC Failed in encrypted file. Wrong password?";
     44 static const char *kDataError = "Data Error";
     45 static const char *kDataErrorEncrypted = "Data Error in encrypted file. Wrong password?";
     46 static const char *kUnknownError = "Unknown Error";
     47 
     48 STDMETHODIMP CExtractCallbackConsole::SetTotal(UInt64)
     49 {
     50   if (NConsoleClose::TestBreakSignal())
     51     return E_ABORT;
     52   return S_OK;
     53 }
     54 
     55 STDMETHODIMP CExtractCallbackConsole::SetCompleted(const UInt64 *)
     56 {
     57   if (NConsoleClose::TestBreakSignal())
     58     return E_ABORT;
     59   return S_OK;
     60 }
     61 
     62 STDMETHODIMP CExtractCallbackConsole::AskOverwrite(
     63     const wchar_t *existName, const FILETIME *, const UInt64 *,
     64     const wchar_t *newName, const FILETIME *, const UInt64 *,
     65     Int32 *answer)
     66 {
     67   (*OutStream) << "file " << existName <<
     68     "\nalready exists. Overwrite with " << endl;
     69   (*OutStream) << newName;
     70 
     71   NUserAnswerMode::EEnum overwriteAnswer = ScanUserYesNoAllQuit(OutStream);
     72 
     73   switch(overwriteAnswer)
     74   {
     75     case NUserAnswerMode::kQuit:  return E_ABORT;
     76     case NUserAnswerMode::kNo:     *answer = NOverwriteAnswer::kNo; break;
     77     case NUserAnswerMode::kNoAll:  *answer = NOverwriteAnswer::kNoToAll; break;
     78     case NUserAnswerMode::kYesAll: *answer = NOverwriteAnswer::kYesToAll; break;
     79     case NUserAnswerMode::kYes:    *answer = NOverwriteAnswer::kYes; break;
     80     case NUserAnswerMode::kAutoRenameAll: *answer = NOverwriteAnswer::kAutoRename; break;
     81     default: return E_FAIL;
     82   }
     83   return S_OK;
     84 }
     85 
     86 STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, bool /* isFolder */, Int32 askExtractMode, const UInt64 *position)
     87 {
     88   switch (askExtractMode)
     89   {
     90     case NArchive::NExtract::NAskMode::kExtract: (*OutStream) << kExtractString; break;
     91     case NArchive::NExtract::NAskMode::kTest:    (*OutStream) << kTestString; break;
     92     case NArchive::NExtract::NAskMode::kSkip:    (*OutStream) << kSkipString; break;
     93   };
     94   (*OutStream) << name;
     95   if (position != 0)
     96     (*OutStream) << " <" << *position << ">";
     97   return S_OK;
     98 }
     99 
    100 STDMETHODIMP CExtractCallbackConsole::MessageError(const wchar_t *message)
    101 {
    102   (*OutStream) << message << endl;
    103   NumFileErrorsInCurrentArchive++;
    104   NumFileErrors++;
    105   return S_OK;
    106 }
    107 
    108 STDMETHODIMP CExtractCallbackConsole::SetOperationResult(Int32 operationResult, bool encrypted)
    109 {
    110   switch(operationResult)
    111   {
    112     case NArchive::NExtract::NOperationResult::kOK:
    113       break;
    114     default:
    115     {
    116       NumFileErrorsInCurrentArchive++;
    117       NumFileErrors++;
    118       (*OutStream) << "     ";
    119       switch(operationResult)
    120       {
    121         case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
    122           (*OutStream) << kUnsupportedMethod;
    123           break;
    124         case NArchive::NExtract::NOperationResult::kCRCError:
    125           (*OutStream) << (encrypted ? kCrcFailedEncrypted: kCrcFailed);
    126           break;
    127         case NArchive::NExtract::NOperationResult::kDataError:
    128           (*OutStream) << (encrypted ? kDataErrorEncrypted : kDataError);
    129           break;
    130         default:
    131           (*OutStream) << kUnknownError;
    132       }
    133     }
    134   }
    135   (*OutStream) << endl;
    136   return S_OK;
    137 }
    138 
    139 #ifndef _NO_CRYPTO
    140 
    141 HRESULT CExtractCallbackConsole::SetPassword(const UString &password)
    142 {
    143   PasswordIsDefined = true;
    144   Password = password;
    145   return S_OK;
    146 }
    147 
    148 STDMETHODIMP CExtractCallbackConsole::CryptoGetTextPassword(BSTR *password)
    149 {
    150   if (!PasswordIsDefined)
    151   {
    152     Password = GetPassword(OutStream);
    153     PasswordIsDefined = true;
    154   }
    155   return StringToBstr(Password, password);
    156 }
    157 
    158 #endif
    159 
    160 HRESULT CExtractCallbackConsole::BeforeOpen(const wchar_t *name)
    161 {
    162   NumArchives++;
    163   NumFileErrorsInCurrentArchive = 0;
    164   (*OutStream) << endl << kProcessing << name << endl;
    165   return S_OK;
    166 }
    167 
    168 HRESULT CExtractCallbackConsole::OpenResult(const wchar_t * /* name */, HRESULT result, bool encrypted)
    169 {
    170   (*OutStream) << endl;
    171   if (result != S_OK)
    172   {
    173     (*OutStream) << "Error: ";
    174     if (result == S_FALSE)
    175     {
    176       (*OutStream) << (encrypted ?
    177         "Can not open encrypted archive. Wrong password?" :
    178         "Can not open file as archive");
    179     }
    180     else
    181     {
    182       if (result == E_OUTOFMEMORY)
    183         (*OutStream) << "Can't allocate required memory";
    184       else
    185         (*OutStream) << NError::MyFormatMessage(result);
    186     }
    187     (*OutStream) << endl;
    188     NumArchiveErrors++;
    189   }
    190   return S_OK;
    191 }
    192 
    193 HRESULT CExtractCallbackConsole::ThereAreNoFiles()
    194 {
    195   (*OutStream) << endl << kNoFiles << endl;
    196   return S_OK;
    197 }
    198 
    199 HRESULT CExtractCallbackConsole::ExtractResult(HRESULT result)
    200 {
    201   if (result == S_OK)
    202   {
    203     (*OutStream) << endl;
    204     if (NumFileErrorsInCurrentArchive == 0)
    205       (*OutStream) << kEverythingIsOk << endl;
    206     else
    207     {
    208       NumArchiveErrors++;
    209       (*OutStream) << "Sub items Errors: " << NumFileErrorsInCurrentArchive << endl;
    210     }
    211   }
    212   if (result == S_OK)
    213     return result;
    214   NumArchiveErrors++;
    215   if (result == E_ABORT || result == ERROR_DISK_FULL)
    216     return result;
    217   (*OutStream) << endl << kError;
    218   if (result == E_OUTOFMEMORY)
    219     (*OutStream) << kMemoryExceptionMessage;
    220   else
    221   {
    222     UString message;
    223     NError::MyFormatMessage(result, message);
    224     (*OutStream) << message;
    225   }
    226   (*OutStream) << endl;
    227   return S_OK;
    228 }
    229