1370b324cSopenharmony_ci// ExtractCallback.cpp 2370b324cSopenharmony_ci 3370b324cSopenharmony_ci#include "StdAfx.h" 4370b324cSopenharmony_ci 5370b324cSopenharmony_ci 6370b324cSopenharmony_ci#include "../../../Common/ComTry.h" 7370b324cSopenharmony_ci#include "../../../Common/IntToString.h" 8370b324cSopenharmony_ci#include "../../../Common/Lang.h" 9370b324cSopenharmony_ci#include "../../../Common/StringConvert.h" 10370b324cSopenharmony_ci 11370b324cSopenharmony_ci#include "../../../Windows/ErrorMsg.h" 12370b324cSopenharmony_ci#include "../../../Windows/FileDir.h" 13370b324cSopenharmony_ci#include "../../../Windows/FileFind.h" 14370b324cSopenharmony_ci#include "../../../Windows/PropVariantConv.h" 15370b324cSopenharmony_ci 16370b324cSopenharmony_ci#include "../../Common/FilePathAutoRename.h" 17370b324cSopenharmony_ci#include "../../Common/StreamUtils.h" 18370b324cSopenharmony_ci#include "../Common/ExtractingFilePath.h" 19370b324cSopenharmony_ci 20370b324cSopenharmony_ci#ifndef Z7_SFX 21370b324cSopenharmony_ci#include "../Common/ZipRegistry.h" 22370b324cSopenharmony_ci#endif 23370b324cSopenharmony_ci 24370b324cSopenharmony_ci#include "../GUI/ExtractRes.h" 25370b324cSopenharmony_ci#include "resourceGui.h" 26370b324cSopenharmony_ci 27370b324cSopenharmony_ci#include "ExtractCallback.h" 28370b324cSopenharmony_ci#include "FormatUtils.h" 29370b324cSopenharmony_ci#include "LangUtils.h" 30370b324cSopenharmony_ci#include "OverwriteDialog.h" 31370b324cSopenharmony_ci#ifndef Z7_NO_CRYPTO 32370b324cSopenharmony_ci#include "PasswordDialog.h" 33370b324cSopenharmony_ci#endif 34370b324cSopenharmony_ci#include "PropertyName.h" 35370b324cSopenharmony_ci 36370b324cSopenharmony_ciusing namespace NWindows; 37370b324cSopenharmony_ciusing namespace NFile; 38370b324cSopenharmony_ciusing namespace NFind; 39370b324cSopenharmony_ci 40370b324cSopenharmony_ciCExtractCallbackImp::~CExtractCallbackImp() {} 41370b324cSopenharmony_ci 42370b324cSopenharmony_civoid CExtractCallbackImp::Init() 43370b324cSopenharmony_ci{ 44370b324cSopenharmony_ci _lang_Extracting = LangString(IDS_PROGRESS_EXTRACTING); 45370b324cSopenharmony_ci _lang_Testing = LangString(IDS_PROGRESS_TESTING); 46370b324cSopenharmony_ci _lang_Skipping = LangString(IDS_PROGRESS_SKIPPING); 47370b324cSopenharmony_ci _lang_Reading = "Reading"; 48370b324cSopenharmony_ci 49370b324cSopenharmony_ci NumArchiveErrors = 0; 50370b324cSopenharmony_ci ThereAreMessageErrors = false; 51370b324cSopenharmony_ci #ifndef Z7_SFX 52370b324cSopenharmony_ci NumFolders = NumFiles = 0; 53370b324cSopenharmony_ci NeedAddFile = false; 54370b324cSopenharmony_ci #endif 55370b324cSopenharmony_ci} 56370b324cSopenharmony_ci 57370b324cSopenharmony_civoid CExtractCallbackImp::AddError_Message(LPCWSTR s) 58370b324cSopenharmony_ci{ 59370b324cSopenharmony_ci ThereAreMessageErrors = true; 60370b324cSopenharmony_ci ProgressDialog->Sync.AddError_Message(s); 61370b324cSopenharmony_ci} 62370b324cSopenharmony_ci 63370b324cSopenharmony_ci#ifndef Z7_SFX 64370b324cSopenharmony_ci 65370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::SetNumFiles(UInt64 numFiles)) 66370b324cSopenharmony_ci{ 67370b324cSopenharmony_ci #ifdef Z7_SFX 68370b324cSopenharmony_ci UNUSED_VAR(numFiles) 69370b324cSopenharmony_ci #else 70370b324cSopenharmony_ci ProgressDialog->Sync.Set_NumFilesTotal(numFiles); 71370b324cSopenharmony_ci #endif 72370b324cSopenharmony_ci return S_OK; 73370b324cSopenharmony_ci} 74370b324cSopenharmony_ci 75370b324cSopenharmony_ci#endif 76370b324cSopenharmony_ci 77370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::SetTotal(UInt64 total)) 78370b324cSopenharmony_ci{ 79370b324cSopenharmony_ci ProgressDialog->Sync.Set_NumBytesTotal(total); 80370b324cSopenharmony_ci return S_OK; 81370b324cSopenharmony_ci} 82370b324cSopenharmony_ci 83370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::SetCompleted(const UInt64 *value)) 84370b324cSopenharmony_ci{ 85370b324cSopenharmony_ci return ProgressDialog->Sync.Set_NumBytesCur(value); 86370b324cSopenharmony_ci} 87370b324cSopenharmony_ci 88370b324cSopenharmony_ciHRESULT CExtractCallbackImp::Open_CheckBreak() 89370b324cSopenharmony_ci{ 90370b324cSopenharmony_ci return ProgressDialog->Sync.CheckStop(); 91370b324cSopenharmony_ci} 92370b324cSopenharmony_ci 93370b324cSopenharmony_ciHRESULT CExtractCallbackImp::Open_SetTotal(const UInt64 *files, const UInt64 *bytes) 94370b324cSopenharmony_ci{ 95370b324cSopenharmony_ci HRESULT res = S_OK; 96370b324cSopenharmony_ci if (!MultiArcMode) 97370b324cSopenharmony_ci { 98370b324cSopenharmony_ci if (files) 99370b324cSopenharmony_ci { 100370b324cSopenharmony_ci _totalFilesDefined = true; 101370b324cSopenharmony_ci // res = ProgressDialog->Sync.Set_NumFilesTotal(*files); 102370b324cSopenharmony_ci } 103370b324cSopenharmony_ci else 104370b324cSopenharmony_ci _totalFilesDefined = false; 105370b324cSopenharmony_ci 106370b324cSopenharmony_ci if (bytes) 107370b324cSopenharmony_ci { 108370b324cSopenharmony_ci _totalBytesDefined = true; 109370b324cSopenharmony_ci ProgressDialog->Sync.Set_NumBytesTotal(*bytes); 110370b324cSopenharmony_ci } 111370b324cSopenharmony_ci else 112370b324cSopenharmony_ci _totalBytesDefined = false; 113370b324cSopenharmony_ci } 114370b324cSopenharmony_ci 115370b324cSopenharmony_ci return res; 116370b324cSopenharmony_ci} 117370b324cSopenharmony_ci 118370b324cSopenharmony_ciHRESULT CExtractCallbackImp::Open_SetCompleted(const UInt64 *files, const UInt64 *bytes) 119370b324cSopenharmony_ci{ 120370b324cSopenharmony_ci if (!MultiArcMode) 121370b324cSopenharmony_ci { 122370b324cSopenharmony_ci if (files) 123370b324cSopenharmony_ci { 124370b324cSopenharmony_ci ProgressDialog->Sync.Set_NumFilesCur(*files); 125370b324cSopenharmony_ci } 126370b324cSopenharmony_ci 127370b324cSopenharmony_ci if (bytes) 128370b324cSopenharmony_ci { 129370b324cSopenharmony_ci } 130370b324cSopenharmony_ci } 131370b324cSopenharmony_ci 132370b324cSopenharmony_ci return ProgressDialog->Sync.CheckStop(); 133370b324cSopenharmony_ci} 134370b324cSopenharmony_ci 135370b324cSopenharmony_ciHRESULT CExtractCallbackImp::Open_Finished() 136370b324cSopenharmony_ci{ 137370b324cSopenharmony_ci return ProgressDialog->Sync.CheckStop(); 138370b324cSopenharmony_ci} 139370b324cSopenharmony_ci 140370b324cSopenharmony_ci#ifndef Z7_NO_CRYPTO 141370b324cSopenharmony_ci 142370b324cSopenharmony_ciHRESULT CExtractCallbackImp::Open_CryptoGetTextPassword(BSTR *password) 143370b324cSopenharmony_ci{ 144370b324cSopenharmony_ci return CryptoGetTextPassword(password); 145370b324cSopenharmony_ci} 146370b324cSopenharmony_ci 147370b324cSopenharmony_ci/* 148370b324cSopenharmony_ciHRESULT CExtractCallbackImp::Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password) 149370b324cSopenharmony_ci{ 150370b324cSopenharmony_ci passwordIsDefined = PasswordIsDefined; 151370b324cSopenharmony_ci password = Password; 152370b324cSopenharmony_ci return S_OK; 153370b324cSopenharmony_ci} 154370b324cSopenharmony_ci 155370b324cSopenharmony_cibool CExtractCallbackImp::Open_WasPasswordAsked() 156370b324cSopenharmony_ci{ 157370b324cSopenharmony_ci return PasswordWasAsked; 158370b324cSopenharmony_ci} 159370b324cSopenharmony_ci 160370b324cSopenharmony_civoid CExtractCallbackImp::Open_Clear_PasswordWasAsked_Flag() 161370b324cSopenharmony_ci{ 162370b324cSopenharmony_ci PasswordWasAsked = false; 163370b324cSopenharmony_ci} 164370b324cSopenharmony_ci*/ 165370b324cSopenharmony_ci 166370b324cSopenharmony_ci#endif 167370b324cSopenharmony_ci 168370b324cSopenharmony_ci 169370b324cSopenharmony_ci#ifndef Z7_SFX 170370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) 171370b324cSopenharmony_ci{ 172370b324cSopenharmony_ci ProgressDialog->Sync.Set_Ratio(inSize, outSize); 173370b324cSopenharmony_ci return S_OK; 174370b324cSopenharmony_ci} 175370b324cSopenharmony_ci#endif 176370b324cSopenharmony_ci 177370b324cSopenharmony_ci/* 178370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::SetTotalFiles(UInt64 total) 179370b324cSopenharmony_ci{ 180370b324cSopenharmony_ci ProgressDialog->Sync.SetNumFilesTotal(total); 181370b324cSopenharmony_ci return S_OK; 182370b324cSopenharmony_ci} 183370b324cSopenharmony_ci 184370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::SetCompletedFiles(const UInt64 *value) 185370b324cSopenharmony_ci{ 186370b324cSopenharmony_ci if (value != NULL) 187370b324cSopenharmony_ci ProgressDialog->Sync.SetNumFilesCur(*value); 188370b324cSopenharmony_ci return S_OK; 189370b324cSopenharmony_ci} 190370b324cSopenharmony_ci*/ 191370b324cSopenharmony_ci 192370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::AskOverwrite( 193370b324cSopenharmony_ci const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, 194370b324cSopenharmony_ci const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, 195370b324cSopenharmony_ci Int32 *answer)) 196370b324cSopenharmony_ci{ 197370b324cSopenharmony_ci COverwriteDialog dialog; 198370b324cSopenharmony_ci 199370b324cSopenharmony_ci dialog.OldFileInfo.SetTime(existTime); 200370b324cSopenharmony_ci dialog.OldFileInfo.SetSize(existSize); 201370b324cSopenharmony_ci dialog.OldFileInfo.Name = existName; 202370b324cSopenharmony_ci 203370b324cSopenharmony_ci dialog.NewFileInfo.SetTime(newTime); 204370b324cSopenharmony_ci dialog.NewFileInfo.SetSize(newSize); 205370b324cSopenharmony_ci dialog.NewFileInfo.Name = newName; 206370b324cSopenharmony_ci 207370b324cSopenharmony_ci ProgressDialog->WaitCreating(); 208370b324cSopenharmony_ci INT_PTR writeAnswer = dialog.Create(*ProgressDialog); 209370b324cSopenharmony_ci 210370b324cSopenharmony_ci switch (writeAnswer) 211370b324cSopenharmony_ci { 212370b324cSopenharmony_ci case IDCANCEL: *answer = NOverwriteAnswer::kCancel; return E_ABORT; 213370b324cSopenharmony_ci case IDYES: *answer = NOverwriteAnswer::kYes; break; 214370b324cSopenharmony_ci case IDNO: *answer = NOverwriteAnswer::kNo; break; 215370b324cSopenharmony_ci case IDB_YES_TO_ALL: *answer = NOverwriteAnswer::kYesToAll; break; 216370b324cSopenharmony_ci case IDB_NO_TO_ALL: *answer = NOverwriteAnswer::kNoToAll; break; 217370b324cSopenharmony_ci case IDB_AUTO_RENAME: *answer = NOverwriteAnswer::kAutoRename; break; 218370b324cSopenharmony_ci default: return E_FAIL; 219370b324cSopenharmony_ci } 220370b324cSopenharmony_ci return S_OK; 221370b324cSopenharmony_ci} 222370b324cSopenharmony_ci 223370b324cSopenharmony_ci 224370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::PrepareOperation(const wchar_t *name, Int32 isFolder, Int32 askExtractMode, const UInt64 * /* position */)) 225370b324cSopenharmony_ci{ 226370b324cSopenharmony_ci _isFolder = IntToBool(isFolder); 227370b324cSopenharmony_ci _currentFilePath = name; 228370b324cSopenharmony_ci 229370b324cSopenharmony_ci const UString *msg = &_lang_Empty; 230370b324cSopenharmony_ci switch (askExtractMode) 231370b324cSopenharmony_ci { 232370b324cSopenharmony_ci case NArchive::NExtract::NAskMode::kExtract: msg = &_lang_Extracting; break; 233370b324cSopenharmony_ci case NArchive::NExtract::NAskMode::kTest: msg = &_lang_Testing; break; 234370b324cSopenharmony_ci case NArchive::NExtract::NAskMode::kSkip: msg = &_lang_Skipping; break; 235370b324cSopenharmony_ci case NArchive::NExtract::NAskMode::kReadExternal: msg = &_lang_Reading; break; 236370b324cSopenharmony_ci // default: s = "Unknown operation"; 237370b324cSopenharmony_ci } 238370b324cSopenharmony_ci 239370b324cSopenharmony_ci return ProgressDialog->Sync.Set_Status2(*msg, name, IntToBool(isFolder)); 240370b324cSopenharmony_ci} 241370b324cSopenharmony_ci 242370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::MessageError(const wchar_t *s)) 243370b324cSopenharmony_ci{ 244370b324cSopenharmony_ci AddError_Message(s); 245370b324cSopenharmony_ci return S_OK; 246370b324cSopenharmony_ci} 247370b324cSopenharmony_ci 248370b324cSopenharmony_ciHRESULT CExtractCallbackImp::MessageError(const char *message, const FString &path) 249370b324cSopenharmony_ci{ 250370b324cSopenharmony_ci ThereAreMessageErrors = true; 251370b324cSopenharmony_ci ProgressDialog->Sync.AddError_Message_Name(GetUnicodeString(message), fs2us(path)); 252370b324cSopenharmony_ci return S_OK; 253370b324cSopenharmony_ci} 254370b324cSopenharmony_ci 255370b324cSopenharmony_ci#ifndef Z7_SFX 256370b324cSopenharmony_ci 257370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::ShowMessage(const wchar_t *s)) 258370b324cSopenharmony_ci{ 259370b324cSopenharmony_ci AddError_Message(s); 260370b324cSopenharmony_ci return S_OK; 261370b324cSopenharmony_ci} 262370b324cSopenharmony_ci 263370b324cSopenharmony_ci#endif 264370b324cSopenharmony_ci 265370b324cSopenharmony_civoid SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileName, UString &s); 266370b324cSopenharmony_civoid SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileName, UString &s) 267370b324cSopenharmony_ci{ 268370b324cSopenharmony_ci s.Empty(); 269370b324cSopenharmony_ci 270370b324cSopenharmony_ci if (opRes == NArchive::NExtract::NOperationResult::kOK) 271370b324cSopenharmony_ci return; 272370b324cSopenharmony_ci 273370b324cSopenharmony_ci #ifndef Z7_SFX 274370b324cSopenharmony_ci UINT messageID = 0; 275370b324cSopenharmony_ci #endif 276370b324cSopenharmony_ci UINT id = 0; 277370b324cSopenharmony_ci 278370b324cSopenharmony_ci switch (opRes) 279370b324cSopenharmony_ci { 280370b324cSopenharmony_ci case NArchive::NExtract::NOperationResult::kUnsupportedMethod: 281370b324cSopenharmony_ci #ifndef Z7_SFX 282370b324cSopenharmony_ci messageID = IDS_EXTRACT_MESSAGE_UNSUPPORTED_METHOD; 283370b324cSopenharmony_ci #endif 284370b324cSopenharmony_ci id = IDS_EXTRACT_MSG_UNSUPPORTED_METHOD; 285370b324cSopenharmony_ci break; 286370b324cSopenharmony_ci case NArchive::NExtract::NOperationResult::kDataError: 287370b324cSopenharmony_ci #ifndef Z7_SFX 288370b324cSopenharmony_ci messageID = encrypted ? 289370b324cSopenharmony_ci IDS_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED: 290370b324cSopenharmony_ci IDS_EXTRACT_MESSAGE_DATA_ERROR; 291370b324cSopenharmony_ci #endif 292370b324cSopenharmony_ci id = IDS_EXTRACT_MSG_DATA_ERROR; 293370b324cSopenharmony_ci break; 294370b324cSopenharmony_ci case NArchive::NExtract::NOperationResult::kCRCError: 295370b324cSopenharmony_ci #ifndef Z7_SFX 296370b324cSopenharmony_ci messageID = encrypted ? 297370b324cSopenharmony_ci IDS_EXTRACT_MESSAGE_CRC_ERROR_ENCRYPTED: 298370b324cSopenharmony_ci IDS_EXTRACT_MESSAGE_CRC_ERROR; 299370b324cSopenharmony_ci #endif 300370b324cSopenharmony_ci id = IDS_EXTRACT_MSG_CRC_ERROR; 301370b324cSopenharmony_ci break; 302370b324cSopenharmony_ci case NArchive::NExtract::NOperationResult::kUnavailable: 303370b324cSopenharmony_ci id = IDS_EXTRACT_MSG_UNAVAILABLE_DATA; 304370b324cSopenharmony_ci break; 305370b324cSopenharmony_ci case NArchive::NExtract::NOperationResult::kUnexpectedEnd: 306370b324cSopenharmony_ci id = IDS_EXTRACT_MSG_UEXPECTED_END; 307370b324cSopenharmony_ci break; 308370b324cSopenharmony_ci case NArchive::NExtract::NOperationResult::kDataAfterEnd: 309370b324cSopenharmony_ci id = IDS_EXTRACT_MSG_DATA_AFTER_END; 310370b324cSopenharmony_ci break; 311370b324cSopenharmony_ci case NArchive::NExtract::NOperationResult::kIsNotArc: 312370b324cSopenharmony_ci id = IDS_EXTRACT_MSG_IS_NOT_ARC; 313370b324cSopenharmony_ci break; 314370b324cSopenharmony_ci case NArchive::NExtract::NOperationResult::kHeadersError: 315370b324cSopenharmony_ci id = IDS_EXTRACT_MSG_HEADERS_ERROR; 316370b324cSopenharmony_ci break; 317370b324cSopenharmony_ci case NArchive::NExtract::NOperationResult::kWrongPassword: 318370b324cSopenharmony_ci id = IDS_EXTRACT_MSG_WRONG_PSW_CLAIM; 319370b324cSopenharmony_ci break; 320370b324cSopenharmony_ci /* 321370b324cSopenharmony_ci default: 322370b324cSopenharmony_ci messageID = IDS_EXTRACT_MESSAGE_UNKNOWN_ERROR; 323370b324cSopenharmony_ci break; 324370b324cSopenharmony_ci */ 325370b324cSopenharmony_ci } 326370b324cSopenharmony_ci 327370b324cSopenharmony_ci UString msg; 328370b324cSopenharmony_ci 329370b324cSopenharmony_ci #ifndef Z7_SFX 330370b324cSopenharmony_ci UString msgOld; 331370b324cSopenharmony_ci #ifdef Z7_LANG 332370b324cSopenharmony_ci if (id != 0) 333370b324cSopenharmony_ci LangString_OnlyFromLangFile(id, msg); 334370b324cSopenharmony_ci if (messageID != 0 && msg.IsEmpty()) 335370b324cSopenharmony_ci LangString_OnlyFromLangFile(messageID, msgOld); 336370b324cSopenharmony_ci #endif 337370b324cSopenharmony_ci if (msg.IsEmpty() && !msgOld.IsEmpty()) 338370b324cSopenharmony_ci s = MyFormatNew(msgOld, fileName); 339370b324cSopenharmony_ci else 340370b324cSopenharmony_ci #endif 341370b324cSopenharmony_ci { 342370b324cSopenharmony_ci if (msg.IsEmpty() && id != 0) 343370b324cSopenharmony_ci LangString(id, msg); 344370b324cSopenharmony_ci if (!msg.IsEmpty()) 345370b324cSopenharmony_ci s += msg; 346370b324cSopenharmony_ci else 347370b324cSopenharmony_ci { 348370b324cSopenharmony_ci s += "Error #"; 349370b324cSopenharmony_ci s.Add_UInt32((UInt32)opRes); 350370b324cSopenharmony_ci } 351370b324cSopenharmony_ci 352370b324cSopenharmony_ci if (encrypted && opRes != NArchive::NExtract::NOperationResult::kWrongPassword) 353370b324cSopenharmony_ci { 354370b324cSopenharmony_ci // s += " : "; 355370b324cSopenharmony_ci // AddLangString(s, IDS_EXTRACT_MSG_ENCRYPTED); 356370b324cSopenharmony_ci s += " : "; 357370b324cSopenharmony_ci AddLangString(s, IDS_EXTRACT_MSG_WRONG_PSW_GUESS); 358370b324cSopenharmony_ci } 359370b324cSopenharmony_ci s += " : "; 360370b324cSopenharmony_ci s += fileName; 361370b324cSopenharmony_ci } 362370b324cSopenharmony_ci} 363370b324cSopenharmony_ci 364370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::SetOperationResult(Int32 opRes, Int32 encrypted)) 365370b324cSopenharmony_ci{ 366370b324cSopenharmony_ci switch (opRes) 367370b324cSopenharmony_ci { 368370b324cSopenharmony_ci case NArchive::NExtract::NOperationResult::kOK: 369370b324cSopenharmony_ci break; 370370b324cSopenharmony_ci default: 371370b324cSopenharmony_ci { 372370b324cSopenharmony_ci UString s; 373370b324cSopenharmony_ci SetExtractErrorMessage(opRes, encrypted, _currentFilePath, s); 374370b324cSopenharmony_ci Add_ArchiveName_Error(); 375370b324cSopenharmony_ci AddError_Message(s); 376370b324cSopenharmony_ci } 377370b324cSopenharmony_ci } 378370b324cSopenharmony_ci 379370b324cSopenharmony_ci #ifndef Z7_SFX 380370b324cSopenharmony_ci if (_isFolder) 381370b324cSopenharmony_ci NumFolders++; 382370b324cSopenharmony_ci else 383370b324cSopenharmony_ci NumFiles++; 384370b324cSopenharmony_ci ProgressDialog->Sync.Set_NumFilesCur(NumFiles); 385370b324cSopenharmony_ci #endif 386370b324cSopenharmony_ci 387370b324cSopenharmony_ci return S_OK; 388370b324cSopenharmony_ci} 389370b324cSopenharmony_ci 390370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::ReportExtractResult(Int32 opRes, Int32 encrypted, const wchar_t *name)) 391370b324cSopenharmony_ci{ 392370b324cSopenharmony_ci if (opRes != NArchive::NExtract::NOperationResult::kOK) 393370b324cSopenharmony_ci { 394370b324cSopenharmony_ci UString s; 395370b324cSopenharmony_ci SetExtractErrorMessage(opRes, encrypted, name, s); 396370b324cSopenharmony_ci Add_ArchiveName_Error(); 397370b324cSopenharmony_ci AddError_Message(s); 398370b324cSopenharmony_ci } 399370b324cSopenharmony_ci return S_OK; 400370b324cSopenharmony_ci} 401370b324cSopenharmony_ci 402370b324cSopenharmony_ci//////////////////////////////////////// 403370b324cSopenharmony_ci// IExtractCallbackUI 404370b324cSopenharmony_ci 405370b324cSopenharmony_ciHRESULT CExtractCallbackImp::BeforeOpen(const wchar_t *name, bool /* testMode */) 406370b324cSopenharmony_ci{ 407370b324cSopenharmony_ci #ifndef Z7_SFX 408370b324cSopenharmony_ci RINOK(ProgressDialog->Sync.CheckStop()) 409370b324cSopenharmony_ci ProgressDialog->Sync.Set_TitleFileName(name); 410370b324cSopenharmony_ci #endif 411370b324cSopenharmony_ci _currentArchivePath = name; 412370b324cSopenharmony_ci return S_OK; 413370b324cSopenharmony_ci} 414370b324cSopenharmony_ci 415370b324cSopenharmony_ciHRESULT CExtractCallbackImp::SetCurrentFilePath2(const wchar_t *path) 416370b324cSopenharmony_ci{ 417370b324cSopenharmony_ci _currentFilePath = path; 418370b324cSopenharmony_ci #ifndef Z7_SFX 419370b324cSopenharmony_ci ProgressDialog->Sync.Set_FilePath(path); 420370b324cSopenharmony_ci #endif 421370b324cSopenharmony_ci return S_OK; 422370b324cSopenharmony_ci} 423370b324cSopenharmony_ci 424370b324cSopenharmony_ci#ifndef Z7_SFX 425370b324cSopenharmony_ci 426370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::SetCurrentFilePath(const wchar_t *path)) 427370b324cSopenharmony_ci{ 428370b324cSopenharmony_ci #ifndef Z7_SFX 429370b324cSopenharmony_ci if (NeedAddFile) 430370b324cSopenharmony_ci NumFiles++; 431370b324cSopenharmony_ci NeedAddFile = true; 432370b324cSopenharmony_ci ProgressDialog->Sync.Set_NumFilesCur(NumFiles); 433370b324cSopenharmony_ci #endif 434370b324cSopenharmony_ci return SetCurrentFilePath2(path); 435370b324cSopenharmony_ci} 436370b324cSopenharmony_ci 437370b324cSopenharmony_ci#endif 438370b324cSopenharmony_ci 439370b324cSopenharmony_ciUString HResultToMessage(HRESULT errorCode); 440370b324cSopenharmony_ci 441370b324cSopenharmony_cistatic const UInt32 k_ErrorFlagsIds[] = 442370b324cSopenharmony_ci{ 443370b324cSopenharmony_ci IDS_EXTRACT_MSG_IS_NOT_ARC, 444370b324cSopenharmony_ci IDS_EXTRACT_MSG_HEADERS_ERROR, 445370b324cSopenharmony_ci IDS_EXTRACT_MSG_HEADERS_ERROR, 446370b324cSopenharmony_ci IDS_OPEN_MSG_UNAVAILABLE_START, 447370b324cSopenharmony_ci IDS_OPEN_MSG_UNCONFIRMED_START, 448370b324cSopenharmony_ci IDS_EXTRACT_MSG_UEXPECTED_END, 449370b324cSopenharmony_ci IDS_EXTRACT_MSG_DATA_AFTER_END, 450370b324cSopenharmony_ci IDS_EXTRACT_MSG_UNSUPPORTED_METHOD, 451370b324cSopenharmony_ci IDS_OPEN_MSG_UNSUPPORTED_FEATURE, 452370b324cSopenharmony_ci IDS_EXTRACT_MSG_DATA_ERROR, 453370b324cSopenharmony_ci IDS_EXTRACT_MSG_CRC_ERROR 454370b324cSopenharmony_ci}; 455370b324cSopenharmony_ci 456370b324cSopenharmony_cistatic void AddNewLineString(UString &s, const UString &m) 457370b324cSopenharmony_ci{ 458370b324cSopenharmony_ci s += m; 459370b324cSopenharmony_ci s.Add_LF(); 460370b324cSopenharmony_ci} 461370b324cSopenharmony_ci 462370b324cSopenharmony_ciUString GetOpenArcErrorMessage(UInt32 errorFlags); 463370b324cSopenharmony_ciUString GetOpenArcErrorMessage(UInt32 errorFlags) 464370b324cSopenharmony_ci{ 465370b324cSopenharmony_ci UString s; 466370b324cSopenharmony_ci 467370b324cSopenharmony_ci for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_ErrorFlagsIds); i++) 468370b324cSopenharmony_ci { 469370b324cSopenharmony_ci UInt32 f = ((UInt32)1 << i); 470370b324cSopenharmony_ci if ((errorFlags & f) == 0) 471370b324cSopenharmony_ci continue; 472370b324cSopenharmony_ci UInt32 id = k_ErrorFlagsIds[i]; 473370b324cSopenharmony_ci UString m = LangString(id); 474370b324cSopenharmony_ci if (m.IsEmpty()) 475370b324cSopenharmony_ci continue; 476370b324cSopenharmony_ci if (f == kpv_ErrorFlags_EncryptedHeadersError) 477370b324cSopenharmony_ci { 478370b324cSopenharmony_ci m += " : "; 479370b324cSopenharmony_ci AddLangString(m, IDS_EXTRACT_MSG_WRONG_PSW_GUESS); 480370b324cSopenharmony_ci } 481370b324cSopenharmony_ci if (!s.IsEmpty()) 482370b324cSopenharmony_ci s.Add_LF(); 483370b324cSopenharmony_ci s += m; 484370b324cSopenharmony_ci errorFlags &= ~f; 485370b324cSopenharmony_ci } 486370b324cSopenharmony_ci 487370b324cSopenharmony_ci if (errorFlags != 0) 488370b324cSopenharmony_ci { 489370b324cSopenharmony_ci char sz[16]; 490370b324cSopenharmony_ci sz[0] = '0'; 491370b324cSopenharmony_ci sz[1] = 'x'; 492370b324cSopenharmony_ci ConvertUInt32ToHex(errorFlags, sz + 2); 493370b324cSopenharmony_ci if (!s.IsEmpty()) 494370b324cSopenharmony_ci s.Add_LF(); 495370b324cSopenharmony_ci s += sz; 496370b324cSopenharmony_ci } 497370b324cSopenharmony_ci 498370b324cSopenharmony_ci return s; 499370b324cSopenharmony_ci} 500370b324cSopenharmony_ci 501370b324cSopenharmony_cistatic void ErrorInfo_Print(UString &s, const CArcErrorInfo &er) 502370b324cSopenharmony_ci{ 503370b324cSopenharmony_ci UInt32 errorFlags = er.GetErrorFlags(); 504370b324cSopenharmony_ci UInt32 warningFlags = er.GetWarningFlags(); 505370b324cSopenharmony_ci 506370b324cSopenharmony_ci if (errorFlags != 0) 507370b324cSopenharmony_ci AddNewLineString(s, GetOpenArcErrorMessage(errorFlags)); 508370b324cSopenharmony_ci 509370b324cSopenharmony_ci if (!er.ErrorMessage.IsEmpty()) 510370b324cSopenharmony_ci AddNewLineString(s, er.ErrorMessage); 511370b324cSopenharmony_ci 512370b324cSopenharmony_ci if (warningFlags != 0) 513370b324cSopenharmony_ci { 514370b324cSopenharmony_ci s += GetNameOfProperty(kpidWarningFlags, L"Warnings"); 515370b324cSopenharmony_ci s += ":"; 516370b324cSopenharmony_ci s.Add_LF(); 517370b324cSopenharmony_ci AddNewLineString(s, GetOpenArcErrorMessage(warningFlags)); 518370b324cSopenharmony_ci } 519370b324cSopenharmony_ci 520370b324cSopenharmony_ci if (!er.WarningMessage.IsEmpty()) 521370b324cSopenharmony_ci { 522370b324cSopenharmony_ci s += GetNameOfProperty(kpidWarning, L"Warning"); 523370b324cSopenharmony_ci s += ": "; 524370b324cSopenharmony_ci s += er.WarningMessage; 525370b324cSopenharmony_ci s.Add_LF(); 526370b324cSopenharmony_ci } 527370b324cSopenharmony_ci} 528370b324cSopenharmony_ci 529370b324cSopenharmony_cistatic UString GetBracedType(const wchar_t *type) 530370b324cSopenharmony_ci{ 531370b324cSopenharmony_ci UString s ('['); 532370b324cSopenharmony_ci s += type; 533370b324cSopenharmony_ci s += ']'; 534370b324cSopenharmony_ci return s; 535370b324cSopenharmony_ci} 536370b324cSopenharmony_ci 537370b324cSopenharmony_civoid OpenResult_GUI(UString &s, const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result); 538370b324cSopenharmony_civoid OpenResult_GUI(UString &s, const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result) 539370b324cSopenharmony_ci{ 540370b324cSopenharmony_ci FOR_VECTOR (level, arcLink.Arcs) 541370b324cSopenharmony_ci { 542370b324cSopenharmony_ci const CArc &arc = arcLink.Arcs[level]; 543370b324cSopenharmony_ci const CArcErrorInfo &er = arc.ErrorInfo; 544370b324cSopenharmony_ci 545370b324cSopenharmony_ci if (!er.IsThereErrorOrWarning() && er.ErrorFormatIndex < 0) 546370b324cSopenharmony_ci continue; 547370b324cSopenharmony_ci 548370b324cSopenharmony_ci if (s.IsEmpty()) 549370b324cSopenharmony_ci { 550370b324cSopenharmony_ci s += name; 551370b324cSopenharmony_ci s.Add_LF(); 552370b324cSopenharmony_ci } 553370b324cSopenharmony_ci 554370b324cSopenharmony_ci if (level != 0) 555370b324cSopenharmony_ci { 556370b324cSopenharmony_ci AddNewLineString(s, arc.Path); 557370b324cSopenharmony_ci } 558370b324cSopenharmony_ci 559370b324cSopenharmony_ci ErrorInfo_Print(s, er); 560370b324cSopenharmony_ci 561370b324cSopenharmony_ci if (er.ErrorFormatIndex >= 0) 562370b324cSopenharmony_ci { 563370b324cSopenharmony_ci AddNewLineString(s, GetNameOfProperty(kpidWarning, L"Warning")); 564370b324cSopenharmony_ci if (arc.FormatIndex == er.ErrorFormatIndex) 565370b324cSopenharmony_ci { 566370b324cSopenharmony_ci AddNewLineString(s, LangString(IDS_IS_OPEN_WITH_OFFSET)); 567370b324cSopenharmony_ci } 568370b324cSopenharmony_ci else 569370b324cSopenharmony_ci { 570370b324cSopenharmony_ci AddNewLineString(s, MyFormatNew(IDS_CANT_OPEN_AS_TYPE, GetBracedType(codecs->GetFormatNamePtr(er.ErrorFormatIndex)))); 571370b324cSopenharmony_ci AddNewLineString(s, MyFormatNew(IDS_IS_OPEN_AS_TYPE, GetBracedType(codecs->GetFormatNamePtr(arc.FormatIndex)))); 572370b324cSopenharmony_ci } 573370b324cSopenharmony_ci } 574370b324cSopenharmony_ci } 575370b324cSopenharmony_ci 576370b324cSopenharmony_ci if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0 || result != S_OK) 577370b324cSopenharmony_ci { 578370b324cSopenharmony_ci s += name; 579370b324cSopenharmony_ci s.Add_LF(); 580370b324cSopenharmony_ci if (!arcLink.Arcs.IsEmpty()) 581370b324cSopenharmony_ci AddNewLineString(s, arcLink.NonOpen_ArcPath); 582370b324cSopenharmony_ci 583370b324cSopenharmony_ci if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0 || result == S_FALSE) 584370b324cSopenharmony_ci { 585370b324cSopenharmony_ci UINT id = IDS_CANT_OPEN_ARCHIVE; 586370b324cSopenharmony_ci UString param; 587370b324cSopenharmony_ci if (arcLink.PasswordWasAsked) 588370b324cSopenharmony_ci id = IDS_CANT_OPEN_ENCRYPTED_ARCHIVE; 589370b324cSopenharmony_ci else if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0) 590370b324cSopenharmony_ci { 591370b324cSopenharmony_ci id = IDS_CANT_OPEN_AS_TYPE; 592370b324cSopenharmony_ci param = GetBracedType(codecs->GetFormatNamePtr(arcLink.NonOpen_ErrorInfo.ErrorFormatIndex)); 593370b324cSopenharmony_ci } 594370b324cSopenharmony_ci UString s2 = MyFormatNew(id, param); 595370b324cSopenharmony_ci s2.Replace(L" ''", L""); 596370b324cSopenharmony_ci s2.Replace(L"''", L""); 597370b324cSopenharmony_ci s += s2; 598370b324cSopenharmony_ci } 599370b324cSopenharmony_ci else 600370b324cSopenharmony_ci s += HResultToMessage(result); 601370b324cSopenharmony_ci 602370b324cSopenharmony_ci s.Add_LF(); 603370b324cSopenharmony_ci ErrorInfo_Print(s, arcLink.NonOpen_ErrorInfo); 604370b324cSopenharmony_ci } 605370b324cSopenharmony_ci 606370b324cSopenharmony_ci if (!s.IsEmpty() && s.Back() == '\n') 607370b324cSopenharmony_ci s.DeleteBack(); 608370b324cSopenharmony_ci} 609370b324cSopenharmony_ci 610370b324cSopenharmony_ciHRESULT CExtractCallbackImp::OpenResult(const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result) 611370b324cSopenharmony_ci{ 612370b324cSopenharmony_ci _currentArchivePath = name; 613370b324cSopenharmony_ci _needWriteArchivePath = true; 614370b324cSopenharmony_ci 615370b324cSopenharmony_ci UString s; 616370b324cSopenharmony_ci OpenResult_GUI(s, codecs, arcLink, name, result); 617370b324cSopenharmony_ci if (!s.IsEmpty()) 618370b324cSopenharmony_ci { 619370b324cSopenharmony_ci NumArchiveErrors++; 620370b324cSopenharmony_ci AddError_Message(s); 621370b324cSopenharmony_ci _needWriteArchivePath = false; 622370b324cSopenharmony_ci } 623370b324cSopenharmony_ci 624370b324cSopenharmony_ci return S_OK; 625370b324cSopenharmony_ci} 626370b324cSopenharmony_ci 627370b324cSopenharmony_ciHRESULT CExtractCallbackImp::ThereAreNoFiles() 628370b324cSopenharmony_ci{ 629370b324cSopenharmony_ci return S_OK; 630370b324cSopenharmony_ci} 631370b324cSopenharmony_ci 632370b324cSopenharmony_civoid CExtractCallbackImp::Add_ArchiveName_Error() 633370b324cSopenharmony_ci{ 634370b324cSopenharmony_ci if (_needWriteArchivePath) 635370b324cSopenharmony_ci { 636370b324cSopenharmony_ci if (!_currentArchivePath.IsEmpty()) 637370b324cSopenharmony_ci AddError_Message(_currentArchivePath); 638370b324cSopenharmony_ci _needWriteArchivePath = false; 639370b324cSopenharmony_ci } 640370b324cSopenharmony_ci} 641370b324cSopenharmony_ci 642370b324cSopenharmony_ciHRESULT CExtractCallbackImp::ExtractResult(HRESULT result) 643370b324cSopenharmony_ci{ 644370b324cSopenharmony_ci if (result == S_OK) 645370b324cSopenharmony_ci return result; 646370b324cSopenharmony_ci NumArchiveErrors++; 647370b324cSopenharmony_ci if (result == E_ABORT 648370b324cSopenharmony_ci || result == HRESULT_FROM_WIN32(ERROR_DISK_FULL) 649370b324cSopenharmony_ci ) 650370b324cSopenharmony_ci return result; 651370b324cSopenharmony_ci 652370b324cSopenharmony_ci Add_ArchiveName_Error(); 653370b324cSopenharmony_ci if (!_currentFilePath.IsEmpty()) 654370b324cSopenharmony_ci MessageError(_currentFilePath); 655370b324cSopenharmony_ci MessageError(NError::MyFormatMessage(result)); 656370b324cSopenharmony_ci return S_OK; 657370b324cSopenharmony_ci} 658370b324cSopenharmony_ci 659370b324cSopenharmony_ci#ifndef Z7_NO_CRYPTO 660370b324cSopenharmony_ci 661370b324cSopenharmony_ciHRESULT CExtractCallbackImp::SetPassword(const UString &password) 662370b324cSopenharmony_ci{ 663370b324cSopenharmony_ci PasswordIsDefined = true; 664370b324cSopenharmony_ci Password = password; 665370b324cSopenharmony_ci return S_OK; 666370b324cSopenharmony_ci} 667370b324cSopenharmony_ci 668370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::CryptoGetTextPassword(BSTR *password)) 669370b324cSopenharmony_ci{ 670370b324cSopenharmony_ci PasswordWasAsked = true; 671370b324cSopenharmony_ci if (!PasswordIsDefined) 672370b324cSopenharmony_ci { 673370b324cSopenharmony_ci CPasswordDialog dialog; 674370b324cSopenharmony_ci #ifndef Z7_SFX 675370b324cSopenharmony_ci const bool showPassword = NExtract::Read_ShowPassword(); 676370b324cSopenharmony_ci dialog.ShowPassword = showPassword; 677370b324cSopenharmony_ci #endif 678370b324cSopenharmony_ci ProgressDialog->WaitCreating(); 679370b324cSopenharmony_ci if (dialog.Create(*ProgressDialog) != IDOK) 680370b324cSopenharmony_ci return E_ABORT; 681370b324cSopenharmony_ci Password = dialog.Password; 682370b324cSopenharmony_ci PasswordIsDefined = true; 683370b324cSopenharmony_ci #ifndef Z7_SFX 684370b324cSopenharmony_ci if (dialog.ShowPassword != showPassword) 685370b324cSopenharmony_ci NExtract::Save_ShowPassword(dialog.ShowPassword); 686370b324cSopenharmony_ci #endif 687370b324cSopenharmony_ci } 688370b324cSopenharmony_ci return StringToBstr(Password, password); 689370b324cSopenharmony_ci} 690370b324cSopenharmony_ci 691370b324cSopenharmony_ci#endif 692370b324cSopenharmony_ci 693370b324cSopenharmony_ci#ifndef Z7_SFX 694370b324cSopenharmony_ci 695370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::AskWrite( 696370b324cSopenharmony_ci const wchar_t *srcPath, Int32 srcIsFolder, 697370b324cSopenharmony_ci const FILETIME *srcTime, const UInt64 *srcSize, 698370b324cSopenharmony_ci const wchar_t *destPath, 699370b324cSopenharmony_ci BSTR *destPathResult, 700370b324cSopenharmony_ci Int32 *writeAnswer)) 701370b324cSopenharmony_ci{ 702370b324cSopenharmony_ci UString destPathResultTemp = destPath; 703370b324cSopenharmony_ci 704370b324cSopenharmony_ci // RINOK(StringToBstr(destPath, destPathResult)); 705370b324cSopenharmony_ci 706370b324cSopenharmony_ci *destPathResult = NULL; 707370b324cSopenharmony_ci *writeAnswer = BoolToInt(false); 708370b324cSopenharmony_ci 709370b324cSopenharmony_ci FString destPathSys = us2fs(destPath); 710370b324cSopenharmony_ci const bool srcIsFolderSpec = IntToBool(srcIsFolder); 711370b324cSopenharmony_ci CFileInfo destFileInfo; 712370b324cSopenharmony_ci 713370b324cSopenharmony_ci if (destFileInfo.Find(destPathSys)) 714370b324cSopenharmony_ci { 715370b324cSopenharmony_ci if (srcIsFolderSpec) 716370b324cSopenharmony_ci { 717370b324cSopenharmony_ci if (!destFileInfo.IsDir()) 718370b324cSopenharmony_ci { 719370b324cSopenharmony_ci RINOK(MessageError("Cannot replace file with folder with same name", destPathSys)) 720370b324cSopenharmony_ci return E_ABORT; 721370b324cSopenharmony_ci } 722370b324cSopenharmony_ci *writeAnswer = BoolToInt(false); 723370b324cSopenharmony_ci return S_OK; 724370b324cSopenharmony_ci } 725370b324cSopenharmony_ci 726370b324cSopenharmony_ci if (destFileInfo.IsDir()) 727370b324cSopenharmony_ci { 728370b324cSopenharmony_ci RINOK(MessageError("Cannot replace folder with file with same name", destPathSys)) 729370b324cSopenharmony_ci *writeAnswer = BoolToInt(false); 730370b324cSopenharmony_ci return S_OK; 731370b324cSopenharmony_ci } 732370b324cSopenharmony_ci 733370b324cSopenharmony_ci switch ((int)OverwriteMode) 734370b324cSopenharmony_ci { 735370b324cSopenharmony_ci case NExtract::NOverwriteMode::kSkip: 736370b324cSopenharmony_ci return S_OK; 737370b324cSopenharmony_ci case NExtract::NOverwriteMode::kAsk: 738370b324cSopenharmony_ci { 739370b324cSopenharmony_ci Int32 overwriteResult; 740370b324cSopenharmony_ci UString destPathSpec = destPath; 741370b324cSopenharmony_ci const int slashPos = destPathSpec.ReverseFind_PathSepar(); 742370b324cSopenharmony_ci destPathSpec.DeleteFrom((unsigned)(slashPos + 1)); 743370b324cSopenharmony_ci destPathSpec += fs2us(destFileInfo.Name); 744370b324cSopenharmony_ci 745370b324cSopenharmony_ci RINOK(AskOverwrite( 746370b324cSopenharmony_ci destPathSpec, 747370b324cSopenharmony_ci &destFileInfo.MTime, &destFileInfo.Size, 748370b324cSopenharmony_ci srcPath, 749370b324cSopenharmony_ci srcTime, srcSize, 750370b324cSopenharmony_ci &overwriteResult)) 751370b324cSopenharmony_ci 752370b324cSopenharmony_ci switch (overwriteResult) 753370b324cSopenharmony_ci { 754370b324cSopenharmony_ci case NOverwriteAnswer::kCancel: return E_ABORT; 755370b324cSopenharmony_ci case NOverwriteAnswer::kNo: return S_OK; 756370b324cSopenharmony_ci case NOverwriteAnswer::kNoToAll: OverwriteMode = NExtract::NOverwriteMode::kSkip; return S_OK; 757370b324cSopenharmony_ci case NOverwriteAnswer::kYes: break; 758370b324cSopenharmony_ci case NOverwriteAnswer::kYesToAll: OverwriteMode = NExtract::NOverwriteMode::kOverwrite; break; 759370b324cSopenharmony_ci case NOverwriteAnswer::kAutoRename: OverwriteMode = NExtract::NOverwriteMode::kRename; break; 760370b324cSopenharmony_ci default: 761370b324cSopenharmony_ci return E_FAIL; 762370b324cSopenharmony_ci } 763370b324cSopenharmony_ci break; 764370b324cSopenharmony_ci } 765370b324cSopenharmony_ci default: 766370b324cSopenharmony_ci break; 767370b324cSopenharmony_ci } 768370b324cSopenharmony_ci 769370b324cSopenharmony_ci if (OverwriteMode == NExtract::NOverwriteMode::kRename) 770370b324cSopenharmony_ci { 771370b324cSopenharmony_ci if (!AutoRenamePath(destPathSys)) 772370b324cSopenharmony_ci { 773370b324cSopenharmony_ci RINOK(MessageError("Cannot create name for file", destPathSys)) 774370b324cSopenharmony_ci return E_ABORT; 775370b324cSopenharmony_ci } 776370b324cSopenharmony_ci destPathResultTemp = fs2us(destPathSys); 777370b324cSopenharmony_ci } 778370b324cSopenharmony_ci else 779370b324cSopenharmony_ci { 780370b324cSopenharmony_ci if (NFind::DoesFileExist_Raw(destPathSys)) 781370b324cSopenharmony_ci if (!NDir::DeleteFileAlways(destPathSys)) 782370b324cSopenharmony_ci if (GetLastError() != ERROR_FILE_NOT_FOUND) 783370b324cSopenharmony_ci { 784370b324cSopenharmony_ci RINOK(MessageError("Cannot delete output file", destPathSys)) 785370b324cSopenharmony_ci return E_ABORT; 786370b324cSopenharmony_ci } 787370b324cSopenharmony_ci } 788370b324cSopenharmony_ci } 789370b324cSopenharmony_ci *writeAnswer = BoolToInt(true); 790370b324cSopenharmony_ci return StringToBstr(destPathResultTemp, destPathResult); 791370b324cSopenharmony_ci} 792370b324cSopenharmony_ci 793370b324cSopenharmony_ci 794370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::UseExtractToStream(Int32 *res)) 795370b324cSopenharmony_ci{ 796370b324cSopenharmony_ci *res = BoolToInt(StreamMode); 797370b324cSopenharmony_ci return S_OK; 798370b324cSopenharmony_ci} 799370b324cSopenharmony_ci 800370b324cSopenharmony_cistatic HRESULT GetTime(IGetProp *getProp, PROPID propID, FILETIME &ft, bool &ftDefined) 801370b324cSopenharmony_ci{ 802370b324cSopenharmony_ci ftDefined = false; 803370b324cSopenharmony_ci NCOM::CPropVariant prop; 804370b324cSopenharmony_ci RINOK(getProp->GetProp(propID, &prop)) 805370b324cSopenharmony_ci if (prop.vt == VT_FILETIME) 806370b324cSopenharmony_ci { 807370b324cSopenharmony_ci ft = prop.filetime; 808370b324cSopenharmony_ci ftDefined = (ft.dwHighDateTime != 0 || ft.dwLowDateTime != 0); 809370b324cSopenharmony_ci } 810370b324cSopenharmony_ci else if (prop.vt != VT_EMPTY) 811370b324cSopenharmony_ci return E_FAIL; 812370b324cSopenharmony_ci return S_OK; 813370b324cSopenharmony_ci} 814370b324cSopenharmony_ci 815370b324cSopenharmony_ci 816370b324cSopenharmony_cistatic HRESULT GetItemBoolProp(IGetProp *getProp, PROPID propID, bool &result) 817370b324cSopenharmony_ci{ 818370b324cSopenharmony_ci NCOM::CPropVariant prop; 819370b324cSopenharmony_ci result = false; 820370b324cSopenharmony_ci RINOK(getProp->GetProp(propID, &prop)) 821370b324cSopenharmony_ci if (prop.vt == VT_BOOL) 822370b324cSopenharmony_ci result = VARIANT_BOOLToBool(prop.boolVal); 823370b324cSopenharmony_ci else if (prop.vt != VT_EMPTY) 824370b324cSopenharmony_ci return E_FAIL; 825370b324cSopenharmony_ci return S_OK; 826370b324cSopenharmony_ci} 827370b324cSopenharmony_ci 828370b324cSopenharmony_ci 829370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::GetStream7(const wchar_t *name, 830370b324cSopenharmony_ci Int32 isDir, 831370b324cSopenharmony_ci ISequentialOutStream **outStream, Int32 askExtractMode, 832370b324cSopenharmony_ci IGetProp *getProp)) 833370b324cSopenharmony_ci{ 834370b324cSopenharmony_ci COM_TRY_BEGIN 835370b324cSopenharmony_ci *outStream = NULL; 836370b324cSopenharmony_ci _newVirtFileWasAdded = false; 837370b324cSopenharmony_ci _hashStreamWasUsed = false; 838370b324cSopenharmony_ci _needUpdateStat = false; 839370b324cSopenharmony_ci 840370b324cSopenharmony_ci if (_hashStream) 841370b324cSopenharmony_ci _hashStreamSpec->ReleaseStream(); 842370b324cSopenharmony_ci 843370b324cSopenharmony_ci GetItemBoolProp(getProp, kpidIsAltStream, _isAltStream); 844370b324cSopenharmony_ci 845370b324cSopenharmony_ci if (!ProcessAltStreams && _isAltStream) 846370b324cSopenharmony_ci return S_OK; 847370b324cSopenharmony_ci 848370b324cSopenharmony_ci _filePath = name; 849370b324cSopenharmony_ci _isFolder = IntToBool(isDir); 850370b324cSopenharmony_ci _curSize = 0; 851370b324cSopenharmony_ci _curSize_Defined = false; 852370b324cSopenharmony_ci 853370b324cSopenharmony_ci UInt64 size = 0; 854370b324cSopenharmony_ci bool sizeDefined; 855370b324cSopenharmony_ci { 856370b324cSopenharmony_ci NCOM::CPropVariant prop; 857370b324cSopenharmony_ci RINOK(getProp->GetProp(kpidSize, &prop)) 858370b324cSopenharmony_ci sizeDefined = ConvertPropVariantToUInt64(prop, size); 859370b324cSopenharmony_ci } 860370b324cSopenharmony_ci 861370b324cSopenharmony_ci if (sizeDefined) 862370b324cSopenharmony_ci { 863370b324cSopenharmony_ci _curSize = size; 864370b324cSopenharmony_ci _curSize_Defined = true; 865370b324cSopenharmony_ci } 866370b324cSopenharmony_ci 867370b324cSopenharmony_ci if (askExtractMode != NArchive::NExtract::NAskMode::kExtract && 868370b324cSopenharmony_ci askExtractMode != NArchive::NExtract::NAskMode::kTest) 869370b324cSopenharmony_ci return S_OK; 870370b324cSopenharmony_ci 871370b324cSopenharmony_ci _needUpdateStat = true; 872370b324cSopenharmony_ci 873370b324cSopenharmony_ci CMyComPtr<ISequentialOutStream> outStreamLoc; 874370b324cSopenharmony_ci 875370b324cSopenharmony_ci if (VirtFileSystem && askExtractMode == NArchive::NExtract::NAskMode::kExtract) 876370b324cSopenharmony_ci { 877370b324cSopenharmony_ci CVirtFile &file = VirtFileSystemSpec->AddNewFile(); 878370b324cSopenharmony_ci _newVirtFileWasAdded = true; 879370b324cSopenharmony_ci file.Name = name; 880370b324cSopenharmony_ci file.IsDir = IntToBool(isDir); 881370b324cSopenharmony_ci file.IsAltStream = _isAltStream; 882370b324cSopenharmony_ci file.Size = 0; 883370b324cSopenharmony_ci 884370b324cSopenharmony_ci RINOK(GetTime(getProp, kpidCTime, file.CTime, file.CTimeDefined)) 885370b324cSopenharmony_ci RINOK(GetTime(getProp, kpidATime, file.ATime, file.ATimeDefined)) 886370b324cSopenharmony_ci RINOK(GetTime(getProp, kpidMTime, file.MTime, file.MTimeDefined)) 887370b324cSopenharmony_ci 888370b324cSopenharmony_ci NCOM::CPropVariant prop; 889370b324cSopenharmony_ci RINOK(getProp->GetProp(kpidAttrib, &prop)) 890370b324cSopenharmony_ci if (prop.vt == VT_UI4) 891370b324cSopenharmony_ci { 892370b324cSopenharmony_ci file.Attrib = prop.ulVal; 893370b324cSopenharmony_ci file.AttribDefined = true; 894370b324cSopenharmony_ci } 895370b324cSopenharmony_ci // else if (isDir) file.Attrib = FILE_ATTRIBUTE_DIRECTORY; 896370b324cSopenharmony_ci 897370b324cSopenharmony_ci file.ExpectedSize = 0; 898370b324cSopenharmony_ci if (sizeDefined) 899370b324cSopenharmony_ci file.ExpectedSize = size; 900370b324cSopenharmony_ci outStreamLoc = VirtFileSystem; 901370b324cSopenharmony_ci } 902370b324cSopenharmony_ci 903370b324cSopenharmony_ci if (_hashStream) 904370b324cSopenharmony_ci { 905370b324cSopenharmony_ci { 906370b324cSopenharmony_ci _hashStreamSpec->SetStream(outStreamLoc); 907370b324cSopenharmony_ci outStreamLoc = _hashStream; 908370b324cSopenharmony_ci _hashStreamSpec->Init(true); 909370b324cSopenharmony_ci _hashStreamWasUsed = true; 910370b324cSopenharmony_ci } 911370b324cSopenharmony_ci } 912370b324cSopenharmony_ci 913370b324cSopenharmony_ci if (outStreamLoc) 914370b324cSopenharmony_ci *outStream = outStreamLoc.Detach(); 915370b324cSopenharmony_ci return S_OK; 916370b324cSopenharmony_ci COM_TRY_END 917370b324cSopenharmony_ci} 918370b324cSopenharmony_ci 919370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::PrepareOperation7(Int32 askExtractMode)) 920370b324cSopenharmony_ci{ 921370b324cSopenharmony_ci COM_TRY_BEGIN 922370b324cSopenharmony_ci _needUpdateStat = ( 923370b324cSopenharmony_ci askExtractMode == NArchive::NExtract::NAskMode::kExtract 924370b324cSopenharmony_ci || askExtractMode == NArchive::NExtract::NAskMode::kTest 925370b324cSopenharmony_ci || askExtractMode == NArchive::NExtract::NAskMode::kReadExternal 926370b324cSopenharmony_ci ); 927370b324cSopenharmony_ci 928370b324cSopenharmony_ci /* 929370b324cSopenharmony_ci _extractMode = false; 930370b324cSopenharmony_ci switch (askExtractMode) 931370b324cSopenharmony_ci { 932370b324cSopenharmony_ci case NArchive::NExtract::NAskMode::kExtract: 933370b324cSopenharmony_ci if (_testMode) 934370b324cSopenharmony_ci askExtractMode = NArchive::NExtract::NAskMode::kTest; 935370b324cSopenharmony_ci else 936370b324cSopenharmony_ci _extractMode = true; 937370b324cSopenharmony_ci break; 938370b324cSopenharmony_ci }; 939370b324cSopenharmony_ci */ 940370b324cSopenharmony_ci return SetCurrentFilePath2(_filePath); 941370b324cSopenharmony_ci COM_TRY_END 942370b324cSopenharmony_ci} 943370b324cSopenharmony_ci 944370b324cSopenharmony_ciZ7_COM7F_IMF(CExtractCallbackImp::SetOperationResult8(Int32 opRes, Int32 encrypted, UInt64 size)) 945370b324cSopenharmony_ci{ 946370b324cSopenharmony_ci COM_TRY_BEGIN 947370b324cSopenharmony_ci if (VirtFileSystem && _newVirtFileWasAdded) 948370b324cSopenharmony_ci { 949370b324cSopenharmony_ci // FIXME: probably we must request file size from VirtFileSystem 950370b324cSopenharmony_ci // _curSize = VirtFileSystem->GetLastFileSize() 951370b324cSopenharmony_ci // _curSize_Defined = true; 952370b324cSopenharmony_ci RINOK(VirtFileSystemSpec->CloseMemFile()) 953370b324cSopenharmony_ci } 954370b324cSopenharmony_ci if (_hashStream && _hashStreamWasUsed) 955370b324cSopenharmony_ci { 956370b324cSopenharmony_ci _hashStreamSpec->_hash->Final(_isFolder, _isAltStream, _filePath); 957370b324cSopenharmony_ci _curSize = _hashStreamSpec->GetSize(); 958370b324cSopenharmony_ci _curSize_Defined = true; 959370b324cSopenharmony_ci _hashStreamSpec->ReleaseStream(); 960370b324cSopenharmony_ci _hashStreamWasUsed = false; 961370b324cSopenharmony_ci } 962370b324cSopenharmony_ci else if (_hashCalc && _needUpdateStat) 963370b324cSopenharmony_ci { 964370b324cSopenharmony_ci _hashCalc->SetSize(size); // (_curSize) before 21.04 965370b324cSopenharmony_ci _hashCalc->Final(_isFolder, _isAltStream, _filePath); 966370b324cSopenharmony_ci } 967370b324cSopenharmony_ci return SetOperationResult(opRes, encrypted); 968370b324cSopenharmony_ci COM_TRY_END 969370b324cSopenharmony_ci} 970370b324cSopenharmony_ci 971370b324cSopenharmony_ci 972370b324cSopenharmony_ci 973370b324cSopenharmony_ci// static const UInt32 kBlockSize = ((UInt32)1 << 31); 974370b324cSopenharmony_ci 975370b324cSopenharmony_ciZ7_COM7F_IMF(CVirtFileSystem::Write(const void *data, UInt32 size, UInt32 *processedSize)) 976370b324cSopenharmony_ci{ 977370b324cSopenharmony_ci if (processedSize) 978370b324cSopenharmony_ci *processedSize = 0; 979370b324cSopenharmony_ci if (size == 0) 980370b324cSopenharmony_ci return S_OK; 981370b324cSopenharmony_ci if (!_fileMode) 982370b324cSopenharmony_ci { 983370b324cSopenharmony_ci CVirtFile &file = Files.Back(); 984370b324cSopenharmony_ci size_t rem = file.Data.Size() - (size_t)file.Size; 985370b324cSopenharmony_ci bool useMem = true; 986370b324cSopenharmony_ci if (rem < size) 987370b324cSopenharmony_ci { 988370b324cSopenharmony_ci UInt64 b = 0; 989370b324cSopenharmony_ci if (file.Data.Size() == 0) 990370b324cSopenharmony_ci b = file.ExpectedSize; 991370b324cSopenharmony_ci UInt64 a = file.Size + size; 992370b324cSopenharmony_ci if (b < a) 993370b324cSopenharmony_ci b = a; 994370b324cSopenharmony_ci a = (UInt64)file.Data.Size() * 2; 995370b324cSopenharmony_ci if (b < a) 996370b324cSopenharmony_ci b = a; 997370b324cSopenharmony_ci useMem = false; 998370b324cSopenharmony_ci const size_t b_sizet = (size_t)b; 999370b324cSopenharmony_ci if (b == b_sizet && b <= MaxTotalAllocSize) 1000370b324cSopenharmony_ci useMem = file.Data.ReAlloc_KeepData(b_sizet, (size_t)file.Size); 1001370b324cSopenharmony_ci } 1002370b324cSopenharmony_ci if (useMem) 1003370b324cSopenharmony_ci { 1004370b324cSopenharmony_ci memcpy(file.Data + file.Size, data, size); 1005370b324cSopenharmony_ci file.Size += size; 1006370b324cSopenharmony_ci if (processedSize) 1007370b324cSopenharmony_ci *processedSize = (UInt32)size; 1008370b324cSopenharmony_ci return S_OK; 1009370b324cSopenharmony_ci } 1010370b324cSopenharmony_ci _fileMode = true; 1011370b324cSopenharmony_ci } 1012370b324cSopenharmony_ci RINOK(FlushToDisk(false)) 1013370b324cSopenharmony_ci return _outFileStream->Write(data, size, processedSize); 1014370b324cSopenharmony_ci} 1015370b324cSopenharmony_ci 1016370b324cSopenharmony_ciHRESULT CVirtFileSystem::FlushToDisk(bool closeLast) 1017370b324cSopenharmony_ci{ 1018370b324cSopenharmony_ci if (!_outFileStream) 1019370b324cSopenharmony_ci { 1020370b324cSopenharmony_ci _outFileStreamSpec = new COutFileStream; 1021370b324cSopenharmony_ci _outFileStream = _outFileStreamSpec; 1022370b324cSopenharmony_ci } 1023370b324cSopenharmony_ci while (_numFlushed < Files.Size()) 1024370b324cSopenharmony_ci { 1025370b324cSopenharmony_ci const CVirtFile &file = Files[_numFlushed]; 1026370b324cSopenharmony_ci const FString path = DirPrefix + us2fs(Get_Correct_FsFile_Name(file.Name)); 1027370b324cSopenharmony_ci if (!_fileIsOpen) 1028370b324cSopenharmony_ci { 1029370b324cSopenharmony_ci if (!_outFileStreamSpec->Create(path, false)) 1030370b324cSopenharmony_ci { 1031370b324cSopenharmony_ci _outFileStream.Release(); 1032370b324cSopenharmony_ci return E_FAIL; 1033370b324cSopenharmony_ci // MessageBoxMyError(UString("Can't create file ") + fs2us(tempFilePath)); 1034370b324cSopenharmony_ci } 1035370b324cSopenharmony_ci _fileIsOpen = true; 1036370b324cSopenharmony_ci RINOK(WriteStream(_outFileStream, file.Data, (size_t)file.Size)) 1037370b324cSopenharmony_ci } 1038370b324cSopenharmony_ci if (_numFlushed == Files.Size() - 1 && !closeLast) 1039370b324cSopenharmony_ci break; 1040370b324cSopenharmony_ci if (file.CTimeDefined || 1041370b324cSopenharmony_ci file.ATimeDefined || 1042370b324cSopenharmony_ci file.MTimeDefined) 1043370b324cSopenharmony_ci _outFileStreamSpec->SetTime( 1044370b324cSopenharmony_ci file.CTimeDefined ? &file.CTime : NULL, 1045370b324cSopenharmony_ci file.ATimeDefined ? &file.ATime : NULL, 1046370b324cSopenharmony_ci file.MTimeDefined ? &file.MTime : NULL); 1047370b324cSopenharmony_ci _outFileStreamSpec->Close(); 1048370b324cSopenharmony_ci _numFlushed++; 1049370b324cSopenharmony_ci _fileIsOpen = false; 1050370b324cSopenharmony_ci if (file.AttribDefined) 1051370b324cSopenharmony_ci NDir::SetFileAttrib_PosixHighDetect(path, file.Attrib); 1052370b324cSopenharmony_ci } 1053370b324cSopenharmony_ci return S_OK; 1054370b324cSopenharmony_ci} 1055370b324cSopenharmony_ci 1056370b324cSopenharmony_ci#endif 1057