1370b324cSopenharmony_ci// 7zHandler.cpp 2370b324cSopenharmony_ci 3370b324cSopenharmony_ci#include "StdAfx.h" 4370b324cSopenharmony_ci 5370b324cSopenharmony_ci#include "../../../../C/CpuArch.h" 6370b324cSopenharmony_ci 7370b324cSopenharmony_ci#include "../../../Common/ComTry.h" 8370b324cSopenharmony_ci#include "../../../Common/IntToString.h" 9370b324cSopenharmony_ci 10370b324cSopenharmony_ci#ifndef Z7_7Z_SET_PROPERTIES 11370b324cSopenharmony_ci#include "../../../Windows/System.h" 12370b324cSopenharmony_ci#endif 13370b324cSopenharmony_ci 14370b324cSopenharmony_ci#include "../Common/ItemNameUtils.h" 15370b324cSopenharmony_ci 16370b324cSopenharmony_ci#include "7zHandler.h" 17370b324cSopenharmony_ci#include "7zProperties.h" 18370b324cSopenharmony_ci 19370b324cSopenharmony_ci#ifdef Z7_7Z_SET_PROPERTIES 20370b324cSopenharmony_ci#ifdef Z7_EXTRACT_ONLY 21370b324cSopenharmony_ci#include "../Common/ParseProperties.h" 22370b324cSopenharmony_ci#endif 23370b324cSopenharmony_ci#endif 24370b324cSopenharmony_ci 25370b324cSopenharmony_ciusing namespace NWindows; 26370b324cSopenharmony_ciusing namespace NCOM; 27370b324cSopenharmony_ci 28370b324cSopenharmony_cinamespace NArchive { 29370b324cSopenharmony_cinamespace N7z { 30370b324cSopenharmony_ci 31370b324cSopenharmony_ciCHandler::CHandler() 32370b324cSopenharmony_ci{ 33370b324cSopenharmony_ci #ifndef Z7_NO_CRYPTO 34370b324cSopenharmony_ci _isEncrypted = false; 35370b324cSopenharmony_ci _passwordIsDefined = false; 36370b324cSopenharmony_ci #endif 37370b324cSopenharmony_ci 38370b324cSopenharmony_ci #ifdef Z7_EXTRACT_ONLY 39370b324cSopenharmony_ci 40370b324cSopenharmony_ci _crcSize = 4; 41370b324cSopenharmony_ci 42370b324cSopenharmony_ci #ifdef Z7_7Z_SET_PROPERTIES 43370b324cSopenharmony_ci _useMultiThreadMixer = true; 44370b324cSopenharmony_ci #endif 45370b324cSopenharmony_ci 46370b324cSopenharmony_ci #endif 47370b324cSopenharmony_ci} 48370b324cSopenharmony_ci 49370b324cSopenharmony_ciZ7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) 50370b324cSopenharmony_ci{ 51370b324cSopenharmony_ci *numItems = _db.Files.Size(); 52370b324cSopenharmony_ci return S_OK; 53370b324cSopenharmony_ci} 54370b324cSopenharmony_ci 55370b324cSopenharmony_ci#ifdef Z7_SFX 56370b324cSopenharmony_ci 57370b324cSopenharmony_ciIMP_IInArchive_ArcProps_NO_Table 58370b324cSopenharmony_ci 59370b324cSopenharmony_ciZ7_COM7F_IMF(CHandler::GetNumberOfProperties(UInt32 *numProps)) 60370b324cSopenharmony_ci{ 61370b324cSopenharmony_ci *numProps = 0; 62370b324cSopenharmony_ci return S_OK; 63370b324cSopenharmony_ci} 64370b324cSopenharmony_ci 65370b324cSopenharmony_ciZ7_COM7F_IMF(CHandler::GetPropertyInfo(UInt32 /* index */, 66370b324cSopenharmony_ci BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)) 67370b324cSopenharmony_ci{ 68370b324cSopenharmony_ci return E_NOTIMPL; 69370b324cSopenharmony_ci} 70370b324cSopenharmony_ci 71370b324cSopenharmony_ci#else 72370b324cSopenharmony_ci 73370b324cSopenharmony_cistatic const Byte kArcProps[] = 74370b324cSopenharmony_ci{ 75370b324cSopenharmony_ci kpidHeadersSize, 76370b324cSopenharmony_ci kpidMethod, 77370b324cSopenharmony_ci kpidSolid, 78370b324cSopenharmony_ci kpidNumBlocks 79370b324cSopenharmony_ci // , kpidIsTree 80370b324cSopenharmony_ci}; 81370b324cSopenharmony_ci 82370b324cSopenharmony_ciIMP_IInArchive_ArcProps 83370b324cSopenharmony_ci 84370b324cSopenharmony_cistatic inline char GetHex(unsigned value) 85370b324cSopenharmony_ci{ 86370b324cSopenharmony_ci return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10))); 87370b324cSopenharmony_ci} 88370b324cSopenharmony_ci 89370b324cSopenharmony_cistatic unsigned ConvertMethodIdToString_Back(char *s, UInt64 id) 90370b324cSopenharmony_ci{ 91370b324cSopenharmony_ci int len = 0; 92370b324cSopenharmony_ci do 93370b324cSopenharmony_ci { 94370b324cSopenharmony_ci s[--len] = GetHex((unsigned)id & 0xF); id >>= 4; 95370b324cSopenharmony_ci s[--len] = GetHex((unsigned)id & 0xF); id >>= 4; 96370b324cSopenharmony_ci } 97370b324cSopenharmony_ci while (id != 0); 98370b324cSopenharmony_ci return (unsigned)-len; 99370b324cSopenharmony_ci} 100370b324cSopenharmony_ci 101370b324cSopenharmony_cistatic void ConvertMethodIdToString(AString &res, UInt64 id) 102370b324cSopenharmony_ci{ 103370b324cSopenharmony_ci const unsigned kLen = 32; 104370b324cSopenharmony_ci char s[kLen]; 105370b324cSopenharmony_ci unsigned len = kLen - 1; 106370b324cSopenharmony_ci s[len] = 0; 107370b324cSopenharmony_ci res += s + len - ConvertMethodIdToString_Back(s + len, id); 108370b324cSopenharmony_ci} 109370b324cSopenharmony_ci 110370b324cSopenharmony_ci 111370b324cSopenharmony_cistatic char *GetStringForSizeValue(char *s, UInt32 val) 112370b324cSopenharmony_ci{ 113370b324cSopenharmony_ci for (unsigned i = 0; i < 32; i++) 114370b324cSopenharmony_ci if (((UInt32)1 << i) == val) 115370b324cSopenharmony_ci { 116370b324cSopenharmony_ci if (i >= 10) 117370b324cSopenharmony_ci { 118370b324cSopenharmony_ci *s++= (char)('0' + i / 10); 119370b324cSopenharmony_ci i %= 10; 120370b324cSopenharmony_ci } 121370b324cSopenharmony_ci *s++ = (char)('0' + i); 122370b324cSopenharmony_ci *s = 0; 123370b324cSopenharmony_ci return s; 124370b324cSopenharmony_ci } 125370b324cSopenharmony_ci 126370b324cSopenharmony_ci char c = 'b'; 127370b324cSopenharmony_ci if ((val & ((1 << 20) - 1)) == 0) { val >>= 20; c = 'm'; } 128370b324cSopenharmony_ci else if ((val & ((1 << 10) - 1)) == 0) { val >>= 10; c = 'k'; } 129370b324cSopenharmony_ci s = ConvertUInt32ToString(val, s); 130370b324cSopenharmony_ci *s++ = c; 131370b324cSopenharmony_ci *s = 0; 132370b324cSopenharmony_ci return s; 133370b324cSopenharmony_ci} 134370b324cSopenharmony_ci 135370b324cSopenharmony_ci 136370b324cSopenharmony_cistatic void GetLzma2String(char *s, unsigned d) 137370b324cSopenharmony_ci{ 138370b324cSopenharmony_ci if (d > 40) 139370b324cSopenharmony_ci { 140370b324cSopenharmony_ci *s = 0; 141370b324cSopenharmony_ci return; 142370b324cSopenharmony_ci // s = MyStpCpy(s, "unsup"); 143370b324cSopenharmony_ci } 144370b324cSopenharmony_ci else if ((d & 1) == 0) 145370b324cSopenharmony_ci d = (d >> 1) + 12; 146370b324cSopenharmony_ci else 147370b324cSopenharmony_ci { 148370b324cSopenharmony_ci // s = GetStringForSizeValue(s, (UInt32)3 << ((d >> 1) + 11)); 149370b324cSopenharmony_ci d = (d >> 1) + 1; 150370b324cSopenharmony_ci char c = 'k'; 151370b324cSopenharmony_ci if (d >= 10) 152370b324cSopenharmony_ci { 153370b324cSopenharmony_ci c = 'm'; 154370b324cSopenharmony_ci d -= 10; 155370b324cSopenharmony_ci } 156370b324cSopenharmony_ci s = ConvertUInt32ToString((UInt32)3 << d, s); 157370b324cSopenharmony_ci *s++ = c; 158370b324cSopenharmony_ci *s = 0; 159370b324cSopenharmony_ci return; 160370b324cSopenharmony_ci } 161370b324cSopenharmony_ci ConvertUInt32ToString(d, s); 162370b324cSopenharmony_ci} 163370b324cSopenharmony_ci 164370b324cSopenharmony_ci 165370b324cSopenharmony_ci/* 166370b324cSopenharmony_cistatic inline void AddHexToString(UString &res, Byte value) 167370b324cSopenharmony_ci{ 168370b324cSopenharmony_ci res += GetHex((Byte)(value >> 4)); 169370b324cSopenharmony_ci res += GetHex((Byte)(value & 0xF)); 170370b324cSopenharmony_ci} 171370b324cSopenharmony_ci*/ 172370b324cSopenharmony_ci 173370b324cSopenharmony_cistatic char *AddProp32(char *s, const char *name, UInt32 v) 174370b324cSopenharmony_ci{ 175370b324cSopenharmony_ci *s++ = ':'; 176370b324cSopenharmony_ci s = MyStpCpy(s, name); 177370b324cSopenharmony_ci return ConvertUInt32ToString(v, s); 178370b324cSopenharmony_ci} 179370b324cSopenharmony_ci 180370b324cSopenharmony_civoid CHandler::AddMethodName(AString &s, UInt64 id) 181370b324cSopenharmony_ci{ 182370b324cSopenharmony_ci AString name; 183370b324cSopenharmony_ci FindMethod(EXTERNAL_CODECS_VARS id, name); 184370b324cSopenharmony_ci if (name.IsEmpty()) 185370b324cSopenharmony_ci ConvertMethodIdToString(s, id); 186370b324cSopenharmony_ci else 187370b324cSopenharmony_ci s += name; 188370b324cSopenharmony_ci} 189370b324cSopenharmony_ci 190370b324cSopenharmony_ci#endif 191370b324cSopenharmony_ci 192370b324cSopenharmony_ciZ7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) 193370b324cSopenharmony_ci{ 194370b324cSopenharmony_ci #ifndef Z7_SFX 195370b324cSopenharmony_ci COM_TRY_BEGIN 196370b324cSopenharmony_ci #endif 197370b324cSopenharmony_ci NCOM::CPropVariant prop; 198370b324cSopenharmony_ci switch (propID) 199370b324cSopenharmony_ci { 200370b324cSopenharmony_ci #ifndef Z7_SFX 201370b324cSopenharmony_ci case kpidMethod: 202370b324cSopenharmony_ci { 203370b324cSopenharmony_ci AString s; 204370b324cSopenharmony_ci const CParsedMethods &pm = _db.ParsedMethods; 205370b324cSopenharmony_ci FOR_VECTOR (i, pm.IDs) 206370b324cSopenharmony_ci { 207370b324cSopenharmony_ci UInt64 id = pm.IDs[i]; 208370b324cSopenharmony_ci s.Add_Space_if_NotEmpty(); 209370b324cSopenharmony_ci char temp[16]; 210370b324cSopenharmony_ci if (id == k_LZMA2) 211370b324cSopenharmony_ci { 212370b324cSopenharmony_ci s += "LZMA2:"; 213370b324cSopenharmony_ci GetLzma2String(temp, pm.Lzma2Prop); 214370b324cSopenharmony_ci s += temp; 215370b324cSopenharmony_ci } 216370b324cSopenharmony_ci else if (id == k_LZMA) 217370b324cSopenharmony_ci { 218370b324cSopenharmony_ci s += "LZMA:"; 219370b324cSopenharmony_ci GetStringForSizeValue(temp, pm.LzmaDic); 220370b324cSopenharmony_ci s += temp; 221370b324cSopenharmony_ci } 222370b324cSopenharmony_ci /* 223370b324cSopenharmony_ci else if (id == k_ZSTD) 224370b324cSopenharmony_ci { 225370b324cSopenharmony_ci s += "ZSTD"; 226370b324cSopenharmony_ci } 227370b324cSopenharmony_ci */ 228370b324cSopenharmony_ci else 229370b324cSopenharmony_ci AddMethodName(s, id); 230370b324cSopenharmony_ci } 231370b324cSopenharmony_ci prop = s; 232370b324cSopenharmony_ci break; 233370b324cSopenharmony_ci } 234370b324cSopenharmony_ci case kpidSolid: prop = _db.IsSolid(); break; 235370b324cSopenharmony_ci case kpidNumBlocks: prop = (UInt32)_db.NumFolders; break; 236370b324cSopenharmony_ci case kpidHeadersSize: prop = _db.HeadersSize; break; 237370b324cSopenharmony_ci case kpidPhySize: prop = _db.PhySize; break; 238370b324cSopenharmony_ci case kpidOffset: if (_db.ArcInfo.StartPosition != 0) prop = _db.ArcInfo.StartPosition; break; 239370b324cSopenharmony_ci /* 240370b324cSopenharmony_ci case kpidIsTree: if (_db.IsTree) prop = true; break; 241370b324cSopenharmony_ci case kpidIsAltStream: if (_db.ThereAreAltStreams) prop = true; break; 242370b324cSopenharmony_ci case kpidIsAux: if (_db.IsTree) prop = true; break; 243370b324cSopenharmony_ci */ 244370b324cSopenharmony_ci // case kpidError: if (_db.ThereIsHeaderError) prop = "Header error"; break; 245370b324cSopenharmony_ci #endif 246370b324cSopenharmony_ci 247370b324cSopenharmony_ci case kpidWarningFlags: 248370b324cSopenharmony_ci { 249370b324cSopenharmony_ci UInt32 v = 0; 250370b324cSopenharmony_ci if (_db.StartHeaderWasRecovered) v |= kpv_ErrorFlags_HeadersError; 251370b324cSopenharmony_ci if (_db.UnsupportedFeatureWarning) v |= kpv_ErrorFlags_UnsupportedFeature; 252370b324cSopenharmony_ci if (v != 0) 253370b324cSopenharmony_ci prop = v; 254370b324cSopenharmony_ci break; 255370b324cSopenharmony_ci } 256370b324cSopenharmony_ci 257370b324cSopenharmony_ci case kpidErrorFlags: 258370b324cSopenharmony_ci { 259370b324cSopenharmony_ci UInt32 v = 0; 260370b324cSopenharmony_ci if (!_db.IsArc) v |= kpv_ErrorFlags_IsNotArc; 261370b324cSopenharmony_ci if (_db.ThereIsHeaderError) v |= kpv_ErrorFlags_HeadersError; 262370b324cSopenharmony_ci if (_db.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd; 263370b324cSopenharmony_ci // if (_db.UnsupportedVersion) v |= kpv_ErrorFlags_Unsupported; 264370b324cSopenharmony_ci if (_db.UnsupportedFeatureError) v |= kpv_ErrorFlags_UnsupportedFeature; 265370b324cSopenharmony_ci prop = v; 266370b324cSopenharmony_ci break; 267370b324cSopenharmony_ci } 268370b324cSopenharmony_ci 269370b324cSopenharmony_ci case kpidReadOnly: 270370b324cSopenharmony_ci { 271370b324cSopenharmony_ci if (!_db.CanUpdate()) 272370b324cSopenharmony_ci prop = true; 273370b324cSopenharmony_ci break; 274370b324cSopenharmony_ci } 275370b324cSopenharmony_ci } 276370b324cSopenharmony_ci return prop.Detach(value); 277370b324cSopenharmony_ci #ifndef Z7_SFX 278370b324cSopenharmony_ci COM_TRY_END 279370b324cSopenharmony_ci #endif 280370b324cSopenharmony_ci} 281370b324cSopenharmony_ci 282370b324cSopenharmony_cistatic void SetFileTimeProp_From_UInt64Def(PROPVARIANT *prop, const CUInt64DefVector &v, unsigned index) 283370b324cSopenharmony_ci{ 284370b324cSopenharmony_ci UInt64 value; 285370b324cSopenharmony_ci if (v.GetItem(index, value)) 286370b324cSopenharmony_ci PropVarEm_Set_FileTime64_Prec(prop, value, k_PropVar_TimePrec_100ns); 287370b324cSopenharmony_ci} 288370b324cSopenharmony_ci 289370b324cSopenharmony_cibool CHandler::IsFolderEncrypted(CNum folderIndex) const 290370b324cSopenharmony_ci{ 291370b324cSopenharmony_ci if (folderIndex == kNumNoIndex) 292370b324cSopenharmony_ci return false; 293370b324cSopenharmony_ci const size_t startPos = _db.FoCodersDataOffset[folderIndex]; 294370b324cSopenharmony_ci const Byte *p = _db.CodersData + startPos; 295370b324cSopenharmony_ci const size_t size = _db.FoCodersDataOffset[folderIndex + 1] - startPos; 296370b324cSopenharmony_ci CInByte2 inByte; 297370b324cSopenharmony_ci inByte.Init(p, size); 298370b324cSopenharmony_ci 299370b324cSopenharmony_ci CNum numCoders = inByte.ReadNum(); 300370b324cSopenharmony_ci for (; numCoders != 0; numCoders--) 301370b324cSopenharmony_ci { 302370b324cSopenharmony_ci const Byte mainByte = inByte.ReadByte(); 303370b324cSopenharmony_ci const unsigned idSize = (mainByte & 0xF); 304370b324cSopenharmony_ci const Byte *longID = inByte.GetPtr(); 305370b324cSopenharmony_ci UInt64 id64 = 0; 306370b324cSopenharmony_ci for (unsigned j = 0; j < idSize; j++) 307370b324cSopenharmony_ci id64 = ((id64 << 8) | longID[j]); 308370b324cSopenharmony_ci inByte.SkipDataNoCheck(idSize); 309370b324cSopenharmony_ci if (id64 == k_AES) 310370b324cSopenharmony_ci return true; 311370b324cSopenharmony_ci if ((mainByte & 0x20) != 0) 312370b324cSopenharmony_ci inByte.SkipDataNoCheck(inByte.ReadNum()); 313370b324cSopenharmony_ci } 314370b324cSopenharmony_ci return false; 315370b324cSopenharmony_ci} 316370b324cSopenharmony_ci 317370b324cSopenharmony_ciZ7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps)) 318370b324cSopenharmony_ci{ 319370b324cSopenharmony_ci *numProps = 0; 320370b324cSopenharmony_ci return S_OK; 321370b324cSopenharmony_ci} 322370b324cSopenharmony_ci 323370b324cSopenharmony_ciZ7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID)) 324370b324cSopenharmony_ci{ 325370b324cSopenharmony_ci *name = NULL; 326370b324cSopenharmony_ci *propID = kpidNtSecure; 327370b324cSopenharmony_ci return S_OK; 328370b324cSopenharmony_ci} 329370b324cSopenharmony_ci 330370b324cSopenharmony_ciZ7_COM7F_IMF(CHandler::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *parentType)) 331370b324cSopenharmony_ci{ 332370b324cSopenharmony_ci /* 333370b324cSopenharmony_ci const CFileItem &file = _db.Files[index]; 334370b324cSopenharmony_ci *parentType = (file.IsAltStream ? NParentType::kAltStream : NParentType::kDir); 335370b324cSopenharmony_ci *parent = (UInt32)(Int32)file.Parent; 336370b324cSopenharmony_ci */ 337370b324cSopenharmony_ci *parentType = NParentType::kDir; 338370b324cSopenharmony_ci *parent = (UInt32)(Int32)-1; 339370b324cSopenharmony_ci return S_OK; 340370b324cSopenharmony_ci} 341370b324cSopenharmony_ci 342370b324cSopenharmony_ciZ7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) 343370b324cSopenharmony_ci{ 344370b324cSopenharmony_ci *data = NULL; 345370b324cSopenharmony_ci *dataSize = 0; 346370b324cSopenharmony_ci *propType = 0; 347370b324cSopenharmony_ci 348370b324cSopenharmony_ci if (/* _db.IsTree && propID == kpidName || 349370b324cSopenharmony_ci !_db.IsTree && */ propID == kpidPath) 350370b324cSopenharmony_ci { 351370b324cSopenharmony_ci if (_db.NameOffsets && _db.NamesBuf) 352370b324cSopenharmony_ci { 353370b324cSopenharmony_ci size_t offset = _db.NameOffsets[index]; 354370b324cSopenharmony_ci size_t size = (_db.NameOffsets[index + 1] - offset) * 2; 355370b324cSopenharmony_ci if (size < ((UInt32)1 << 31)) 356370b324cSopenharmony_ci { 357370b324cSopenharmony_ci *data = (const void *)(_db.NamesBuf + offset * 2); 358370b324cSopenharmony_ci *dataSize = (UInt32)size; 359370b324cSopenharmony_ci *propType = NPropDataType::kUtf16z; 360370b324cSopenharmony_ci } 361370b324cSopenharmony_ci } 362370b324cSopenharmony_ci return S_OK; 363370b324cSopenharmony_ci } 364370b324cSopenharmony_ci /* 365370b324cSopenharmony_ci if (propID == kpidNtSecure) 366370b324cSopenharmony_ci { 367370b324cSopenharmony_ci if (index < (UInt32)_db.SecureIDs.Size()) 368370b324cSopenharmony_ci { 369370b324cSopenharmony_ci int id = _db.SecureIDs[index]; 370370b324cSopenharmony_ci size_t offs = _db.SecureOffsets[id]; 371370b324cSopenharmony_ci size_t size = _db.SecureOffsets[id + 1] - offs; 372370b324cSopenharmony_ci if (size >= 0) 373370b324cSopenharmony_ci { 374370b324cSopenharmony_ci *data = _db.SecureBuf + offs; 375370b324cSopenharmony_ci *dataSize = (UInt32)size; 376370b324cSopenharmony_ci *propType = NPropDataType::kRaw; 377370b324cSopenharmony_ci } 378370b324cSopenharmony_ci } 379370b324cSopenharmony_ci } 380370b324cSopenharmony_ci */ 381370b324cSopenharmony_ci return S_OK; 382370b324cSopenharmony_ci} 383370b324cSopenharmony_ci 384370b324cSopenharmony_ci#ifndef Z7_SFX 385370b324cSopenharmony_ci 386370b324cSopenharmony_ciHRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const 387370b324cSopenharmony_ci{ 388370b324cSopenharmony_ci PropVariant_Clear(prop); 389370b324cSopenharmony_ci if (folderIndex == kNumNoIndex) 390370b324cSopenharmony_ci return S_OK; 391370b324cSopenharmony_ci // for (int ttt = 0; ttt < 1; ttt++) { 392370b324cSopenharmony_ci const unsigned kTempSize = 256; 393370b324cSopenharmony_ci char temp[kTempSize]; 394370b324cSopenharmony_ci unsigned pos = kTempSize; 395370b324cSopenharmony_ci temp[--pos] = 0; 396370b324cSopenharmony_ci 397370b324cSopenharmony_ci const size_t startPos = _db.FoCodersDataOffset[folderIndex]; 398370b324cSopenharmony_ci const Byte *p = _db.CodersData + startPos; 399370b324cSopenharmony_ci const size_t size = _db.FoCodersDataOffset[folderIndex + 1] - startPos; 400370b324cSopenharmony_ci CInByte2 inByte; 401370b324cSopenharmony_ci inByte.Init(p, size); 402370b324cSopenharmony_ci 403370b324cSopenharmony_ci // numCoders == 0 ??? 404370b324cSopenharmony_ci CNum numCoders = inByte.ReadNum(); 405370b324cSopenharmony_ci bool needSpace = false; 406370b324cSopenharmony_ci 407370b324cSopenharmony_ci for (; numCoders != 0; numCoders--, needSpace = true) 408370b324cSopenharmony_ci { 409370b324cSopenharmony_ci if (pos < 32) // max size of property 410370b324cSopenharmony_ci break; 411370b324cSopenharmony_ci const Byte mainByte = inByte.ReadByte(); 412370b324cSopenharmony_ci UInt64 id64 = 0; 413370b324cSopenharmony_ci const unsigned idSize = (mainByte & 0xF); 414370b324cSopenharmony_ci const Byte *longID = inByte.GetPtr(); 415370b324cSopenharmony_ci for (unsigned j = 0; j < idSize; j++) 416370b324cSopenharmony_ci id64 = ((id64 << 8) | longID[j]); 417370b324cSopenharmony_ci inByte.SkipDataNoCheck(idSize); 418370b324cSopenharmony_ci 419370b324cSopenharmony_ci if ((mainByte & 0x10) != 0) 420370b324cSopenharmony_ci { 421370b324cSopenharmony_ci inByte.ReadNum(); // NumInStreams 422370b324cSopenharmony_ci inByte.ReadNum(); // NumOutStreams 423370b324cSopenharmony_ci } 424370b324cSopenharmony_ci 425370b324cSopenharmony_ci CNum propsSize = 0; 426370b324cSopenharmony_ci const Byte *props = NULL; 427370b324cSopenharmony_ci if ((mainByte & 0x20) != 0) 428370b324cSopenharmony_ci { 429370b324cSopenharmony_ci propsSize = inByte.ReadNum(); 430370b324cSopenharmony_ci props = inByte.GetPtr(); 431370b324cSopenharmony_ci inByte.SkipDataNoCheck(propsSize); 432370b324cSopenharmony_ci } 433370b324cSopenharmony_ci 434370b324cSopenharmony_ci const char *name = NULL; 435370b324cSopenharmony_ci char s[32]; 436370b324cSopenharmony_ci s[0] = 0; 437370b324cSopenharmony_ci 438370b324cSopenharmony_ci if (id64 <= (UInt32)0xFFFFFFFF) 439370b324cSopenharmony_ci { 440370b324cSopenharmony_ci const UInt32 id = (UInt32)id64; 441370b324cSopenharmony_ci if (id == k_LZMA) 442370b324cSopenharmony_ci { 443370b324cSopenharmony_ci name = "LZMA"; 444370b324cSopenharmony_ci if (propsSize == 5) 445370b324cSopenharmony_ci { 446370b324cSopenharmony_ci const UInt32 dicSize = GetUi32((const Byte *)props + 1); 447370b324cSopenharmony_ci char *dest = GetStringForSizeValue(s, dicSize); 448370b324cSopenharmony_ci UInt32 d = props[0]; 449370b324cSopenharmony_ci if (d != 0x5D) 450370b324cSopenharmony_ci { 451370b324cSopenharmony_ci const UInt32 lc = d % 9; 452370b324cSopenharmony_ci d /= 9; 453370b324cSopenharmony_ci const UInt32 pb = d / 5; 454370b324cSopenharmony_ci const UInt32 lp = d % 5; 455370b324cSopenharmony_ci if (lc != 3) dest = AddProp32(dest, "lc", lc); 456370b324cSopenharmony_ci if (lp != 0) dest = AddProp32(dest, "lp", lp); 457370b324cSopenharmony_ci if (pb != 2) dest = AddProp32(dest, "pb", pb); 458370b324cSopenharmony_ci } 459370b324cSopenharmony_ci } 460370b324cSopenharmony_ci } 461370b324cSopenharmony_ci else if (id == k_LZMA2) 462370b324cSopenharmony_ci { 463370b324cSopenharmony_ci name = "LZMA2"; 464370b324cSopenharmony_ci if (propsSize == 1) 465370b324cSopenharmony_ci GetLzma2String(s, props[0]); 466370b324cSopenharmony_ci } 467370b324cSopenharmony_ci else if (id == k_PPMD) 468370b324cSopenharmony_ci { 469370b324cSopenharmony_ci name = "PPMD"; 470370b324cSopenharmony_ci if (propsSize == 5) 471370b324cSopenharmony_ci { 472370b324cSopenharmony_ci char *dest = s; 473370b324cSopenharmony_ci *dest++ = 'o'; 474370b324cSopenharmony_ci dest = ConvertUInt32ToString(*props, dest); 475370b324cSopenharmony_ci dest = MyStpCpy(dest, ":mem"); 476370b324cSopenharmony_ci GetStringForSizeValue(dest, GetUi32(props + 1)); 477370b324cSopenharmony_ci } 478370b324cSopenharmony_ci } 479370b324cSopenharmony_ci else if (id == k_Delta) 480370b324cSopenharmony_ci { 481370b324cSopenharmony_ci name = "Delta"; 482370b324cSopenharmony_ci if (propsSize == 1) 483370b324cSopenharmony_ci ConvertUInt32ToString((UInt32)props[0] + 1, s); 484370b324cSopenharmony_ci } 485370b324cSopenharmony_ci else if (id == k_ARM64) 486370b324cSopenharmony_ci { 487370b324cSopenharmony_ci name = "ARM64"; 488370b324cSopenharmony_ci if (propsSize == 4) 489370b324cSopenharmony_ci ConvertUInt32ToString(GetUi32(props), s); 490370b324cSopenharmony_ci /* 491370b324cSopenharmony_ci else if (propsSize != 0) 492370b324cSopenharmony_ci MyStringCopy(s, "unsupported"); 493370b324cSopenharmony_ci */ 494370b324cSopenharmony_ci } 495370b324cSopenharmony_ci else if (id == k_BCJ2) name = "BCJ2"; 496370b324cSopenharmony_ci else if (id == k_BCJ) name = "BCJ"; 497370b324cSopenharmony_ci else if (id == k_AES) 498370b324cSopenharmony_ci { 499370b324cSopenharmony_ci name = "7zAES"; 500370b324cSopenharmony_ci if (propsSize >= 1) 501370b324cSopenharmony_ci { 502370b324cSopenharmony_ci const Byte firstByte = props[0]; 503370b324cSopenharmony_ci const UInt32 numCyclesPower = firstByte & 0x3F; 504370b324cSopenharmony_ci ConvertUInt32ToString(numCyclesPower, s); 505370b324cSopenharmony_ci } 506370b324cSopenharmony_ci } 507370b324cSopenharmony_ci } 508370b324cSopenharmony_ci 509370b324cSopenharmony_ci if (name) 510370b324cSopenharmony_ci { 511370b324cSopenharmony_ci const unsigned nameLen = MyStringLen(name); 512370b324cSopenharmony_ci const unsigned propsLen = MyStringLen(s); 513370b324cSopenharmony_ci unsigned totalLen = nameLen + propsLen; 514370b324cSopenharmony_ci if (propsLen != 0) 515370b324cSopenharmony_ci totalLen++; 516370b324cSopenharmony_ci if (needSpace) 517370b324cSopenharmony_ci totalLen++; 518370b324cSopenharmony_ci if (totalLen + 5 >= pos) 519370b324cSopenharmony_ci break; 520370b324cSopenharmony_ci pos -= totalLen; 521370b324cSopenharmony_ci MyStringCopy(temp + pos, name); 522370b324cSopenharmony_ci if (propsLen != 0) 523370b324cSopenharmony_ci { 524370b324cSopenharmony_ci char *dest = temp + pos + nameLen; 525370b324cSopenharmony_ci *dest++ = ':'; 526370b324cSopenharmony_ci MyStringCopy(dest, s); 527370b324cSopenharmony_ci } 528370b324cSopenharmony_ci if (needSpace) 529370b324cSopenharmony_ci temp[pos + totalLen - 1] = ' '; 530370b324cSopenharmony_ci } 531370b324cSopenharmony_ci else 532370b324cSopenharmony_ci { 533370b324cSopenharmony_ci AString methodName; 534370b324cSopenharmony_ci FindMethod(EXTERNAL_CODECS_VARS id64, methodName); 535370b324cSopenharmony_ci if (needSpace) 536370b324cSopenharmony_ci temp[--pos] = ' '; 537370b324cSopenharmony_ci if (methodName.IsEmpty()) 538370b324cSopenharmony_ci pos -= ConvertMethodIdToString_Back(temp + pos, id64); 539370b324cSopenharmony_ci else 540370b324cSopenharmony_ci { 541370b324cSopenharmony_ci const unsigned len = methodName.Len(); 542370b324cSopenharmony_ci if (len + 5 > pos) 543370b324cSopenharmony_ci break; 544370b324cSopenharmony_ci pos -= len; 545370b324cSopenharmony_ci for (unsigned i = 0; i < len; i++) 546370b324cSopenharmony_ci temp[pos + i] = methodName[i]; 547370b324cSopenharmony_ci } 548370b324cSopenharmony_ci } 549370b324cSopenharmony_ci } 550370b324cSopenharmony_ci 551370b324cSopenharmony_ci if (numCoders != 0 && pos >= 4) 552370b324cSopenharmony_ci { 553370b324cSopenharmony_ci temp[--pos] = ' '; 554370b324cSopenharmony_ci temp[--pos] = '.'; 555370b324cSopenharmony_ci temp[--pos] = '.'; 556370b324cSopenharmony_ci temp[--pos] = '.'; 557370b324cSopenharmony_ci } 558370b324cSopenharmony_ci 559370b324cSopenharmony_ci return PropVarEm_Set_Str(prop, temp + pos); 560370b324cSopenharmony_ci // } 561370b324cSopenharmony_ci} 562370b324cSopenharmony_ci 563370b324cSopenharmony_ci#endif 564370b324cSopenharmony_ci 565370b324cSopenharmony_ciZ7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) 566370b324cSopenharmony_ci{ 567370b324cSopenharmony_ci RINOK(PropVariant_Clear(value)) 568370b324cSopenharmony_ci // COM_TRY_BEGIN 569370b324cSopenharmony_ci // NCOM::CPropVariant prop; 570370b324cSopenharmony_ci 571370b324cSopenharmony_ci /* 572370b324cSopenharmony_ci const CRef2 &ref2 = _refs[index]; 573370b324cSopenharmony_ci if (ref2.Refs.IsEmpty()) 574370b324cSopenharmony_ci return E_FAIL; 575370b324cSopenharmony_ci const CRef &ref = ref2.Refs.Front(); 576370b324cSopenharmony_ci */ 577370b324cSopenharmony_ci 578370b324cSopenharmony_ci const CFileItem &item = _db.Files[index]; 579370b324cSopenharmony_ci const UInt32 index2 = index; 580370b324cSopenharmony_ci 581370b324cSopenharmony_ci switch (propID) 582370b324cSopenharmony_ci { 583370b324cSopenharmony_ci case kpidIsDir: PropVarEm_Set_Bool(value, item.IsDir); break; 584370b324cSopenharmony_ci case kpidSize: 585370b324cSopenharmony_ci { 586370b324cSopenharmony_ci PropVarEm_Set_UInt64(value, item.Size); 587370b324cSopenharmony_ci // prop = ref2.Size; 588370b324cSopenharmony_ci break; 589370b324cSopenharmony_ci } 590370b324cSopenharmony_ci case kpidPackSize: 591370b324cSopenharmony_ci { 592370b324cSopenharmony_ci // prop = ref2.PackSize; 593370b324cSopenharmony_ci { 594370b324cSopenharmony_ci const CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; 595370b324cSopenharmony_ci if (folderIndex != kNumNoIndex) 596370b324cSopenharmony_ci { 597370b324cSopenharmony_ci if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2) 598370b324cSopenharmony_ci PropVarEm_Set_UInt64(value, _db.GetFolderFullPackSize(folderIndex)); 599370b324cSopenharmony_ci /* 600370b324cSopenharmony_ci else 601370b324cSopenharmony_ci PropVarEm_Set_UInt64(value, 0); 602370b324cSopenharmony_ci */ 603370b324cSopenharmony_ci } 604370b324cSopenharmony_ci else 605370b324cSopenharmony_ci PropVarEm_Set_UInt64(value, 0); 606370b324cSopenharmony_ci } 607370b324cSopenharmony_ci break; 608370b324cSopenharmony_ci } 609370b324cSopenharmony_ci // case kpidIsAux: prop = _db.IsItemAux(index2); break; 610370b324cSopenharmony_ci case kpidPosition: { UInt64 v; if (_db.StartPos.GetItem(index2, v)) PropVarEm_Set_UInt64(value, v); break; } 611370b324cSopenharmony_ci case kpidCTime: SetFileTimeProp_From_UInt64Def(value, _db.CTime, index2); break; 612370b324cSopenharmony_ci case kpidATime: SetFileTimeProp_From_UInt64Def(value, _db.ATime, index2); break; 613370b324cSopenharmony_ci case kpidMTime: SetFileTimeProp_From_UInt64Def(value, _db.MTime, index2); break; 614370b324cSopenharmony_ci case kpidAttrib: if (_db.Attrib.ValidAndDefined(index2)) PropVarEm_Set_UInt32(value, _db.Attrib.Vals[index2]); break; 615370b324cSopenharmony_ci case kpidCRC: if (item.CrcDefined) PropVarEm_Set_UInt32(value, item.Crc); break; 616370b324cSopenharmony_ci case kpidEncrypted: PropVarEm_Set_Bool(value, IsFolderEncrypted(_db.FileIndexToFolderIndexMap[index2])); break; 617370b324cSopenharmony_ci case kpidIsAnti: PropVarEm_Set_Bool(value, _db.IsItemAnti(index2)); break; 618370b324cSopenharmony_ci /* 619370b324cSopenharmony_ci case kpidIsAltStream: prop = item.IsAltStream; break; 620370b324cSopenharmony_ci case kpidNtSecure: 621370b324cSopenharmony_ci { 622370b324cSopenharmony_ci int id = _db.SecureIDs[index]; 623370b324cSopenharmony_ci size_t offs = _db.SecureOffsets[id]; 624370b324cSopenharmony_ci size_t size = _db.SecureOffsets[id + 1] - offs; 625370b324cSopenharmony_ci if (size >= 0) 626370b324cSopenharmony_ci { 627370b324cSopenharmony_ci prop.SetBlob(_db.SecureBuf + offs, (ULONG)size); 628370b324cSopenharmony_ci } 629370b324cSopenharmony_ci break; 630370b324cSopenharmony_ci } 631370b324cSopenharmony_ci */ 632370b324cSopenharmony_ci 633370b324cSopenharmony_ci case kpidPath: return _db.GetPath_Prop(index, value); 634370b324cSopenharmony_ci 635370b324cSopenharmony_ci #ifndef Z7_SFX 636370b324cSopenharmony_ci 637370b324cSopenharmony_ci case kpidMethod: return SetMethodToProp(_db.FileIndexToFolderIndexMap[index2], value); 638370b324cSopenharmony_ci case kpidBlock: 639370b324cSopenharmony_ci { 640370b324cSopenharmony_ci const CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; 641370b324cSopenharmony_ci if (folderIndex != kNumNoIndex) 642370b324cSopenharmony_ci PropVarEm_Set_UInt32(value, (UInt32)folderIndex); 643370b324cSopenharmony_ci } 644370b324cSopenharmony_ci break; 645370b324cSopenharmony_ci #ifdef Z7_7Z_SHOW_PACK_STREAMS_SIZES 646370b324cSopenharmony_ci case kpidPackedSize0: 647370b324cSopenharmony_ci case kpidPackedSize1: 648370b324cSopenharmony_ci case kpidPackedSize2: 649370b324cSopenharmony_ci case kpidPackedSize3: 650370b324cSopenharmony_ci case kpidPackedSize4: 651370b324cSopenharmony_ci { 652370b324cSopenharmony_ci const CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; 653370b324cSopenharmony_ci if (folderIndex != kNumNoIndex) 654370b324cSopenharmony_ci { 655370b324cSopenharmony_ci if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2 && 656370b324cSopenharmony_ci _db.FoStartPackStreamIndex[folderIndex + 1] - 657370b324cSopenharmony_ci _db.FoStartPackStreamIndex[folderIndex] > (propID - kpidPackedSize0)) 658370b324cSopenharmony_ci { 659370b324cSopenharmony_ci PropVarEm_Set_UInt64(value, _db.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0)); 660370b324cSopenharmony_ci } 661370b324cSopenharmony_ci } 662370b324cSopenharmony_ci else 663370b324cSopenharmony_ci PropVarEm_Set_UInt64(value, 0); 664370b324cSopenharmony_ci } 665370b324cSopenharmony_ci break; 666370b324cSopenharmony_ci #endif 667370b324cSopenharmony_ci 668370b324cSopenharmony_ci #endif 669370b324cSopenharmony_ci } 670370b324cSopenharmony_ci // return prop.Detach(value); 671370b324cSopenharmony_ci return S_OK; 672370b324cSopenharmony_ci // COM_TRY_END 673370b324cSopenharmony_ci} 674370b324cSopenharmony_ci 675370b324cSopenharmony_ciZ7_COM7F_IMF(CHandler::Open(IInStream *stream, 676370b324cSopenharmony_ci const UInt64 *maxCheckStartPosition, 677370b324cSopenharmony_ci IArchiveOpenCallback *openArchiveCallback)) 678370b324cSopenharmony_ci{ 679370b324cSopenharmony_ci COM_TRY_BEGIN 680370b324cSopenharmony_ci Close(); 681370b324cSopenharmony_ci #ifndef Z7_SFX 682370b324cSopenharmony_ci _fileInfoPopIDs.Clear(); 683370b324cSopenharmony_ci #endif 684370b324cSopenharmony_ci 685370b324cSopenharmony_ci try 686370b324cSopenharmony_ci { 687370b324cSopenharmony_ci CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback; 688370b324cSopenharmony_ci 689370b324cSopenharmony_ci #ifndef Z7_NO_CRYPTO 690370b324cSopenharmony_ci CMyComPtr<ICryptoGetTextPassword> getTextPassword; 691370b324cSopenharmony_ci if (openArchiveCallback) 692370b324cSopenharmony_ci openArchiveCallbackTemp.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); 693370b324cSopenharmony_ci #endif 694370b324cSopenharmony_ci 695370b324cSopenharmony_ci CInArchive archive( 696370b324cSopenharmony_ci #ifdef Z7_7Z_SET_PROPERTIES 697370b324cSopenharmony_ci _useMultiThreadMixer 698370b324cSopenharmony_ci #else 699370b324cSopenharmony_ci true 700370b324cSopenharmony_ci #endif 701370b324cSopenharmony_ci ); 702370b324cSopenharmony_ci _db.IsArc = false; 703370b324cSopenharmony_ci RINOK(archive.Open(stream, maxCheckStartPosition)) 704370b324cSopenharmony_ci _db.IsArc = true; 705370b324cSopenharmony_ci 706370b324cSopenharmony_ci HRESULT result = archive.ReadDatabase( 707370b324cSopenharmony_ci EXTERNAL_CODECS_VARS 708370b324cSopenharmony_ci _db 709370b324cSopenharmony_ci #ifndef Z7_NO_CRYPTO 710370b324cSopenharmony_ci , getTextPassword, _isEncrypted, _passwordIsDefined, _password 711370b324cSopenharmony_ci #endif 712370b324cSopenharmony_ci ); 713370b324cSopenharmony_ci RINOK(result) 714370b324cSopenharmony_ci 715370b324cSopenharmony_ci _inStream = stream; 716370b324cSopenharmony_ci } 717370b324cSopenharmony_ci catch(...) 718370b324cSopenharmony_ci { 719370b324cSopenharmony_ci Close(); 720370b324cSopenharmony_ci // return E_INVALIDARG; 721370b324cSopenharmony_ci // return S_FALSE; 722370b324cSopenharmony_ci // we must return out_of_memory here 723370b324cSopenharmony_ci return E_OUTOFMEMORY; 724370b324cSopenharmony_ci } 725370b324cSopenharmony_ci // _inStream = stream; 726370b324cSopenharmony_ci #ifndef Z7_SFX 727370b324cSopenharmony_ci FillPopIDs(); 728370b324cSopenharmony_ci #endif 729370b324cSopenharmony_ci return S_OK; 730370b324cSopenharmony_ci COM_TRY_END 731370b324cSopenharmony_ci} 732370b324cSopenharmony_ci 733370b324cSopenharmony_ciZ7_COM7F_IMF(CHandler::Close()) 734370b324cSopenharmony_ci{ 735370b324cSopenharmony_ci COM_TRY_BEGIN 736370b324cSopenharmony_ci _inStream.Release(); 737370b324cSopenharmony_ci _db.Clear(); 738370b324cSopenharmony_ci #ifndef Z7_NO_CRYPTO 739370b324cSopenharmony_ci _isEncrypted = false; 740370b324cSopenharmony_ci _passwordIsDefined = false; 741370b324cSopenharmony_ci _password.Wipe_and_Empty(); 742370b324cSopenharmony_ci #endif 743370b324cSopenharmony_ci return S_OK; 744370b324cSopenharmony_ci COM_TRY_END 745370b324cSopenharmony_ci} 746370b324cSopenharmony_ci 747370b324cSopenharmony_ci#ifdef Z7_7Z_SET_PROPERTIES 748370b324cSopenharmony_ci#ifdef Z7_EXTRACT_ONLY 749370b324cSopenharmony_ci 750370b324cSopenharmony_ciZ7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) 751370b324cSopenharmony_ci{ 752370b324cSopenharmony_ci COM_TRY_BEGIN 753370b324cSopenharmony_ci 754370b324cSopenharmony_ci InitCommon(); 755370b324cSopenharmony_ci _useMultiThreadMixer = true; 756370b324cSopenharmony_ci 757370b324cSopenharmony_ci for (UInt32 i = 0; i < numProps; i++) 758370b324cSopenharmony_ci { 759370b324cSopenharmony_ci UString name = names[i]; 760370b324cSopenharmony_ci name.MakeLower_Ascii(); 761370b324cSopenharmony_ci if (name.IsEmpty()) 762370b324cSopenharmony_ci return E_INVALIDARG; 763370b324cSopenharmony_ci const PROPVARIANT &value = values[i]; 764370b324cSopenharmony_ci UInt32 number; 765370b324cSopenharmony_ci const unsigned index = ParseStringToUInt32(name, number); 766370b324cSopenharmony_ci if (index == 0) 767370b324cSopenharmony_ci { 768370b324cSopenharmony_ci if (name.IsEqualTo("mtf")) 769370b324cSopenharmony_ci { 770370b324cSopenharmony_ci RINOK(PROPVARIANT_to_bool(value, _useMultiThreadMixer)) 771370b324cSopenharmony_ci continue; 772370b324cSopenharmony_ci } 773370b324cSopenharmony_ci { 774370b324cSopenharmony_ci HRESULT hres; 775370b324cSopenharmony_ci if (SetCommonProperty(name, value, hres)) 776370b324cSopenharmony_ci { 777370b324cSopenharmony_ci RINOK(hres) 778370b324cSopenharmony_ci continue; 779370b324cSopenharmony_ci } 780370b324cSopenharmony_ci } 781370b324cSopenharmony_ci return E_INVALIDARG; 782370b324cSopenharmony_ci } 783370b324cSopenharmony_ci } 784370b324cSopenharmony_ci return S_OK; 785370b324cSopenharmony_ci COM_TRY_END 786370b324cSopenharmony_ci} 787370b324cSopenharmony_ci 788370b324cSopenharmony_ci#endif 789370b324cSopenharmony_ci#endif 790370b324cSopenharmony_ci 791370b324cSopenharmony_ciIMPL_ISetCompressCodecsInfo 792370b324cSopenharmony_ci 793370b324cSopenharmony_ci}} 794