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