1370b324cSopenharmony_ci// Client7z.cpp 2370b324cSopenharmony_ci 3370b324cSopenharmony_ci#include "StdAfx.h" 4370b324cSopenharmony_ci 5370b324cSopenharmony_ci#include <stdio.h> 6370b324cSopenharmony_ci 7370b324cSopenharmony_ci#include "../../../Common/MyWindows.h" 8370b324cSopenharmony_ci#include "../../../Common/MyInitGuid.h" 9370b324cSopenharmony_ci 10370b324cSopenharmony_ci#include "../../../Common/Defs.h" 11370b324cSopenharmony_ci#include "../../../Common/IntToString.h" 12370b324cSopenharmony_ci#include "../../../Common/StringConvert.h" 13370b324cSopenharmony_ci 14370b324cSopenharmony_ci#include "../../../Windows/DLL.h" 15370b324cSopenharmony_ci#include "../../../Windows/FileDir.h" 16370b324cSopenharmony_ci#include "../../../Windows/FileFind.h" 17370b324cSopenharmony_ci#include "../../../Windows/FileName.h" 18370b324cSopenharmony_ci#include "../../../Windows/NtCheck.h" 19370b324cSopenharmony_ci#include "../../../Windows/PropVariant.h" 20370b324cSopenharmony_ci#include "../../../Windows/PropVariantConv.h" 21370b324cSopenharmony_ci 22370b324cSopenharmony_ci#include "../../Common/FileStreams.h" 23370b324cSopenharmony_ci 24370b324cSopenharmony_ci#include "../../Archive/IArchive.h" 25370b324cSopenharmony_ci 26370b324cSopenharmony_ci#include "../../IPassword.h" 27370b324cSopenharmony_ci#include "../../../../C/7zVersion.h" 28370b324cSopenharmony_ci 29370b324cSopenharmony_ci#ifdef _WIN32 30370b324cSopenharmony_ciextern 31370b324cSopenharmony_ciHINSTANCE g_hInstance; 32370b324cSopenharmony_ciHINSTANCE g_hInstance = NULL; 33370b324cSopenharmony_ci#endif 34370b324cSopenharmony_ci 35370b324cSopenharmony_ci// You can find full list of all GUIDs supported by 7-Zip in Guid.txt file. 36370b324cSopenharmony_ci// 7z format GUID: {23170F69-40C1-278A-1000-000110070000} 37370b324cSopenharmony_ci 38370b324cSopenharmony_ci#define DEFINE_GUID_ARC(name, id) Z7_DEFINE_GUID(name, \ 39370b324cSopenharmony_ci 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, id, 0x00, 0x00); 40370b324cSopenharmony_ci 41370b324cSopenharmony_cienum 42370b324cSopenharmony_ci{ 43370b324cSopenharmony_ci kId_Zip = 1, 44370b324cSopenharmony_ci kId_BZip2 = 2, 45370b324cSopenharmony_ci kId_7z = 7, 46370b324cSopenharmony_ci kId_Xz = 0xC, 47370b324cSopenharmony_ci kId_Tar = 0xEE, 48370b324cSopenharmony_ci kId_GZip = 0xEF 49370b324cSopenharmony_ci}; 50370b324cSopenharmony_ci 51370b324cSopenharmony_ci// use another id, if you want to support other formats (zip, Xz, ...). 52370b324cSopenharmony_ci// DEFINE_GUID_ARC (CLSID_Format, kId_Zip) 53370b324cSopenharmony_ci// DEFINE_GUID_ARC (CLSID_Format, kId_BZip2) 54370b324cSopenharmony_ci// DEFINE_GUID_ARC (CLSID_Format, kId_Xz) 55370b324cSopenharmony_ci// DEFINE_GUID_ARC (CLSID_Format, kId_Tar) 56370b324cSopenharmony_ci// DEFINE_GUID_ARC (CLSID_Format, kId_GZip) 57370b324cSopenharmony_ciDEFINE_GUID_ARC (CLSID_Format, kId_7z) 58370b324cSopenharmony_ci 59370b324cSopenharmony_ciusing namespace NWindows; 60370b324cSopenharmony_ciusing namespace NFile; 61370b324cSopenharmony_ciusing namespace NDir; 62370b324cSopenharmony_ci 63370b324cSopenharmony_ci#ifdef _WIN32 64370b324cSopenharmony_ci#define kDllName "7z.dll" 65370b324cSopenharmony_ci#else 66370b324cSopenharmony_ci#define kDllName "7z.so" 67370b324cSopenharmony_ci#endif 68370b324cSopenharmony_ci 69370b324cSopenharmony_cistatic const char * const kCopyrightString = 70370b324cSopenharmony_ci "\n" 71370b324cSopenharmony_ci "7-Zip" 72370b324cSopenharmony_ci " (" kDllName " client)" 73370b324cSopenharmony_ci " " MY_VERSION 74370b324cSopenharmony_ci " : " MY_COPYRIGHT_DATE 75370b324cSopenharmony_ci "\n"; 76370b324cSopenharmony_ci 77370b324cSopenharmony_cistatic const char * const kHelpString = 78370b324cSopenharmony_ci"Usage: 7zcl.exe [a | l | x] archive.7z [fileName ...]\n" 79370b324cSopenharmony_ci"Examples:\n" 80370b324cSopenharmony_ci" 7zcl.exe a archive.7z f1.txt f2.txt : compress two files to archive.7z\n" 81370b324cSopenharmony_ci" 7zcl.exe l archive.7z : List contents of archive.7z\n" 82370b324cSopenharmony_ci" 7zcl.exe x archive.7z : eXtract files from archive.7z\n"; 83370b324cSopenharmony_ci 84370b324cSopenharmony_ci 85370b324cSopenharmony_cistatic void Convert_UString_to_AString(const UString &s, AString &temp) 86370b324cSopenharmony_ci{ 87370b324cSopenharmony_ci int codePage = CP_OEMCP; 88370b324cSopenharmony_ci /* 89370b324cSopenharmony_ci int g_CodePage = -1; 90370b324cSopenharmony_ci int codePage = g_CodePage; 91370b324cSopenharmony_ci if (codePage == -1) 92370b324cSopenharmony_ci codePage = CP_OEMCP; 93370b324cSopenharmony_ci if (codePage == CP_UTF8) 94370b324cSopenharmony_ci ConvertUnicodeToUTF8(s, temp); 95370b324cSopenharmony_ci else 96370b324cSopenharmony_ci */ 97370b324cSopenharmony_ci UnicodeStringToMultiByte2(temp, s, (UINT)codePage); 98370b324cSopenharmony_ci} 99370b324cSopenharmony_ci 100370b324cSopenharmony_cistatic FString CmdStringToFString(const char *s) 101370b324cSopenharmony_ci{ 102370b324cSopenharmony_ci return us2fs(GetUnicodeString(s)); 103370b324cSopenharmony_ci} 104370b324cSopenharmony_ci 105370b324cSopenharmony_cistatic void Print(const char *s) 106370b324cSopenharmony_ci{ 107370b324cSopenharmony_ci fputs(s, stdout); 108370b324cSopenharmony_ci} 109370b324cSopenharmony_ci 110370b324cSopenharmony_cistatic void Print(const AString &s) 111370b324cSopenharmony_ci{ 112370b324cSopenharmony_ci Print(s.Ptr()); 113370b324cSopenharmony_ci} 114370b324cSopenharmony_ci 115370b324cSopenharmony_cistatic void Print(const UString &s) 116370b324cSopenharmony_ci{ 117370b324cSopenharmony_ci AString as; 118370b324cSopenharmony_ci Convert_UString_to_AString(s, as); 119370b324cSopenharmony_ci Print(as); 120370b324cSopenharmony_ci} 121370b324cSopenharmony_ci 122370b324cSopenharmony_cistatic void Print(const wchar_t *s) 123370b324cSopenharmony_ci{ 124370b324cSopenharmony_ci Print(UString(s)); 125370b324cSopenharmony_ci} 126370b324cSopenharmony_ci 127370b324cSopenharmony_cistatic void PrintNewLine() 128370b324cSopenharmony_ci{ 129370b324cSopenharmony_ci Print("\n"); 130370b324cSopenharmony_ci} 131370b324cSopenharmony_ci 132370b324cSopenharmony_cistatic void PrintStringLn(const char *s) 133370b324cSopenharmony_ci{ 134370b324cSopenharmony_ci Print(s); 135370b324cSopenharmony_ci PrintNewLine(); 136370b324cSopenharmony_ci} 137370b324cSopenharmony_ci 138370b324cSopenharmony_cistatic void PrintError(const char *message) 139370b324cSopenharmony_ci{ 140370b324cSopenharmony_ci Print("Error: "); 141370b324cSopenharmony_ci PrintNewLine(); 142370b324cSopenharmony_ci Print(message); 143370b324cSopenharmony_ci PrintNewLine(); 144370b324cSopenharmony_ci} 145370b324cSopenharmony_ci 146370b324cSopenharmony_cistatic void PrintError(const char *message, const FString &name) 147370b324cSopenharmony_ci{ 148370b324cSopenharmony_ci PrintError(message); 149370b324cSopenharmony_ci Print(name); 150370b324cSopenharmony_ci} 151370b324cSopenharmony_ci 152370b324cSopenharmony_ci 153370b324cSopenharmony_cistatic HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result) 154370b324cSopenharmony_ci{ 155370b324cSopenharmony_ci NCOM::CPropVariant prop; 156370b324cSopenharmony_ci RINOK(archive->GetProperty(index, propID, &prop)) 157370b324cSopenharmony_ci if (prop.vt == VT_BOOL) 158370b324cSopenharmony_ci result = VARIANT_BOOLToBool(prop.boolVal); 159370b324cSopenharmony_ci else if (prop.vt == VT_EMPTY) 160370b324cSopenharmony_ci result = false; 161370b324cSopenharmony_ci else 162370b324cSopenharmony_ci return E_FAIL; 163370b324cSopenharmony_ci return S_OK; 164370b324cSopenharmony_ci} 165370b324cSopenharmony_ci 166370b324cSopenharmony_cistatic HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result) 167370b324cSopenharmony_ci{ 168370b324cSopenharmony_ci return IsArchiveItemProp(archive, index, kpidIsDir, result); 169370b324cSopenharmony_ci} 170370b324cSopenharmony_ci 171370b324cSopenharmony_ci 172370b324cSopenharmony_cistatic const wchar_t * const kEmptyFileAlias = L"[Content]"; 173370b324cSopenharmony_ci 174370b324cSopenharmony_ci 175370b324cSopenharmony_ci////////////////////////////////////////////////////////////// 176370b324cSopenharmony_ci// Archive Open callback class 177370b324cSopenharmony_ci 178370b324cSopenharmony_ci 179370b324cSopenharmony_ciclass CArchiveOpenCallback Z7_final: 180370b324cSopenharmony_ci public IArchiveOpenCallback, 181370b324cSopenharmony_ci public ICryptoGetTextPassword, 182370b324cSopenharmony_ci public CMyUnknownImp 183370b324cSopenharmony_ci{ 184370b324cSopenharmony_ci Z7_IFACES_IMP_UNK_2(IArchiveOpenCallback, ICryptoGetTextPassword) 185370b324cSopenharmony_cipublic: 186370b324cSopenharmony_ci 187370b324cSopenharmony_ci bool PasswordIsDefined; 188370b324cSopenharmony_ci UString Password; 189370b324cSopenharmony_ci 190370b324cSopenharmony_ci CArchiveOpenCallback() : PasswordIsDefined(false) {} 191370b324cSopenharmony_ci}; 192370b324cSopenharmony_ci 193370b324cSopenharmony_ciZ7_COM7F_IMF(CArchiveOpenCallback::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */)) 194370b324cSopenharmony_ci{ 195370b324cSopenharmony_ci return S_OK; 196370b324cSopenharmony_ci} 197370b324cSopenharmony_ci 198370b324cSopenharmony_ciZ7_COM7F_IMF(CArchiveOpenCallback::SetCompleted(const UInt64 * /* files */, const UInt64 * /* bytes */)) 199370b324cSopenharmony_ci{ 200370b324cSopenharmony_ci return S_OK; 201370b324cSopenharmony_ci} 202370b324cSopenharmony_ci 203370b324cSopenharmony_ciZ7_COM7F_IMF(CArchiveOpenCallback::CryptoGetTextPassword(BSTR *password)) 204370b324cSopenharmony_ci{ 205370b324cSopenharmony_ci if (!PasswordIsDefined) 206370b324cSopenharmony_ci { 207370b324cSopenharmony_ci // You can ask real password here from user 208370b324cSopenharmony_ci // Password = GetPassword(OutStream); 209370b324cSopenharmony_ci // PasswordIsDefined = true; 210370b324cSopenharmony_ci PrintError("Password is not defined"); 211370b324cSopenharmony_ci return E_ABORT; 212370b324cSopenharmony_ci } 213370b324cSopenharmony_ci return StringToBstr(Password, password); 214370b324cSopenharmony_ci} 215370b324cSopenharmony_ci 216370b324cSopenharmony_ci 217370b324cSopenharmony_ci 218370b324cSopenharmony_cistatic const char * const kIncorrectCommand = "incorrect command"; 219370b324cSopenharmony_ci 220370b324cSopenharmony_ci////////////////////////////////////////////////////////////// 221370b324cSopenharmony_ci// Archive Extracting callback class 222370b324cSopenharmony_ci 223370b324cSopenharmony_cistatic const char * const kTestingString = "Testing "; 224370b324cSopenharmony_cistatic const char * const kExtractingString = "Extracting "; 225370b324cSopenharmony_cistatic const char * const kSkippingString = "Skipping "; 226370b324cSopenharmony_cistatic const char * const kReadingString = "Reading "; 227370b324cSopenharmony_ci 228370b324cSopenharmony_cistatic const char * const kUnsupportedMethod = "Unsupported Method"; 229370b324cSopenharmony_cistatic const char * const kCRCFailed = "CRC Failed"; 230370b324cSopenharmony_cistatic const char * const kDataError = "Data Error"; 231370b324cSopenharmony_cistatic const char * const kUnavailableData = "Unavailable data"; 232370b324cSopenharmony_cistatic const char * const kUnexpectedEnd = "Unexpected end of data"; 233370b324cSopenharmony_cistatic const char * const kDataAfterEnd = "There are some data after the end of the payload data"; 234370b324cSopenharmony_cistatic const char * const kIsNotArc = "Is not archive"; 235370b324cSopenharmony_cistatic const char * const kHeadersError = "Headers Error"; 236370b324cSopenharmony_ci 237370b324cSopenharmony_ci 238370b324cSopenharmony_cistruct CArcTime 239370b324cSopenharmony_ci{ 240370b324cSopenharmony_ci FILETIME FT; 241370b324cSopenharmony_ci UInt16 Prec; 242370b324cSopenharmony_ci Byte Ns100; 243370b324cSopenharmony_ci bool Def; 244370b324cSopenharmony_ci 245370b324cSopenharmony_ci CArcTime() 246370b324cSopenharmony_ci { 247370b324cSopenharmony_ci Clear(); 248370b324cSopenharmony_ci } 249370b324cSopenharmony_ci 250370b324cSopenharmony_ci void Clear() 251370b324cSopenharmony_ci { 252370b324cSopenharmony_ci FT.dwHighDateTime = FT.dwLowDateTime = 0; 253370b324cSopenharmony_ci Prec = 0; 254370b324cSopenharmony_ci Ns100 = 0; 255370b324cSopenharmony_ci Def = false; 256370b324cSopenharmony_ci } 257370b324cSopenharmony_ci 258370b324cSopenharmony_ci bool IsZero() const 259370b324cSopenharmony_ci { 260370b324cSopenharmony_ci return FT.dwLowDateTime == 0 && FT.dwHighDateTime == 0 && Ns100 == 0; 261370b324cSopenharmony_ci } 262370b324cSopenharmony_ci 263370b324cSopenharmony_ci int GetNumDigits() const 264370b324cSopenharmony_ci { 265370b324cSopenharmony_ci if (Prec == k_PropVar_TimePrec_Unix || 266370b324cSopenharmony_ci Prec == k_PropVar_TimePrec_DOS) 267370b324cSopenharmony_ci return 0; 268370b324cSopenharmony_ci if (Prec == k_PropVar_TimePrec_HighPrec) 269370b324cSopenharmony_ci return 9; 270370b324cSopenharmony_ci if (Prec == k_PropVar_TimePrec_0) 271370b324cSopenharmony_ci return 7; 272370b324cSopenharmony_ci int digits = (int)Prec - (int)k_PropVar_TimePrec_Base; 273370b324cSopenharmony_ci if (digits < 0) 274370b324cSopenharmony_ci digits = 0; 275370b324cSopenharmony_ci return digits; 276370b324cSopenharmony_ci } 277370b324cSopenharmony_ci 278370b324cSopenharmony_ci void Write_To_FiTime(CFiTime &dest) const 279370b324cSopenharmony_ci { 280370b324cSopenharmony_ci #ifdef _WIN32 281370b324cSopenharmony_ci dest = FT; 282370b324cSopenharmony_ci #else 283370b324cSopenharmony_ci if (FILETIME_To_timespec(FT, dest)) 284370b324cSopenharmony_ci if ((Prec == k_PropVar_TimePrec_Base + 8 || 285370b324cSopenharmony_ci Prec == k_PropVar_TimePrec_Base + 9) 286370b324cSopenharmony_ci && Ns100 != 0) 287370b324cSopenharmony_ci { 288370b324cSopenharmony_ci dest.tv_nsec += Ns100; 289370b324cSopenharmony_ci } 290370b324cSopenharmony_ci #endif 291370b324cSopenharmony_ci } 292370b324cSopenharmony_ci 293370b324cSopenharmony_ci void Set_From_Prop(const PROPVARIANT &prop) 294370b324cSopenharmony_ci { 295370b324cSopenharmony_ci FT = prop.filetime; 296370b324cSopenharmony_ci unsigned prec = 0; 297370b324cSopenharmony_ci unsigned ns100 = 0; 298370b324cSopenharmony_ci const unsigned prec_Temp = prop.wReserved1; 299370b324cSopenharmony_ci if (prec_Temp != 0 300370b324cSopenharmony_ci && prec_Temp <= k_PropVar_TimePrec_1ns 301370b324cSopenharmony_ci && prop.wReserved3 == 0) 302370b324cSopenharmony_ci { 303370b324cSopenharmony_ci const unsigned ns100_Temp = prop.wReserved2; 304370b324cSopenharmony_ci if (ns100_Temp < 100) 305370b324cSopenharmony_ci { 306370b324cSopenharmony_ci ns100 = ns100_Temp; 307370b324cSopenharmony_ci prec = prec_Temp; 308370b324cSopenharmony_ci } 309370b324cSopenharmony_ci } 310370b324cSopenharmony_ci Prec = (UInt16)prec; 311370b324cSopenharmony_ci Ns100 = (Byte)ns100; 312370b324cSopenharmony_ci Def = true; 313370b324cSopenharmony_ci } 314370b324cSopenharmony_ci}; 315370b324cSopenharmony_ci 316370b324cSopenharmony_ci 317370b324cSopenharmony_ci 318370b324cSopenharmony_ciclass CArchiveExtractCallback Z7_final: 319370b324cSopenharmony_ci public IArchiveExtractCallback, 320370b324cSopenharmony_ci public ICryptoGetTextPassword, 321370b324cSopenharmony_ci public CMyUnknownImp 322370b324cSopenharmony_ci{ 323370b324cSopenharmony_ci Z7_IFACES_IMP_UNK_2(IArchiveExtractCallback, ICryptoGetTextPassword) 324370b324cSopenharmony_ci Z7_IFACE_COM7_IMP(IProgress) 325370b324cSopenharmony_ci 326370b324cSopenharmony_ci CMyComPtr<IInArchive> _archiveHandler; 327370b324cSopenharmony_ci FString _directoryPath; // Output directory 328370b324cSopenharmony_ci UString _filePath; // name inside arcvhive 329370b324cSopenharmony_ci FString _diskFilePath; // full path to file on disk 330370b324cSopenharmony_ci bool _extractMode; 331370b324cSopenharmony_ci struct CProcessedFileInfo 332370b324cSopenharmony_ci { 333370b324cSopenharmony_ci CArcTime MTime; 334370b324cSopenharmony_ci UInt32 Attrib; 335370b324cSopenharmony_ci bool isDir; 336370b324cSopenharmony_ci bool Attrib_Defined; 337370b324cSopenharmony_ci } _processedFileInfo; 338370b324cSopenharmony_ci 339370b324cSopenharmony_ci COutFileStream *_outFileStreamSpec; 340370b324cSopenharmony_ci CMyComPtr<ISequentialOutStream> _outFileStream; 341370b324cSopenharmony_ci 342370b324cSopenharmony_cipublic: 343370b324cSopenharmony_ci void Init(IInArchive *archiveHandler, const FString &directoryPath); 344370b324cSopenharmony_ci 345370b324cSopenharmony_ci UInt64 NumErrors; 346370b324cSopenharmony_ci bool PasswordIsDefined; 347370b324cSopenharmony_ci UString Password; 348370b324cSopenharmony_ci 349370b324cSopenharmony_ci CArchiveExtractCallback() : PasswordIsDefined(false) {} 350370b324cSopenharmony_ci}; 351370b324cSopenharmony_ci 352370b324cSopenharmony_civoid CArchiveExtractCallback::Init(IInArchive *archiveHandler, const FString &directoryPath) 353370b324cSopenharmony_ci{ 354370b324cSopenharmony_ci NumErrors = 0; 355370b324cSopenharmony_ci _archiveHandler = archiveHandler; 356370b324cSopenharmony_ci _directoryPath = directoryPath; 357370b324cSopenharmony_ci NName::NormalizeDirPathPrefix(_directoryPath); 358370b324cSopenharmony_ci} 359370b324cSopenharmony_ci 360370b324cSopenharmony_ciZ7_COM7F_IMF(CArchiveExtractCallback::SetTotal(UInt64 /* size */)) 361370b324cSopenharmony_ci{ 362370b324cSopenharmony_ci return S_OK; 363370b324cSopenharmony_ci} 364370b324cSopenharmony_ci 365370b324cSopenharmony_ciZ7_COM7F_IMF(CArchiveExtractCallback::SetCompleted(const UInt64 * /* completeValue */)) 366370b324cSopenharmony_ci{ 367370b324cSopenharmony_ci return S_OK; 368370b324cSopenharmony_ci} 369370b324cSopenharmony_ci 370370b324cSopenharmony_ciZ7_COM7F_IMF(CArchiveExtractCallback::GetStream(UInt32 index, 371370b324cSopenharmony_ci ISequentialOutStream **outStream, Int32 askExtractMode)) 372370b324cSopenharmony_ci{ 373370b324cSopenharmony_ci *outStream = NULL; 374370b324cSopenharmony_ci _outFileStream.Release(); 375370b324cSopenharmony_ci 376370b324cSopenharmony_ci { 377370b324cSopenharmony_ci // Get Name 378370b324cSopenharmony_ci NCOM::CPropVariant prop; 379370b324cSopenharmony_ci RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop)) 380370b324cSopenharmony_ci 381370b324cSopenharmony_ci UString fullPath; 382370b324cSopenharmony_ci if (prop.vt == VT_EMPTY) 383370b324cSopenharmony_ci fullPath = kEmptyFileAlias; 384370b324cSopenharmony_ci else 385370b324cSopenharmony_ci { 386370b324cSopenharmony_ci if (prop.vt != VT_BSTR) 387370b324cSopenharmony_ci return E_FAIL; 388370b324cSopenharmony_ci fullPath = prop.bstrVal; 389370b324cSopenharmony_ci } 390370b324cSopenharmony_ci _filePath = fullPath; 391370b324cSopenharmony_ci } 392370b324cSopenharmony_ci 393370b324cSopenharmony_ci if (askExtractMode != NArchive::NExtract::NAskMode::kExtract) 394370b324cSopenharmony_ci return S_OK; 395370b324cSopenharmony_ci 396370b324cSopenharmony_ci { 397370b324cSopenharmony_ci // Get Attrib 398370b324cSopenharmony_ci NCOM::CPropVariant prop; 399370b324cSopenharmony_ci RINOK(_archiveHandler->GetProperty(index, kpidAttrib, &prop)) 400370b324cSopenharmony_ci if (prop.vt == VT_EMPTY) 401370b324cSopenharmony_ci { 402370b324cSopenharmony_ci _processedFileInfo.Attrib = 0; 403370b324cSopenharmony_ci _processedFileInfo.Attrib_Defined = false; 404370b324cSopenharmony_ci } 405370b324cSopenharmony_ci else 406370b324cSopenharmony_ci { 407370b324cSopenharmony_ci if (prop.vt != VT_UI4) 408370b324cSopenharmony_ci return E_FAIL; 409370b324cSopenharmony_ci _processedFileInfo.Attrib = prop.ulVal; 410370b324cSopenharmony_ci _processedFileInfo.Attrib_Defined = true; 411370b324cSopenharmony_ci } 412370b324cSopenharmony_ci } 413370b324cSopenharmony_ci 414370b324cSopenharmony_ci RINOK(IsArchiveItemFolder(_archiveHandler, index, _processedFileInfo.isDir)) 415370b324cSopenharmony_ci 416370b324cSopenharmony_ci { 417370b324cSopenharmony_ci _processedFileInfo.MTime.Clear(); 418370b324cSopenharmony_ci // Get Modified Time 419370b324cSopenharmony_ci NCOM::CPropVariant prop; 420370b324cSopenharmony_ci RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop)) 421370b324cSopenharmony_ci switch (prop.vt) 422370b324cSopenharmony_ci { 423370b324cSopenharmony_ci case VT_EMPTY: 424370b324cSopenharmony_ci // _processedFileInfo.MTime = _utcMTimeDefault; 425370b324cSopenharmony_ci break; 426370b324cSopenharmony_ci case VT_FILETIME: 427370b324cSopenharmony_ci _processedFileInfo.MTime.Set_From_Prop(prop); 428370b324cSopenharmony_ci break; 429370b324cSopenharmony_ci default: 430370b324cSopenharmony_ci return E_FAIL; 431370b324cSopenharmony_ci } 432370b324cSopenharmony_ci 433370b324cSopenharmony_ci } 434370b324cSopenharmony_ci { 435370b324cSopenharmony_ci // Get Size 436370b324cSopenharmony_ci NCOM::CPropVariant prop; 437370b324cSopenharmony_ci RINOK(_archiveHandler->GetProperty(index, kpidSize, &prop)) 438370b324cSopenharmony_ci UInt64 newFileSize; 439370b324cSopenharmony_ci /* bool newFileSizeDefined = */ ConvertPropVariantToUInt64(prop, newFileSize); 440370b324cSopenharmony_ci } 441370b324cSopenharmony_ci 442370b324cSopenharmony_ci 443370b324cSopenharmony_ci { 444370b324cSopenharmony_ci // Create folders for file 445370b324cSopenharmony_ci int slashPos = _filePath.ReverseFind_PathSepar(); 446370b324cSopenharmony_ci if (slashPos >= 0) 447370b324cSopenharmony_ci CreateComplexDir(_directoryPath + us2fs(_filePath.Left(slashPos))); 448370b324cSopenharmony_ci } 449370b324cSopenharmony_ci 450370b324cSopenharmony_ci FString fullProcessedPath = _directoryPath + us2fs(_filePath); 451370b324cSopenharmony_ci _diskFilePath = fullProcessedPath; 452370b324cSopenharmony_ci 453370b324cSopenharmony_ci if (_processedFileInfo.isDir) 454370b324cSopenharmony_ci { 455370b324cSopenharmony_ci CreateComplexDir(fullProcessedPath); 456370b324cSopenharmony_ci } 457370b324cSopenharmony_ci else 458370b324cSopenharmony_ci { 459370b324cSopenharmony_ci NFind::CFileInfo fi; 460370b324cSopenharmony_ci if (fi.Find(fullProcessedPath)) 461370b324cSopenharmony_ci { 462370b324cSopenharmony_ci if (!DeleteFileAlways(fullProcessedPath)) 463370b324cSopenharmony_ci { 464370b324cSopenharmony_ci PrintError("Cannot delete output file", fullProcessedPath); 465370b324cSopenharmony_ci return E_ABORT; 466370b324cSopenharmony_ci } 467370b324cSopenharmony_ci } 468370b324cSopenharmony_ci 469370b324cSopenharmony_ci _outFileStreamSpec = new COutFileStream; 470370b324cSopenharmony_ci CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec); 471370b324cSopenharmony_ci if (!_outFileStreamSpec->Open(fullProcessedPath, CREATE_ALWAYS)) 472370b324cSopenharmony_ci { 473370b324cSopenharmony_ci PrintError("Cannot open output file", fullProcessedPath); 474370b324cSopenharmony_ci return E_ABORT; 475370b324cSopenharmony_ci } 476370b324cSopenharmony_ci _outFileStream = outStreamLoc; 477370b324cSopenharmony_ci *outStream = outStreamLoc.Detach(); 478370b324cSopenharmony_ci } 479370b324cSopenharmony_ci return S_OK; 480370b324cSopenharmony_ci} 481370b324cSopenharmony_ci 482370b324cSopenharmony_ciZ7_COM7F_IMF(CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)) 483370b324cSopenharmony_ci{ 484370b324cSopenharmony_ci _extractMode = false; 485370b324cSopenharmony_ci switch (askExtractMode) 486370b324cSopenharmony_ci { 487370b324cSopenharmony_ci case NArchive::NExtract::NAskMode::kExtract: _extractMode = true; break; 488370b324cSopenharmony_ci } 489370b324cSopenharmony_ci switch (askExtractMode) 490370b324cSopenharmony_ci { 491370b324cSopenharmony_ci case NArchive::NExtract::NAskMode::kExtract: Print(kExtractingString); break; 492370b324cSopenharmony_ci case NArchive::NExtract::NAskMode::kTest: Print(kTestingString); break; 493370b324cSopenharmony_ci case NArchive::NExtract::NAskMode::kSkip: Print(kSkippingString); break; 494370b324cSopenharmony_ci case NArchive::NExtract::NAskMode::kReadExternal: Print(kReadingString); break; 495370b324cSopenharmony_ci default: 496370b324cSopenharmony_ci Print("??? "); break; 497370b324cSopenharmony_ci } 498370b324cSopenharmony_ci Print(_filePath); 499370b324cSopenharmony_ci return S_OK; 500370b324cSopenharmony_ci} 501370b324cSopenharmony_ci 502370b324cSopenharmony_ciZ7_COM7F_IMF(CArchiveExtractCallback::SetOperationResult(Int32 operationResult)) 503370b324cSopenharmony_ci{ 504370b324cSopenharmony_ci switch (operationResult) 505370b324cSopenharmony_ci { 506370b324cSopenharmony_ci case NArchive::NExtract::NOperationResult::kOK: 507370b324cSopenharmony_ci break; 508370b324cSopenharmony_ci default: 509370b324cSopenharmony_ci { 510370b324cSopenharmony_ci NumErrors++; 511370b324cSopenharmony_ci Print(" : "); 512370b324cSopenharmony_ci const char *s = NULL; 513370b324cSopenharmony_ci switch (operationResult) 514370b324cSopenharmony_ci { 515370b324cSopenharmony_ci case NArchive::NExtract::NOperationResult::kUnsupportedMethod: 516370b324cSopenharmony_ci s = kUnsupportedMethod; 517370b324cSopenharmony_ci break; 518370b324cSopenharmony_ci case NArchive::NExtract::NOperationResult::kCRCError: 519370b324cSopenharmony_ci s = kCRCFailed; 520370b324cSopenharmony_ci break; 521370b324cSopenharmony_ci case NArchive::NExtract::NOperationResult::kDataError: 522370b324cSopenharmony_ci s = kDataError; 523370b324cSopenharmony_ci break; 524370b324cSopenharmony_ci case NArchive::NExtract::NOperationResult::kUnavailable: 525370b324cSopenharmony_ci s = kUnavailableData; 526370b324cSopenharmony_ci break; 527370b324cSopenharmony_ci case NArchive::NExtract::NOperationResult::kUnexpectedEnd: 528370b324cSopenharmony_ci s = kUnexpectedEnd; 529370b324cSopenharmony_ci break; 530370b324cSopenharmony_ci case NArchive::NExtract::NOperationResult::kDataAfterEnd: 531370b324cSopenharmony_ci s = kDataAfterEnd; 532370b324cSopenharmony_ci break; 533370b324cSopenharmony_ci case NArchive::NExtract::NOperationResult::kIsNotArc: 534370b324cSopenharmony_ci s = kIsNotArc; 535370b324cSopenharmony_ci break; 536370b324cSopenharmony_ci case NArchive::NExtract::NOperationResult::kHeadersError: 537370b324cSopenharmony_ci s = kHeadersError; 538370b324cSopenharmony_ci break; 539370b324cSopenharmony_ci } 540370b324cSopenharmony_ci if (s) 541370b324cSopenharmony_ci { 542370b324cSopenharmony_ci Print("Error : "); 543370b324cSopenharmony_ci Print(s); 544370b324cSopenharmony_ci } 545370b324cSopenharmony_ci else 546370b324cSopenharmony_ci { 547370b324cSopenharmony_ci char temp[16]; 548370b324cSopenharmony_ci ConvertUInt32ToString((UInt32)operationResult, temp); 549370b324cSopenharmony_ci Print("Error #"); 550370b324cSopenharmony_ci Print(temp); 551370b324cSopenharmony_ci } 552370b324cSopenharmony_ci } 553370b324cSopenharmony_ci } 554370b324cSopenharmony_ci 555370b324cSopenharmony_ci if (_outFileStream) 556370b324cSopenharmony_ci { 557370b324cSopenharmony_ci if (_processedFileInfo.MTime.Def) 558370b324cSopenharmony_ci { 559370b324cSopenharmony_ci CFiTime ft; 560370b324cSopenharmony_ci _processedFileInfo.MTime.Write_To_FiTime(ft); 561370b324cSopenharmony_ci _outFileStreamSpec->SetMTime(&ft); 562370b324cSopenharmony_ci } 563370b324cSopenharmony_ci RINOK(_outFileStreamSpec->Close()) 564370b324cSopenharmony_ci } 565370b324cSopenharmony_ci _outFileStream.Release(); 566370b324cSopenharmony_ci if (_extractMode && _processedFileInfo.Attrib_Defined) 567370b324cSopenharmony_ci SetFileAttrib_PosixHighDetect(_diskFilePath, _processedFileInfo.Attrib); 568370b324cSopenharmony_ci PrintNewLine(); 569370b324cSopenharmony_ci return S_OK; 570370b324cSopenharmony_ci} 571370b324cSopenharmony_ci 572370b324cSopenharmony_ci 573370b324cSopenharmony_ciZ7_COM7F_IMF(CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)) 574370b324cSopenharmony_ci{ 575370b324cSopenharmony_ci if (!PasswordIsDefined) 576370b324cSopenharmony_ci { 577370b324cSopenharmony_ci // You can ask real password here from user 578370b324cSopenharmony_ci // Password = GetPassword(OutStream); 579370b324cSopenharmony_ci // PasswordIsDefined = true; 580370b324cSopenharmony_ci PrintError("Password is not defined"); 581370b324cSopenharmony_ci return E_ABORT; 582370b324cSopenharmony_ci } 583370b324cSopenharmony_ci return StringToBstr(Password, password); 584370b324cSopenharmony_ci} 585370b324cSopenharmony_ci 586370b324cSopenharmony_ci 587370b324cSopenharmony_ci 588370b324cSopenharmony_ci////////////////////////////////////////////////////////////// 589370b324cSopenharmony_ci// Archive Creating callback class 590370b324cSopenharmony_ci 591370b324cSopenharmony_cistruct CDirItem: public NWindows::NFile::NFind::CFileInfoBase 592370b324cSopenharmony_ci{ 593370b324cSopenharmony_ci UString Path_For_Handler; 594370b324cSopenharmony_ci FString FullPath; // for filesystem 595370b324cSopenharmony_ci 596370b324cSopenharmony_ci CDirItem(const NWindows::NFile::NFind::CFileInfo &fi): 597370b324cSopenharmony_ci CFileInfoBase(fi) 598370b324cSopenharmony_ci {} 599370b324cSopenharmony_ci}; 600370b324cSopenharmony_ci 601370b324cSopenharmony_ciclass CArchiveUpdateCallback Z7_final: 602370b324cSopenharmony_ci public IArchiveUpdateCallback2, 603370b324cSopenharmony_ci public ICryptoGetTextPassword2, 604370b324cSopenharmony_ci public CMyUnknownImp 605370b324cSopenharmony_ci{ 606370b324cSopenharmony_ci Z7_IFACES_IMP_UNK_2(IArchiveUpdateCallback2, ICryptoGetTextPassword2) 607370b324cSopenharmony_ci Z7_IFACE_COM7_IMP(IProgress) 608370b324cSopenharmony_ci Z7_IFACE_COM7_IMP(IArchiveUpdateCallback) 609370b324cSopenharmony_ci 610370b324cSopenharmony_cipublic: 611370b324cSopenharmony_ci CRecordVector<UInt64> VolumesSizes; 612370b324cSopenharmony_ci UString VolName; 613370b324cSopenharmony_ci UString VolExt; 614370b324cSopenharmony_ci 615370b324cSopenharmony_ci FString DirPrefix; 616370b324cSopenharmony_ci const CObjectVector<CDirItem> *DirItems; 617370b324cSopenharmony_ci 618370b324cSopenharmony_ci bool PasswordIsDefined; 619370b324cSopenharmony_ci UString Password; 620370b324cSopenharmony_ci bool AskPassword; 621370b324cSopenharmony_ci 622370b324cSopenharmony_ci bool m_NeedBeClosed; 623370b324cSopenharmony_ci 624370b324cSopenharmony_ci FStringVector FailedFiles; 625370b324cSopenharmony_ci CRecordVector<HRESULT> FailedCodes; 626370b324cSopenharmony_ci 627370b324cSopenharmony_ci CArchiveUpdateCallback(): 628370b324cSopenharmony_ci DirItems(NULL), 629370b324cSopenharmony_ci PasswordIsDefined(false), 630370b324cSopenharmony_ci AskPassword(false) 631370b324cSopenharmony_ci {} 632370b324cSopenharmony_ci 633370b324cSopenharmony_ci ~CArchiveUpdateCallback() { Finilize(); } 634370b324cSopenharmony_ci HRESULT Finilize(); 635370b324cSopenharmony_ci 636370b324cSopenharmony_ci void Init(const CObjectVector<CDirItem> *dirItems) 637370b324cSopenharmony_ci { 638370b324cSopenharmony_ci DirItems = dirItems; 639370b324cSopenharmony_ci m_NeedBeClosed = false; 640370b324cSopenharmony_ci FailedFiles.Clear(); 641370b324cSopenharmony_ci FailedCodes.Clear(); 642370b324cSopenharmony_ci } 643370b324cSopenharmony_ci}; 644370b324cSopenharmony_ci 645370b324cSopenharmony_ciZ7_COM7F_IMF(CArchiveUpdateCallback::SetTotal(UInt64 /* size */)) 646370b324cSopenharmony_ci{ 647370b324cSopenharmony_ci return S_OK; 648370b324cSopenharmony_ci} 649370b324cSopenharmony_ci 650370b324cSopenharmony_ciZ7_COM7F_IMF(CArchiveUpdateCallback::SetCompleted(const UInt64 * /* completeValue */)) 651370b324cSopenharmony_ci{ 652370b324cSopenharmony_ci return S_OK; 653370b324cSopenharmony_ci} 654370b324cSopenharmony_ci 655370b324cSopenharmony_ciZ7_COM7F_IMF(CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 /* index */, 656370b324cSopenharmony_ci Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive)) 657370b324cSopenharmony_ci{ 658370b324cSopenharmony_ci if (newData) 659370b324cSopenharmony_ci *newData = BoolToInt(true); 660370b324cSopenharmony_ci if (newProperties) 661370b324cSopenharmony_ci *newProperties = BoolToInt(true); 662370b324cSopenharmony_ci if (indexInArchive) 663370b324cSopenharmony_ci *indexInArchive = (UInt32)(Int32)-1; 664370b324cSopenharmony_ci return S_OK; 665370b324cSopenharmony_ci} 666370b324cSopenharmony_ci 667370b324cSopenharmony_ciZ7_COM7F_IMF(CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) 668370b324cSopenharmony_ci{ 669370b324cSopenharmony_ci NCOM::CPropVariant prop; 670370b324cSopenharmony_ci 671370b324cSopenharmony_ci if (propID == kpidIsAnti) 672370b324cSopenharmony_ci { 673370b324cSopenharmony_ci prop = false; 674370b324cSopenharmony_ci prop.Detach(value); 675370b324cSopenharmony_ci return S_OK; 676370b324cSopenharmony_ci } 677370b324cSopenharmony_ci 678370b324cSopenharmony_ci { 679370b324cSopenharmony_ci const CDirItem &di = (*DirItems)[index]; 680370b324cSopenharmony_ci switch (propID) 681370b324cSopenharmony_ci { 682370b324cSopenharmony_ci case kpidPath: prop = di.Path_For_Handler; break; 683370b324cSopenharmony_ci case kpidIsDir: prop = di.IsDir(); break; 684370b324cSopenharmony_ci case kpidSize: prop = di.Size; break; 685370b324cSopenharmony_ci case kpidCTime: PropVariant_SetFrom_FiTime(prop, di.CTime); break; 686370b324cSopenharmony_ci case kpidATime: PropVariant_SetFrom_FiTime(prop, di.ATime); break; 687370b324cSopenharmony_ci case kpidMTime: PropVariant_SetFrom_FiTime(prop, di.MTime); break; 688370b324cSopenharmony_ci case kpidAttrib: prop = (UInt32)di.GetWinAttrib(); break; 689370b324cSopenharmony_ci case kpidPosixAttrib: prop = (UInt32)di.GetPosixAttrib(); break; 690370b324cSopenharmony_ci } 691370b324cSopenharmony_ci } 692370b324cSopenharmony_ci prop.Detach(value); 693370b324cSopenharmony_ci return S_OK; 694370b324cSopenharmony_ci} 695370b324cSopenharmony_ci 696370b324cSopenharmony_ciHRESULT CArchiveUpdateCallback::Finilize() 697370b324cSopenharmony_ci{ 698370b324cSopenharmony_ci if (m_NeedBeClosed) 699370b324cSopenharmony_ci { 700370b324cSopenharmony_ci PrintNewLine(); 701370b324cSopenharmony_ci m_NeedBeClosed = false; 702370b324cSopenharmony_ci } 703370b324cSopenharmony_ci return S_OK; 704370b324cSopenharmony_ci} 705370b324cSopenharmony_ci 706370b324cSopenharmony_cistatic void GetStream2(const wchar_t *name) 707370b324cSopenharmony_ci{ 708370b324cSopenharmony_ci Print("Compressing "); 709370b324cSopenharmony_ci if (name[0] == 0) 710370b324cSopenharmony_ci name = kEmptyFileAlias; 711370b324cSopenharmony_ci Print(name); 712370b324cSopenharmony_ci} 713370b324cSopenharmony_ci 714370b324cSopenharmony_ciZ7_COM7F_IMF(CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)) 715370b324cSopenharmony_ci{ 716370b324cSopenharmony_ci RINOK(Finilize()) 717370b324cSopenharmony_ci 718370b324cSopenharmony_ci const CDirItem &dirItem = (*DirItems)[index]; 719370b324cSopenharmony_ci GetStream2(dirItem.Path_For_Handler); 720370b324cSopenharmony_ci 721370b324cSopenharmony_ci if (dirItem.IsDir()) 722370b324cSopenharmony_ci return S_OK; 723370b324cSopenharmony_ci 724370b324cSopenharmony_ci { 725370b324cSopenharmony_ci CInFileStream *inStreamSpec = new CInFileStream; 726370b324cSopenharmony_ci CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec); 727370b324cSopenharmony_ci FString path = DirPrefix + dirItem.FullPath; 728370b324cSopenharmony_ci if (!inStreamSpec->Open(path)) 729370b324cSopenharmony_ci { 730370b324cSopenharmony_ci const DWORD sysError = ::GetLastError(); 731370b324cSopenharmony_ci FailedCodes.Add(HRESULT_FROM_WIN32(sysError)); 732370b324cSopenharmony_ci FailedFiles.Add(path); 733370b324cSopenharmony_ci // if (systemError == ERROR_SHARING_VIOLATION) 734370b324cSopenharmony_ci { 735370b324cSopenharmony_ci PrintNewLine(); 736370b324cSopenharmony_ci PrintError("WARNING: can't open file"); 737370b324cSopenharmony_ci // Print(NError::MyFormatMessageW(systemError)); 738370b324cSopenharmony_ci return S_FALSE; 739370b324cSopenharmony_ci } 740370b324cSopenharmony_ci // return sysError; 741370b324cSopenharmony_ci } 742370b324cSopenharmony_ci *inStream = inStreamLoc.Detach(); 743370b324cSopenharmony_ci } 744370b324cSopenharmony_ci return S_OK; 745370b324cSopenharmony_ci} 746370b324cSopenharmony_ci 747370b324cSopenharmony_ciZ7_COM7F_IMF(CArchiveUpdateCallback::SetOperationResult(Int32 /* operationResult */)) 748370b324cSopenharmony_ci{ 749370b324cSopenharmony_ci m_NeedBeClosed = true; 750370b324cSopenharmony_ci return S_OK; 751370b324cSopenharmony_ci} 752370b324cSopenharmony_ci 753370b324cSopenharmony_ciZ7_COM7F_IMF(CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)) 754370b324cSopenharmony_ci{ 755370b324cSopenharmony_ci if (VolumesSizes.Size() == 0) 756370b324cSopenharmony_ci return S_FALSE; 757370b324cSopenharmony_ci if (index >= (UInt32)VolumesSizes.Size()) 758370b324cSopenharmony_ci index = VolumesSizes.Size() - 1; 759370b324cSopenharmony_ci *size = VolumesSizes[index]; 760370b324cSopenharmony_ci return S_OK; 761370b324cSopenharmony_ci} 762370b324cSopenharmony_ci 763370b324cSopenharmony_ciZ7_COM7F_IMF(CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)) 764370b324cSopenharmony_ci{ 765370b324cSopenharmony_ci wchar_t temp[16]; 766370b324cSopenharmony_ci ConvertUInt32ToString(index + 1, temp); 767370b324cSopenharmony_ci UString res = temp; 768370b324cSopenharmony_ci while (res.Len() < 2) 769370b324cSopenharmony_ci res.InsertAtFront(L'0'); 770370b324cSopenharmony_ci UString fileName = VolName; 771370b324cSopenharmony_ci fileName.Add_Dot(); 772370b324cSopenharmony_ci fileName += res; 773370b324cSopenharmony_ci fileName += VolExt; 774370b324cSopenharmony_ci COutFileStream *streamSpec = new COutFileStream; 775370b324cSopenharmony_ci CMyComPtr<ISequentialOutStream> streamLoc(streamSpec); 776370b324cSopenharmony_ci if (!streamSpec->Create(us2fs(fileName), false)) 777370b324cSopenharmony_ci return GetLastError_noZero_HRESULT(); 778370b324cSopenharmony_ci *volumeStream = streamLoc.Detach(); 779370b324cSopenharmony_ci return S_OK; 780370b324cSopenharmony_ci} 781370b324cSopenharmony_ci 782370b324cSopenharmony_ciZ7_COM7F_IMF(CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)) 783370b324cSopenharmony_ci{ 784370b324cSopenharmony_ci if (!PasswordIsDefined) 785370b324cSopenharmony_ci { 786370b324cSopenharmony_ci if (AskPassword) 787370b324cSopenharmony_ci { 788370b324cSopenharmony_ci // You can ask real password here from user 789370b324cSopenharmony_ci // Password = GetPassword(OutStream); 790370b324cSopenharmony_ci // PasswordIsDefined = true; 791370b324cSopenharmony_ci PrintError("Password is not defined"); 792370b324cSopenharmony_ci return E_ABORT; 793370b324cSopenharmony_ci } 794370b324cSopenharmony_ci } 795370b324cSopenharmony_ci *passwordIsDefined = BoolToInt(PasswordIsDefined); 796370b324cSopenharmony_ci return StringToBstr(Password, password); 797370b324cSopenharmony_ci} 798370b324cSopenharmony_ci 799370b324cSopenharmony_ci 800370b324cSopenharmony_ci// Main function 801370b324cSopenharmony_ci 802370b324cSopenharmony_ci#if defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE) 803370b324cSopenharmony_ci#define NT_CHECK_FAIL_ACTION PrintError("Unsupported Windows version"); return 1; 804370b324cSopenharmony_ci#endif 805370b324cSopenharmony_ci 806370b324cSopenharmony_ciint Z7_CDECL main(int numArgs, const char *args[]) 807370b324cSopenharmony_ci{ 808370b324cSopenharmony_ci NT_CHECK 809370b324cSopenharmony_ci 810370b324cSopenharmony_ci #ifdef ENV_HAVE_LOCALE 811370b324cSopenharmony_ci MY_SetLocale(); 812370b324cSopenharmony_ci #endif 813370b324cSopenharmony_ci 814370b324cSopenharmony_ci PrintStringLn(kCopyrightString); 815370b324cSopenharmony_ci 816370b324cSopenharmony_ci if (numArgs < 2) 817370b324cSopenharmony_ci { 818370b324cSopenharmony_ci PrintStringLn(kHelpString); 819370b324cSopenharmony_ci return 0; 820370b324cSopenharmony_ci } 821370b324cSopenharmony_ci 822370b324cSopenharmony_ci FString dllPrefix; 823370b324cSopenharmony_ci 824370b324cSopenharmony_ci #ifdef _WIN32 825370b324cSopenharmony_ci dllPrefix = NDLL::GetModuleDirPrefix(); 826370b324cSopenharmony_ci #else 827370b324cSopenharmony_ci { 828370b324cSopenharmony_ci AString s (args[0]); 829370b324cSopenharmony_ci int sep = s.ReverseFind_PathSepar(); 830370b324cSopenharmony_ci s.DeleteFrom(sep + 1); 831370b324cSopenharmony_ci dllPrefix = s; 832370b324cSopenharmony_ci } 833370b324cSopenharmony_ci #endif 834370b324cSopenharmony_ci 835370b324cSopenharmony_ci NDLL::CLibrary lib; 836370b324cSopenharmony_ci if (!lib.Load(dllPrefix + FTEXT(kDllName))) 837370b324cSopenharmony_ci { 838370b324cSopenharmony_ci PrintError("Cannot load 7-zip library"); 839370b324cSopenharmony_ci return 1; 840370b324cSopenharmony_ci } 841370b324cSopenharmony_ci 842370b324cSopenharmony_ci Func_CreateObject 843370b324cSopenharmony_ci f_CreateObject = Z7_GET_PROC_ADDRESS( 844370b324cSopenharmony_ci Func_CreateObject, lib.Get_HMODULE(), 845370b324cSopenharmony_ci "CreateObject"); 846370b324cSopenharmony_ci if (!f_CreateObject) 847370b324cSopenharmony_ci { 848370b324cSopenharmony_ci PrintError("Cannot get CreateObject"); 849370b324cSopenharmony_ci return 1; 850370b324cSopenharmony_ci } 851370b324cSopenharmony_ci 852370b324cSopenharmony_ci char c = 0; 853370b324cSopenharmony_ci UString password; 854370b324cSopenharmony_ci bool passwordIsDefined = false; 855370b324cSopenharmony_ci CObjectVector<FString> params; 856370b324cSopenharmony_ci 857370b324cSopenharmony_ci for (int curCmd = 1; curCmd < numArgs; curCmd++) 858370b324cSopenharmony_ci { 859370b324cSopenharmony_ci AString a(args[curCmd]); 860370b324cSopenharmony_ci 861370b324cSopenharmony_ci if (!a.IsEmpty()) 862370b324cSopenharmony_ci { 863370b324cSopenharmony_ci if (a[0] == '-') 864370b324cSopenharmony_ci { 865370b324cSopenharmony_ci if (!passwordIsDefined && a[1] == 'p') 866370b324cSopenharmony_ci { 867370b324cSopenharmony_ci password = GetUnicodeString(a.Ptr(2)); 868370b324cSopenharmony_ci passwordIsDefined = true; 869370b324cSopenharmony_ci continue; 870370b324cSopenharmony_ci } 871370b324cSopenharmony_ci } 872370b324cSopenharmony_ci else 873370b324cSopenharmony_ci { 874370b324cSopenharmony_ci if (c) 875370b324cSopenharmony_ci { 876370b324cSopenharmony_ci params.Add(CmdStringToFString(a)); 877370b324cSopenharmony_ci continue; 878370b324cSopenharmony_ci } 879370b324cSopenharmony_ci if (a.Len() == 1) 880370b324cSopenharmony_ci { 881370b324cSopenharmony_ci c = (char)MyCharLower_Ascii(a[0]); 882370b324cSopenharmony_ci continue; 883370b324cSopenharmony_ci } 884370b324cSopenharmony_ci } 885370b324cSopenharmony_ci } 886370b324cSopenharmony_ci { 887370b324cSopenharmony_ci PrintError(kIncorrectCommand); 888370b324cSopenharmony_ci return 1; 889370b324cSopenharmony_ci } 890370b324cSopenharmony_ci } 891370b324cSopenharmony_ci 892370b324cSopenharmony_ci if (!c || params.Size() < 1) 893370b324cSopenharmony_ci { 894370b324cSopenharmony_ci PrintError(kIncorrectCommand); 895370b324cSopenharmony_ci return 1; 896370b324cSopenharmony_ci } 897370b324cSopenharmony_ci 898370b324cSopenharmony_ci const FString &archiveName = params[0]; 899370b324cSopenharmony_ci 900370b324cSopenharmony_ci if (c == 'a') 901370b324cSopenharmony_ci { 902370b324cSopenharmony_ci // create archive command 903370b324cSopenharmony_ci if (params.Size() < 2) 904370b324cSopenharmony_ci { 905370b324cSopenharmony_ci PrintError(kIncorrectCommand); 906370b324cSopenharmony_ci return 1; 907370b324cSopenharmony_ci } 908370b324cSopenharmony_ci CObjectVector<CDirItem> dirItems; 909370b324cSopenharmony_ci { 910370b324cSopenharmony_ci unsigned i; 911370b324cSopenharmony_ci for (i = 1; i < params.Size(); i++) 912370b324cSopenharmony_ci { 913370b324cSopenharmony_ci const FString &name = params[i]; 914370b324cSopenharmony_ci 915370b324cSopenharmony_ci NFind::CFileInfo fi; 916370b324cSopenharmony_ci if (!fi.Find(name)) 917370b324cSopenharmony_ci { 918370b324cSopenharmony_ci PrintError("Can't find file", name); 919370b324cSopenharmony_ci return 1; 920370b324cSopenharmony_ci } 921370b324cSopenharmony_ci 922370b324cSopenharmony_ci CDirItem di(fi); 923370b324cSopenharmony_ci 924370b324cSopenharmony_ci di.Path_For_Handler = fs2us(name); 925370b324cSopenharmony_ci di.FullPath = name; 926370b324cSopenharmony_ci dirItems.Add(di); 927370b324cSopenharmony_ci } 928370b324cSopenharmony_ci } 929370b324cSopenharmony_ci 930370b324cSopenharmony_ci COutFileStream *outFileStreamSpec = new COutFileStream; 931370b324cSopenharmony_ci CMyComPtr<IOutStream> outFileStream = outFileStreamSpec; 932370b324cSopenharmony_ci if (!outFileStreamSpec->Create(archiveName, false)) 933370b324cSopenharmony_ci { 934370b324cSopenharmony_ci PrintError("can't create archive file"); 935370b324cSopenharmony_ci return 1; 936370b324cSopenharmony_ci } 937370b324cSopenharmony_ci 938370b324cSopenharmony_ci CMyComPtr<IOutArchive> outArchive; 939370b324cSopenharmony_ci if (f_CreateObject(&CLSID_Format, &IID_IOutArchive, (void **)&outArchive) != S_OK) 940370b324cSopenharmony_ci { 941370b324cSopenharmony_ci PrintError("Cannot get class object"); 942370b324cSopenharmony_ci return 1; 943370b324cSopenharmony_ci } 944370b324cSopenharmony_ci 945370b324cSopenharmony_ci CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; 946370b324cSopenharmony_ci CMyComPtr<IArchiveUpdateCallback2> updateCallback(updateCallbackSpec); 947370b324cSopenharmony_ci updateCallbackSpec->Init(&dirItems); 948370b324cSopenharmony_ci updateCallbackSpec->PasswordIsDefined = passwordIsDefined; 949370b324cSopenharmony_ci updateCallbackSpec->Password = password; 950370b324cSopenharmony_ci 951370b324cSopenharmony_ci /* 952370b324cSopenharmony_ci { 953370b324cSopenharmony_ci const wchar_t *names[] = 954370b324cSopenharmony_ci { 955370b324cSopenharmony_ci L"m", 956370b324cSopenharmony_ci L"s", 957370b324cSopenharmony_ci L"x" 958370b324cSopenharmony_ci }; 959370b324cSopenharmony_ci const unsigned kNumProps = Z7_ARRAY_SIZE(names); 960370b324cSopenharmony_ci NCOM::CPropVariant values[kNumProps] = 961370b324cSopenharmony_ci { 962370b324cSopenharmony_ci L"lzma", 963370b324cSopenharmony_ci false, // solid mode OFF 964370b324cSopenharmony_ci (UInt32)9 // compression level = 9 - ultra 965370b324cSopenharmony_ci }; 966370b324cSopenharmony_ci CMyComPtr<ISetProperties> setProperties; 967370b324cSopenharmony_ci outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties); 968370b324cSopenharmony_ci if (!setProperties) 969370b324cSopenharmony_ci { 970370b324cSopenharmony_ci PrintError("ISetProperties unsupported"); 971370b324cSopenharmony_ci return 1; 972370b324cSopenharmony_ci } 973370b324cSopenharmony_ci if (setProperties->SetProperties(names, values, kNumProps) != S_OK) 974370b324cSopenharmony_ci { 975370b324cSopenharmony_ci PrintError("SetProperties() error"); 976370b324cSopenharmony_ci return 1; 977370b324cSopenharmony_ci } 978370b324cSopenharmony_ci } 979370b324cSopenharmony_ci */ 980370b324cSopenharmony_ci 981370b324cSopenharmony_ci HRESULT result = outArchive->UpdateItems(outFileStream, dirItems.Size(), updateCallback); 982370b324cSopenharmony_ci 983370b324cSopenharmony_ci updateCallbackSpec->Finilize(); 984370b324cSopenharmony_ci 985370b324cSopenharmony_ci if (result != S_OK) 986370b324cSopenharmony_ci { 987370b324cSopenharmony_ci PrintError("Update Error"); 988370b324cSopenharmony_ci return 1; 989370b324cSopenharmony_ci } 990370b324cSopenharmony_ci 991370b324cSopenharmony_ci FOR_VECTOR (i, updateCallbackSpec->FailedFiles) 992370b324cSopenharmony_ci { 993370b324cSopenharmony_ci PrintNewLine(); 994370b324cSopenharmony_ci PrintError("Error for file", updateCallbackSpec->FailedFiles[i]); 995370b324cSopenharmony_ci } 996370b324cSopenharmony_ci 997370b324cSopenharmony_ci if (updateCallbackSpec->FailedFiles.Size() != 0) 998370b324cSopenharmony_ci return 1; 999370b324cSopenharmony_ci } 1000370b324cSopenharmony_ci else 1001370b324cSopenharmony_ci { 1002370b324cSopenharmony_ci if (params.Size() != 1) 1003370b324cSopenharmony_ci { 1004370b324cSopenharmony_ci PrintError(kIncorrectCommand); 1005370b324cSopenharmony_ci return 1; 1006370b324cSopenharmony_ci } 1007370b324cSopenharmony_ci 1008370b324cSopenharmony_ci bool listCommand; 1009370b324cSopenharmony_ci 1010370b324cSopenharmony_ci if (c == 'l') 1011370b324cSopenharmony_ci listCommand = true; 1012370b324cSopenharmony_ci else if (c == 'x') 1013370b324cSopenharmony_ci listCommand = false; 1014370b324cSopenharmony_ci else 1015370b324cSopenharmony_ci { 1016370b324cSopenharmony_ci PrintError(kIncorrectCommand); 1017370b324cSopenharmony_ci return 1; 1018370b324cSopenharmony_ci } 1019370b324cSopenharmony_ci 1020370b324cSopenharmony_ci CMyComPtr<IInArchive> archive; 1021370b324cSopenharmony_ci if (f_CreateObject(&CLSID_Format, &IID_IInArchive, (void **)&archive) != S_OK) 1022370b324cSopenharmony_ci { 1023370b324cSopenharmony_ci PrintError("Cannot get class object"); 1024370b324cSopenharmony_ci return 1; 1025370b324cSopenharmony_ci } 1026370b324cSopenharmony_ci 1027370b324cSopenharmony_ci CInFileStream *fileSpec = new CInFileStream; 1028370b324cSopenharmony_ci CMyComPtr<IInStream> file = fileSpec; 1029370b324cSopenharmony_ci 1030370b324cSopenharmony_ci if (!fileSpec->Open(archiveName)) 1031370b324cSopenharmony_ci { 1032370b324cSopenharmony_ci PrintError("Cannot open archive file", archiveName); 1033370b324cSopenharmony_ci return 1; 1034370b324cSopenharmony_ci } 1035370b324cSopenharmony_ci 1036370b324cSopenharmony_ci { 1037370b324cSopenharmony_ci CArchiveOpenCallback *openCallbackSpec = new CArchiveOpenCallback; 1038370b324cSopenharmony_ci CMyComPtr<IArchiveOpenCallback> openCallback(openCallbackSpec); 1039370b324cSopenharmony_ci openCallbackSpec->PasswordIsDefined = passwordIsDefined; 1040370b324cSopenharmony_ci openCallbackSpec->Password = password; 1041370b324cSopenharmony_ci 1042370b324cSopenharmony_ci const UInt64 scanSize = 1 << 23; 1043370b324cSopenharmony_ci if (archive->Open(file, &scanSize, openCallback) != S_OK) 1044370b324cSopenharmony_ci { 1045370b324cSopenharmony_ci PrintError("Cannot open file as archive", archiveName); 1046370b324cSopenharmony_ci return 1; 1047370b324cSopenharmony_ci } 1048370b324cSopenharmony_ci } 1049370b324cSopenharmony_ci 1050370b324cSopenharmony_ci if (listCommand) 1051370b324cSopenharmony_ci { 1052370b324cSopenharmony_ci // List command 1053370b324cSopenharmony_ci UInt32 numItems = 0; 1054370b324cSopenharmony_ci archive->GetNumberOfItems(&numItems); 1055370b324cSopenharmony_ci for (UInt32 i = 0; i < numItems; i++) 1056370b324cSopenharmony_ci { 1057370b324cSopenharmony_ci { 1058370b324cSopenharmony_ci // Get uncompressed size of file 1059370b324cSopenharmony_ci NCOM::CPropVariant prop; 1060370b324cSopenharmony_ci archive->GetProperty(i, kpidSize, &prop); 1061370b324cSopenharmony_ci char s[32]; 1062370b324cSopenharmony_ci ConvertPropVariantToShortString(prop, s); 1063370b324cSopenharmony_ci Print(s); 1064370b324cSopenharmony_ci Print(" "); 1065370b324cSopenharmony_ci } 1066370b324cSopenharmony_ci { 1067370b324cSopenharmony_ci // Get name of file 1068370b324cSopenharmony_ci NCOM::CPropVariant prop; 1069370b324cSopenharmony_ci archive->GetProperty(i, kpidPath, &prop); 1070370b324cSopenharmony_ci if (prop.vt == VT_BSTR) 1071370b324cSopenharmony_ci Print(prop.bstrVal); 1072370b324cSopenharmony_ci else if (prop.vt != VT_EMPTY) 1073370b324cSopenharmony_ci Print("ERROR!"); 1074370b324cSopenharmony_ci } 1075370b324cSopenharmony_ci PrintNewLine(); 1076370b324cSopenharmony_ci } 1077370b324cSopenharmony_ci } 1078370b324cSopenharmony_ci else 1079370b324cSopenharmony_ci { 1080370b324cSopenharmony_ci // Extract command 1081370b324cSopenharmony_ci CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback; 1082370b324cSopenharmony_ci CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec); 1083370b324cSopenharmony_ci extractCallbackSpec->Init(archive, FString()); // second parameter is output folder path 1084370b324cSopenharmony_ci extractCallbackSpec->PasswordIsDefined = passwordIsDefined; 1085370b324cSopenharmony_ci extractCallbackSpec->Password = password; 1086370b324cSopenharmony_ci 1087370b324cSopenharmony_ci /* 1088370b324cSopenharmony_ci const wchar_t *names[] = 1089370b324cSopenharmony_ci { 1090370b324cSopenharmony_ci L"mt", 1091370b324cSopenharmony_ci L"mtf" 1092370b324cSopenharmony_ci }; 1093370b324cSopenharmony_ci const unsigned kNumProps = sizeof(names) / sizeof(names[0]); 1094370b324cSopenharmony_ci NCOM::CPropVariant values[kNumProps] = 1095370b324cSopenharmony_ci { 1096370b324cSopenharmony_ci (UInt32)1, 1097370b324cSopenharmony_ci false 1098370b324cSopenharmony_ci }; 1099370b324cSopenharmony_ci CMyComPtr<ISetProperties> setProperties; 1100370b324cSopenharmony_ci archive->QueryInterface(IID_ISetProperties, (void **)&setProperties); 1101370b324cSopenharmony_ci if (setProperties) 1102370b324cSopenharmony_ci { 1103370b324cSopenharmony_ci if (setProperties->SetProperties(names, values, kNumProps) != S_OK) 1104370b324cSopenharmony_ci { 1105370b324cSopenharmony_ci PrintError("SetProperties() error"); 1106370b324cSopenharmony_ci return 1; 1107370b324cSopenharmony_ci } 1108370b324cSopenharmony_ci } 1109370b324cSopenharmony_ci */ 1110370b324cSopenharmony_ci 1111370b324cSopenharmony_ci HRESULT result = archive->Extract(NULL, (UInt32)(Int32)(-1), false, extractCallback); 1112370b324cSopenharmony_ci 1113370b324cSopenharmony_ci if (result != S_OK) 1114370b324cSopenharmony_ci { 1115370b324cSopenharmony_ci PrintError("Extract Error"); 1116370b324cSopenharmony_ci return 1; 1117370b324cSopenharmony_ci } 1118370b324cSopenharmony_ci } 1119370b324cSopenharmony_ci } 1120370b324cSopenharmony_ci 1121370b324cSopenharmony_ci return 0; 1122370b324cSopenharmony_ci} 1123